Skip to content

Add boolean-fragment UNREALIZABLE pre-check via BDD - #14

Merged
gaperez64 merged 2 commits into
mainfrom
tlsf-unreal-precheck
Jun 25, 2026
Merged

Add boolean-fragment UNREALIZABLE pre-check via BDD#14
gaperez64 merged 2 commits into
mainfrom
tlsf-unreal-precheck

Conversation

@gaperez64

Copy link
Copy Markdown
Owner

Implements a fast, sound structural pre-check for unrealizability that runs before the main synthesis pipeline. This catches trivially unrealizable specs where the controller has no influence over a boolean guarantee.

Summary

Adds precheck_trivially_unreal(), a TRUST_OVER (over-approximation) pre-check that proves unrealizability by analyzing the propositional safety fragment of the expanded cover. It uses BDDs to test whether the environment has a winning one-step strategy: an input assignment that satisfies all boolean assumptions while making all boolean guarantees false.

Key Changes

  • New module src/precheck_unreal.c / include/tlsf/precheck_unreal.h: Implements the boolean-fragment UNREALIZABLE pre-check using OxiDD BDDs. The check:

    • Extracts step-0 boolean bodies from constraints (propositional formulas and G(boolean) patterns)
    • Bails on any temporal assumption (to avoid false positives)
    • Ignores temporal guarantees (safe weakening)
    • Computes EnvWin = ¬∃outputs. ¬(A ∧ ¬G) where A is the assumption conjunction and G is the guarantee conjunction
    • Returns true only if the environment has a winning input
  • Integration into src/main_tlsfcompose.c: Calls the pre-check immediately after cover expansion, before the expensive recognize/certify/residual stages. Matches ltlsynt's fast-path behavior for input-only guarantees.

  • Test cases: Four new TLSF specs validating the pre-check:

    • precheck_input_only.tlsf: Input-only guarantee (must fire)
    • precheck_outputs_rescue.tlsf: Output can satisfy guarantee (must not fire)
    • precheck_assume_rescues.tlsf: Assumption forces input (must not fire, spec is REALIZABLE)
    • precheck_temporal_assume_bail.tlsf: Temporal assumption present (must bail, downstream ltlsynt decides)
  • Build integration: Added src/precheck_unreal.c to the tlsfcompose target in meson.build

  • Documentation updates: Clarified benchmark scripts and README to reflect removal of syfco baseline comparisons; marked structural census plots as stale

Verdict Trust Model

The pre-check is an OVER-approximation that refutes a weakening of the spec:

  • Keeps every assumption (no false negatives from dropped assumptions)
  • Drops only temporal guarantees (safe weakening)
  • Bails on temporal assumptions (strict superset of liveness-assumption concern)

Therefore: UNREALIZABLE verdict is sound and trustworthy; it never claims REALIZABLE.

https://claude.ai/code/session_01KvbjHkBHLYwxrFrvHae2xV

gaperez64 and others added 2 commits June 25, 2026 11:21
Add a fast, sound structural pre-check for trivially unrealizable specs at
the TLSF level (the analog of ltlsynt's try_create_direct_strategy
input-only-G shortcut; acacia-bonsai issue #109's idea, here over OxiDD).

It runs right after cover_build (whole-spec, pre-cluster) and decides UNREAL
via a one-step environment win over the propositional fragment:

  G = conj of step-0 boolean guarantee bodies
  A = conj of step-0 boolean assumption bodies
  EnvWin = NOT exists outputs. NOT(A and NOT G)   ->  UNREAL iff EnvWin != empty

Catches input-only-G (Light/Warnlight), output-can't-rescue, and UNSAT
guarantees (G(o) and G(!o)).

Verdict-trust class TRUST_OVER (new enum value): it refutes a *weakening* of
the spec (drops temporal guarantees, keeps every assumption, bails on any
temporal assumption), so its UNREALIZABLE is trustworthy, it never claims
REALIZABLE, and it needs no re-validation -- the temporal-assumption bail is a
strict superset of the cover_has_liveness_assumption UNREAL-trust concern.
Surfaced under --route-stats as unreal_precheck=1.

Tests (all OxiDD-gated; soundness guards): fires on input-only without
ltlsynt, route-stats counter, output-rescue and assume-rescue stay silent
(false-UNREAL guards), temporal-assume bails to the downstream path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KvbjHkBHLYwxrFrvHae2xV
README: remove the syfco comparison/benchmarking references (the tlsf2ltl-vs-syfco
perf claim, the check-against-syfco command, the syfco-style descriptive notes);
keep only the canonical TLSF-format link. Drop the Limitations section.

Make the scripts syfco-free: bench/bench.sh loses the syfco comparison columns
but keeps the self-regression guard (--baseline/--check); benchgraph.py drops the
syfco baseline mode and resolves the standalone-ltlsynt baseline to the
tlsf-tools translation.

benchgraph plots: only the head-to-head survival plot is current. Delete the 7
structural-census plots (built from tlsf-selection-2026 / tlsf-fin-selection-2026
+ build-release-local, all no longer present) and mark scripts/benchgraph_plots.py
stale; add a STALE banner to the BENCHGRAPH.md structural section (prose kept for
design rationale, dead embeds removed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KvbjHkBHLYwxrFrvHae2xV
@gaperez64
gaperez64 merged commit be6313b into main Jun 25, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant