Dane Sabo cebf8c167a Initial umbrella repo: thesis + FRET pipeline + plant model with first controllers
Folds three previously-separate pieces into one preliminary-example repo
for the HAHACS thesis:

- thesis/ (submodule) → gitea Thesis.git — the PhD proposal
- fret-pipeline/ — FRET requirements to AIGER controller (was
  ~/Documents/fret_processing/; prior single-commit history abandoned
  per user decision)
- plant-model/ — 10-state PKE + lumped T/H PWR model (was
  ~/Documents/PKE_Playground/; never version-controlled before)
- presentations/2026DICE/ (submodule) → gitea 2026DICE.git
- reachability/, hardware/ — empty placeholders for Thrust 3 and HIL
- docs/architecture.md — how the discrete and continuous layers compose
- claude_memory/ — session notes and scratch knowledge pattern

Plant model refactored to thesis naming (x, plant, u, ref); pke_th_rhs
now takes u as an explicit arg instead of reading rho_ext from the
params struct. First two controllers built to the contract
u = ctrl_<mode>(t, x, plant, ref): ctrl_null (baseline) and
ctrl_operation (stabilizing, proportional on T_avg). Validated under a
100% -> 80% Q_sg step: ctrl_operation reduces steady-state T_avg drift
~47% vs. the unforced plant.

Root CLAUDE.md emphasizes that CLAUDE.md files are living documents and
that any knowledge not captured before a session ends is lost forever;
claude_memory/ holds the session-level notes that haven't stabilized
enough to graduate into a CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 16:24:11 -04:00

100 lines
4.4 KiB
Markdown

# CLAUDE.md
Guidance for Claude Code (claude.ai/code) working in this subdirectory.
## What this is
A deterministic pipeline that converts FRET natural-language requirements into
a reactive controller and a state-machine diagram. Implements Thrust 1 + 2 of
the HAHACS methodology (`../thesis/3-research-approach/approach.tex`).
The pipeline is four stages:
```
FRET JSON --> fret_to_synth.py --> synthesis config JSON
synthesis config --> synthesize.sh --> AIGER circuit (.aag)
AIGER circuit --> trace_aiger.py --> DOT + PNG + SVG state machine
AIGER circuit --> aag2dot.py --> gate-level circuit diagram
```
## Running
```bash
python3 scripts/fret_to_synth.py pwr_hybrid_3.json specs/synthesis_config_v3.json
bash scripts/synthesize.sh specs/synthesis_config_v3.json circuits
python3 scripts/trace_aiger.py circuits/PWR_HYBRID_3_DRC.aag diagrams
dot -Tpng diagrams/PWR_HYBRID_3_DRC_states.dot -o diagrams/PWR_HYBRID_3_DRC_states.png
```
All scripts are pure Python 3 stdlib + bash. External binaries required:
- `ltlsynt` (Spot) — `brew install spot`
- `dot` (Graphviz) — `brew install graphviz`
## Architecture
**`scripts/fret_to_synth.py`** — Auto-discovers mode groups by regex-scanning
LTL formulas for `(control_X = q_Y)` patterns. Decomposes multi-valued mode
variables into independent booleans and generates mutual-exclusion constraints
so the synthesizer can't assert two modes simultaneously. Classifies every
other variable as an environment input. See `docs/fret_to_synth.md`.
**`scripts/synthesize.sh`** — Thin wrapper around `ltlsynt` that reads the
synthesis config, extracts inputs/outputs/formula, and calls ltlsynt with
AIGER output. Strips the `REALIZABLE` header line from the output. See
`docs/synthesize.md`.
**`scripts/trace_aiger.py`** — Exhaustive circuit evaluation: enumerates all
reachable latch states, extracts guard conditions on transitions via boolean
function simplification, emits DOT. See `docs/trace_aiger.md`.
**`scripts/aag2dot.py`** — Gate-level diagram of the AIGER circuit (wires,
AND gates, latches). Useful for debugging unexpectedly large circuits. See
`docs/aag2dot.md`.
## Key design decisions
- **Mode decomposition with mutex constraint.** FRET's `control_mode = q_X`
is a single integer variable that inherently holds one value. ltlsynt works
over independent booleans. So we decompose into `in_mode_shutdown`,
`in_mode_heatup`, etc., and add a "G(exactly one active)" constraint. The
mutex is a *synthesis encoding artifact*, not a missing FRET requirement.
- **Prefer `ftInfAUExpanded` over `ft`.** FRET emits multiple LTL forms; we
use the expanded infinite-horizon form because ltlsynt works over infinite
traces. The `ft` form can contain LAST operators that bias toward finite
traces.
- **Regex-based mode discovery.** Fully automatic — no hardcoded variable
lists. Add a new mode in FRET and re-export; the script picks it up.
- **Strict sanity check.** If any `control_` or `q_` token survives the
boolean encoding, the script errors out rather than producing silent bugs.
## FRET naming conventions
Enforced by `fret_to_synth.py`. See `README.md` for the full rules.
- Mode variables: `control_<group>` with values `q_<value>`.
Decomposed to `in_<group_suffix>_<value_suffix>`.
- Environment inputs: anything else. Assumed boolean; continuous quantities
should be abstracted to predicates at the FRET level
(e.g., `t_avg_above_min`).
## Extending
- **New requirement.** Add it in FRET, re-export JSON, re-run the pipeline.
No code changes needed as long as the new variables follow the naming rule.
- **New mode group.** Same as above — `fret_to_synth.py` auto-discovers.
- **Unrealizable spec.** Use FRET's realizability checking first to isolate
the conflicting requirement. `synthesize.sh` will print `UNREALIZABLE` if
the full spec is inconsistent.
- **Output format.** Current targets are DOT and AIGER. Translating AIGER to
Stateflow is the next planned extension (see parent `CLAUDE.md` — this is
flagged as the known pain point in the thesis workflow).
## Conventions in this subtree
- Scripts are self-contained and take explicit I/O paths as args — no global
config file, no env vars.
- Generated artifacts live in `circuits/`, `diagrams/`, and `specs/`. Treat
them as derived; regenerate rather than hand-edit.
- `pwr_hybrid_3.json` is the source of truth. Never hand-edit the generated
`synthesis_config_v3.json`.