# synthesize.sh -- ltlsynt Reactive Synthesis Wrapper ## Purpose Reads a synthesis configuration JSON and invokes `ltlsynt` (from the Spot library) to produce a reactive controller as an AIGER circuit. This is the step where temporal logic specifications become a concrete implementation. ## Usage ```bash bash scripts/synthesize.sh [output_dir] ``` - `synthesis_config.json`: output of `fret_to_synth.py` - `output_dir`: where to write the `.aag` file (default: `circuits/`) ## How It Works ### Parameter Extraction A small inline Python script reads the JSON config and extracts: - `INPUTS`: comma-separated list of environment variables (uncontrollable) - `OUTPUTS`: comma-separated list of system variables (controllable) - `LTL_FORMULA`: the conjoined LTL specification - `SPEC_NAME`: used for the output filename ### The ltlsynt Call ```bash ltlsynt -f "$LTL_FORMULA" \ --ins="$INPUTS" \ --outs="$OUTPUTS" \ --aiger=both+ud+dc \ --simplify=bwoa-sat ``` **Flags explained:** | Flag | Meaning | |---|---| | `-f` | LTL formula (the specification) | | `--ins` | Input (environment/uncontrollable) propositions | | `--outs` | Output (system/controllable) propositions | | `--aiger=both+ud+dc` | Output as ASCII AIGER with both latches and gates, using unit delays and don't-cares for optimization | | `--simplify=bwoa-sat` | Best simplification: bounded width with SAT-based optimization. Produces the smallest circuit | ### The Two-Player Game Reactive synthesis frames controller design as a two-player game: - **Player 1 (Environment)**: controls the `--ins` variables. Assumed to be adversarial -- the synthesizer must find a strategy that wins against ALL possible environment behaviors, including worst-case. - **Player 2 (Controller)**: controls the `--outs` variables. The synthesizer searches for a strategy (a Mealy machine) such that no matter what Player 1 does, the LTL specification is satisfied. **Why adversarial?** Because we need a controller that works in ALL operating conditions, not just typical ones. If the environment CAN violate a safety invariant, the synthesizer assumes it WILL, and the controller must handle it. This is why the old PWR_Hybrid specs produced a degenerate controller: the environment could force `t_max_exceeded` every step, triggering irrecoverable SCRAM. The only winning strategy was to SCRAM immediately. The new specs have proper guard conditions that give the controller legal responses to every environment move. ### Realizability ltlsynt outputs one of two results: - **REALIZABLE**: A winning strategy exists. The AIGER circuit is printed after the `REALIZABLE` line. The script strips this line and writes the circuit to `{output_dir}/{spec_name}.aag`. - **UNREALIZABLE**: No controller can satisfy the specification against all possible environment behaviors. This means the specs have a fundamental conflict. Use FRET's realizability checking and counterexample traces to diagnose which requirements conflict. ### Output: AIGER Format The `.aag` (ASCII AIGER) file is a text-based hardware description: ``` aag M I L O A Header: Max-var, Inputs, Latches, Outputs, ANDs One per line, even numbers (2, 4, 6, ...) current_lit next_lit (state registers) Which literals are outputs lhs rhs0 rhs1 (lhs = rhs0 AND rhs1) i0 name, o0 name, etc. ``` **Literal encoding:** Variable `n` has literal `2n` (positive) and `2n+1` (negated). Literal `0` = constant FALSE, literal `1` = constant TRUE. XOR-ing a literal with 1 flips its polarity. **Latches** are 1-bit registers that initialize to 0. With `L` latches, the controller has up to `2^L` internal states. The circuit is a Mealy machine: outputs depend on both current state (latches) and current inputs. ## Future Improvements - **Environment assumptions**: ltlsynt supports `--from-ltlf` for finite traces and can separate assumptions from guarantees. Adding support for environment assumptions (e.g., fairness constraints like "the environment won't hold t_max_exceeded forever") would expand the class of realizable specifications. - **Decomposed synthesis**: For large specs, monolithic synthesis can be expensive. Compositional synthesis (synthesizing each mode's controller separately and composing them) could improve scalability. - **Alternative output formats**: The AIGER circuit could be translated to Verilog, VHDL, or Simulink/Stateflow for integration with existing control system toolchains. - **Timeout handling**: Currently no timeout on the ltlsynt call. Very complex specifications can take hours. Adding a configurable timeout with a clear error message would improve usability.