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>
This commit is contained in:
Dane Sabo 2026-04-16 16:24:11 -04:00
commit cebf8c167a
83 changed files with 16293 additions and 0 deletions

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
.DS_Store
__pycache__/
*.pyc
.claude/
# LaTeX build artifacts (for anything built in-tree; thesis submodule handles its own)
*.aux
*.log
*.fls
*.fdb_latexmk
*.toc
*.bbl
*.blg
*.out
*.synctex.gz
# MATLAB/Octave
*.asv
*.autosave
octave-workspace
# editor scratch
*.swp
*~

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "thesis"]
path = thesis
url = ssh://git@gitea.danesabo.com:1738/danesabo/Thesis.git
[submodule "presentations/2026DICE"]
path = presentations/2026DICE
url = ssh://git@gitea.danesabo.com:1738/danesabo/2026DICE.git

109
CLAUDE.md Normal file
View File

@ -0,0 +1,109 @@
# CLAUDE.md
Guidance for Claude Code (and any AI agent) working in this repository.
## Living documentation — update these files
**`CLAUDE.md` files are living.** This one and the ones in subdirectories.
When you learn something new about the system that a future agent would
benefit from, update the appropriate `CLAUDE.md` before the session ends.
**Context that exits a session uncaptured is lost forever** — treat this as
the single most important rule in this repo.
**Where to write:**
- Stable, authoritative knowledge (architecture, conventions, interfaces,
design decisions) → the relevant `CLAUDE.md`. Root for cross-cutting;
subdirectory for layer-specific.
- Session-level findings, in-progress investigations, paths that didn't pan
out → `claude_memory/YYYY-MM-DD-topic.md`. See `claude_memory/README.md`
for the pattern.
**When to write:**
- After a non-trivial debugging session (what broke, root cause, how you knew).
- After an architectural or structural decision (what we chose, what we
rejected, why).
- After discovering a non-obvious fact (subtle constraint, undocumented tool
behavior, counterintuitive data format).
- Before ending a session where you explored paths that didn't pan out — so
the next agent doesn't waste effort redoing them.
Over time, session notes that stabilize get distilled up into the relevant
`CLAUDE.md`; the rest get archived or deleted. This is a discipline, not
automation — do the graduation explicitly when knowledge becomes authoritative.
## What this is
The preliminary example for the HAHACS thesis — a PWR startup controller
demonstrating the full pipeline from written operating procedures to verified
hybrid controller. This repo composes three layers of the same story:
| Layer | Location | Role | Thesis mapping |
|---|---|---|---|
| Story | `thesis/` (submodule) | The PhD proposal: math, prose, claims | Motivates and defines the methodology |
| Discrete | `fret-pipeline/` | FRET requirements → LTL → ltlsynt → AIGER circuit → state machine | Implements Thrust 1 + 2 |
| Continuous | `plant-model/` | 10-state PKE + thermal-hydraulics PWR model (MATLAB/Octave) | Plant for Thrust 3 (reachability / barrier certs) |
| Verification | `reachability/` | Continuous-mode verification artifacts | Thrust 3 output — currently empty |
| Hardware | `hardware/` | Ovation HIL artifacts | Integration milestone — currently empty |
| Deliverables | `presentations/` | Conference papers and talks (submodules) | Dissemination |
Running example: the `PWR_HYBRID_3` controller. The discrete automaton it
synthesizes is literally the state machine drawn in `thesis/3-research-approach/approach.tex`
Figure 1 (Cold Shutdown → Heatup → Power Operation, with SCRAM).
## How changes flow
1. **Requirement change.** Edit the FRET export (`fret-pipeline/pwr_hybrid_3.json`)
→ run `fret-pipeline/scripts/fret_to_synth.py` → re-synthesize via
`synthesize.sh` → re-trace via `trace_aiger.py`. New `.svg` / `.dot` /
`.png` land in `fret-pipeline/diagrams/`. Copy the figure you want to cite
into `docs/figures/` so the thesis can pick it up.
2. **Plant change.** Edit `plant-model/pke_params.m` or dynamics in
`pke_th_rhs.m` → re-run `main.m` to verify behavior. Steady-state values
feed the `T_avg`, `P_crit` thresholds in the FRET requirements — if you
change them here, check the requirement predicates match.
3. **Verification work.** Continuous-mode verification (reachability, barrier
certificates) reads the guards from `fret-pipeline/specs/synthesis_config_v3.json`
and the dynamics from `plant-model/pke_th_rhs.m`. Results go in `reachability/`.
4. **Thesis edit.** `cd thesis && <edit> && git commit && git push origin main`,
then from the umbrella root: `git add thesis && git commit` to bump the
submodule pointer.
## Where to look for what
- Reactor physics, steady-state, ODE dynamics → `plant-model/`
- Controller synthesis, requirements, state machines → `fret-pipeline/`
- Research narrative, math, claims, citations → `thesis/`
- Shared figures (for the thesis or talks) → `docs/figures/`
- How the layers compose → `docs/architecture.md`
## Submodule rituals
- Fresh clone: `git clone <url> && git submodule update --init --recursive`
(or `git clone --recurse-submodules <url>`). Without this, `thesis/` and
`presentations/2026DICE/` are empty directories.
- Editing the thesis: `cd thesis && git checkout main` first — submodules
default to detached HEAD. Then edit, commit, push inside the submodule,
then `cd ..` and commit the new submodule pointer in the umbrella.
- Pulling upstream thesis changes: `cd thesis && git pull origin main`, then
commit the new pointer in the umbrella.
## Conventions
- FRET variables: `control_<group> = q_<value>` for modes; everything else is
an environment input. See `fret-pipeline/README.md` for the full naming rule.
- Plant model units: internal SI (W, kg, °C); printed/plotted in °F.
- Continuous state vector: `y = [n; C1..C6; T_f; T_c; T_cold]`. Guards in
FRET should reference the algebraic outputs (`T_hot`, `T_avg`) or direct
states, not derived quantities.
- `Q_sg(t)` is the bounded disturbance — never treat `T_cold` as an input.
## What's deliberately missing (so you don't go looking)
- LTL-to-Stateflow translator — there's a known pain point in the thesis
workflow where AIGER circuits still need to become Stateflow. Not yet
automated. Current path: generate AIGER → eyeball the state machine
diagram → hand-translate to Stateflow. Roadmapped.
- Hardware bring-up (Ovation DCS) — scheduled for the integration thrust.
`hardware/` is a placeholder.
- Continuous-mode verification — `reachability/` is empty. Choice of tool
(CORA / Flow* / SpaceEx / JuliaReach) still pending.

71
README.md Normal file
View File

@ -0,0 +1,71 @@
# pwr-hybrid-3-demo
Preliminary example for the HAHACS thesis — a verified hybrid controller for
a small modular PWR startup. Composes three layers into one demonstrable
pipeline:
- **Discrete layer** (`fret-pipeline/`): FRET natural-language requirements
→ LTL → synthesized AIGER controller → state-machine diagram.
- **Continuous layer** (`plant-model/`): 10-state point kinetic equation +
thermal-hydraulics PWR model with bounded steam-generator heat removal as
the disturbance input.
- **Research context** (`thesis/`): the HAHACS PhD proposal that motivates
and formalizes the methodology.
## Layout
```
pwr-hybrid-3-demo/
CLAUDE.md AI-facing context and architecture map
docs/
architecture.md How the discrete and continuous layers compose
figures/ Shared figures for thesis + talks
fret-pipeline/ FRET → ltlsynt → AIGER → state machine
plant-model/ PWR point kinetics + thermal-hydraulics
reachability/ Continuous-mode verification (TBD)
hardware/ Ovation HIL artifacts (TBD)
thesis/ [submodule] PhD proposal
presentations/
2026DICE/ [submodule] DICE 2026 abstract
```
## Quickstart
Clone with submodules:
```bash
git clone --recurse-submodules <url>
cd pwr-hybrid-3-demo
```
Run the controller synthesis pipeline:
```bash
cd fret-pipeline
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
```
Run the plant model (MATLAB or GNU Octave in `plant-model/`):
```matlab
main
```
## Prerequisites
- Python 3.10+
- [Spot](https://spot.lre.epita.fr/) for `ltlsynt` (`brew install spot`)
- [Graphviz](https://graphviz.org/) for `dot` (`brew install graphviz`)
- MATLAB or GNU Octave for the plant model
- LaTeX (via `latexmk`) for the thesis submodule
## Further reading
- `CLAUDE.md` — orientation for AI agents working in this repo
- `docs/architecture.md` — how the layers compose
- `thesis/CLAUDE.md` — the thesis project structure
- `fret-pipeline/README.md` — FRET naming conventions and pipeline details
- `plant-model/README.md` — scenario setup and model equations

View File

@ -0,0 +1,112 @@
# 2026-04-16 — controllers scaffold and ctrl_operation rough-out
First continuous controller. Established the controller contract, refactored
the plant to thesis naming, and got a closed-loop sim running end-to-end
with a meaningful comparison against the unforced baseline.
## Naming convention (locked in)
Thesis-aligned. Applied to plant and controllers:
- `t` — time
- `x` — continuous state vector `[n; C1..C6; T_f; T_c; T_cold]`
- `plant` — params struct (was `p`; renamed to avoid collision with `p_i`
predicates from the thesis)
- `u` — control input: external rod reactivity (scalar, `dk/k`)
- `ref` — reference/setpoint struct (e.g. `ref.T_avg`)
- `Q_sg` — bounded disturbance (SG heat removal, `W`), a function handle
of time
Captured in `plant-model/CLAUDE.md` under "Naming convention" — any future
file in `plant-model/` or `controllers/` uses these names.
## Controller contract
```matlab
u = ctrl_<mode>(t, x, plant, ref)
```
Pure function. Returns scalar `u`. All four args required even if unused
(so `pke_solver` can swap controllers by function handle without branching).
## Plant refactor
Four files touched. Non-cosmetic changes:
- `pke_th_rhs.m` now takes `u` as an **explicit argument** instead of
reading `p.rho_ext(t)` from the params struct. This decouples plant from
controller and matches the thesis's `f(x, u)` form. Old `rho_ext` field
on the params struct is gone.
- `pke_solver.m` signature changed:
`[t, X, U] = pke_solver(plant, Q_sg, ctrl_fn, ref, tspan)`.
Returns `U` (the control trajectory), reconstructed post-hoc by
re-evaluating `ctrl_fn` at each returned time step.
- `plot_pke_results.m` takes `(t, X, U, plant, Q_sg, title)` — reactivity
panel now shows `u`, feedback, and total separately rather than relying on
a `p.rho_ext` handle.
- `pke_initial_conditions.m` trivial rename `p → plant`, output `x0`.
## ctrl_operation
Proportional-only for now. `Kp = 1e-4 /K`, chosen to roughly double the
effective moderator coefficient (`alpha_c ≈ -1e-4 /K`). Not tuned for
precision — this is rough-out. PI upgrade would require augmenting state
with integral error; deferred until we actually need tighter tracking.
**Validation run** (100% → 80% Q_sg step at t=30s, 600s horizon):
| Metric | ctrl_null | ctrl_operation |
|---|---|---|
| Final T_avg drift from setpoint | +1.5 °F | +0.8 °F |
| Final `u` | 0 $ | -0.0068 $ |
| Final power | 800 MW ✓ | 800 MW ✓ |
Sign polarity: T_avg > ref → e < 0 u < 0 (rods in). Correct for a PWR.
Controller reduces steady-state offset by ~47%. Expected result — gain is
modest; the point is the plumbing works, not that the tuning is final.
## What's deferred (on purpose)
- **Integral action in ctrl_operation.** P-only for now. If we want to hit
`ref.T_avg` exactly (zero steady-state error), augment state with
`int_e` and upgrade to PI.
- **Gain config.** Gains hardcoded in the controller file. Fine for one
mode; once we tune 34 modes we should lift to a `ctrl_params.m` or
similar.
- **Mode dispatcher.** No `ctrl_dispatch.m` yet because there's only one
real controller. Will introduce when we add the second mode and need to
switch based on discrete state.
- **ctrl_heatup, ctrl_scram, ctrl_shutdown.** Next. Each is a separate
design problem with its own verification method (reachability, parametric
reach, trivial).
- **Invariants and `X_safe` regions.** User explicitly said: rough out
controllers first, then come back to invariants. Per the thesis, we're
not trying to verify the whole hybrid system at once — one mode's reach
set at a time.
## Things worth remembering
- `addpath('controllers')` is required in `main.m` — MATLAB won't find
`@ctrl_operation` otherwise. Putting controllers in a subfolder is
ergonomically clean but the path has to be set.
- `U` is reconstructed post-hoc in `pke_solver`. If a future controller
has hysteresis or switching behavior, this reconstruction may not match
the ODE's internal trajectory (the solver might have evaluated `ctrl_fn`
at interior points that don't appear in the returned `t`). For smooth
controllers (P, PI) this is fine; for event-driven / hybrid controllers
we'll need to log `u` during the solve instead.
- MATLAB `-batch` mode runs `main.m` cleanly without a display — figures
are created off-screen but the script completes. Good for CI or sanity
checks without opening the IDE.
- `T_avg` is literally `T_c` in the state vector (`x(9)`). Don't let the
two names confuse future debugging — `T_avg` is the nuclear-industry term,
`T_c` is the code variable, they're the same quantity.
## Paths touched
- Modified: `plant-model/pke_th_rhs.m`, `pke_solver.m`,
`pke_initial_conditions.m`, `plot_pke_results.m`, `main.m`, `README.md`,
`CLAUDE.md`
- Created: `plant-model/controllers/ctrl_null.m`,
`plant-model/controllers/ctrl_operation.m`
- Nothing outside `plant-model/` was touched this session.

View File

@ -0,0 +1,94 @@
# 2026-04-16 — repo restructure
Folded three previously-separate pieces into this umbrella repo. Created the
initial layout, the root `CLAUDE.md`, `README.md`, `docs/architecture.md`,
and `fret-pipeline/CLAUDE.md`.
## What we did
- Created `~/Documents/pwr-hybrid-3-demo/` as the umbrella repo (`git init`,
`main` branch, not yet pushed to any remote).
- Copied `~/Documents/fret_processing/``fret-pipeline/` via `rsync`
excluding `.git`, `.DS_Store`, `.claude`, `__pycache__`. **Git history
abandoned by explicit user decision** — the old single-commit history did
not carry forward.
- Copied `~/Documents/PKE_Playground/``plant-model/` via `rsync`. Never
was a git repo; nothing to abandon.
- Added `thesis/` as a submodule pointing at
`ssh://git@gitea.danesabo.com:1738/danesabo/Thesis.git` (also has GitHub
mirror at `namelessfaceless/dissertation`).
- Added `presentations/2026DICE/` as a submodule pointing at
`ssh://git@gitea.danesabo.com:1738/danesabo/2026DICE.git`.
- Created empty placeholders: `reachability/`, `hardware/`, `docs/figures/`.
## What we decided and why
- **Monorepo with thesis as a submodule, not the reverse.** Code iterates
daily, thesis weekly. A slow parent with fast children is painful; a fast
parent pointing at a slow submodule matches the actual cadence. Also
preserves the thesis's independent git history for advisor/committee use.
- **Copy, not move.** Old `~/Documents/fret_processing/` and
`~/Documents/PKE_Playground/` still exist. User will delete them later;
this gives a safe rollback window.
- **Folder renames:** `fret_processing``fret-pipeline` (more accurate —
it's a pipeline, not a processing step), `PKE_Playground``plant-model`
(describes function not content). Both switched to hyphens for consistency.
- **No `git init` on `PKE_Playground` before the move** — user said to skip
it and fold in clean.
- **Used `git submodule add`, not `git subtree`.** Submodule pain
acknowledged (detached HEAD, two-step commits, `--recurse-submodules` on
clone) but accepted in exchange for preserving the thesis's independent
git life. Revisit if pain outweighs benefit.
## Things that surprised us / are worth remembering
- The thesis's Figure 1 (Cold Shutdown → Heatup → Power Operation + SCRAM)
and the `fret-pipeline/` running example `PWR_HYBRID_3` are the same
automaton. This is the integration point — the figure should eventually
be swapped from hand-drawn TikZ to `\includegraphics` of a generated
state-machine PNG.
- The plant model's state vector `[n; C1..C6; T_f; T_c; T_cold]` exposes
exactly the quantities the FRET predicates reference (`T_avg = T_c`,
`T_hot = 2*T_c - T_cold`). The two layers are already semantically
aligned; nobody wired them because they were in different folders.
- `Q_sg(t)` is the physical input, not `T_cold`. Cold leg temperature is a
dynamic state that *results from* SG heat removal. This matters for the
reachability/barrier-cert formulation where `Q_sg ∈ [Q_min, Q_max]` is
the bounded disturbance.
- `fret_to_synth.py` adds a mutual-exclusion LTL constraint because
decomposing `control_mode = q_X` into independent booleans lets the
synthesizer assert multiple modes simultaneously. **This is a synthesis
encoding artifact, not a missing FRET requirement.** Do not add it in
FRET.
## Open items (for future sessions)
- **`presentations/2026DICE/` submodule reflects gitea HEAD, not user's
local state.** The original `~/Documents/Writing/2026DICE/` had
uncommitted changes: `M DANE_SABO_ABSTRACT.pages` plus three untracked
PDFs (`DANE_SABO.pdf`, `DANE_SABO_ABSTRACT.pdf`, `DANE_SABO_ABSTRACT_V2.pdf`,
`DANE_SABO_ABSTRACT_V3.pdf`). If user wants these in the submodule, commit
from the original location, push to gitea, then from umbrella:
`cd presentations/2026DICE && git pull` and commit the new pointer.
- **Old folders not yet deleted.** `~/Documents/fret_processing/` and
`~/Documents/PKE_Playground/` still live at their old paths. Delete when
user confirms the umbrella is working.
- **No initial commit yet.** Everything is staged but uncommitted. User
wanted to review the four new docs before committing.
- **No remote yet.** Need to create `gitea.danesabo.com/danesabo/pwr-hybrid-3-demo`
and `git remote add origin` + push.
- **`fret-pipeline/README.md` still says `fret_processing/` in its directory
structure section.** Didn't update — it's a minor inconsistency but worth
fixing on the next pass.
- **No bridge between discrete and continuous layers yet.** The whole point
of the umbrella is to eventually wire them — `reachability/` is where
that work lands. Not started.
## Paths touched
- Created: `/Users/danesabo/Documents/pwr-hybrid-3-demo/` (entire tree)
- Untouched: `/Users/danesabo/Documents/fret_processing/`,
`/Users/danesabo/Documents/PKE_Playground/`,
`/Users/danesabo/Documents/Writing/Thesis/`,
`/Users/danesabo/Documents/Writing/2026DICE/` — all still present,
unchanged.

View File

@ -0,0 +1,53 @@
# 2026-04-16 — session wrap, switching to nvim
Short capstone note. The substantive work is captured in two earlier notes
from today:
- `2026-04-16-repo-restructure.md` — umbrella repo created, submodules wired,
CLAUDE.md / README / architecture docs written, claude_memory/ pattern
established.
- `2026-04-16-controllers-roughout.md` — plant refactored to thesis naming,
controller contract locked, `ctrl_null` and `ctrl_operation` built,
validated live in MATLAB (ctrl_operation cuts T_avg drift by ~47% under
a 100%→80% Q_sg step).
Both notes have the full paths-touched lists.
## Last-minute adds
- **MATLAB terminal invocation (from `plant-model/CLAUDE.md`):**
`matlab -nodesktop -nosplash -r "main"` — runs from the terminal, figures
open in their own windows, drops at `>>` prompt. Use `-batch "main"` for
headless CI-style checks (no figures shown), or `matlab -r "main" &` to
launch the full IDE backgrounded.
- **MATLAB version:** R2025b installed at
`/Applications/MATLAB_R2025b.app/bin/matlab`. Octave not installed.
- **One-time gotcha fixed at wrap:** my earlier Write of the thesis-aligned
`plant-model/CLAUDE.md` silently didn't persist (tool reported success
but the file held the pre-refactor content on re-Read). Rewrote it at
wrap time. If this recurs, verify with `Read` after any `Write` on an
existing file, not just trust the tool's success message.
## Repo state at wrap
- Initial commit made: see `git log --oneline` in
`~/Documents/pwr-hybrid-3-demo/`.
- Submodules at: `thesis/` @ gitea main tip, `presentations/2026DICE/` @
gitea main tip (note: original `~/Documents/Writing/2026DICE/` still has
uncommitted local edits that were NOT pulled into the submodule — user
was warned earlier and deferred).
- Old folders `~/Documents/fret_processing/` and
`~/Documents/PKE_Playground/` still exist untouched. Delete whenever
user is confident the umbrella is right.
- No remote yet for the umbrella repo. Will need to create
`gitea.danesabo.com/danesabo/pwr-hybrid-3-demo` and `git remote add origin`
+ push when user is ready.
## What's on deck (for the next session, whichever agent)
Per the controllers rough-out note: knock out `ctrl_shutdown` (one line),
`ctrl_scram` (a few lines + uncertainty later), then `ctrl_heatup` (the
interesting transitory one — ramp + temperature tracking). Invariants and
`X_safe` regions come after, explicitly deferred by the user. Do not try
to verify the whole hybrid system at once — pick one mode, discharge its
reach-set obligation, move on.

39
claude_memory/README.md Normal file
View File

@ -0,0 +1,39 @@
# claude_memory/
Session notes and scratch knowledge that hasn't (yet) earned a place in a
`CLAUDE.md`. **Anything that leaves a context window uncaptured is lost
forever** — this folder exists so session-level insight doesn't evaporate.
## Purpose
A Claude context window is finite. Anything an agent figures out in a session
that isn't written down is gone when the session ends. The curated
`CLAUDE.md` files hold stable, authoritative knowledge; this folder holds
everything else that's still worth remembering.
## Pattern
- One file per session with non-trivial insight.
- Filename: `YYYY-MM-DD-short-topic.md`. Date first so `ls` is chronological.
- Freeform. Rough edges encouraged. Don't polish — capture.
- At minimum, answer: *what did we do, what did we decide, what surprised
us, what's still open.*
- Cross-reference files you edited, alternatives you considered, dead-ends
you hit.
## What graduates vs. what stays
Three futures for a note in here:
1. **Graduates up** into a `CLAUDE.md` (or `docs/architecture.md`, or a
code comment) when the knowledge stabilizes and becomes authoritative.
After graduating, consider deleting the note or leaving it as historical
context.
2. **Stays here** as historical context — useful for "why did we do X last
month?" or "what have we already tried?"
3. **Gets deleted** when it's no longer relevant (a fixed bug, an abandoned
approach, a stale investigation).
The graduation step is a discipline, not automation. When you're finishing a
session and think "a future agent needs this to avoid re-discovering it,"
ask: is this stable enough for a `CLAUDE.md`, or is it still forming?

94
docs/architecture.md Normal file
View File

@ -0,0 +1,94 @@
# Architecture — how the layers compose
This is the integration guide. Each subdirectory has its own docs for internal
detail; this file explains the interfaces between them.
## The three layers of a hybrid controller
The HAHACS methodology (see `thesis/3-research-approach/approach.tex`) splits
verification into two decoupled problems:
1. **Discrete layer** — proves that mode switching is correct given guard
predicates on the continuous state. Handled by reactive synthesis of an
AIGER circuit from LTL specifications. Lives in `fret-pipeline/`.
2. **Continuous layer** — proves that each continuous controller (one per
discrete mode) satisfies its entry/exit/safety obligations. Handled by
reachability analysis (transitory modes) or barrier certificates
(stabilizing modes). Lives in `plant-model/` (dynamics) and `reachability/`
(verification, TBD).
The interface between them is a small set of predicates over the continuous
state: the guards `G` that transition between modes, and the invariants `Inv`
that the continuous mode must maintain.
## Interface: predicates bridging discrete and continuous
FRET variables of the form `control_<group> = q_<value>` define the discrete
state space. Everything else in the FRET export is treated as a boolean
environment input. Real plant quantities are continuous, so the boolean
environment inputs are *abstractions* of continuous predicates.
For the PWR_HYBRID_3 example, representative predicates:
| FRET input | Continuous predicate | Plant-model source |
|---|---|---|
| `t_avg_above_min` | `T_avg > T_min` (where `T_avg = T_c`) | `pke_th_rhs.m` state `T_c` |
| `t_max_exceeded` | `T_hot > T_max` (where `T_hot = 2*T_c - T_cold`) | algebraic output |
| `inv1_holds` | domain-specific safety invariant | combine from states |
| `manual_reset` | operator input | exogenous |
The continuous controller is responsible for driving `T_avg`, `T_hot`, `n`, etc.
so the predicates hold (or don't hold) at the right times. The discrete
controller is responsible for choosing the correct mode given the predicate
truth values.
## Data flow
```
Written procedure
|
v (manual encoding in FRET GUI)
FRET JSON export <---- fret-pipeline/pwr_hybrid_3.json
|
v (fret_to_synth.py)
Synthesis config JSON <---- fret-pipeline/specs/synthesis_config_v3.json
| (LTL + mode groups + mutex constraints + inputs/outputs)
|
v (synthesize.sh -> ltlsynt)
AIGER circuit <---- fret-pipeline/circuits/*.aag
|
v (trace_aiger.py)
State machine DOT/SVG/PNG <---- fret-pipeline/diagrams/*
|
v (eyeball / future automation)
Stateflow model <---- TBD; known pain point in workflow
Continuous side, in parallel:
plant-model/main.m defines Q_sg(t)
plant-model/pke_solver.m runs ode15s
plant-model/plot_pke_results.m visualizes
reachability/ (empty) will verify each
continuous mode against the guards from
synthesis_config_v3.json
```
## Current integration state
- Discrete synthesis: **works end-to-end.** `pwr_hybrid_3.json` synthesizes
to `PWR_HYBRID_3_DRC.aag` and traces to a state-machine diagram.
- Continuous simulation: **works end-to-end.** The PKE model runs
load-following transients driven by `Q_sg(t)`.
- Cross-layer check: **not yet wired.** Nothing currently proves that the
continuous dynamics in `plant-model/` satisfies the guards assumed by
`fret-pipeline/`. That is the next piece (`reachability/`).
- Thesis integration: **loose.** Thesis currently uses a hand-drawn TikZ
figure for the reactor automaton. Once the pipeline output stabilizes,
swap it for an `\includegraphics` of the generated `.png` from
`docs/figures/`.
## Open questions tracked elsewhere
The thesis CLAUDE.md enumerates open technical questions (numerical barriers,
timing verification, partial observability). When those get resolved in the
proposal, the implementation lands in this repo — usually as a new
subdirectory or as additions to an existing one.

View File

@ -0,0 +1,195 @@
#!/usr/bin/env python3
"""Abstract the LPC spec into boolean LTL for reactive synthesis.
The LPC spec uses real-valued variables (kias/kgs) and enumerated modes.
This script creates a boolean abstraction suitable for ltlsynt.
Speed regions (kias = kgs, so one variable):
A: speed <= 20 (hover zone)
B: 20 < speed <= 30
C: 30 < speed <= 40
D: 40 < speed <= 90
E: 90 < speed <= 100
F: speed > 100
Modes (lift_mode):
tb: thrust_borne
stb: semi_thrust_borne
swb: semi_wing_borne
wb: wing_borne
The environment controls speed (within adjacency constraints).
The controller chooses the mode.
"""
import json
from pathlib import Path
def build_lpc_spec():
regions = ['a', 'b', 'c', 'd', 'e', 'f']
modes = ['tb', 'stb', 'swb', 'wb']
# Helper: exactly one of a list is true
def exactly_one(vars):
# At least one
at_least = ' | '.join(vars)
# At most one (pairwise exclusion)
pairs = []
for i in range(len(vars)):
for j in range(i + 1, len(vars)):
pairs.append(f'(!{vars[i]} | !{vars[j]})')
at_most = ' & '.join(pairs)
return f'({at_least}) & {at_most}'
region_vars = [f'r_{r}' for r in regions]
mode_vars = [f'm_{m}' for m in modes]
# === ENVIRONMENT ASSUMPTIONS ===
assumptions = []
# Exactly one speed region (always)
assumptions.append(f'G({exactly_one(region_vars)})')
# Initial speed: region F (kias = 120 > 100)
assumptions.append('r_f')
# Speed adjacency: can only move to adjacent region per tick
# (from the derivative constraint: |delta kias| <= 10 per tick)
adjacency = {
'r_a': ['r_a', 'r_b'],
'r_b': ['r_a', 'r_b', 'r_c'],
'r_c': ['r_b', 'r_c', 'r_d'],
'r_d': ['r_c', 'r_d', 'r_e'],
'r_e': ['r_d', 'r_e', 'r_f'],
'r_f': ['r_e', 'r_f'],
}
for region, neighbors in adjacency.items():
next_options = ' | '.join(f'X({n})' for n in neighbors)
assumptions.append(f'G({region} -> ({next_options}))')
# hover_control_mode <=> speed <= 20 (region A)
# We absorb hover into r_a directly in the guarantees
# === CONTROLLER GUARANTEES ===
guarantees = []
# Exactly one mode (always)
guarantees.append(f'G({exactly_one(mode_vars)})')
# Initial mode: wing_borne (since kias = 120 >= 90)
# LPC_INIT_LIFT_MODE: lift_mode = wb <=> kias >= 90, and kias = 120
guarantees.append('m_wb')
# === MODE TRANSITIONS (from FRET requirements) ===
# LPC_WB_STAY_ON_NEXT: While wb & kias > 90 -> next wb
# kias > 90 means region E or F
guarantees.append('G((m_wb & (r_e | r_f)) -> X(m_wb))')
# LPC_WB_TO_SWB: Upon wb & kias <= 90 -> next swb
# kias <= 90 means region A-D
guarantees.append('G((m_wb & (r_a | r_b | r_c | r_d)) -> X(m_swb))')
# LPC_SWB_STAY_ON_NEXT: While swb & kias <= 100 & kias > 30 -> next swb
# 30 < kias <= 100 means region D or E
guarantees.append('G((m_swb & (r_d | r_e)) -> X(m_swb))')
# LPC_SWB_TO_WB: Upon swb & kias > 100 -> next wb
# kias > 100 means region F
guarantees.append('G((m_swb & r_f) -> X(m_wb))')
# LPC_SWB_TO_STB: Upon swb & kias <= 30 -> next stb
# kias <= 30 means region A or B
guarantees.append('G((m_swb & (r_a | r_b)) -> X(m_stb))')
# LPC_STB_STAY_ON_NEXT: While stb & kias <= 40 & (kgs > 20 | !hover)
# kias <= 40 means region A-C; kgs > 20 | !hover means NOT region A
# So: stb & (region B or C) -> next stb
guarantees.append('G((m_stb & (r_b | r_c)) -> X(m_stb))')
# LPC_STB_TO_SWB: Upon stb & kias > 40 -> next swb
# kias > 40 means region D-F
guarantees.append('G((m_stb & (r_d | r_e | r_f)) -> X(m_swb))')
# LPC_STB_TO_TB: Upon stb & hover & kgs <= 20 -> next tb
# hover & kgs <= 20 means region A
guarantees.append('G((m_stb & r_a) -> X(m_tb))')
# LPC_TB_STAY_ON_NEXT: While tb & kgs <= 20 & hover -> next tb
# region A
guarantees.append('G((m_tb & r_a) -> X(m_tb))')
# LPC_TB_TO_STB: Upon tb & (!hover | kgs > 20) -> next stb
# NOT region A
guarantees.append('G((m_tb & (r_b | r_c | r_d | r_e | r_f)) -> X(m_tb | m_stb))')
# Wait, the original says -> next stb. Let me fix:
# Actually: Upon tb & (!hover | kgs > 20) -> next stb
# !hover | kgs > 20 means NOT in region A
guarantees[-1] = 'G((m_tb & !r_a) -> X(m_stb))'
# Note: we skip LPC_REACH_HOVER_06 and _12 (bounded temporal F[0,n])
# ltlsynt doesn't support bounded-F natively
# === BUILD FORMULA ===
# assume-guarantee: assumptions -> guarantees
assume_str = ' & '.join(f'({a})' for a in assumptions)
guarantee_str = ' & '.join(f'({g})' for g in guarantees)
formula = f'({assume_str}) -> ({guarantee_str})'
inputs = region_vars
outputs = mode_vars
return {
'_comment': 'Boolean abstraction of LPC lift-mode controller. Assumes -> Guarantees form.',
'spec_name': 'LPC_mini',
'source_file': 'specs/LPC_mini_reqts_and_vars.json',
'inputs': inputs,
'outputs': outputs,
'assumptions': assumptions,
'guarantees': guarantees,
'conjoined_ltl': formula,
'abstraction_notes': {
'speed_regions': {
'r_a': 'speed <= 20 (hover zone)',
'r_b': '20 < speed <= 30',
'r_c': '30 < speed <= 40',
'r_d': '40 < speed <= 90',
'r_e': '90 < speed <= 100',
'r_f': 'speed > 100',
},
'modes': {
'm_tb': 'thrust_borne',
'm_stb': 'semi_thrust_borne',
'm_swb': 'semi_wing_borne',
'm_wb': 'wing_borne',
},
'skipped_requirements': [
'LPC_REACH_HOVER_06 (bounded temporal F[0,6])',
'LPC_REACH_HOVER_12 (bounded temporal F[0,12])',
'LPC_KIAS_DERIVATIVE (absorbed into adjacency constraint)',
'LPC_KIAS_KGS (absorbed - single speed variable)',
'LPC_INIT_KIAS (absorbed into initial region)',
'LPC_KIAS_0 (trivially satisfied)',
'LPC_INIT_HOVER_MODE (absorbed - hover = region A)',
],
},
}
if __name__ == '__main__':
config = build_lpc_spec()
out = Path('specs/lpc_synthesis_config.json')
out.write_text(json.dumps(config, indent=2) + '\n')
print(f'LPC Boolean Abstraction')
print(f'Inputs ({len(config["inputs"])}): {", ".join(config["inputs"])}')
print(f'Outputs ({len(config["outputs"])}): {", ".join(config["outputs"])}')
print(f'\nAssumptions ({len(config["assumptions"])}):')
for a in config['assumptions']:
print(f' {a}')
print(f'\nGuarantees ({len(config["guarantees"])}):')
for g in config['guarantees']:
print(f' {g}')
print(f'\nSkipped: {len(config["abstraction_notes"]["skipped_requirements"])} requirements')
print(f'Config written to: {out}')

View File

@ -0,0 +1,258 @@
aag 243 6 4 4 233
2
4
6
8
10
12
14 294
16 327
18 358
20 486
69
137
205
240
22 19 21
24 17 22
26 15 24
28 12 26
30 11 28
32 16 22
34 14 32
36 13 34
38 11 36
40 8 38
42 9 30
44 41 43
46 7 45
48 13 26
50 11 48
52 9 50
54 7 52
56 2 54
58 3 46
60 57 59
62 3 54
64 4 62
66 5 61
68 65 67
70 18 21
72 16 70
74 17 70
76 14 74
78 15 72
80 77 79
82 12 81
84 14 70
86 79 85
88 13 87
90 10 88
92 11 82
94 91 93
96 13 84
98 11 96
100 8 98
102 9 95
104 101 103
106 14 72
108 13 106
110 11 108
112 9 110
114 6 112
116 7 105
118 115 117
120 3 119
122 13 78
124 11 122
126 9 124
128 7 126
130 3 128
132 4 130
134 5 120
136 133 135
138 14 24
140 15 32
142 139 141
144 12 143
146 15 74
148 139 147
150 13 149
152 10 150
154 11 144
156 153 155
158 13 146
160 11 158
162 8 160
164 9 157
166 163 165
168 9 160
170 6 168
172 7 167
174 171 173
176 13 140
178 11 176
180 9 178
182 7 180
184 2 182
186 3 175
188 185 187
190 13 143
192 11 190
194 9 192
196 7 194
198 3 196
200 4 198
202 5 189
204 201 203
206 12 34
208 10 36
210 11 206
212 209 211
214 19 20
216 17 214
218 15 216
220 13 218
222 11 220
224 8 222
226 9 213
228 225 227
230 9 222
232 6 230
234 7 229
236 233 235
238 3 237
240 5 238
242 16 21
244 25 243
246 17 21
248 14 246
250 15 245
252 249 251
254 12 253
256 14 21
258 15 70
260 257 259
262 13 261
264 10 262
266 11 254
268 265 267
270 71 215
272 17 271
274 15 272
276 85 275
278 13 277
280 11 278
282 8 280
284 9 269
286 283 285
288 7 287
290 171 289
292 3 291
294 5 292
296 153 211
298 9 297
300 283 299
302 7 301
304 171 303
306 3 305
308 15 242
310 139 309
312 13 311
314 11 312
316 9 314
318 7 316
320 3 318
322 4 320
324 5 306
326 323 325
328 75 243
330 14 329
332 79 331
334 13 333
336 10 334
338 211 337
340 275 331
342 13 341
344 11 342
346 8 344
348 9 339
350 347 349
352 7 351
354 171 353
356 3 355
358 5 356
360 3 5
362 7 9
364 11 12
366 15 16
368 360 362
370 364 366
372 368 370
374 14 17
376 364 374
378 368 376
380 22 360
382 362 364
384 380 382
386 10 13
388 14 360
390 362 386
392 388 390
394 18 360
396 390 394
398 7 8
400 11 13
402 14 16
404 360 398
406 400 402
408 404 406
410 17 18
412 400 410
414 404 412
416 20 360
418 398 400
420 416 418
422 6 9
424 15 410
426 360 400
428 422 424
430 426 428
432 2 5
434 15 22
436 362 400
438 432 434
440 436 438
442 3 4
444 362 366
446 400 442
448 444 446
450 24 362
452 446 450
454 14 20
456 16 20
458 18 20
460 373 379
462 385 393
464 397 409
466 415 421
468 431 441
470 449 453
472 455 457
474 459 460
476 462 464
478 466 468
480 470 472
482 474 476
484 478 480
486 482 484
i0 r_f
i1 r_e
i2 r_a
i3 r_b
i4 r_c
i5 r_d
o0 m_wb
o1 m_stb
o2 m_swb
o3 m_tb

View File

@ -0,0 +1,37 @@
aag 22 4 2 5 16
2
4
6
8
10 42
12 45
14
18
32
0
1
14 11 13
16 10 12
18 15 17
20 3 7
22 13 20
24 3 5
26 9 13
28 24 26
30 11 23
32 29 30
34 14 20
36 9 14
38 24 36
40 17 35
42 39 40
44 35 39
i0 t_max_exceeded
i1 t_dot_exceeded
i2 startup
i3 t_power_min
o0 cold_shutdown
o1 scram
o2 heatup
o3 op_mode
o4 load_follow

View File

@ -0,0 +1,18 @@
digraph DRC_Controller {
rankdir=LR;
node [shape=circle, style=filled, fontname="Helvetica"];
edge [fontname="Helvetica", fontsize=10];
s00 [label="S(0,0)\nColdShut+Heatup+LoadFollow\nColdShut+LoadFollow", fillcolor=lightblue];
s01 [label="S(0,1)\nSCRAM+Heatup+LoadFollow", fillcolor=lightgreen];
s10 [label="S(1,0)\nSCRAM+LoadFollow", fillcolor=lightgreen];
s11 [label="S(1,1)\nLoadFollow", fillcolor=gray90];
init [shape=point, width=0.2];
init -> s00;
s00 -> s01 [label="5/16", penwidth=1.0];
s00 -> s10 [label="11/16", penwidth=2.0];
s01 -> s10 [label="always", penwidth=2.0];
s10 -> s10 [label="always", penwidth=2.0];
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 14.1.4 (20260321.0153)
-->
<!-- Title: DRC_Controller Pages: 1 -->
<svg width="1047pt" height="438pt"
viewBox="0.00 0.00 1047.00 438.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 434.31)">
<title>DRC_Controller</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-434.31 1043.2,-434.31 1043.2,4 -4,4"/>
<!-- s00 -->
<g id="node1" class="node">
<title>s00</title>
<ellipse fill="lightblue" stroke="black" cx="298.98" cy="-141.77" rx="141.77" ry="141.77"/>
<text xml:space="preserve" text-anchor="middle" x="298.98" y="-150.97" font-family="Helvetica,sans-Serif" font-size="14.00">S(0,0)</text>
<text xml:space="preserve" text-anchor="middle" x="298.98" y="-135.97" font-family="Helvetica,sans-Serif" font-size="14.00">ColdShut+Heatup+LoadFollow</text>
<text xml:space="preserve" text-anchor="middle" x="298.98" y="-120.97" font-family="Helvetica,sans-Serif" font-size="14.00">ColdShut+LoadFollow</text>
</g>
<!-- s01 -->
<g id="node2" class="node">
<title>s01</title>
<ellipse fill="lightgreen" stroke="black" cx="633.04" cy="-292.77" rx="137.53" ry="137.53"/>
<text xml:space="preserve" text-anchor="middle" x="633.04" y="-294.47" font-family="Helvetica,sans-Serif" font-size="14.00">S(0,1)</text>
<text xml:space="preserve" text-anchor="middle" x="633.04" y="-279.47" font-family="Helvetica,sans-Serif" font-size="14.00">SCRAM+Heatup+LoadFollow</text>
</g>
<!-- s00&#45;&gt;s01 -->
<g id="edge2" class="edge">
<title>s00&#45;&gt;s01</title>
<path fill="none" stroke="black" d="M428.37,-200.16C450.84,-210.38 474.28,-221.04 496.93,-231.34"/>
<polygon fill="black" stroke="black" points="495.35,-234.46 505.9,-235.41 498.24,-228.09 495.35,-234.46"/>
<text xml:space="preserve" text-anchor="middle" x="468.13" y="-223.55" font-family="Helvetica,sans-Serif" font-size="10.00">5/16</text>
</g>
<!-- s10 -->
<g id="node3" class="node">
<title>s10</title>
<ellipse fill="lightgreen" stroke="black" cx="938.26" cy="-141.77" rx="100.94" ry="100.94"/>
<text xml:space="preserve" text-anchor="middle" x="938.26" y="-143.47" font-family="Helvetica,sans-Serif" font-size="14.00">S(1,0)</text>
<text xml:space="preserve" text-anchor="middle" x="938.26" y="-128.47" font-family="Helvetica,sans-Serif" font-size="14.00">SCRAM+LoadFollow</text>
</g>
<!-- s00&#45;&gt;s10 -->
<g id="edge3" class="edge">
<title>s00&#45;&gt;s10</title>
<path fill="none" stroke="black" stroke-width="2" d="M440.94,-135.92C459.29,-135.35 477.85,-134.85 495.51,-134.52 617.74,-132.26 648.35,-131.87 770.57,-134.52 787.93,-134.9 806.3,-135.5 824.26,-136.2"/>
<polygon fill="black" stroke="black" stroke-width="2" points="824.08,-139.69 834.22,-136.6 824.37,-132.7 824.08,-139.69"/>
<text xml:space="preserve" text-anchor="middle" x="633.04" y="-136.27" font-family="Helvetica,sans-Serif" font-size="10.00">11/16</text>
</g>
<!-- s01&#45;&gt;s10 -->
<g id="edge4" class="edge">
<title>s01&#45;&gt;s10</title>
<path fill="none" stroke="black" stroke-width="2" d="M756.5,-231.79C782.87,-218.66 810.46,-204.92 835.92,-192.24"/>
<polygon fill="black" stroke="black" stroke-width="2" points="837.35,-195.44 844.74,-187.85 834.23,-189.17 837.35,-195.44"/>
<text xml:space="preserve" text-anchor="middle" x="803.95" y="-214.5" font-family="Helvetica,sans-Serif" font-size="10.00">always</text>
</g>
<!-- s10&#45;&gt;s10 -->
<g id="edge5" class="edge">
<title>s10&#45;&gt;s10</title>
<path fill="none" stroke="black" stroke-width="2" d="M916.47,-240.67C920.37,-252.78 927.64,-260.71 938.26,-260.71 945.07,-260.71 950.5,-257.46 954.54,-251.93"/>
<polygon fill="black" stroke="black" stroke-width="2" points="957.47,-253.91 958.72,-243.39 951.18,-250.83 957.47,-253.91"/>
<text xml:space="preserve" text-anchor="middle" x="938.26" y="-262.46" font-family="Helvetica,sans-Serif" font-size="10.00">always</text>
</g>
<!-- s11 -->
<g id="node4" class="node">
<title>s11</title>
<ellipse fill="#e5e5e5" stroke="black" cx="60.1" cy="-226.77" rx="60.1" ry="60.1"/>
<text xml:space="preserve" text-anchor="middle" x="60.1" y="-228.47" font-family="Helvetica,sans-Serif" font-size="14.00">S(1,1)</text>
<text xml:space="preserve" text-anchor="middle" x="60.1" y="-213.47" font-family="Helvetica,sans-Serif" font-size="14.00">LoadFollow</text>
</g>
<!-- init -->
<g id="node5" class="node">
<title>init</title>
<ellipse fill="black" stroke="black" cx="60.1" cy="-141.77" rx="7.2" ry="7.2"/>
</g>
<!-- init&#45;&gt;s00 -->
<g id="edge1" class="edge">
<title>init&#45;&gt;s00</title>
<path fill="none" stroke="black" d="M67.44,-141.77C80.19,-141.77 110.7,-141.77 145.51,-141.77"/>
<polygon fill="black" stroke="black" points="145.43,-145.28 155.43,-141.77 145.43,-138.28 145.43,-145.28"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 301 KiB

View File

@ -0,0 +1,46 @@
digraph DRC_Controller {
rankdir=LR;
splines=true;
nodesep=1.2;
ranksep=1.5;
node [shape=circle, style=filled, fontname="Helvetica", fontsize=14, width=1.5, fixedsize=false];
edge [fontname="Helvetica", fontsize=11];
// States
shutdown [label="SHUTDOWN\n(0,0)", fillcolor="#B3D9FF"];
heatup [label="HEATUP\n(1,0)", fillcolor="#FFFFB3"];
operation [label="OPERATION\n(0,1)", fillcolor="#B3FFB3"];
scram [label="SCRAM\n(1,1)", fillcolor="#FFB3B3"];
// Init
init [shape=point, width=0.25];
init -> shutdown [penwidth=2.0];
// Transitions with guard conditions
// S001: shutdown stays when !t_avg_above_min
shutdown -> shutdown [label="!t_avg_above_min\n(S001)", color="#4477AA", penwidth=1.5];
// T001: shutdown -> heatup when t_avg_above_min
shutdown -> heatup [label="t_avg_above_min\n(T001)", color="#228B22", penwidth=2.0];
// S002: heatup stays when inv1_holds & !(t_in_range & p_above_crit)
heatup -> heatup [label="inv1 & !(t_range & p_crit)\n(S002)", color="#4477AA", penwidth=1.5];
// T002: heatup -> operation when inv1 & t_in_range & p_above_crit
heatup -> operation [label="inv1 & t_range & p_crit\n(T002)", color="#228B22", penwidth=2.0];
// T003: heatup -> scram when !inv1_holds
heatup -> scram [label="!inv1_holds\n(T003)", color="#CC0000", penwidth=2.0];
// S003: operation stays when inv2_holds
operation -> operation [label="inv2_holds\n(S003)", color="#4477AA", penwidth=1.5];
// T004: operation -> scram when !inv2_holds
operation -> scram [label="!inv2_holds\n(T004)", color="#CC0000", penwidth=2.0];
// S004: scram stays when !manual_reset
scram -> scram [label="!manual_reset\n(S004)", color="#4477AA", penwidth=1.5];
// T005: scram -> shutdown when manual_reset
scram -> shutdown [label="manual_reset\n(T005)", color="#228B22", penwidth=2.0];
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 14.1.4 (20260321.0153)
-->
<!-- Title: DRC_Controller Pages: 1 -->
<svg width="1139pt" height="539pt"
viewBox="0.00 0.00 1139.00 539.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 535)">
<title>DRC_Controller</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-535 1135.25,-535 1135.25,4 -4,4"/>
<!-- shutdown -->
<g id="node1" class="node">
<title>shutdown</title>
<ellipse fill="#b3d9ff" stroke="black" cx="181" cy="-54" rx="54" ry="54"/>
<text xml:space="preserve" text-anchor="middle" x="181" y="-55.7" font-family="Helvetica,sans-Serif" font-size="14.00">SHUTDOWN</text>
<text xml:space="preserve" text-anchor="middle" x="181" y="-40.7" font-family="Helvetica,sans-Serif" font-size="14.00">(0,0)</text>
</g>
<!-- shutdown&#45;&gt;shutdown -->
<g id="edge2" class="edge">
<title>shutdown&#45;&gt;shutdown</title>
<path fill="none" stroke="#4477aa" stroke-width="1.5" d="M163.76,-105.69C156.39,-148.88 162.14,-194 181,-194 198.13,-194 204.44,-156.78 199.94,-117.6"/>
<polygon fill="#4477aa" stroke="#4477aa" stroke-width="1.5" points="203.44,-117.35 198.56,-107.94 196.51,-118.33 203.44,-117.35"/>
<text xml:space="preserve" text-anchor="middle" x="181" y="-207.55" font-family="Helvetica,sans-Serif" font-size="11.00">!t_avg_above_min</text>
<text xml:space="preserve" text-anchor="middle" x="181" y="-195.55" font-family="Helvetica,sans-Serif" font-size="11.00">(S001)</text>
</g>
<!-- heatup -->
<g id="node2" class="node">
<title>heatup</title>
<ellipse fill="#ffffb3" stroke="black" cx="481.75" cy="-203" rx="54" ry="54"/>
<text xml:space="preserve" text-anchor="middle" x="481.75" y="-204.7" font-family="Helvetica,sans-Serif" font-size="14.00">HEATUP</text>
<text xml:space="preserve" text-anchor="middle" x="481.75" y="-189.7" font-family="Helvetica,sans-Serif" font-size="14.00">(1,0)</text>
</g>
<!-- shutdown&#45;&gt;heatup -->
<g id="edge3" class="edge">
<title>shutdown&#45;&gt;heatup</title>
<path fill="none" stroke="#228b22" stroke-width="2" d="M229.67,-77.77C281.81,-103.78 365.42,-145.48 421.68,-173.54"/>
<polygon fill="#228b22" stroke="#228b22" stroke-width="2" points="420.03,-176.63 430.54,-177.96 423.16,-170.36 420.03,-176.63"/>
<text xml:space="preserve" text-anchor="middle" x="331.38" y="-159.78" font-family="Helvetica,sans-Serif" font-size="11.00">t_avg_above_min</text>
<text xml:space="preserve" text-anchor="middle" x="331.38" y="-147.78" font-family="Helvetica,sans-Serif" font-size="11.00">(T001)</text>
</g>
<!-- heatup&#45;&gt;heatup -->
<g id="edge4" class="edge">
<title>heatup&#45;&gt;heatup</title>
<path fill="none" stroke="#4477aa" stroke-width="1.5" d="M458.48,-252.15C447.34,-296.09 455.1,-343 481.75,-343 506.01,-343 514.61,-304.14 507.56,-264.03"/>
<polygon fill="#4477aa" stroke="#4477aa" stroke-width="1.5" points="511.01,-263.41 505.5,-254.37 504.17,-264.88 511.01,-263.41"/>
<text xml:space="preserve" text-anchor="middle" x="481.75" y="-356.55" font-family="Helvetica,sans-Serif" font-size="11.00">inv1 &amp; !(t_range &amp; p_crit)</text>
<text xml:space="preserve" text-anchor="middle" x="481.75" y="-344.55" font-family="Helvetica,sans-Serif" font-size="11.00">(S002)</text>
</g>
<!-- operation -->
<g id="node3" class="node">
<title>operation</title>
<ellipse fill="#b3ffb3" stroke="black" cx="807.25" cy="-367" rx="54" ry="54"/>
<text xml:space="preserve" text-anchor="middle" x="807.25" y="-368.7" font-family="Helvetica,sans-Serif" font-size="14.00">OPERATION</text>
<text xml:space="preserve" text-anchor="middle" x="807.25" y="-353.7" font-family="Helvetica,sans-Serif" font-size="14.00">(0,1)</text>
</g>
<!-- heatup&#45;&gt;operation -->
<g id="edge5" class="edge">
<title>heatup&#45;&gt;operation</title>
<path fill="none" stroke="#228b22" stroke-width="2" d="M529.34,-229.38C548,-239.77 569.78,-251.66 589.75,-262 642.08,-289.09 702.48,-318.21 746.16,-338.89"/>
<polygon fill="#228b22" stroke="#228b22" stroke-width="2" points="744.46,-341.96 755,-343.07 747.45,-335.63 744.46,-341.96"/>
<text xml:space="preserve" text-anchor="middle" x="644.5" y="-328.33" font-family="Helvetica,sans-Serif" font-size="11.00">inv1 &amp; t_range &amp; p_crit</text>
<text xml:space="preserve" text-anchor="middle" x="644.5" y="-316.33" font-family="Helvetica,sans-Serif" font-size="11.00">(T002)</text>
</g>
<!-- scram -->
<g id="node4" class="node">
<title>scram</title>
<ellipse fill="#ffb3b3" stroke="black" cx="1077.25" cy="-203" rx="54" ry="54"/>
<text xml:space="preserve" text-anchor="middle" x="1077.25" y="-204.7" font-family="Helvetica,sans-Serif" font-size="14.00">SCRAM</text>
<text xml:space="preserve" text-anchor="middle" x="1077.25" y="-189.7" font-family="Helvetica,sans-Serif" font-size="14.00">(1,1)</text>
</g>
<!-- heatup&#45;&gt;scram -->
<g id="edge6" class="edge">
<title>heatup&#45;&gt;scram</title>
<path fill="none" stroke="#cc0000" stroke-width="2" d="M536.2,-203C644.96,-203 891.7,-203 1010.25,-203"/>
<polygon fill="#cc0000" stroke="#cc0000" stroke-width="2" points="1010,-206.5 1020,-203 1010,-199.5 1010,-206.5"/>
<text xml:space="preserve" text-anchor="middle" x="807.25" y="-216.55" font-family="Helvetica,sans-Serif" font-size="11.00">!inv1_holds</text>
<text xml:space="preserve" text-anchor="middle" x="807.25" y="-204.55" font-family="Helvetica,sans-Serif" font-size="11.00">(T003)</text>
</g>
<!-- operation&#45;&gt;operation -->
<g id="edge7" class="edge">
<title>operation&#45;&gt;operation</title>
<path fill="none" stroke="#4477aa" stroke-width="1.5" d="M786.2,-416.87C776.44,-460.6 783.45,-507 807.25,-507 828.91,-507 836.67,-468.56 830.53,-428.69"/>
<polygon fill="#4477aa" stroke="#4477aa" stroke-width="1.5" points="834.01,-428.29 828.72,-419.11 827.14,-429.58 834.01,-428.29"/>
<text xml:space="preserve" text-anchor="middle" x="807.25" y="-520.55" font-family="Helvetica,sans-Serif" font-size="11.00">inv2_holds</text>
<text xml:space="preserve" text-anchor="middle" x="807.25" y="-508.55" font-family="Helvetica,sans-Serif" font-size="11.00">(S003)</text>
</g>
<!-- operation&#45;&gt;scram -->
<g id="edge8" class="edge">
<title>operation&#45;&gt;scram</title>
<path fill="none" stroke="#cc0000" stroke-width="2" d="M853.71,-339.18C899.53,-311.14 970.34,-267.81 1019.74,-237.58"/>
<polygon fill="#cc0000" stroke="#cc0000" stroke-width="2" points="1021.28,-240.74 1027.98,-232.54 1017.63,-234.77 1021.28,-240.74"/>
<text xml:space="preserve" text-anchor="middle" x="942.25" y="-313.24" font-family="Helvetica,sans-Serif" font-size="11.00">!inv2_holds</text>
<text xml:space="preserve" text-anchor="middle" x="942.25" y="-301.24" font-family="Helvetica,sans-Serif" font-size="11.00">(T004)</text>
</g>
<!-- scram&#45;&gt;shutdown -->
<g id="edge10" class="edge">
<title>scram&#45;&gt;shutdown</title>
<path fill="none" stroke="#228b22" stroke-width="2" d="M1024.04,-192.53C1006.63,-189.1 987.12,-185.32 969.25,-182 776.94,-146.27 728.86,-137.12 535.75,-106 435.36,-89.83 318.61,-73.06 247.54,-63.08"/>
<polygon fill="#228b22" stroke="#228b22" stroke-width="2" points="248.2,-59.64 237.81,-61.72 247.23,-66.57 248.2,-59.64"/>
<text xml:space="preserve" text-anchor="middle" x="644.5" y="-146.48" font-family="Helvetica,sans-Serif" font-size="11.00">manual_reset</text>
<text xml:space="preserve" text-anchor="middle" x="644.5" y="-134.48" font-family="Helvetica,sans-Serif" font-size="11.00">(T005)</text>
</g>
<!-- scram&#45;&gt;scram -->
<g id="edge9" class="edge">
<title>scram&#45;&gt;scram</title>
<path fill="none" stroke="#4477aa" stroke-width="1.5" d="M1056.2,-252.87C1046.44,-296.6 1053.45,-343 1077.25,-343 1098.91,-343 1106.67,-304.56 1100.53,-264.69"/>
<polygon fill="#4477aa" stroke="#4477aa" stroke-width="1.5" points="1104.01,-264.29 1098.72,-255.11 1097.14,-265.58 1104.01,-264.29"/>
<text xml:space="preserve" text-anchor="middle" x="1077.25" y="-356.55" font-family="Helvetica,sans-Serif" font-size="11.00">!manual_reset</text>
<text xml:space="preserve" text-anchor="middle" x="1077.25" y="-344.55" font-family="Helvetica,sans-Serif" font-size="11.00">(S004)</text>
</g>
<!-- init -->
<g id="node5" class="node">
<title>init</title>
<ellipse fill="black" stroke="black" cx="9" cy="-54" rx="9" ry="9"/>
</g>
<!-- init&#45;&gt;shutdown -->
<g id="edge1" class="edge">
<title>init&#45;&gt;shutdown</title>
<path fill="none" stroke="black" stroke-width="2" d="M18.2,-54C35.52,-54 77.28,-54 114.04,-54"/>
<polygon fill="black" stroke="black" stroke-width="2" points="113.75,-57.5 123.75,-54 113.75,-50.5 113.75,-57.5"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

View File

@ -0,0 +1,437 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 14.1.4 (20260321.0153)
-->
<!-- Title: aiger Pages: 1 -->
<svg width="746pt" height="898pt"
viewBox="0.00 0.00 746.00 898.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 893.6)">
<title>aiger</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-893.6 741.53,-893.6 741.53,4 -4,4"/>
<!-- n0 -->
<g id="node1" class="node">
<title>n0</title>
<ellipse fill="#e5e5e5" stroke="black" cx="152.5" cy="-45" rx="18" ry="18"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-39.95" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- out_3 -->
<g id="node27" class="node">
<title>out_3</title>
<polygon fill="lightgreen" stroke="black" points="721.78,-90 654.78,-90 654.78,-54 721.78,-54 721.78,-90"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-66.95" font-family="Times,serif" font-size="14.00">op_mode</text>
</g>
<!-- n0&#45;&gt;out_3 -->
<g id="edge38" class="edge">
<title>n0&#45;&gt;out_3</title>
<path fill="none" stroke="black" d="M169.86,-51.26C192.2,-59.24 233.66,-72 270.29,-72 270.29,-72 270.29,-72 548.24,-72 580.03,-72 615.91,-72 643.25,-72"/>
<polygon fill="black" stroke="black" points="642.9,-75.5 652.9,-72 642.9,-68.5 642.9,-75.5"/>
</g>
<!-- out_4 -->
<g id="node28" class="node">
<title>out_4</title>
<polygon fill="lightgreen" stroke="black" points="728.91,-36 647.66,-36 647.66,0 728.91,0 728.91,-36"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-12.95" font-family="Times,serif" font-size="14.00">load_follow</text>
</g>
<!-- n0&#45;&gt;out_4 -->
<g id="edge39" class="edge">
<title>n0&#45;&gt;out_4</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M169.86,-38.74C192.2,-30.76 233.66,-18 270.29,-18 270.29,-18 270.29,-18 548.24,-18 577.37,-18 609.92,-18 636.2,-18"/>
<polygon fill="red" stroke="red" points="635.91,-21.5 645.91,-18 635.91,-14.5 635.91,-21.5"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-21.2" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n1 -->
<g id="node2" class="node">
<title>n1</title>
<polygon fill="lightblue" stroke="black" points="107.5,-826 0,-826 0,-790 107.5,-790 107.5,-826"/>
<text xml:space="preserve" text-anchor="middle" x="53.75" y="-802.95" font-family="Times,serif" font-size="14.00">t_max_exceeded</text>
</g>
<!-- n10 -->
<g id="node11" class="node">
<title>n10</title>
<ellipse fill="white" stroke="black" cx="216.1" cy="-683" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-677.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n1&#45;&gt;n10 -->
<g id="edge7" class="edge">
<title>n1&#45;&gt;n10</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M103.65,-789.56C128.43,-778.49 157.78,-762.53 179.5,-742 188.89,-733.12 196.69,-721.24 202.57,-710.46"/>
<polygon fill="red" stroke="red" points="205.69,-712.05 207.12,-701.55 199.46,-708.87 205.69,-712.05"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-782.05" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n12 -->
<g id="node13" class="node">
<title>n12</title>
<ellipse fill="white" stroke="black" cx="216.1" cy="-871" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-865.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n1&#45;&gt;n12 -->
<g id="edge11" class="edge">
<title>n1&#45;&gt;n12</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M107.83,-823.57C130.32,-830.81 156.58,-840.11 179.5,-850.5 182.94,-852.06 186.49,-853.85 189.94,-855.71"/>
<polygon fill="red" stroke="red" points="188.11,-858.7 198.53,-860.6 191.57,-852.61 188.11,-858.7"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-853.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n2 -->
<g id="node3" class="node">
<title>n2</title>
<polygon fill="lightblue" stroke="black" points="104.12,-889 3.38,-889 3.38,-853 104.12,-853 104.12,-889"/>
<text xml:space="preserve" text-anchor="middle" x="53.75" y="-865.95" font-family="Times,serif" font-size="14.00">t_dot_exceeded</text>
</g>
<!-- n2&#45;&gt;n12 -->
<g id="edge12" class="edge">
<title>n2&#45;&gt;n12</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M104.61,-871C131.26,-871 163.15,-871 185.8,-871"/>
<polygon fill="red" stroke="red" points="185.53,-874.5 195.53,-871 185.53,-867.5 185.53,-874.5"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-874.2" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n3 -->
<g id="node4" class="node">
<title>n3</title>
<polygon fill="lightblue" stroke="black" points="80.75,-701 26.75,-701 26.75,-665 80.75,-665 80.75,-701"/>
<text xml:space="preserve" text-anchor="middle" x="53.75" y="-677.95" font-family="Times,serif" font-size="14.00">startup</text>
</g>
<!-- n3&#45;&gt;n10 -->
<g id="edge8" class="edge">
<title>n3&#45;&gt;n10</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M81.23,-683C110,-683 155.84,-683 185.7,-683"/>
<polygon fill="red" stroke="red" points="185.54,-686.5 195.54,-683 185.54,-679.5 185.54,-686.5"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-686.2" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n4 -->
<g id="node5" class="node">
<title>n4</title>
<polygon fill="lightblue" stroke="black" points="98.12,-766 9.38,-766 9.38,-730 98.12,-730 98.12,-766"/>
<text xml:space="preserve" text-anchor="middle" x="53.75" y="-742.95" font-family="Times,serif" font-size="14.00">t_power_min</text>
</g>
<!-- n13 -->
<g id="node14" class="node">
<title>n13</title>
<ellipse fill="white" stroke="black" cx="271.29" cy="-730" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="271.29" y="-724.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n4&#45;&gt;n13 -->
<g id="edge13" class="edge">
<title>n4&#45;&gt;n13</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M96.32,-729.62C105.74,-726.25 115.82,-723.25 125.5,-721.5 165.35,-714.28 212.28,-719.49 241.66,-724.36"/>
<polygon fill="red" stroke="red" points="240.8,-727.76 251.25,-726.05 242.01,-720.87 240.8,-727.76"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-724.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n18 -->
<g id="node19" class="node">
<title>n18</title>
<ellipse fill="white" stroke="black" cx="381.67" cy="-792" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-786.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n4&#45;&gt;n18 -->
<g id="edge23" class="edge">
<title>n4&#45;&gt;n18</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M86.11,-766.47C98.04,-772.57 112.01,-778.65 125.5,-782 205.25,-801.82 303.29,-798.18 351.33,-794.66"/>
<polygon fill="red" stroke="red" points="351.49,-798.16 361.18,-793.88 350.93,-791.18 351.49,-798.16"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-799.59" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n5 -->
<g id="node6" class="node">
<title>n5</title>
<path fill="lightyellow" stroke="black" d="M167.5,-367C167.5,-367 137.5,-367 137.5,-367 131.5,-367 125.5,-361 125.5,-355 125.5,-355 125.5,-343 125.5,-343 125.5,-337 131.5,-331 137.5,-331 137.5,-331 167.5,-331 167.5,-331 173.5,-331 179.5,-337 179.5,-343 179.5,-343 179.5,-355 179.5,-355 179.5,-361 173.5,-367 167.5,-367"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-343.95" font-family="Times,serif" font-size="14.00">L0</text>
</g>
<!-- n7 -->
<g id="node8" class="node">
<title>n7</title>
<ellipse fill="white" stroke="black" cx="271.29" cy="-484" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="271.29" y="-478.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n5&#45;&gt;n7 -->
<g id="edge1" class="edge">
<title>n5&#45;&gt;n7</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M169.49,-367.49C190.73,-392.03 228.2,-435.34 250.98,-461.68"/>
<polygon fill="red" stroke="red" points="248.2,-463.81 257.39,-469.09 253.49,-459.23 248.2,-463.81"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-443.53" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n8 -->
<g id="node9" class="node">
<title>n8</title>
<ellipse fill="white" stroke="black" cx="271.29" cy="-311" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="271.29" y="-305.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n5&#45;&gt;n8 -->
<g id="edge3" class="edge">
<title>n5&#45;&gt;n8</title>
<path fill="none" stroke="black" d="M179.71,-340.47C198.4,-334.39 223.48,-326.23 242.52,-320.04"/>
<polygon fill="black" stroke="black" points="243.34,-323.45 251.76,-317.03 241.17,-316.79 243.34,-323.45"/>
</g>
<!-- n15 -->
<g id="node16" class="node">
<title>n15</title>
<ellipse fill="white" stroke="black" cx="436.86" cy="-597" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="436.86" y="-591.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n5&#45;&gt;n15 -->
<g id="edge17" class="edge">
<title>n5&#45;&gt;n15</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M179.67,-362.9C195.87,-371.81 216.9,-383.93 234.69,-396 311.85,-448.35 384.65,-532.85 417.53,-573.58"/>
<polygon fill="red" stroke="red" points="414.73,-575.68 423.7,-581.31 420.2,-571.31 414.73,-575.68"/>
<text xml:space="preserve" text-anchor="middle" x="271.29" y="-440.28" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n6 -->
<g id="node7" class="node">
<title>n6</title>
<path fill="lightyellow" stroke="black" d="M167.5,-572C167.5,-572 137.5,-572 137.5,-572 131.5,-572 125.5,-566 125.5,-560 125.5,-560 125.5,-548 125.5,-548 125.5,-542 131.5,-536 137.5,-536 137.5,-536 167.5,-536 167.5,-536 173.5,-536 179.5,-542 179.5,-548 179.5,-548 179.5,-560 179.5,-560 179.5,-566 173.5,-572 167.5,-572"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-548.95" font-family="Times,serif" font-size="14.00">L1</text>
</g>
<!-- n6&#45;&gt;n7 -->
<g id="edge2" class="edge">
<title>n6&#45;&gt;n7</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M179.71,-538.29C199.32,-526.54 225.97,-510.56 245.28,-498.99"/>
<polygon fill="red" stroke="red" points="246.83,-502.14 253.6,-494 243.23,-496.14 246.83,-502.14"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-530.53" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n6&#45;&gt;n8 -->
<g id="edge4" class="edge">
<title>n6&#45;&gt;n8</title>
<path fill="none" stroke="black" d="M156.33,-535.69C161.42,-506.06 173.89,-446.35 197.5,-401 211.17,-374.74 233.21,-348.9 249.46,-331.69"/>
<polygon fill="black" stroke="black" points="251.87,-334.23 256.31,-324.61 246.84,-329.37 251.87,-334.23"/>
</g>
<!-- n11 -->
<g id="node12" class="node">
<title>n11</title>
<ellipse fill="white" stroke="black" cx="326.48" cy="-603" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="326.48" y="-597.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n6&#45;&gt;n11 -->
<g id="edge9" class="edge">
<title>n6&#45;&gt;n11</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M179.99,-561.55C211.71,-570.59 264.62,-585.66 297.14,-594.93"/>
<polygon fill="red" stroke="red" points="296.09,-598.26 306.66,-597.64 298,-591.53 296.09,-598.26"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-579.6" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n6&#45;&gt;n13 -->
<g id="edge14" class="edge">
<title>n6&#45;&gt;n13</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M171.69,-572.16C194.13,-594.68 229.93,-631.04 234.69,-638.5 247.07,-657.89 256.29,-682.27 262.24,-700.99"/>
<polygon fill="red" stroke="red" points="258.84,-701.82 265.09,-710.37 265.54,-699.78 258.84,-701.82"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-641.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n9 -->
<g id="node10" class="node">
<title>n9</title>
<ellipse fill="white" stroke="black" cx="381.67" cy="-186" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-180.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n7&#45;&gt;n9 -->
<g id="edge5" class="edge">
<title>n7&#45;&gt;n9</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M278,-466.31C291.67,-424.27 327.82,-315.2 363.07,-226 364.75,-221.76 366.61,-217.3 368.48,-212.96"/>
<polygon fill="red" stroke="red" points="371.59,-214.57 372.41,-204 365.19,-211.75 371.59,-214.57"/>
<text xml:space="preserve" text-anchor="middle" x="326.48" y="-375.42" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n17 -->
<g id="node18" class="node">
<title>n17</title>
<ellipse fill="white" stroke="black" cx="381.67" cy="-668" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-662.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n7&#45;&gt;n17 -->
<g id="edge21" class="edge">
<title>n7&#45;&gt;n17</title>
<path fill="none" stroke="black" d="M288.27,-492.39C305.07,-502.07 330.98,-519.56 345.07,-542 364.23,-572.49 352.74,-586.5 363.07,-621 364.95,-627.26 367.24,-633.89 369.53,-640.13"/>
<polygon fill="black" stroke="black" points="366.22,-641.26 373.05,-649.37 372.76,-638.77 366.22,-641.26"/>
</g>
<!-- n7&#45;&gt;n18 -->
<g id="edge24" class="edge">
<title>n7&#45;&gt;n18</title>
<path fill="none" stroke="black" d="M281.46,-499.72C288.22,-510.82 297.93,-525.83 307.88,-538 322.64,-556.05 334.56,-554.19 345.07,-575 369.59,-623.53 354.17,-642.36 363.07,-696 366.78,-718.32 371.41,-743.47 374.98,-762.43"/>
<polygon fill="black" stroke="black" points="371.52,-762.97 376.83,-772.14 378.4,-761.66 371.52,-762.97"/>
</g>
<!-- out_0 -->
<g id="node24" class="node">
<title>out_0</title>
<polygon fill="lightgreen" stroke="black" points="737.53,-498 639.03,-498 639.03,-462 737.53,-462 737.53,-498"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-474.95" font-family="Times,serif" font-size="14.00">cold_shutdown</text>
</g>
<!-- n7&#45;&gt;out_0 -->
<g id="edge35" class="edge">
<title>n7&#45;&gt;out_0</title>
<path fill="none" stroke="black" d="M290.31,-482.93C311.81,-481.74 348.85,-480 380.67,-480 380.67,-480 380.67,-480 548.24,-480 574.19,-480 602.85,-480 627.38,-480"/>
<polygon fill="black" stroke="black" points="627.19,-483.5 637.19,-480 627.19,-476.5 627.19,-483.5"/>
</g>
<!-- n8&#45;&gt;n9 -->
<g id="edge6" class="edge">
<title>n8&#45;&gt;n9</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M277.18,-293C285.98,-260.89 303.95,-196.75 307.88,-193.5 319.95,-183.55 337.24,-181.44 351.94,-181.92"/>
<polygon fill="red" stroke="red" points="351.28,-185.38 361.52,-182.65 351.81,-178.4 351.28,-185.38"/>
<text xml:space="preserve" text-anchor="middle" x="326.48" y="-196.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n20 -->
<g id="node21" class="node">
<title>n20</title>
<ellipse fill="white" stroke="black" cx="492.05" cy="-603" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="492.05" y="-597.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n8&#45;&gt;n20 -->
<g id="edge27" class="edge">
<title>n8&#45;&gt;n20</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M289.79,-307.06C316.67,-302.1 368.36,-297.03 400.27,-322.5 477.94,-384.51 490.02,-513.84 491.32,-572.68"/>
<polygon fill="red" stroke="red" points="487.82,-572.65 491.43,-582.61 494.81,-572.57 487.82,-572.65"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-325.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- out_1 -->
<g id="node25" class="node">
<title>out_1</title>
<polygon fill="lightgreen" stroke="black" points="715.28,-204 661.28,-204 661.28,-168 715.28,-168 715.28,-204"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-180.95" font-family="Times,serif" font-size="14.00">scram</text>
</g>
<!-- n9&#45;&gt;out_1 -->
<g id="edge36" class="edge">
<title>n9&#45;&gt;out_1</title>
<path fill="none" stroke="black" d="M400.36,-186C448.76,-186 584.08,-186 650.11,-186"/>
<polygon fill="black" stroke="black" points="649.7,-189.5 659.7,-186 649.7,-182.5 649.7,-189.5"/>
</g>
<!-- n10&#45;&gt;n11 -->
<g id="edge10" class="edge">
<title>n10&#45;&gt;n11</title>
<path fill="none" stroke="black" d="M231.71,-672.21C249.75,-658.9 280.65,-636.09 302.02,-620.31"/>
<polygon fill="black" stroke="black" points="303.91,-623.27 309.88,-614.52 299.75,-617.64 303.91,-623.27"/>
</g>
<!-- n10&#45;&gt;n17 -->
<g id="edge22" class="edge">
<title>n10&#45;&gt;n17</title>
<path fill="none" stroke="black" d="M234.91,-681.37C262.94,-678.8 317.6,-673.78 351.44,-670.68"/>
<polygon fill="black" stroke="black" points="351.73,-674.17 361.37,-669.77 351.09,-667.2 351.73,-674.17"/>
</g>
<!-- n11&#45;&gt;n15 -->
<g id="edge18" class="edge">
<title>n11&#45;&gt;n15</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M345.38,-602.01C362.01,-601.09 387.08,-599.7 406.61,-598.62"/>
<polygon fill="red" stroke="red" points="406.64,-602.12 416.43,-598.08 406.25,-595.13 406.64,-602.12"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-604.09" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n14 -->
<g id="node15" class="node">
<title>n14</title>
<ellipse fill="white" stroke="black" cx="381.67" cy="-834" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-828.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n12&#45;&gt;n14 -->
<g id="edge15" class="edge">
<title>n12&#45;&gt;n14</title>
<path fill="none" stroke="black" d="M234.6,-867.04C262.76,-860.67 318.4,-848.09 352.29,-840.42"/>
<polygon fill="black" stroke="black" points="352.83,-843.89 361.81,-838.27 351.29,-837.06 352.83,-843.89"/>
</g>
<!-- n19 -->
<g id="node20" class="node">
<title>n19</title>
<ellipse fill="white" stroke="black" cx="492.05" cy="-795" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="492.05" y="-789.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n12&#45;&gt;n19 -->
<g id="edge25" class="edge">
<title>n12&#45;&gt;n19</title>
<path fill="none" stroke="black" d="M234.76,-873.68C268.32,-878.01 343.07,-884.02 400.27,-862 427.04,-851.69 452.9,-831.25 470.12,-815.64"/>
<polygon fill="black" stroke="black" points="472.28,-818.41 477.19,-809.03 467.5,-813.3 472.28,-818.41"/>
</g>
<!-- n13&#45;&gt;n14 -->
<g id="edge16" class="edge">
<title>n13&#45;&gt;n14</title>
<path fill="none" stroke="black" d="M285.15,-742.34C303.46,-759.91 337.29,-792.37 359.38,-813.57"/>
<polygon fill="black" stroke="black" points="356.76,-815.91 366.4,-820.31 361.61,-810.86 356.76,-815.91"/>
</g>
<!-- n16 -->
<g id="node17" class="node">
<title>n16</title>
<ellipse fill="white" stroke="black" cx="547.24" cy="-650" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="547.24" y="-644.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n14&#45;&gt;n16 -->
<g id="edge19" class="edge">
<title>n14&#45;&gt;n16</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M397.25,-823.53C422.74,-804.69 475.97,-762.83 510.65,-718 520.2,-705.65 528.47,-690.36 534.62,-677.4"/>
<polygon fill="red" stroke="red" points="537.69,-679.12 538.65,-668.57 531.32,-676.21 537.69,-679.12"/>
<text xml:space="preserve" text-anchor="middle" x="436.86" y="-809" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n15&#45;&gt;n16 -->
<g id="edge20" class="edge">
<title>n15&#45;&gt;n16</title>
<path fill="none" stroke="black" d="M449.94,-610.4C456.37,-616.83 464.74,-624.16 473.46,-629 487.11,-636.58 503.76,-641.64 517.69,-644.9"/>
<polygon fill="black" stroke="black" points="516.63,-648.25 527.14,-646.91 518.09,-641.4 516.63,-648.25"/>
</g>
<!-- out_2 -->
<g id="node26" class="node">
<title>out_2</title>
<polygon fill="lightgreen" stroke="black" points="715.28,-668 661.28,-668 661.28,-632 715.28,-632 715.28,-668"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-644.95" font-family="Times,serif" font-size="14.00">heatup</text>
</g>
<!-- n16&#45;&gt;out_2 -->
<g id="edge37" class="edge">
<title>n16&#45;&gt;out_2</title>
<path fill="none" stroke="black" d="M566.14,-650C587.09,-650 622.39,-650 649.49,-650"/>
<polygon fill="black" stroke="black" points="649.4,-653.5 659.4,-650 649.4,-646.5 649.4,-653.5"/>
</g>
<!-- n17&#45;&gt;n20 -->
<g id="edge28" class="edge">
<title>n17&#45;&gt;n20</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M398.34,-658.86C413.12,-650.22 435.86,-636.84 455.46,-625 458.92,-622.91 462.56,-620.68 466.14,-618.49"/>
<polygon fill="red" stroke="red" points="467.89,-621.52 474.56,-613.28 464.22,-615.56 467.89,-621.52"/>
<text xml:space="preserve" text-anchor="middle" x="436.86" y="-649.5" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n22 -->
<g id="node23" class="node">
<title>n22</title>
<ellipse fill="white" stroke="black" cx="602.44" cy="-775" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="602.44" y="-769.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n17&#45;&gt;n22 -->
<g id="edge31" class="edge">
<title>n17&#45;&gt;n22</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M400.56,-670.76C435.16,-676.78 512.54,-693.67 565.84,-731 573.14,-736.11 579.74,-743.13 585.22,-750.06"/>
<polygon fill="red" stroke="red" points="582.33,-752.04 591.06,-758.05 587.98,-747.91 582.33,-752.04"/>
<text xml:space="preserve" text-anchor="middle" x="492.05" y="-704.07" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n18&#45;&gt;n19 -->
<g id="edge26" class="edge">
<title>n18&#45;&gt;n19</title>
<path fill="none" stroke="black" d="M400.57,-792.5C417.2,-792.96 442.27,-793.65 461.8,-794.19"/>
<polygon fill="black" stroke="black" points="461.52,-797.68 471.62,-794.46 461.72,-790.69 461.52,-797.68"/>
</g>
<!-- n21 -->
<g id="node22" class="node">
<title>n21</title>
<ellipse fill="white" stroke="black" cx="602.44" cy="-713" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="602.44" y="-707.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n19&#45;&gt;n21 -->
<g id="edge29" class="edge">
<title>n19&#45;&gt;n21</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M505.77,-782.05C512.36,-775.59 520.68,-767.84 528.65,-761.5 543.76,-749.49 561.82,-737.45 576.16,-728.37"/>
<polygon fill="red" stroke="red" points="577.94,-731.38 584.58,-723.12 574.24,-725.44 577.94,-731.38"/>
<text xml:space="preserve" text-anchor="middle" x="547.24" y="-764.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n19&#45;&gt;n22 -->
<g id="edge32" class="edge">
<title>n19&#45;&gt;n22</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M510.47,-791.79C527.19,-788.7 552.78,-783.98 572.56,-780.33"/>
<polygon fill="red" stroke="red" points="573.02,-783.8 582.22,-778.55 571.75,-776.92 573.02,-783.8"/>
<text xml:space="preserve" text-anchor="middle" x="547.24" y="-791.16" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n20&#45;&gt;n21 -->
<g id="edge30" class="edge">
<title>n20&#45;&gt;n21</title>
<path fill="none" stroke="black" d="M511.04,-603.26C527.22,-604.42 550.71,-608.55 565.84,-622 583.54,-637.73 592.52,-663.37 597.03,-683.43"/>
<polygon fill="black" stroke="black" points="593.55,-683.85 598.91,-692.99 600.41,-682.5 593.55,-683.85"/>
</g>
<!-- n21&#45;&gt;n5 -->
<g id="edge33" class="edge">
<title>n21&#45;&gt;n5</title>
<path fill="none" stroke="black" d="M600.84,-694.19C599.03,-651.12 592.03,-542.43 565.84,-456 521.9,-311 532.11,-232.66 400.27,-158 304.5,-103.78 205.34,-255.86 168.47,-320.99"/>
<polygon fill="black" stroke="black" points="165.64,-318.89 163.84,-329.33 171.76,-322.29 165.64,-318.89"/>
</g>
<!-- n22&#45;&gt;n6 -->
<g id="edge34" class="edge">
<title>n22&#45;&gt;n6</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M591.9,-759.21C588.9,-753.63 585.85,-747.2 583.84,-741 567.33,-690.12 579.55,-673.7 565.84,-622 558.4,-593.96 533.72,-337.34 400.27,-285.5 384.86,-279.51 377.53,-277.48 363.07,-285.5 309.28,-315.37 323.83,-351.69 289.88,-403 274,-427 265.19,-430.08 252.69,-456 240.41,-481.46 253.23,-495.66 234.69,-517 223.14,-530.3 205.82,-539.09 190.15,-544.75"/>
<polygon fill="red" stroke="red" points="189.5,-541.28 181.08,-547.71 191.68,-547.93 189.5,-541.28"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-288.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

View File

@ -0,0 +1,437 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 14.1.4 (20260321.0153)
-->
<!-- Title: aiger Pages: 1 -->
<svg width="746pt" height="898pt"
viewBox="0.00 0.00 746.00 898.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 893.6)">
<title>aiger</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-893.6 741.53,-893.6 741.53,4 -4,4"/>
<!-- n0 -->
<g id="node1" class="node">
<title>n0</title>
<ellipse fill="#e5e5e5" stroke="black" cx="152.5" cy="-45" rx="18" ry="18"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-39.95" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- out_3 -->
<g id="node27" class="node">
<title>out_3</title>
<polygon fill="lightgreen" stroke="black" points="721.78,-90 654.78,-90 654.78,-54 721.78,-54 721.78,-90"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-66.95" font-family="Times,serif" font-size="14.00">op_mode</text>
</g>
<!-- n0&#45;&gt;out_3 -->
<g id="edge38" class="edge">
<title>n0&#45;&gt;out_3</title>
<path fill="none" stroke="black" d="M169.86,-51.26C192.2,-59.24 233.66,-72 270.29,-72 270.29,-72 270.29,-72 548.24,-72 580.03,-72 615.91,-72 643.25,-72"/>
<polygon fill="black" stroke="black" points="642.9,-75.5 652.9,-72 642.9,-68.5 642.9,-75.5"/>
</g>
<!-- out_4 -->
<g id="node28" class="node">
<title>out_4</title>
<polygon fill="lightgreen" stroke="black" points="728.91,-36 647.66,-36 647.66,0 728.91,0 728.91,-36"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-12.95" font-family="Times,serif" font-size="14.00">load_follow</text>
</g>
<!-- n0&#45;&gt;out_4 -->
<g id="edge39" class="edge">
<title>n0&#45;&gt;out_4</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M169.86,-38.74C192.2,-30.76 233.66,-18 270.29,-18 270.29,-18 270.29,-18 548.24,-18 577.37,-18 609.92,-18 636.2,-18"/>
<polygon fill="red" stroke="red" points="635.91,-21.5 645.91,-18 635.91,-14.5 635.91,-21.5"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-21.2" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n1 -->
<g id="node2" class="node">
<title>n1</title>
<polygon fill="lightblue" stroke="black" points="107.5,-826 0,-826 0,-790 107.5,-790 107.5,-826"/>
<text xml:space="preserve" text-anchor="middle" x="53.75" y="-802.95" font-family="Times,serif" font-size="14.00">t_max_exceeded</text>
</g>
<!-- n10 -->
<g id="node11" class="node">
<title>n10</title>
<ellipse fill="white" stroke="black" cx="216.1" cy="-683" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-677.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n1&#45;&gt;n10 -->
<g id="edge7" class="edge">
<title>n1&#45;&gt;n10</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M103.65,-789.56C128.43,-778.49 157.78,-762.53 179.5,-742 188.89,-733.12 196.69,-721.24 202.57,-710.46"/>
<polygon fill="red" stroke="red" points="205.69,-712.05 207.12,-701.55 199.46,-708.87 205.69,-712.05"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-782.05" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n12 -->
<g id="node13" class="node">
<title>n12</title>
<ellipse fill="white" stroke="black" cx="216.1" cy="-871" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-865.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n1&#45;&gt;n12 -->
<g id="edge11" class="edge">
<title>n1&#45;&gt;n12</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M107.83,-823.57C130.32,-830.81 156.58,-840.11 179.5,-850.5 182.94,-852.06 186.49,-853.85 189.94,-855.71"/>
<polygon fill="red" stroke="red" points="188.11,-858.7 198.53,-860.6 191.57,-852.61 188.11,-858.7"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-853.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n2 -->
<g id="node3" class="node">
<title>n2</title>
<polygon fill="lightblue" stroke="black" points="104.12,-889 3.38,-889 3.38,-853 104.12,-853 104.12,-889"/>
<text xml:space="preserve" text-anchor="middle" x="53.75" y="-865.95" font-family="Times,serif" font-size="14.00">t_dot_exceeded</text>
</g>
<!-- n2&#45;&gt;n12 -->
<g id="edge12" class="edge">
<title>n2&#45;&gt;n12</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M104.61,-871C131.26,-871 163.15,-871 185.8,-871"/>
<polygon fill="red" stroke="red" points="185.53,-874.5 195.53,-871 185.53,-867.5 185.53,-874.5"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-874.2" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n3 -->
<g id="node4" class="node">
<title>n3</title>
<polygon fill="lightblue" stroke="black" points="80.75,-701 26.75,-701 26.75,-665 80.75,-665 80.75,-701"/>
<text xml:space="preserve" text-anchor="middle" x="53.75" y="-677.95" font-family="Times,serif" font-size="14.00">startup</text>
</g>
<!-- n3&#45;&gt;n10 -->
<g id="edge8" class="edge">
<title>n3&#45;&gt;n10</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M81.23,-683C110,-683 155.84,-683 185.7,-683"/>
<polygon fill="red" stroke="red" points="185.54,-686.5 195.54,-683 185.54,-679.5 185.54,-686.5"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-686.2" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n4 -->
<g id="node5" class="node">
<title>n4</title>
<polygon fill="lightblue" stroke="black" points="98.12,-766 9.38,-766 9.38,-730 98.12,-730 98.12,-766"/>
<text xml:space="preserve" text-anchor="middle" x="53.75" y="-742.95" font-family="Times,serif" font-size="14.00">t_power_min</text>
</g>
<!-- n13 -->
<g id="node14" class="node">
<title>n13</title>
<ellipse fill="white" stroke="black" cx="271.29" cy="-730" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="271.29" y="-724.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n4&#45;&gt;n13 -->
<g id="edge13" class="edge">
<title>n4&#45;&gt;n13</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M96.32,-729.62C105.74,-726.25 115.82,-723.25 125.5,-721.5 165.35,-714.28 212.28,-719.49 241.66,-724.36"/>
<polygon fill="red" stroke="red" points="240.8,-727.76 251.25,-726.05 242.01,-720.87 240.8,-727.76"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-724.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n18 -->
<g id="node19" class="node">
<title>n18</title>
<ellipse fill="white" stroke="black" cx="381.67" cy="-792" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-786.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n4&#45;&gt;n18 -->
<g id="edge23" class="edge">
<title>n4&#45;&gt;n18</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M86.11,-766.47C98.04,-772.57 112.01,-778.65 125.5,-782 205.25,-801.82 303.29,-798.18 351.33,-794.66"/>
<polygon fill="red" stroke="red" points="351.49,-798.16 361.18,-793.88 350.93,-791.18 351.49,-798.16"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-799.59" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n5 -->
<g id="node6" class="node">
<title>n5</title>
<path fill="lightyellow" stroke="black" d="M167.5,-367C167.5,-367 137.5,-367 137.5,-367 131.5,-367 125.5,-361 125.5,-355 125.5,-355 125.5,-343 125.5,-343 125.5,-337 131.5,-331 137.5,-331 137.5,-331 167.5,-331 167.5,-331 173.5,-331 179.5,-337 179.5,-343 179.5,-343 179.5,-355 179.5,-355 179.5,-361 173.5,-367 167.5,-367"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-343.95" font-family="Times,serif" font-size="14.00">L0</text>
</g>
<!-- n7 -->
<g id="node8" class="node">
<title>n7</title>
<ellipse fill="white" stroke="black" cx="271.29" cy="-484" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="271.29" y="-478.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n5&#45;&gt;n7 -->
<g id="edge1" class="edge">
<title>n5&#45;&gt;n7</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M169.49,-367.49C190.73,-392.03 228.2,-435.34 250.98,-461.68"/>
<polygon fill="red" stroke="red" points="248.2,-463.81 257.39,-469.09 253.49,-459.23 248.2,-463.81"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-443.53" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n8 -->
<g id="node9" class="node">
<title>n8</title>
<ellipse fill="white" stroke="black" cx="271.29" cy="-311" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="271.29" y="-305.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n5&#45;&gt;n8 -->
<g id="edge3" class="edge">
<title>n5&#45;&gt;n8</title>
<path fill="none" stroke="black" d="M179.71,-340.47C198.4,-334.39 223.48,-326.23 242.52,-320.04"/>
<polygon fill="black" stroke="black" points="243.34,-323.45 251.76,-317.03 241.17,-316.79 243.34,-323.45"/>
</g>
<!-- n15 -->
<g id="node16" class="node">
<title>n15</title>
<ellipse fill="white" stroke="black" cx="436.86" cy="-597" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="436.86" y="-591.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n5&#45;&gt;n15 -->
<g id="edge17" class="edge">
<title>n5&#45;&gt;n15</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M179.67,-362.9C195.87,-371.81 216.9,-383.93 234.69,-396 311.85,-448.35 384.65,-532.85 417.53,-573.58"/>
<polygon fill="red" stroke="red" points="414.73,-575.68 423.7,-581.31 420.2,-571.31 414.73,-575.68"/>
<text xml:space="preserve" text-anchor="middle" x="271.29" y="-440.28" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n6 -->
<g id="node7" class="node">
<title>n6</title>
<path fill="lightyellow" stroke="black" d="M167.5,-572C167.5,-572 137.5,-572 137.5,-572 131.5,-572 125.5,-566 125.5,-560 125.5,-560 125.5,-548 125.5,-548 125.5,-542 131.5,-536 137.5,-536 137.5,-536 167.5,-536 167.5,-536 173.5,-536 179.5,-542 179.5,-548 179.5,-548 179.5,-560 179.5,-560 179.5,-566 173.5,-572 167.5,-572"/>
<text xml:space="preserve" text-anchor="middle" x="152.5" y="-548.95" font-family="Times,serif" font-size="14.00">L1</text>
</g>
<!-- n6&#45;&gt;n7 -->
<g id="edge2" class="edge">
<title>n6&#45;&gt;n7</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M179.71,-538.29C199.32,-526.54 225.97,-510.56 245.28,-498.99"/>
<polygon fill="red" stroke="red" points="246.83,-502.14 253.6,-494 243.23,-496.14 246.83,-502.14"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-530.53" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n6&#45;&gt;n8 -->
<g id="edge4" class="edge">
<title>n6&#45;&gt;n8</title>
<path fill="none" stroke="black" d="M156.33,-535.69C161.42,-506.06 173.89,-446.35 197.5,-401 211.17,-374.74 233.21,-348.9 249.46,-331.69"/>
<polygon fill="black" stroke="black" points="251.87,-334.23 256.31,-324.61 246.84,-329.37 251.87,-334.23"/>
</g>
<!-- n11 -->
<g id="node12" class="node">
<title>n11</title>
<ellipse fill="white" stroke="black" cx="326.48" cy="-603" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="326.48" y="-597.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n6&#45;&gt;n11 -->
<g id="edge9" class="edge">
<title>n6&#45;&gt;n11</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M179.99,-561.55C211.71,-570.59 264.62,-585.66 297.14,-594.93"/>
<polygon fill="red" stroke="red" points="296.09,-598.26 306.66,-597.64 298,-591.53 296.09,-598.26"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-579.6" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n6&#45;&gt;n13 -->
<g id="edge14" class="edge">
<title>n6&#45;&gt;n13</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M171.69,-572.16C194.13,-594.68 229.93,-631.04 234.69,-638.5 247.07,-657.89 256.29,-682.27 262.24,-700.99"/>
<polygon fill="red" stroke="red" points="258.84,-701.82 265.09,-710.37 265.54,-699.78 258.84,-701.82"/>
<text xml:space="preserve" text-anchor="middle" x="216.1" y="-641.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n9 -->
<g id="node10" class="node">
<title>n9</title>
<ellipse fill="white" stroke="black" cx="381.67" cy="-186" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-180.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n7&#45;&gt;n9 -->
<g id="edge5" class="edge">
<title>n7&#45;&gt;n9</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M278,-466.31C291.67,-424.27 327.82,-315.2 363.07,-226 364.75,-221.76 366.61,-217.3 368.48,-212.96"/>
<polygon fill="red" stroke="red" points="371.59,-214.57 372.41,-204 365.19,-211.75 371.59,-214.57"/>
<text xml:space="preserve" text-anchor="middle" x="326.48" y="-375.42" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n17 -->
<g id="node18" class="node">
<title>n17</title>
<ellipse fill="white" stroke="black" cx="381.67" cy="-668" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-662.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n7&#45;&gt;n17 -->
<g id="edge21" class="edge">
<title>n7&#45;&gt;n17</title>
<path fill="none" stroke="black" d="M288.27,-492.39C305.07,-502.07 330.98,-519.56 345.07,-542 364.23,-572.49 352.74,-586.5 363.07,-621 364.95,-627.26 367.24,-633.89 369.53,-640.13"/>
<polygon fill="black" stroke="black" points="366.22,-641.26 373.05,-649.37 372.76,-638.77 366.22,-641.26"/>
</g>
<!-- n7&#45;&gt;n18 -->
<g id="edge24" class="edge">
<title>n7&#45;&gt;n18</title>
<path fill="none" stroke="black" d="M281.46,-499.72C288.22,-510.82 297.93,-525.83 307.88,-538 322.64,-556.05 334.56,-554.19 345.07,-575 369.59,-623.53 354.17,-642.36 363.07,-696 366.78,-718.32 371.41,-743.47 374.98,-762.43"/>
<polygon fill="black" stroke="black" points="371.52,-762.97 376.83,-772.14 378.4,-761.66 371.52,-762.97"/>
</g>
<!-- out_0 -->
<g id="node24" class="node">
<title>out_0</title>
<polygon fill="lightgreen" stroke="black" points="737.53,-498 639.03,-498 639.03,-462 737.53,-462 737.53,-498"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-474.95" font-family="Times,serif" font-size="14.00">cold_shutdown</text>
</g>
<!-- n7&#45;&gt;out_0 -->
<g id="edge35" class="edge">
<title>n7&#45;&gt;out_0</title>
<path fill="none" stroke="black" d="M290.31,-482.93C311.81,-481.74 348.85,-480 380.67,-480 380.67,-480 380.67,-480 548.24,-480 574.19,-480 602.85,-480 627.38,-480"/>
<polygon fill="black" stroke="black" points="627.19,-483.5 637.19,-480 627.19,-476.5 627.19,-483.5"/>
</g>
<!-- n8&#45;&gt;n9 -->
<g id="edge6" class="edge">
<title>n8&#45;&gt;n9</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M277.18,-293C285.98,-260.89 303.95,-196.75 307.88,-193.5 319.95,-183.55 337.24,-181.44 351.94,-181.92"/>
<polygon fill="red" stroke="red" points="351.28,-185.38 361.52,-182.65 351.81,-178.4 351.28,-185.38"/>
<text xml:space="preserve" text-anchor="middle" x="326.48" y="-196.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n20 -->
<g id="node21" class="node">
<title>n20</title>
<ellipse fill="white" stroke="black" cx="492.05" cy="-603" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="492.05" y="-597.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n8&#45;&gt;n20 -->
<g id="edge27" class="edge">
<title>n8&#45;&gt;n20</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M289.79,-307.06C316.67,-302.1 368.36,-297.03 400.27,-322.5 477.94,-384.51 490.02,-513.84 491.32,-572.68"/>
<polygon fill="red" stroke="red" points="487.82,-572.65 491.43,-582.61 494.81,-572.57 487.82,-572.65"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-325.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- out_1 -->
<g id="node25" class="node">
<title>out_1</title>
<polygon fill="lightgreen" stroke="black" points="715.28,-204 661.28,-204 661.28,-168 715.28,-168 715.28,-204"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-180.95" font-family="Times,serif" font-size="14.00">scram</text>
</g>
<!-- n9&#45;&gt;out_1 -->
<g id="edge36" class="edge">
<title>n9&#45;&gt;out_1</title>
<path fill="none" stroke="black" d="M400.36,-186C448.76,-186 584.08,-186 650.11,-186"/>
<polygon fill="black" stroke="black" points="649.7,-189.5 659.7,-186 649.7,-182.5 649.7,-189.5"/>
</g>
<!-- n10&#45;&gt;n11 -->
<g id="edge10" class="edge">
<title>n10&#45;&gt;n11</title>
<path fill="none" stroke="black" d="M231.71,-672.21C249.75,-658.9 280.65,-636.09 302.02,-620.31"/>
<polygon fill="black" stroke="black" points="303.91,-623.27 309.88,-614.52 299.75,-617.64 303.91,-623.27"/>
</g>
<!-- n10&#45;&gt;n17 -->
<g id="edge22" class="edge">
<title>n10&#45;&gt;n17</title>
<path fill="none" stroke="black" d="M234.91,-681.37C262.94,-678.8 317.6,-673.78 351.44,-670.68"/>
<polygon fill="black" stroke="black" points="351.73,-674.17 361.37,-669.77 351.09,-667.2 351.73,-674.17"/>
</g>
<!-- n11&#45;&gt;n15 -->
<g id="edge18" class="edge">
<title>n11&#45;&gt;n15</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M345.38,-602.01C362.01,-601.09 387.08,-599.7 406.61,-598.62"/>
<polygon fill="red" stroke="red" points="406.64,-602.12 416.43,-598.08 406.25,-595.13 406.64,-602.12"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-604.09" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n14 -->
<g id="node15" class="node">
<title>n14</title>
<ellipse fill="white" stroke="black" cx="381.67" cy="-834" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-828.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n12&#45;&gt;n14 -->
<g id="edge15" class="edge">
<title>n12&#45;&gt;n14</title>
<path fill="none" stroke="black" d="M234.6,-867.04C262.76,-860.67 318.4,-848.09 352.29,-840.42"/>
<polygon fill="black" stroke="black" points="352.83,-843.89 361.81,-838.27 351.29,-837.06 352.83,-843.89"/>
</g>
<!-- n19 -->
<g id="node20" class="node">
<title>n19</title>
<ellipse fill="white" stroke="black" cx="492.05" cy="-795" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="492.05" y="-789.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n12&#45;&gt;n19 -->
<g id="edge25" class="edge">
<title>n12&#45;&gt;n19</title>
<path fill="none" stroke="black" d="M234.76,-873.68C268.32,-878.01 343.07,-884.02 400.27,-862 427.04,-851.69 452.9,-831.25 470.12,-815.64"/>
<polygon fill="black" stroke="black" points="472.28,-818.41 477.19,-809.03 467.5,-813.3 472.28,-818.41"/>
</g>
<!-- n13&#45;&gt;n14 -->
<g id="edge16" class="edge">
<title>n13&#45;&gt;n14</title>
<path fill="none" stroke="black" d="M285.15,-742.34C303.46,-759.91 337.29,-792.37 359.38,-813.57"/>
<polygon fill="black" stroke="black" points="356.76,-815.91 366.4,-820.31 361.61,-810.86 356.76,-815.91"/>
</g>
<!-- n16 -->
<g id="node17" class="node">
<title>n16</title>
<ellipse fill="white" stroke="black" cx="547.24" cy="-650" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="547.24" y="-644.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n14&#45;&gt;n16 -->
<g id="edge19" class="edge">
<title>n14&#45;&gt;n16</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M397.25,-823.53C422.74,-804.69 475.97,-762.83 510.65,-718 520.2,-705.65 528.47,-690.36 534.62,-677.4"/>
<polygon fill="red" stroke="red" points="537.69,-679.12 538.65,-668.57 531.32,-676.21 537.69,-679.12"/>
<text xml:space="preserve" text-anchor="middle" x="436.86" y="-809" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n15&#45;&gt;n16 -->
<g id="edge20" class="edge">
<title>n15&#45;&gt;n16</title>
<path fill="none" stroke="black" d="M449.94,-610.4C456.37,-616.83 464.74,-624.16 473.46,-629 487.11,-636.58 503.76,-641.64 517.69,-644.9"/>
<polygon fill="black" stroke="black" points="516.63,-648.25 527.14,-646.91 518.09,-641.4 516.63,-648.25"/>
</g>
<!-- out_2 -->
<g id="node26" class="node">
<title>out_2</title>
<polygon fill="lightgreen" stroke="black" points="715.28,-668 661.28,-668 661.28,-632 715.28,-632 715.28,-668"/>
<text xml:space="preserve" text-anchor="middle" x="688.28" y="-644.95" font-family="Times,serif" font-size="14.00">heatup</text>
</g>
<!-- n16&#45;&gt;out_2 -->
<g id="edge37" class="edge">
<title>n16&#45;&gt;out_2</title>
<path fill="none" stroke="black" d="M566.14,-650C587.09,-650 622.39,-650 649.49,-650"/>
<polygon fill="black" stroke="black" points="649.4,-653.5 659.4,-650 649.4,-646.5 649.4,-653.5"/>
</g>
<!-- n17&#45;&gt;n20 -->
<g id="edge28" class="edge">
<title>n17&#45;&gt;n20</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M398.34,-658.86C413.12,-650.22 435.86,-636.84 455.46,-625 458.92,-622.91 462.56,-620.68 466.14,-618.49"/>
<polygon fill="red" stroke="red" points="467.89,-621.52 474.56,-613.28 464.22,-615.56 467.89,-621.52"/>
<text xml:space="preserve" text-anchor="middle" x="436.86" y="-649.5" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n22 -->
<g id="node23" class="node">
<title>n22</title>
<ellipse fill="white" stroke="black" cx="602.44" cy="-775" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="602.44" y="-769.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n17&#45;&gt;n22 -->
<g id="edge31" class="edge">
<title>n17&#45;&gt;n22</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M400.56,-670.76C435.16,-676.78 512.54,-693.67 565.84,-731 573.14,-736.11 579.74,-743.13 585.22,-750.06"/>
<polygon fill="red" stroke="red" points="582.33,-752.04 591.06,-758.05 587.98,-747.91 582.33,-752.04"/>
<text xml:space="preserve" text-anchor="middle" x="492.05" y="-704.07" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n18&#45;&gt;n19 -->
<g id="edge26" class="edge">
<title>n18&#45;&gt;n19</title>
<path fill="none" stroke="black" d="M400.57,-792.5C417.2,-792.96 442.27,-793.65 461.8,-794.19"/>
<polygon fill="black" stroke="black" points="461.52,-797.68 471.62,-794.46 461.72,-790.69 461.52,-797.68"/>
</g>
<!-- n21 -->
<g id="node22" class="node">
<title>n21</title>
<ellipse fill="white" stroke="black" cx="602.44" cy="-713" rx="18.6" ry="18.6"/>
<text xml:space="preserve" text-anchor="middle" x="602.44" y="-707.95" font-family="Times,serif" font-size="14.00">&amp;</text>
</g>
<!-- n19&#45;&gt;n21 -->
<g id="edge29" class="edge">
<title>n19&#45;&gt;n21</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M505.77,-782.05C512.36,-775.59 520.68,-767.84 528.65,-761.5 543.76,-749.49 561.82,-737.45 576.16,-728.37"/>
<polygon fill="red" stroke="red" points="577.94,-731.38 584.58,-723.12 574.24,-725.44 577.94,-731.38"/>
<text xml:space="preserve" text-anchor="middle" x="547.24" y="-764.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n19&#45;&gt;n22 -->
<g id="edge32" class="edge">
<title>n19&#45;&gt;n22</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M510.47,-791.79C527.19,-788.7 552.78,-783.98 572.56,-780.33"/>
<polygon fill="red" stroke="red" points="573.02,-783.8 582.22,-778.55 571.75,-776.92 573.02,-783.8"/>
<text xml:space="preserve" text-anchor="middle" x="547.24" y="-791.16" font-family="Times,serif" font-size="14.00">~</text>
</g>
<!-- n20&#45;&gt;n21 -->
<g id="edge30" class="edge">
<title>n20&#45;&gt;n21</title>
<path fill="none" stroke="black" d="M511.04,-603.26C527.22,-604.42 550.71,-608.55 565.84,-622 583.54,-637.73 592.52,-663.37 597.03,-683.43"/>
<polygon fill="black" stroke="black" points="593.55,-683.85 598.91,-692.99 600.41,-682.5 593.55,-683.85"/>
</g>
<!-- n21&#45;&gt;n5 -->
<g id="edge33" class="edge">
<title>n21&#45;&gt;n5</title>
<path fill="none" stroke="black" d="M600.84,-694.19C599.03,-651.12 592.03,-542.43 565.84,-456 521.9,-311 532.11,-232.66 400.27,-158 304.5,-103.78 205.34,-255.86 168.47,-320.99"/>
<polygon fill="black" stroke="black" points="165.64,-318.89 163.84,-329.33 171.76,-322.29 165.64,-318.89"/>
</g>
<!-- n22&#45;&gt;n6 -->
<g id="edge34" class="edge">
<title>n22&#45;&gt;n6</title>
<path fill="none" stroke="red" stroke-dasharray="5,2" d="M591.9,-759.21C588.9,-753.63 585.85,-747.2 583.84,-741 567.33,-690.12 579.55,-673.7 565.84,-622 558.4,-593.96 533.72,-337.34 400.27,-285.5 384.86,-279.51 377.53,-277.48 363.07,-285.5 309.28,-315.37 323.83,-351.69 289.88,-403 274,-427 265.19,-430.08 252.69,-456 240.41,-481.46 253.23,-495.66 234.69,-517 223.14,-530.3 205.82,-539.09 190.15,-544.75"/>
<polygon fill="red" stroke="red" points="189.5,-541.28 181.08,-547.71 191.68,-547.93 189.5,-541.28"/>
<text xml:space="preserve" text-anchor="middle" x="381.67" y="-288.7" font-family="Times,serif" font-size="14.00">~</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,842 @@
[
{
"reqid": "DRC_S004_SCRAM_STAY",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "Whenever control_mode = q_scram & !manual_reset DRC shall at the next timepoint satisfy control_mode = q_scram",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "holding",
"probability": "null",
"timing": "next",
"response": "satisfaction",
"variables": [
"control_mode",
"q_scram",
"manual_reset"
],
"qualifier_word": "whenever",
"pre_condition": "(control_mode = q_scram & ! manual_reset)",
"regular_condition": "(control_mode = q_scram & ! manual_reset)",
"conditionTextRange": [
0,
46
],
"component_name": "DRC",
"componentTextRange": [
50,
52
],
"timingTextRange": [
60,
80
],
"post_condition": "(control_mode = q_scram)",
"responseTextRange": [
82,
111
],
"diagramVariables": "CC = <b><i>(control_mode = q_scram & ! manual_reset)</i></b>, Response = <b><i>(control_mode = q_scram)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: every point in the interval where <b><i>(control_mode = q_scram & ! manual_reset)</i></b> is true.<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_scram)</i></b> must hold at the next time step.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: every point in the interval where <b><i>(control_mode = q_scram & ! manual_reset)</i></b> is true.<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_scram)</i></b> must hold at the next time step.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_holding_next_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"regular_condition_unexp_pt": "((control_mode = q_scram) & (! manual_reset))",
"regular_condition_unexp_ft": "((control_mode = q_scram) & (! manual_reset))",
"regular_condition_unexp_pctl": "((control_mode = q_scram) & (! manual_reset))",
"regular_condition_SMV_pt": "((control_mode = q_scram) & (! manual_reset))",
"regular_condition_SMV_ft": "((control_mode = q_scram) & (! manual_reset))",
"regular_condition_MLTL_ft": "((control_mode = q_scram) & (! manual_reset))",
"regular_condition_PRISM_pctl": "((control_mode = q_scram) & (! manual_reset))",
"post_condition_unexp_pt": "(control_mode = q_scram)",
"post_condition_unexp_ft": "(control_mode = q_scram)",
"post_condition_unexp_pctl": "(control_mode = q_scram)",
"post_condition_SMV_pt": "(control_mode = q_scram)",
"post_condition_SMV_ft": "(control_mode = q_scram)",
"post_condition_MLTL_ft": "(control_mode = q_scram)",
"post_condition_PRISM_pctl": "(control_mode = q_scram)",
"ft": "(LAST V (((control_mode = q_scram) & (! manual_reset)) -> (LAST | (X (control_mode = q_scram)))))",
"pt": "(H ((Y ((control_mode = q_scram) & (! manual_reset))) -> ((control_mode = q_scram) | (Z FALSE))))",
"pctl": "P>=1[(G (((control_mode = q_scram) & (! manual_reset)) => (P>=1[(LAST | (X (control_mode = q_scram)))])))]",
"ptExpanded": "(H ((Y ((control_mode = q_scram) & (! manual_reset))) -> ((control_mode = q_scram) | (Z FALSE))))",
"CoCoSpecCode": "H((YtoPre(((control_mode = q_scram) and not (manual_reset))) => ((control_mode = q_scram) or ZtoPre(false))))",
"ftExpanded": "(LAST V (((control_mode = q_scram) & (! manual_reset)) -> (LAST | (X (control_mode = q_scram)))))",
"pctlExpanded": "P>=1[(G (((control_mode = q_scram) & (! manual_reset)) => (P>=1[(false | (X (control_mode = q_scram)))])))]",
"ftInfAUExpanded": "(G (((control_mode = q_scram) & (! manual_reset)) -> (X (control_mode = q_scram))))",
"mltlExpanded": "(G[0,M] (p0 -> (F[1,1] p1)))",
"WESTMapping": "p0: ((control_mode = q_scram) & (! manual_reset))<br/>p1: (control_mode = q_scram)",
"R2U2Code": "(((control_mode == q_scram) && (! manual_reset)) -> (F[1,1] (control_mode == q_scram)))",
"component": "DRC"
},
"status": "",
"_id": "68403100-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_T001_SHUTDOWN_TO_HEATUP",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "Upon control_mode = q_shutdown & t_avg_above_min DRC shall at the next timepoint satisfy control_mode = q_heatup",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "regular",
"probability": "null",
"timing": "next",
"response": "satisfaction",
"variables": [
"control_mode",
"q_shutdown",
"t_avg_above_min",
"q_heatup"
],
"qualifier_word": "upon",
"pre_condition": "(control_mode = q_shutdown & t_avg_above_min)",
"regular_condition": "(control_mode = q_shutdown & t_avg_above_min)",
"conditionTextRange": [
0,
47
],
"component_name": "DRC",
"componentTextRange": [
51,
53
],
"timingTextRange": [
61,
81
],
"post_condition": "(control_mode = q_heatup)",
"responseTextRange": [
83,
113
],
"diagramVariables": "TC = <b><i>(control_mode = q_shutdown & t_avg_above_min)</i></b>, Response = <b><i>(control_mode = q_heatup)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_shutdown & t_avg_above_min)</i></b> is true and any point in the interval where <b><i>(control_mode = q_shutdown & t_avg_above_min)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_heatup)</i></b> must hold at the next time step.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_shutdown & t_avg_above_min)</i></b> is true and any point in the interval where <b><i>(control_mode = q_shutdown & t_avg_above_min)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_heatup)</i></b> must hold at the next time step.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_regular_next_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"regular_condition_unexp_pt": "((control_mode = q_shutdown) & t_avg_above_min)",
"regular_condition_unexp_ft": "((control_mode = q_shutdown) & t_avg_above_min)",
"regular_condition_unexp_pctl": "((control_mode = q_shutdown) & t_avg_above_min)",
"regular_condition_SMV_pt": "((control_mode = q_shutdown) & t_avg_above_min)",
"regular_condition_SMV_ft": "((control_mode = q_shutdown) & t_avg_above_min)",
"regular_condition_MLTL_ft": "((control_mode = q_shutdown) & t_avg_above_min)",
"regular_condition_PRISM_pctl": "((control_mode = q_shutdown) & t_avg_above_min)",
"post_condition_unexp_pt": "(control_mode = q_heatup)",
"post_condition_unexp_ft": "(control_mode = q_heatup)",
"post_condition_unexp_pctl": "(control_mode = q_heatup)",
"post_condition_SMV_pt": "(control_mode = q_heatup)",
"post_condition_SMV_ft": "(control_mode = q_heatup)",
"post_condition_MLTL_ft": "(control_mode = q_heatup)",
"post_condition_PRISM_pctl": "(control_mode = q_heatup)",
"ft": "((LAST V (((! ((control_mode = q_shutdown) & t_avg_above_min)) & ((! LAST) & (X ((control_mode = q_shutdown) & t_avg_above_min)))) -> (X (LAST | (X (control_mode = q_heatup)))))) & (((control_mode = q_shutdown) & t_avg_above_min) -> (LAST | (X (control_mode = q_heatup)))))",
"pt": "(H ((Y (((control_mode = q_shutdown) & t_avg_above_min) & (Z (! ((control_mode = q_shutdown) & t_avg_above_min))))) -> ((control_mode = q_heatup) | (Z FALSE))))",
"pctl": "P>=1[((G (((! ((control_mode = q_shutdown) & t_avg_above_min)) & (X ((control_mode = q_shutdown) & t_avg_above_min))) => (X (P>=1[(LAST | (X (control_mode = q_heatup)))])))) & (((control_mode = q_shutdown) & t_avg_above_min) => (P>=1[(LAST | (X (control_mode = q_heatup)))])))]",
"ptExpanded": "(H ((Y (((control_mode = q_shutdown) & t_avg_above_min) & (Z (! ((control_mode = q_shutdown) & t_avg_above_min))))) -> ((control_mode = q_heatup) | (Z FALSE))))",
"CoCoSpecCode": "H((YtoPre((((control_mode = q_shutdown) and t_avg_above_min) and ZtoPre(not (((control_mode = q_shutdown) and t_avg_above_min))))) => ((control_mode = q_heatup) or ZtoPre(false))))",
"ftExpanded": "((LAST V (((! ((control_mode = q_shutdown) & t_avg_above_min)) & ((! LAST) & (X ((control_mode = q_shutdown) & t_avg_above_min)))) -> (X (LAST | (X (control_mode = q_heatup)))))) & (((control_mode = q_shutdown) & t_avg_above_min) -> (LAST | (X (control_mode = q_heatup)))))",
"pctlExpanded": "P>=1[((G (((! ((control_mode = q_shutdown) & t_avg_above_min)) & (X ((control_mode = q_shutdown) & t_avg_above_min))) => (X (P>=1[(false | (X (control_mode = q_heatup)))])))) & (((control_mode = q_shutdown) & t_avg_above_min) => (P>=1[(false | (X (control_mode = q_heatup)))])))]",
"ftInfAUExpanded": "((G (((! ((control_mode = q_shutdown) & t_avg_above_min)) & (X ((control_mode = q_shutdown) & t_avg_above_min))) -> (X (X (control_mode = q_heatup))))) & (((control_mode = q_shutdown) & t_avg_above_min) -> (X (control_mode = q_heatup))))",
"mltlExpanded": "((G[0,M] (((! p0) & (F[1,1] p0)) -> (F[2,2] p1))) & (p0 -> (F[1,1] p1)))",
"WESTMapping": "p0: ((control_mode = q_shutdown) & t_avg_above_min)<br/>p1: (control_mode = q_heatup)",
"R2U2Code": "((((! ((control_mode == q_shutdown) && t_avg_above_min)) && (F[1,1] ((control_mode == q_shutdown) && t_avg_above_min))) -> (F[2,2] (control_mode == q_heatup))) && (((TAU == 0) && ((control_mode == q_shutdown) && t_avg_above_min)) -> (F[1,1] (control_mode == q_heatup))))",
"component": "DRC"
},
"status": "",
"_id": "68403101-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_T002_HEATUP_TO_OPERATION",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "Upon control_mode = q_heatup & t_avg_in_range & p_above_crit & inv1_holds DRC shall at the next timepoint satisfy control_mode = q_operation",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "regular",
"probability": "null",
"timing": "next",
"response": "satisfaction",
"variables": [
"control_mode",
"q_heatup",
"t_avg_in_range",
"p_above_crit",
"inv1_holds",
"q_operation"
],
"qualifier_word": "upon",
"pre_condition": "(control_mode = q_heatup & t_avg_in_range & p_above_crit & inv1_holds)",
"regular_condition": "(control_mode = q_heatup & t_avg_in_range & p_above_crit & inv1_holds)",
"conditionTextRange": [
0,
72
],
"component_name": "DRC",
"componentTextRange": [
75,
77
],
"timingTextRange": [
85,
105
],
"post_condition": "(control_mode = q_operation)",
"responseTextRange": [
107,
140
],
"diagramVariables": "TC = <b><i>(control_mode = q_heatup & t_avg_in_range & p_above_crit & inv1_holds)</i></b>, Response = <b><i>(control_mode = q_operation)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_heatup & t_avg_in_range & p_above_crit & inv1_holds)</i></b> is true and any point in the interval where <b><i>(control_mode = q_heatup & t_avg_in_range & p_above_crit & inv1_holds)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_operation)</i></b> must hold at the next time step.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_heatup & t_avg_in_range & p_above_crit & inv1_holds)</i></b> is true and any point in the interval where <b><i>(control_mode = q_heatup & t_avg_in_range & p_above_crit & inv1_holds)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_operation)</i></b> must hold at the next time step.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_regular_next_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"regular_condition_unexp_pt": "((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)",
"regular_condition_unexp_ft": "((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)",
"regular_condition_unexp_pctl": "((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)",
"regular_condition_SMV_pt": "((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)",
"regular_condition_SMV_ft": "((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)",
"regular_condition_MLTL_ft": "((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)",
"regular_condition_PRISM_pctl": "((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)",
"post_condition_unexp_pt": "(control_mode = q_operation)",
"post_condition_unexp_ft": "(control_mode = q_operation)",
"post_condition_unexp_pctl": "(control_mode = q_operation)",
"post_condition_SMV_pt": "(control_mode = q_operation)",
"post_condition_SMV_ft": "(control_mode = q_operation)",
"post_condition_MLTL_ft": "(control_mode = q_operation)",
"post_condition_PRISM_pctl": "(control_mode = q_operation)",
"ft": "((LAST V (((! ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)) & ((! LAST) & (X ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)))) -> (X (LAST | (X (control_mode = q_operation)))))) & (((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds) -> (LAST | (X (control_mode = q_operation)))))",
"pt": "(H ((Y (((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds) & (Z (! ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds))))) -> ((control_mode = q_operation) | (Z FALSE))))",
"pctl": "P>=1[((G (((! ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)) & (X ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds))) => (X (P>=1[(LAST | (X (control_mode = q_operation)))])))) & (((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds) => (P>=1[(LAST | (X (control_mode = q_operation)))])))]",
"ptExpanded": "(H ((Y (((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds) & (Z (! ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds))))) -> ((control_mode = q_operation) | (Z FALSE))))",
"CoCoSpecCode": "H((YtoPre((((((control_mode = q_heatup) and t_avg_in_range) and p_above_crit) and inv1_holds) and ZtoPre(not (((((control_mode = q_heatup) and t_avg_in_range) and p_above_crit) and inv1_holds))))) => ((control_mode = q_operation) or ZtoPre(false))))",
"ftExpanded": "((LAST V (((! ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)) & ((! LAST) & (X ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)))) -> (X (LAST | (X (control_mode = q_operation)))))) & (((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds) -> (LAST | (X (control_mode = q_operation)))))",
"pctlExpanded": "P>=1[((G (((! ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)) & (X ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds))) => (X (P>=1[(false | (X (control_mode = q_operation)))])))) & (((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds) => (P>=1[(false | (X (control_mode = q_operation)))])))]",
"ftInfAUExpanded": "((G (((! ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)) & (X ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds))) -> (X (X (control_mode = q_operation))))) & (((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds) -> (X (control_mode = q_operation))))",
"mltlExpanded": "((G[0,M] (((! p0) & (F[1,1] p0)) -> (F[2,2] p1))) & (p0 -> (F[1,1] p1)))",
"WESTMapping": "p0: ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)<br/>p1: (control_mode = q_operation)",
"R2U2Code": "((((! ((((control_mode == q_heatup) && t_avg_in_range) && p_above_crit) && inv1_holds)) && (F[1,1] ((((control_mode == q_heatup) && t_avg_in_range) && p_above_crit) && inv1_holds))) -> (F[2,2] (control_mode == q_operation))) && (((TAU == 0) && ((((control_mode == q_heatup) && t_avg_in_range) && p_above_crit) && inv1_holds)) -> (F[1,1] (control_mode == q_operation))))",
"component": "DRC"
},
"status": "",
"_id": "68403102-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_A001_MODE_VALID",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "DRC shall always satisfy control_mode = q_shutdown | control_mode = q_heatup | control_mode = q_operation | control_mode = q_scram",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "null",
"probability": "null",
"timing": "always",
"response": "satisfaction",
"variables": [
"control_mode",
"q_shutdown",
"q_heatup",
"q_operation",
"q_scram"
],
"component_name": "DRC",
"componentTextRange": [
0,
2
],
"timingTextRange": [
10,
15
],
"post_condition": "(control_mode = q_shutdown | control_mode = q_heatup | control_mode = q_operation | control_mode = q_scram)",
"responseTextRange": [
17,
129
],
"diagramVariables": "Response = <b><i>(control_mode = q_shutdown | control_mode = q_heatup | control_mode = q_operation | control_mode = q_scram)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval.<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_shutdown | control_mode = q_heatup | control_mode = q_operation | control_mode = q_scram)</i></b> must hold at all time points between (and including) the trigger and the end of the interval.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval.<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_shutdown | control_mode = q_heatup | control_mode = q_operation | control_mode = q_scram)</i></b> must hold at all time points between (and including) the trigger and the end of the interval.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_null_always_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"post_condition_unexp_pt": "((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram))",
"post_condition_unexp_ft": "((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram))",
"post_condition_unexp_pctl": "((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram))",
"post_condition_SMV_pt": "((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram))",
"post_condition_SMV_ft": "((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram))",
"post_condition_MLTL_ft": "((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram))",
"post_condition_PRISM_pctl": "((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram))",
"ft": "(LAST V ((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram)))",
"pt": "(H ((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram)))",
"pctl": "(P>=1[(G ((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram)))])",
"ptExpanded": "(H ((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram)))",
"CoCoSpecCode": "H(((((control_mode = q_shutdown) or (control_mode = q_heatup)) or (control_mode = q_operation)) or (control_mode = q_scram)))",
"ftExpanded": "(LAST V ((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram)))",
"pctlExpanded": "(P>=1[(G ((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram)))])",
"ftInfAUExpanded": "(G ((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram)))",
"mltlExpanded": "(G[0,M] p0)",
"WESTMapping": "p0: ((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram))",
"R2U2Code": "((((control_mode == q_shutdown) || (control_mode == q_heatup)) || (control_mode == q_operation)) || (control_mode == q_scram))",
"component": "DRC"
},
"status": "",
"_id": "68403103-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_T003_HEATUP_TO_SCRAM",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "Upon control_mode = q_heatup & !inv1_holds DRC shall at the next timepoint satisfy control_mode = q_scram",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "regular",
"probability": "null",
"timing": "next",
"response": "satisfaction",
"variables": [
"control_mode",
"q_heatup",
"inv1_holds",
"q_scram"
],
"qualifier_word": "upon",
"pre_condition": "(control_mode = q_heatup & ! inv1_holds)",
"regular_condition": "(control_mode = q_heatup & ! inv1_holds)",
"conditionTextRange": [
0,
41
],
"component_name": "DRC",
"componentTextRange": [
45,
47
],
"timingTextRange": [
55,
75
],
"post_condition": "(control_mode = q_scram)",
"responseTextRange": [
77,
106
],
"diagramVariables": "TC = <b><i>(control_mode = q_heatup & ! inv1_holds)</i></b>, Response = <b><i>(control_mode = q_scram)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_heatup & ! inv1_holds)</i></b> is true and any point in the interval where <b><i>(control_mode = q_heatup & ! inv1_holds)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_scram)</i></b> must hold at the next time step.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_heatup & ! inv1_holds)</i></b> is true and any point in the interval where <b><i>(control_mode = q_heatup & ! inv1_holds)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_scram)</i></b> must hold at the next time step.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_regular_next_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"regular_condition_unexp_pt": "((control_mode = q_heatup) & (! inv1_holds))",
"regular_condition_unexp_ft": "((control_mode = q_heatup) & (! inv1_holds))",
"regular_condition_unexp_pctl": "((control_mode = q_heatup) & (! inv1_holds))",
"regular_condition_SMV_pt": "((control_mode = q_heatup) & (! inv1_holds))",
"regular_condition_SMV_ft": "((control_mode = q_heatup) & (! inv1_holds))",
"regular_condition_MLTL_ft": "((control_mode = q_heatup) & (! inv1_holds))",
"regular_condition_PRISM_pctl": "((control_mode = q_heatup) & (! inv1_holds))",
"post_condition_unexp_pt": "(control_mode = q_scram)",
"post_condition_unexp_ft": "(control_mode = q_scram)",
"post_condition_unexp_pctl": "(control_mode = q_scram)",
"post_condition_SMV_pt": "(control_mode = q_scram)",
"post_condition_SMV_ft": "(control_mode = q_scram)",
"post_condition_MLTL_ft": "(control_mode = q_scram)",
"post_condition_PRISM_pctl": "(control_mode = q_scram)",
"ft": "((LAST V (((! ((control_mode = q_heatup) & (! inv1_holds))) & ((! LAST) & (X ((control_mode = q_heatup) & (! inv1_holds))))) -> (X (LAST | (X (control_mode = q_scram)))))) & (((control_mode = q_heatup) & (! inv1_holds)) -> (LAST | (X (control_mode = q_scram)))))",
"pt": "(H ((Y (((control_mode = q_heatup) & (! inv1_holds)) & (Z (! ((control_mode = q_heatup) & (! inv1_holds)))))) -> ((control_mode = q_scram) | (Z FALSE))))",
"pctl": "P>=1[((G (((! ((control_mode = q_heatup) & (! inv1_holds))) & (X ((control_mode = q_heatup) & (! inv1_holds)))) => (X (P>=1[(LAST | (X (control_mode = q_scram)))])))) & (((control_mode = q_heatup) & (! inv1_holds)) => (P>=1[(LAST | (X (control_mode = q_scram)))])))]",
"ptExpanded": "(H ((Y (((control_mode = q_heatup) & (! inv1_holds)) & (Z (! ((control_mode = q_heatup) & (! inv1_holds)))))) -> ((control_mode = q_scram) | (Z FALSE))))",
"CoCoSpecCode": "H((YtoPre((((control_mode = q_heatup) and not (inv1_holds)) and ZtoPre(not (((control_mode = q_heatup) and not (inv1_holds)))))) => ((control_mode = q_scram) or ZtoPre(false))))",
"ftExpanded": "((LAST V (((! ((control_mode = q_heatup) & (! inv1_holds))) & ((! LAST) & (X ((control_mode = q_heatup) & (! inv1_holds))))) -> (X (LAST | (X (control_mode = q_scram)))))) & (((control_mode = q_heatup) & (! inv1_holds)) -> (LAST | (X (control_mode = q_scram)))))",
"pctlExpanded": "P>=1[((G (((! ((control_mode = q_heatup) & (! inv1_holds))) & (X ((control_mode = q_heatup) & (! inv1_holds)))) => (X (P>=1[(false | (X (control_mode = q_scram)))])))) & (((control_mode = q_heatup) & (! inv1_holds)) => (P>=1[(false | (X (control_mode = q_scram)))])))]",
"ftInfAUExpanded": "((G (((! ((control_mode = q_heatup) & (! inv1_holds))) & (X ((control_mode = q_heatup) & (! inv1_holds)))) -> (X (X (control_mode = q_scram))))) & (((control_mode = q_heatup) & (! inv1_holds)) -> (X (control_mode = q_scram))))",
"mltlExpanded": "((G[0,M] (((! p0) & (F[1,1] p0)) -> (F[2,2] p1))) & (p0 -> (F[1,1] p1)))",
"WESTMapping": "p0: ((control_mode = q_heatup) & (! inv1_holds))<br/>p1: (control_mode = q_scram)",
"R2U2Code": "((((! ((control_mode == q_heatup) && (! inv1_holds))) && (F[1,1] ((control_mode == q_heatup) && (! inv1_holds)))) -> (F[2,2] (control_mode == q_scram))) && (((TAU == 0) && ((control_mode == q_heatup) && (! inv1_holds))) -> (F[1,1] (control_mode == q_scram))))",
"component": "DRC"
},
"status": "",
"_id": "68403104-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_T004_OPERATION_TO_SCRAM",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "Upon control_mode = q_operation & !inv2_holds DRC shall at the next timepoint satisfy control_mode = q_scram",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "regular",
"probability": "null",
"timing": "next",
"response": "satisfaction",
"variables": [
"control_mode",
"q_operation",
"inv2_holds",
"q_scram"
],
"qualifier_word": "upon",
"pre_condition": "(control_mode = q_operation & ! inv2_holds)",
"regular_condition": "(control_mode = q_operation & ! inv2_holds)",
"conditionTextRange": [
0,
44
],
"component_name": "DRC",
"componentTextRange": [
48,
50
],
"timingTextRange": [
58,
78
],
"post_condition": "(control_mode = q_scram)",
"responseTextRange": [
80,
109
],
"diagramVariables": "TC = <b><i>(control_mode = q_operation & ! inv2_holds)</i></b>, Response = <b><i>(control_mode = q_scram)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_operation & ! inv2_holds)</i></b> is true and any point in the interval where <b><i>(control_mode = q_operation & ! inv2_holds)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_scram)</i></b> must hold at the next time step.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_operation & ! inv2_holds)</i></b> is true and any point in the interval where <b><i>(control_mode = q_operation & ! inv2_holds)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_scram)</i></b> must hold at the next time step.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_regular_next_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"regular_condition_unexp_pt": "((control_mode = q_operation) & (! inv2_holds))",
"regular_condition_unexp_ft": "((control_mode = q_operation) & (! inv2_holds))",
"regular_condition_unexp_pctl": "((control_mode = q_operation) & (! inv2_holds))",
"regular_condition_SMV_pt": "((control_mode = q_operation) & (! inv2_holds))",
"regular_condition_SMV_ft": "((control_mode = q_operation) & (! inv2_holds))",
"regular_condition_MLTL_ft": "((control_mode = q_operation) & (! inv2_holds))",
"regular_condition_PRISM_pctl": "((control_mode = q_operation) & (! inv2_holds))",
"post_condition_unexp_pt": "(control_mode = q_scram)",
"post_condition_unexp_ft": "(control_mode = q_scram)",
"post_condition_unexp_pctl": "(control_mode = q_scram)",
"post_condition_SMV_pt": "(control_mode = q_scram)",
"post_condition_SMV_ft": "(control_mode = q_scram)",
"post_condition_MLTL_ft": "(control_mode = q_scram)",
"post_condition_PRISM_pctl": "(control_mode = q_scram)",
"ft": "((LAST V (((! ((control_mode = q_operation) & (! inv2_holds))) & ((! LAST) & (X ((control_mode = q_operation) & (! inv2_holds))))) -> (X (LAST | (X (control_mode = q_scram)))))) & (((control_mode = q_operation) & (! inv2_holds)) -> (LAST | (X (control_mode = q_scram)))))",
"pt": "(H ((Y (((control_mode = q_operation) & (! inv2_holds)) & (Z (! ((control_mode = q_operation) & (! inv2_holds)))))) -> ((control_mode = q_scram) | (Z FALSE))))",
"pctl": "P>=1[((G (((! ((control_mode = q_operation) & (! inv2_holds))) & (X ((control_mode = q_operation) & (! inv2_holds)))) => (X (P>=1[(LAST | (X (control_mode = q_scram)))])))) & (((control_mode = q_operation) & (! inv2_holds)) => (P>=1[(LAST | (X (control_mode = q_scram)))])))]",
"ptExpanded": "(H ((Y (((control_mode = q_operation) & (! inv2_holds)) & (Z (! ((control_mode = q_operation) & (! inv2_holds)))))) -> ((control_mode = q_scram) | (Z FALSE))))",
"CoCoSpecCode": "H((YtoPre((((control_mode = q_operation) and not (inv2_holds)) and ZtoPre(not (((control_mode = q_operation) and not (inv2_holds)))))) => ((control_mode = q_scram) or ZtoPre(false))))",
"ftExpanded": "((LAST V (((! ((control_mode = q_operation) & (! inv2_holds))) & ((! LAST) & (X ((control_mode = q_operation) & (! inv2_holds))))) -> (X (LAST | (X (control_mode = q_scram)))))) & (((control_mode = q_operation) & (! inv2_holds)) -> (LAST | (X (control_mode = q_scram)))))",
"pctlExpanded": "P>=1[((G (((! ((control_mode = q_operation) & (! inv2_holds))) & (X ((control_mode = q_operation) & (! inv2_holds)))) => (X (P>=1[(false | (X (control_mode = q_scram)))])))) & (((control_mode = q_operation) & (! inv2_holds)) => (P>=1[(false | (X (control_mode = q_scram)))])))]",
"ftInfAUExpanded": "((G (((! ((control_mode = q_operation) & (! inv2_holds))) & (X ((control_mode = q_operation) & (! inv2_holds)))) -> (X (X (control_mode = q_scram))))) & (((control_mode = q_operation) & (! inv2_holds)) -> (X (control_mode = q_scram))))",
"mltlExpanded": "((G[0,M] (((! p0) & (F[1,1] p0)) -> (F[2,2] p1))) & (p0 -> (F[1,1] p1)))",
"WESTMapping": "p0: ((control_mode = q_operation) & (! inv2_holds))<br/>p1: (control_mode = q_scram)",
"R2U2Code": "((((! ((control_mode == q_operation) && (! inv2_holds))) && (F[1,1] ((control_mode == q_operation) && (! inv2_holds)))) -> (F[2,2] (control_mode == q_scram))) && (((TAU == 0) && ((control_mode == q_operation) && (! inv2_holds))) -> (F[1,1] (control_mode == q_scram))))",
"component": "DRC"
},
"status": "",
"_id": "68403105-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_T005_SCRAM_TO_SHUTDOWN",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "Upon control_mode = q_scram & manual_reset DRC shall at the next timepoint satisfy control_mode = q_shutdown",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "regular",
"probability": "null",
"timing": "next",
"response": "satisfaction",
"variables": [
"control_mode",
"q_scram",
"manual_reset",
"q_shutdown"
],
"qualifier_word": "upon",
"pre_condition": "(control_mode = q_scram & manual_reset)",
"regular_condition": "(control_mode = q_scram & manual_reset)",
"conditionTextRange": [
0,
41
],
"component_name": "DRC",
"componentTextRange": [
45,
47
],
"timingTextRange": [
55,
75
],
"post_condition": "(control_mode = q_shutdown)",
"responseTextRange": [
77,
109
],
"diagramVariables": "TC = <b><i>(control_mode = q_scram & manual_reset)</i></b>, Response = <b><i>(control_mode = q_shutdown)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_scram & manual_reset)</i></b> is true and any point in the interval where <b><i>(control_mode = q_scram & manual_reset)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_shutdown)</i></b> must hold at the next time step.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval if <b><i>(control_mode = q_scram & manual_reset)</i></b> is true and any point in the interval where <b><i>(control_mode = q_scram & manual_reset)</i></b> becomes true (from false).<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_shutdown)</i></b> must hold at the next time step.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_regular_next_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"regular_condition_unexp_pt": "((control_mode = q_scram) & manual_reset)",
"regular_condition_unexp_ft": "((control_mode = q_scram) & manual_reset)",
"regular_condition_unexp_pctl": "((control_mode = q_scram) & manual_reset)",
"regular_condition_SMV_pt": "((control_mode = q_scram) & manual_reset)",
"regular_condition_SMV_ft": "((control_mode = q_scram) & manual_reset)",
"regular_condition_MLTL_ft": "((control_mode = q_scram) & manual_reset)",
"regular_condition_PRISM_pctl": "((control_mode = q_scram) & manual_reset)",
"post_condition_unexp_pt": "(control_mode = q_shutdown)",
"post_condition_unexp_ft": "(control_mode = q_shutdown)",
"post_condition_unexp_pctl": "(control_mode = q_shutdown)",
"post_condition_SMV_pt": "(control_mode = q_shutdown)",
"post_condition_SMV_ft": "(control_mode = q_shutdown)",
"post_condition_MLTL_ft": "(control_mode = q_shutdown)",
"post_condition_PRISM_pctl": "(control_mode = q_shutdown)",
"ft": "((LAST V (((! ((control_mode = q_scram) & manual_reset)) & ((! LAST) & (X ((control_mode = q_scram) & manual_reset)))) -> (X (LAST | (X (control_mode = q_shutdown)))))) & (((control_mode = q_scram) & manual_reset) -> (LAST | (X (control_mode = q_shutdown)))))",
"pt": "(H ((Y (((control_mode = q_scram) & manual_reset) & (Z (! ((control_mode = q_scram) & manual_reset))))) -> ((control_mode = q_shutdown) | (Z FALSE))))",
"pctl": "P>=1[((G (((! ((control_mode = q_scram) & manual_reset)) & (X ((control_mode = q_scram) & manual_reset))) => (X (P>=1[(LAST | (X (control_mode = q_shutdown)))])))) & (((control_mode = q_scram) & manual_reset) => (P>=1[(LAST | (X (control_mode = q_shutdown)))])))]",
"ptExpanded": "(H ((Y (((control_mode = q_scram) & manual_reset) & (Z (! ((control_mode = q_scram) & manual_reset))))) -> ((control_mode = q_shutdown) | (Z FALSE))))",
"CoCoSpecCode": "H((YtoPre((((control_mode = q_scram) and manual_reset) and ZtoPre(not (((control_mode = q_scram) and manual_reset))))) => ((control_mode = q_shutdown) or ZtoPre(false))))",
"ftExpanded": "((LAST V (((! ((control_mode = q_scram) & manual_reset)) & ((! LAST) & (X ((control_mode = q_scram) & manual_reset)))) -> (X (LAST | (X (control_mode = q_shutdown)))))) & (((control_mode = q_scram) & manual_reset) -> (LAST | (X (control_mode = q_shutdown)))))",
"pctlExpanded": "P>=1[((G (((! ((control_mode = q_scram) & manual_reset)) & (X ((control_mode = q_scram) & manual_reset))) => (X (P>=1[(false | (X (control_mode = q_shutdown)))])))) & (((control_mode = q_scram) & manual_reset) => (P>=1[(false | (X (control_mode = q_shutdown)))])))]",
"ftInfAUExpanded": "((G (((! ((control_mode = q_scram) & manual_reset)) & (X ((control_mode = q_scram) & manual_reset))) -> (X (X (control_mode = q_shutdown))))) & (((control_mode = q_scram) & manual_reset) -> (X (control_mode = q_shutdown))))",
"mltlExpanded": "((G[0,M] (((! p0) & (F[1,1] p0)) -> (F[2,2] p1))) & (p0 -> (F[1,1] p1)))",
"WESTMapping": "p0: ((control_mode = q_scram) & manual_reset)<br/>p1: (control_mode = q_shutdown)",
"R2U2Code": "((((! ((control_mode == q_scram) && manual_reset)) && (F[1,1] ((control_mode == q_scram) && manual_reset))) -> (F[2,2] (control_mode == q_shutdown))) && (((TAU == 0) && ((control_mode == q_scram) && manual_reset)) -> (F[1,1] (control_mode == q_shutdown))))",
"component": "DRC"
},
"status": "",
"_id": "68403106-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_S001_SHUTDOWN_STAY",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "Whenever control_mode = q_shutdown & !t_avg_above_min DRC shall at the next timepoint satisfy control_mode = q_shutdown",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "holding",
"probability": "null",
"timing": "next",
"response": "satisfaction",
"variables": [
"control_mode",
"q_shutdown",
"t_avg_above_min"
],
"qualifier_word": "whenever",
"pre_condition": "(control_mode = q_shutdown & ! t_avg_above_min)",
"regular_condition": "(control_mode = q_shutdown & ! t_avg_above_min)",
"conditionTextRange": [
0,
52
],
"component_name": "DRC",
"componentTextRange": [
56,
58
],
"timingTextRange": [
66,
86
],
"post_condition": "(control_mode = q_shutdown)",
"responseTextRange": [
88,
120
],
"diagramVariables": "CC = <b><i>(control_mode = q_shutdown & ! t_avg_above_min)</i></b>, Response = <b><i>(control_mode = q_shutdown)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: every point in the interval where <b><i>(control_mode = q_shutdown & ! t_avg_above_min)</i></b> is true.<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_shutdown)</i></b> must hold at the next time step.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: every point in the interval where <b><i>(control_mode = q_shutdown & ! t_avg_above_min)</i></b> is true.<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_shutdown)</i></b> must hold at the next time step.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_holding_next_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"regular_condition_unexp_pt": "((control_mode = q_shutdown) & (! t_avg_above_min))",
"regular_condition_unexp_ft": "((control_mode = q_shutdown) & (! t_avg_above_min))",
"regular_condition_unexp_pctl": "((control_mode = q_shutdown) & (! t_avg_above_min))",
"regular_condition_SMV_pt": "((control_mode = q_shutdown) & (! t_avg_above_min))",
"regular_condition_SMV_ft": "((control_mode = q_shutdown) & (! t_avg_above_min))",
"regular_condition_MLTL_ft": "((control_mode = q_shutdown) & (! t_avg_above_min))",
"regular_condition_PRISM_pctl": "((control_mode = q_shutdown) & (! t_avg_above_min))",
"post_condition_unexp_pt": "(control_mode = q_shutdown)",
"post_condition_unexp_ft": "(control_mode = q_shutdown)",
"post_condition_unexp_pctl": "(control_mode = q_shutdown)",
"post_condition_SMV_pt": "(control_mode = q_shutdown)",
"post_condition_SMV_ft": "(control_mode = q_shutdown)",
"post_condition_MLTL_ft": "(control_mode = q_shutdown)",
"post_condition_PRISM_pctl": "(control_mode = q_shutdown)",
"ft": "(LAST V (((control_mode = q_shutdown) & (! t_avg_above_min)) -> (LAST | (X (control_mode = q_shutdown)))))",
"pt": "(H ((Y ((control_mode = q_shutdown) & (! t_avg_above_min))) -> ((control_mode = q_shutdown) | (Z FALSE))))",
"pctl": "P>=1[(G (((control_mode = q_shutdown) & (! t_avg_above_min)) => (P>=1[(LAST | (X (control_mode = q_shutdown)))])))]",
"ptExpanded": "(H ((Y ((control_mode = q_shutdown) & (! t_avg_above_min))) -> ((control_mode = q_shutdown) | (Z FALSE))))",
"CoCoSpecCode": "H((YtoPre(((control_mode = q_shutdown) and not (t_avg_above_min))) => ((control_mode = q_shutdown) or ZtoPre(false))))",
"ftExpanded": "(LAST V (((control_mode = q_shutdown) & (! t_avg_above_min)) -> (LAST | (X (control_mode = q_shutdown)))))",
"pctlExpanded": "P>=1[(G (((control_mode = q_shutdown) & (! t_avg_above_min)) => (P>=1[(false | (X (control_mode = q_shutdown)))])))]",
"ftInfAUExpanded": "(G (((control_mode = q_shutdown) & (! t_avg_above_min)) -> (X (control_mode = q_shutdown))))",
"mltlExpanded": "(G[0,M] (p0 -> (F[1,1] p1)))",
"WESTMapping": "p0: ((control_mode = q_shutdown) & (! t_avg_above_min))<br/>p1: (control_mode = q_shutdown)",
"R2U2Code": "(((control_mode == q_shutdown) && (! t_avg_above_min)) -> (F[1,1] (control_mode == q_shutdown)))",
"component": "DRC"
},
"status": "",
"_id": "68403107-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_S002_HEATUP_STAY",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "Whenever control_mode = q_heatup & inv1_holds & !(t_avg_in_range & p_above_crit) DRC shall at the next timepoint satisfy control_mode = q_heatup",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "holding",
"probability": "null",
"timing": "next",
"response": "satisfaction",
"variables": [
"control_mode",
"q_heatup",
"inv1_holds",
"t_avg_in_range",
"p_above_crit"
],
"qualifier_word": "whenever",
"pre_condition": "(control_mode = q_heatup & inv1_holds & ! ( t_avg_in_range & p_above_crit ))",
"regular_condition": "(control_mode = q_heatup & inv1_holds & ! ( t_avg_in_range & p_above_crit ))",
"conditionTextRange": [
0,
79
],
"component_name": "DRC",
"componentTextRange": [
83,
85
],
"timingTextRange": [
93,
113
],
"post_condition": "(control_mode = q_heatup)",
"responseTextRange": [
115,
145
],
"diagramVariables": "CC = <b><i>(control_mode = q_heatup & inv1_holds & ! ( t_avg_in_range & p_above_crit ))</i></b>, Response = <b><i>(control_mode = q_heatup)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: every point in the interval where <b><i>(control_mode = q_heatup & inv1_holds & ! ( t_avg_in_range & p_above_crit ))</i></b> is true.<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_heatup)</i></b> must hold at the next time step.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: every point in the interval where <b><i>(control_mode = q_heatup & inv1_holds & ! ( t_avg_in_range & p_above_crit ))</i></b> is true.<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_heatup)</i></b> must hold at the next time step.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_holding_next_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"regular_condition_unexp_pt": "(((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))",
"regular_condition_unexp_ft": "(((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))",
"regular_condition_unexp_pctl": "(((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))",
"regular_condition_SMV_pt": "(((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))",
"regular_condition_SMV_ft": "(((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))",
"regular_condition_MLTL_ft": "(((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))",
"regular_condition_PRISM_pctl": "(((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))",
"post_condition_unexp_pt": "(control_mode = q_heatup)",
"post_condition_unexp_ft": "(control_mode = q_heatup)",
"post_condition_unexp_pctl": "(control_mode = q_heatup)",
"post_condition_SMV_pt": "(control_mode = q_heatup)",
"post_condition_SMV_ft": "(control_mode = q_heatup)",
"post_condition_MLTL_ft": "(control_mode = q_heatup)",
"post_condition_PRISM_pctl": "(control_mode = q_heatup)",
"ft": "(LAST V ((((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit))) -> (LAST | (X (control_mode = q_heatup)))))",
"pt": "(H ((Y (((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))) -> ((control_mode = q_heatup) | (Z FALSE))))",
"pctl": "P>=1[(G ((((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit))) => (P>=1[(LAST | (X (control_mode = q_heatup)))])))]",
"ptExpanded": "(H ((Y (((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))) -> ((control_mode = q_heatup) | (Z FALSE))))",
"CoCoSpecCode": "H((YtoPre((((control_mode = q_heatup) and inv1_holds) and not ((t_avg_in_range and p_above_crit)))) => ((control_mode = q_heatup) or ZtoPre(false))))",
"ftExpanded": "(LAST V ((((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit))) -> (LAST | (X (control_mode = q_heatup)))))",
"pctlExpanded": "P>=1[(G ((((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit))) => (P>=1[(false | (X (control_mode = q_heatup)))])))]",
"ftInfAUExpanded": "(G ((((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit))) -> (X (control_mode = q_heatup))))",
"mltlExpanded": "(G[0,M] (p0 -> (F[1,1] p1)))",
"WESTMapping": "p0: (((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit)))<br/>p1: (control_mode = q_heatup)",
"R2U2Code": "((((control_mode == q_heatup) && inv1_holds) && (! (t_avg_in_range && p_above_crit))) -> (F[1,1] (control_mode == q_heatup)))",
"component": "DRC"
},
"status": "",
"_id": "68403108-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_S003_OPERATION_STAY",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "Whenever control_mode = q_operation & inv2_holds DRC shall at the next timepoint satisfy control_mode = q_operation ",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "holding",
"probability": "null",
"timing": "next",
"response": "satisfaction",
"variables": [
"control_mode",
"q_operation",
"inv2_holds"
],
"qualifier_word": "whenever",
"pre_condition": "(control_mode = q_operation & inv2_holds)",
"regular_condition": "(control_mode = q_operation & inv2_holds)",
"conditionTextRange": [
0,
47
],
"component_name": "DRC",
"componentTextRange": [
50,
52
],
"timingTextRange": [
60,
80
],
"post_condition": "(control_mode = q_operation)",
"responseTextRange": [
82,
115
],
"diagramVariables": "CC = <b><i>(control_mode = q_operation & inv2_holds)</i></b>, Response = <b><i>(control_mode = q_operation)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: every point in the interval where <b><i>(control_mode = q_operation & inv2_holds)</i></b> is true.<br>REQUIRED BEHAVIOR: for every trigger, <b><i>(control_mode = q_operation)</i></b> must hold at the next time step.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: every point in the interval where <b><i>(control_mode = q_operation & inv2_holds)</i></b> is true.<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, <b><i>(control_mode = q_operation)</i></b> must hold at the next time step.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_holding_next_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"regular_condition_unexp_pt": "((control_mode = q_operation) & inv2_holds)",
"regular_condition_unexp_ft": "((control_mode = q_operation) & inv2_holds)",
"regular_condition_unexp_pctl": "((control_mode = q_operation) & inv2_holds)",
"regular_condition_SMV_pt": "((control_mode = q_operation) & inv2_holds)",
"regular_condition_SMV_ft": "((control_mode = q_operation) & inv2_holds)",
"regular_condition_MLTL_ft": "((control_mode = q_operation) & inv2_holds)",
"regular_condition_PRISM_pctl": "((control_mode = q_operation) & inv2_holds)",
"post_condition_unexp_pt": "(control_mode = q_operation)",
"post_condition_unexp_ft": "(control_mode = q_operation)",
"post_condition_unexp_pctl": "(control_mode = q_operation)",
"post_condition_SMV_pt": "(control_mode = q_operation)",
"post_condition_SMV_ft": "(control_mode = q_operation)",
"post_condition_MLTL_ft": "(control_mode = q_operation)",
"post_condition_PRISM_pctl": "(control_mode = q_operation)",
"ft": "(LAST V (((control_mode = q_operation) & inv2_holds) -> (LAST | (X (control_mode = q_operation)))))",
"pt": "(H ((Y ((control_mode = q_operation) & inv2_holds)) -> ((control_mode = q_operation) | (Z FALSE))))",
"pctl": "P>=1[(G (((control_mode = q_operation) & inv2_holds) => (P>=1[(LAST | (X (control_mode = q_operation)))])))]",
"ptExpanded": "(H ((Y ((control_mode = q_operation) & inv2_holds)) -> ((control_mode = q_operation) | (Z FALSE))))",
"CoCoSpecCode": "H((YtoPre(((control_mode = q_operation) and inv2_holds)) => ((control_mode = q_operation) or ZtoPre(false))))",
"ftExpanded": "(LAST V (((control_mode = q_operation) & inv2_holds) -> (LAST | (X (control_mode = q_operation)))))",
"pctlExpanded": "P>=1[(G (((control_mode = q_operation) & inv2_holds) => (P>=1[(false | (X (control_mode = q_operation)))])))]",
"ftInfAUExpanded": "(G (((control_mode = q_operation) & inv2_holds) -> (X (control_mode = q_operation))))",
"mltlExpanded": "(G[0,M] (p0 -> (F[1,1] p1)))",
"WESTMapping": "p0: ((control_mode = q_operation) & inv2_holds)<br/>p1: (control_mode = q_operation)",
"R2U2Code": "(((control_mode == q_operation) && inv2_holds) -> (F[1,1] (control_mode == q_operation)))",
"component": "DRC"
},
"status": "",
"_id": "68403109-3463-11f1-b848-f314240f620d"
},
{
"reqid": "DRC_I001_INIT_SHUTDOWN",
"parent_reqid": "",
"project": "PWR_HYBRID_3",
"rationale": "",
"comments": "",
"fulltext": "DRC shall immediately satisfy control_mode = q_shutdown",
"semantics": {
"type": "nasa",
"scope": {
"type": "null"
},
"condition": "null",
"probability": "null",
"timing": "immediately",
"response": "satisfaction",
"variables": [
"control_mode",
"q_shutdown"
],
"component_name": "DRC",
"componentTextRange": [
0,
2
],
"timingTextRange": [
10,
20
],
"post_condition": "(control_mode = q_shutdown)",
"responseTextRange": [
22,
54
],
"diagramVariables": "Response = <b><i>(control_mode = q_shutdown)</i></b>.",
"description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval.<br>REQUIRED BEHAVIOR: for every trigger, if trigger holds then <b><i>(control_mode = q_shutdown)</i></b> also holds at the same time point.",
"probabilistic_description": "SCOPE: in the interval defined by the entire execution.<br>TRIGGER: first point in the interval.<br>REQUIRED BEHAVIOR: for every trigger, with probability >=1, if trigger holds then <b><i>(control_mode = q_shutdown)</i></b> also holds at the same time point.",
"diagram": "_media/user-interface/examples/svgDiagrams/null_null_immediately_satisfaction.svg",
"scope_mode_pt": "BAD_PT",
"scope_mode_ft": "BAD_FT",
"post_condition_unexp_pt": "(control_mode = q_shutdown)",
"post_condition_unexp_ft": "(control_mode = q_shutdown)",
"post_condition_unexp_pctl": "(control_mode = q_shutdown)",
"post_condition_SMV_pt": "(control_mode = q_shutdown)",
"post_condition_SMV_ft": "(control_mode = q_shutdown)",
"post_condition_MLTL_ft": "(control_mode = q_shutdown)",
"post_condition_PRISM_pctl": "(control_mode = q_shutdown)",
"ft": "(control_mode = q_shutdown)",
"pt": "(H ((Z FALSE) -> (control_mode = q_shutdown)))",
"pctl": "(P>=1[(control_mode = q_shutdown)])",
"ptExpanded": "(H ((Z FALSE) -> (control_mode = q_shutdown)))",
"CoCoSpecCode": "H((ZtoPre(false) => (control_mode = q_shutdown)))",
"ftExpanded": "(control_mode = q_shutdown)",
"pctlExpanded": "(P>=1[(control_mode = q_shutdown)])",
"ftInfAUExpanded": "(control_mode = q_shutdown)",
"mltlExpanded": "p0",
"WESTMapping": "p0: (control_mode = q_shutdown)",
"R2U2Code": "((TAU == 0) -> (control_mode == q_shutdown))",
"component": "DRC"
},
"status": "",
"_id": "6840310a-3463-11f1-b848-f314240f620d"
}
]

View File

View File

@ -0,0 +1,154 @@
#!/usr/bin/env python3
"""Parse FRET JSON export and prepare config for Strix synthesis.
Reads the fretRequirementsVariables.json exported from FRET and produces
a synthesis config with LTL formulas and input/output variable roles.
Usage: python3 scripts/parse_fret_json.py specs/fretRequirementsVariables.json [-o config.json]
"""
import argparse
import json
import re
import sys
from pathlib import Path
# LTL operators that must stay as-is (Spot parses lowercase for these)
LTL_OPERATORS = {'G', 'F', 'X', 'U', 'R', 'V', 'W', 'M', 'H', 'O', 'Y', 'Z', 'S', 'T'}
def lowercase_ltl(formula: str, var_names: set[str]) -> str:
"""Lowercase variable names in an LTL formula, preserving operators."""
def replace_token(match):
token = match.group(0)
if token in LTL_OPERATORS:
return token
if token in var_names or token.lower() in {v.lower() for v in var_names}:
return token.lower()
return token
return re.sub(r'\b[A-Za-z_]\w*\b', replace_token, formula)
def main():
parser = argparse.ArgumentParser(description='Parse FRET JSON export for synthesis')
parser.add_argument('json_file', type=Path, help='FRET JSON export file')
parser.add_argument('-o', '--output', type=Path, default=None,
help='Output config file (default: <json_dir>/synthesis_config.json)')
parser.add_argument('--ltl-field', default='ftInfAUExpanded',
help='Which LTL field to use (default: ftInfAUExpanded)')
parser.add_argument('--fallback-field', default='ft',
help='Fallback LTL field if primary is missing (default: ft)')
parser.add_argument('--liveness', type=Path, default=None,
help='Path to liveness constraints file (one LTL formula per line)')
args = parser.parse_args()
data = json.loads(args.json_file.read_text())
requirements = data.get('requirements', [])
variables = data.get('variables', [])
if not requirements:
print('Error: no requirements found in JSON', file=sys.stderr)
sys.exit(1)
# Extract variable I/O roles
# Collect original names for lowercasing LTL formulas
all_var_names = {v['variable_name'] for v in variables}
inputs = []
outputs = []
var_info = {}
for v in variables:
name = v['variable_name']
id_type = v.get('idType', 'Unknown')
var_info[name] = id_type
if id_type == 'Input':
inputs.append(name.lower())
elif id_type == 'Output':
outputs.append(name.lower())
else:
print(f'Warning: variable {name} has type "{id_type}", defaulting to input',
file=sys.stderr)
inputs.append(name.lower())
# Extract LTL formulas (lowercase variable names for Spot compatibility)
ltl_entries = []
for req in requirements:
sem = req.get('semantics', {})
ltl_raw = sem.get(args.ltl_field) or sem.get(args.fallback_field)
ltl = lowercase_ltl(ltl_raw, all_var_names) if ltl_raw else None
entry = {
'req_id': req['reqid'],
'fulltext': req['fulltext'],
'project': req.get('project', ''),
'component': sem.get('component', ''),
'ltl': ltl,
'ltl_original': ltl_raw,
'variables': sem.get('variables', []),
}
if not ltl:
entry['error'] = f'No LTL found in fields {args.ltl_field} or {args.fallback_field}'
ltl_entries.append(entry)
# Determine spec name from project/component
projects = {req.get('project', '') for req in requirements}
components = {req.get('semantics', {}).get('component', '') for req in requirements}
spec_name = f'{"-".join(sorted(projects))}_{"-".join(sorted(components))}'.strip('_-')
if not spec_name:
spec_name = args.json_file.stem
# Load liveness constraints if provided
liveness = []
if args.liveness and args.liveness.exists():
for line in args.liveness.read_text().strip().split('\n'):
line = line.strip()
if line and not line.startswith('#'):
liveness.append(lowercase_ltl(line, all_var_names))
# Build conjoined formula
all_ltl = [e['ltl'] for e in ltl_entries if e.get('ltl')]
all_ltl.extend(liveness)
conjoined = ' & '.join(f'({f})' for f in all_ltl) if all_ltl else None
config = {
'_comment': 'Generated from FRET JSON export. Ready for ltlsynt synthesis.',
'spec_name': spec_name,
'source_file': str(args.json_file),
'inputs': sorted(inputs),
'outputs': sorted(outputs),
'requirements': ltl_entries,
'liveness_constraints': liveness,
'conjoined_ltl': conjoined,
}
output_path = args.output or (args.json_file.parent / 'synthesis_config.json')
output_path.write_text(json.dumps(config, indent=2) + '\n')
# Summary
print(f'Parsed {len(requirements)} requirements from FRET JSON')
print(f'LTL field: {args.ltl_field} (fallback: {args.fallback_field})')
print()
print(f'Inputs ({len(inputs)}): {", ".join(sorted(inputs))}')
print(f'Outputs ({len(outputs)}): {", ".join(sorted(outputs))}')
print()
for e in ltl_entries:
status = 'ok' if e.get('ltl') else 'MISSING'
print(f' [{status}] {e["req_id"]}: {e["fulltext"][:80]}')
errors = [e for e in ltl_entries if not e.get('ltl')]
if errors:
print(f'\n{len(errors)} requirements missing LTL formulas')
if liveness:
print(f'\nLiveness constraints ({len(liveness)}):')
for l in liveness:
print(f' + {l}')
print(f'\nConfig written to: {output_path}')
if __name__ == '__main__':
main()

View File

@ -0,0 +1,284 @@
#!/usr/bin/env python3
"""Parse FRET SMV exports and extract requirements, variables, and LTL formulas.
Reads .smv files from a directory (e.g., specs/DRC/) and produces a JSON
config file with extracted requirements and inferred input/output roles.
The user can review and adjust the config before synthesis.
"""
import argparse
import json
import re
import sys
from pathlib import Path
def parse_smv_file(path: Path) -> dict:
"""Parse a single FRET-exported SMV file."""
text = path.read_text()
# Extract variables
var_section = re.search(r'VAR\s*(.*?)\s*DEFINE', text, re.DOTALL)
variables = []
if var_section:
for match in re.finditer(r'(\w+)\s*:\s*boolean', var_section.group(1)):
variables.append(match.group(1))
# Extract requirement text and LTLSPEC formulas
req_texts = set()
specs = []
for match in re.finditer(
r'--\s*Req text:\s*(.*?)\n\s*LTLSPEC\s+NAME\s+([\w-]+)\s*:=\s*(.*?)\s*;',
text
):
req_text = match.group(1).strip()
spec_name = match.group(2)
formula = match.group(3).strip()
req_texts.add(req_text)
specs.append({
'name': spec_name,
'formula': formula,
})
# Extract requirement ID from filename
req_id_match = re.search(r'(\w+-\d+)', path.stem)
req_id = req_id_match.group(1) if req_id_match else path.stem
return {
'file': path.name,
'req_id': req_id,
'req_texts': sorted(req_texts),
'variables': variables,
'ltlspecs': specs,
}
# FRETish pattern → LTL conversion
FRETISH_PATTERNS = [
# "shall initially satisfy P"
(r'shall initially satisfy (.+)',
lambda m: m.group(1).strip()),
# "While S If C shall immediately satisfy P"
(r'[Ww]hile (.+?) [Ii]f (.+?) \w+ shall immediately satisfy (.+)',
lambda m: f'G((({m.group(1)}) & ({m.group(2)})) -> X({m.group(3).strip()}))'),
# "While S If C shall at the next timepoint satisfy P"
(r'[Ww]hile (.+?) [Ii]f (.+?) \w+ shall at the next timepoint satisfy (.+)',
lambda m: f'G((({m.group(1)}) & ({m.group(2)})) -> X({m.group(3).strip()}))'),
# "While S If C shall always satisfy P"
(r'[Ww]hile (.+?) [Ii]f (.+?) \w+ shall always satisfy (.+)',
lambda m: f'G((({m.group(1)}) & ({m.group(2)})) -> ({m.group(3).strip()}))'),
# "If C shall immediately satisfy P"
(r'[Ii]f (.+?) \w+ shall immediately satisfy (.+)',
lambda m: f'G(({m.group(1)}) -> X({m.group(2).strip()}))'),
# "if C shall at the next timepoint satisfy P"
(r'[Ii]f (.+?) \w+ shall at the next timepoint satisfy (.+)',
lambda m: f'G(({m.group(1)}) -> X({m.group(2).strip()}))'),
# "When C shall always satisfy P"
(r'[Ww]hen (.+?) \w+ shall always satisfy (.+)',
lambda m: f'G(({m.group(1)}) -> X(G({m.group(2).strip()})))'),
# "While C shall always satisfy P"
(r'[Ww]hile (.+?) \w+ shall always satisfy (.+)',
lambda m: f'G(({m.group(1)}) -> ({m.group(2).strip()}))'),
# "shall always satisfy P" (no condition)
(r'shall always satisfy (.+)',
lambda m: f'G({m.group(1).strip()})'),
]
def fretish_to_ltl(text: str) -> tuple[str | None, str | None, str | None]:
"""Convert FRETish requirement text to LTL.
Returns (ltl_formula, condition_var, satisfaction_expr) or (None, None, None).
"""
for pattern, converter in FRETISH_PATTERNS:
match = re.search(pattern, text)
if match:
ltl = converter(match)
# Extract condition variable (if any)
cond_match = re.search(r'(?:[Ii]f|[Ww]hen|[Ww]hile)\s+(!?\w+)', text)
cond_var = cond_match.group(1) if cond_match else None
# Extract satisfaction expression
sat_match = re.search(r'satisfy\s+(.+)', text)
sat_expr = sat_match.group(1).strip() if sat_match else None
return ltl, cond_var, sat_expr
return None, None, None
def extract_variables_from_expr(expr: str) -> set[str]:
"""Extract variable names from an LTL/boolean expression."""
# Remove LTL operators and punctuation
cleaned = re.sub(r'\b(G|F|X|U|R|W)\b', ' ', expr)
cleaned = re.sub(r'[()!&|>\-]', ' ', cleaned)
return {w for w in cleaned.split() if w and not w.startswith('!')}
def infer_io_roles(requirements: list[dict]) -> dict[str, dict]:
"""Infer input/output roles from FRETish patterns.
Returns {var_name: {'role': 'input'|'output'|'conflict', 'reasons': [...]}}.
"""
var_roles: dict[str, dict] = {}
for req in requirements:
for text in req['req_texts']:
_, cond_var, sat_expr = fretish_to_ltl(text)
# Condition variables → likely inputs
# Also extract from "While X" scope conditions
cond_vars = set()
if cond_var:
cond_vars.update(extract_variables_from_expr(cond_var))
scope_match = re.search(r'[Ww]hile\s+(.+?)\s+(?:[Ii]f|shall)', text)
if scope_match:
cond_vars.update(extract_variables_from_expr(scope_match.group(1)))
trigger_match = re.search(r'[Ii]f\s+(.+?)\s+\w+\s+shall', text)
if trigger_match:
cond_vars.update(extract_variables_from_expr(trigger_match.group(1)))
for cv in cond_vars:
if cv not in var_roles:
var_roles[cv] = {'input_reasons': [], 'output_reasons': []}
var_roles[cv]['input_reasons'].append(
f'{req["req_id"]}: condition in "{text}"'
)
# Variables in satisfaction expression → likely output
if sat_expr:
for var in extract_variables_from_expr(sat_expr):
if var not in var_roles:
var_roles[var] = {'input_reasons': [], 'output_reasons': []}
var_roles[var]['output_reasons'].append(
f'{req["req_id"]}: satisfaction in "{text}"'
)
# Classify
result = {}
for var, info in var_roles.items():
has_input = bool(info['input_reasons'])
has_output = bool(info['output_reasons'])
if has_input and has_output:
role = 'conflict'
elif has_input:
role = 'input'
else:
role = 'output'
result[var] = {
'role': role,
'input_reasons': info['input_reasons'],
'output_reasons': info['output_reasons'],
}
return result
def main():
parser = argparse.ArgumentParser(description='Parse FRET SMV exports')
parser.add_argument('spec_dir', type=Path, help='Directory containing .smv files')
parser.add_argument('-o', '--output', type=Path, default=None,
help='Output JSON config file (default: <spec_dir>/config.json)')
args = parser.parse_args()
if not args.spec_dir.is_dir():
print(f'Error: {args.spec_dir} is not a directory', file=sys.stderr)
sys.exit(1)
smv_files = sorted(args.spec_dir.glob('*.smv'))
if not smv_files:
print(f'Error: no .smv files found in {args.spec_dir}', file=sys.stderr)
sys.exit(1)
# Parse all SMV files
requirements = [parse_smv_file(f) for f in smv_files]
# Convert FRETish to LTL
ltl_formulas = []
for req in requirements:
for text in req['req_texts']:
ltl, _, _ = fretish_to_ltl(text)
if ltl:
ltl_formulas.append({
'req_id': req['req_id'],
'fretish': text,
'ltl': ltl,
})
else:
ltl_formulas.append({
'req_id': req['req_id'],
'fretish': text,
'ltl': None,
'error': 'Could not convert FRETish to LTL — manual entry needed',
})
# Infer I/O roles
io_roles = infer_io_roles(requirements)
# Collect all variables
all_vars = set()
for req in requirements:
all_vars.update(req['variables'])
# Add any variables found in formulas but not in VAR sections
for entry in ltl_formulas:
if entry['ltl']:
all_vars.update(extract_variables_from_expr(entry['ltl']))
# Build config
config = {
'_comment': 'Generated by parse_smv.py. Review and edit variable roles before synthesis.',
'spec_name': args.spec_dir.name,
'variables': {},
'requirements': ltl_formulas,
}
for var in sorted(all_vars):
role_info = io_roles.get(var, {'role': 'unknown', 'input_reasons': [], 'output_reasons': []})
config['variables'][var] = {
'role': role_info['role'],
'input_reasons': role_info['input_reasons'],
'output_reasons': role_info['output_reasons'],
}
# Output
output_path = args.output or (args.spec_dir / 'config.json')
output_path.write_text(json.dumps(config, indent=2) + '\n')
# Summary
print(f'Parsed {len(smv_files)} SMV files')
print(f'Found {len(ltl_formulas)} requirements')
print(f'Found {len(all_vars)} variables:')
for var in sorted(all_vars):
role = io_roles.get(var, {}).get('role', 'unknown')
marker = ' ⚠ CONFLICT' if role == 'conflict' else ''
print(f' {var}: {role}{marker}')
unconverted = [e for e in ltl_formulas if e['ltl'] is None]
if unconverted:
print(f'\n{len(unconverted)} requirements could not be auto-converted:')
for e in unconverted:
print(f' {e["req_id"]}: {e["fretish"]}')
conflicts = [v for v, info in io_roles.items() if info['role'] == 'conflict']
if conflicts:
print(f'\n{len(conflicts)} variables have conflicting roles (appear as both input and output):')
for v in conflicts:
print(f' {v}')
for r in io_roles[v]['input_reasons']:
print(f' INPUT: {r}')
for r in io_roles[v]['output_reasons']:
print(f' OUTPUT: {r}')
print('\nPlease resolve conflicts in the config file before synthesis.')
print(f'\nConfig written to: {output_path}')
print('Review the config, resolve any conflicts, then run synthesize.py')
if __name__ == '__main__':
main()

Binary file not shown.

View File

@ -0,0 +1,19 @@
-- DRCSpec
MODULE main
VAR
Cold_Shutdown: boolean;
SCRAM: boolean;
DEFINE
-- Req text: DRC shall initially satisfy (Cold_Shutdown & !SCRAM)
LTLSPEC NAME PWR-0000_Cold_Shutdown_0 := (! (Cold_Shutdown & (! SCRAM)));
-- Req text: DRC shall initially satisfy (Cold_Shutdown & !SCRAM)
LTLSPEC NAME PWR-0000_SCRAM_0 := (! (Cold_Shutdown & (! SCRAM)));

View File

@ -0,0 +1,28 @@
-- DRCSpec
MODULE main
VAR
OP_MODE: boolean;
SCRAM: boolean;
DEFINE
-- Req text: If SCRAM DRC shall immediately satisfy !OP_MODE
LTLSPEC NAME PWR-0100_SCRAM_0 := (! ((G ((SCRAM | (X (! SCRAM))) | (X (! OP_MODE)))) & ((! SCRAM) & (! (! OP_MODE)))));
-- Req text: If SCRAM DRC shall immediately satisfy !OP_MODE
LTLSPEC NAME PWR-0100_SCRAM_1 := (! (((G ((SCRAM | (X (! SCRAM))) | (X (! OP_MODE)))) & (F (((! SCRAM) & (X (! SCRAM))) & (! (X (! OP_MODE)))))) & ((! SCRAM) | (! OP_MODE))));
-- Req text: If SCRAM DRC shall immediately satisfy !OP_MODE
LTLSPEC NAME PWR-0100_SCRAM_2 := (! (((G ((SCRAM | (X (! SCRAM))) | (X (! OP_MODE)))) & (F ((SCRAM & (! (X (! SCRAM)))) & (! (X (! OP_MODE)))))) & ((! SCRAM) | (! OP_MODE))));
-- Req text: If SCRAM DRC shall immediately satisfy !OP_MODE
LTLSPEC NAME PWR-0100_OP_MODE_0 := (! ((G ((SCRAM | (X (! SCRAM))) | (X (! OP_MODE)))) & ((! (! SCRAM)) & (! OP_MODE))));
-- Req text: If SCRAM DRC shall immediately satisfy !OP_MODE
LTLSPEC NAME PWR-0100_OP_MODE_1 := (! (((G ((SCRAM | (X (! SCRAM))) | (X (! OP_MODE)))) & (F ((! (SCRAM | (X (! SCRAM)))) & (X (! OP_MODE))))) & ((! SCRAM) | (! OP_MODE))));

View File

@ -0,0 +1,27 @@
-- DRCSpec
MODULE main
VAR
SCRAM: boolean;
DEFINE
-- Req text: If SCRAM DRC shall always satisfy SCRAM
LTLSPEC NAME PWR-0102_SCRAM_0 := (! ((G ((SCRAM | (X (! SCRAM))) | (X (G SCRAM)))) & ((! (! SCRAM)) & ((G SCRAM) & (F SCRAM)))));
-- Req text: If SCRAM DRC shall always satisfy SCRAM
LTLSPEC NAME PWR-0102_SCRAM_1 := (! ((G ((SCRAM | (X (! SCRAM))) | (X (G SCRAM)))) & ((! SCRAM) & (! (G SCRAM)))));
-- Req text: If SCRAM DRC shall always satisfy SCRAM
LTLSPEC NAME PWR-0102_SCRAM_2 := (! (((G ((SCRAM | (X (! SCRAM))) | (X (G SCRAM)))) & (F ((! (SCRAM | (X (! SCRAM)))) & (X ((G SCRAM) & (F SCRAM)))))) & ((! SCRAM) | (G SCRAM))));
-- Req text: If SCRAM DRC shall always satisfy SCRAM
LTLSPEC NAME PWR-0102_SCRAM_3 := (! (((G ((SCRAM | (X (! SCRAM))) | (X (G SCRAM)))) & (F (((! SCRAM) & (X (! SCRAM))) & (! (X (G SCRAM)))))) & ((! SCRAM) | (G SCRAM))));
-- Req text: If SCRAM DRC shall always satisfy SCRAM
LTLSPEC NAME PWR-0102_SCRAM_4 := (! (((G ((SCRAM | (X (! SCRAM))) | (X (G SCRAM)))) & (F ((SCRAM & (! (X (! SCRAM)))) & (! (X (G SCRAM)))))) & ((! SCRAM) | (G SCRAM))));

View File

@ -0,0 +1,23 @@
-- DRCSpec
MODULE main
VAR
Heatup: boolean;
Load_Follow: boolean;
OP_MODE: boolean;
DEFINE
-- Req text: While OP_MODE DRC shall always satisfy Heatup | Load_Follow
LTLSPEC NAME PWR-0200_OP_MODE_0 := (! ((G ((! OP_MODE) | (Heatup | Load_Follow))) & (F ((! OP_MODE) & (! (Heatup | Load_Follow))))));
-- Req text: While OP_MODE DRC shall always satisfy Heatup | Load_Follow
LTLSPEC NAME PWR-0200_Heatup_0 := (! ((G ((! OP_MODE) | (Heatup | Load_Follow))) & (F ((! (! OP_MODE)) & (Heatup & (! Load_Follow))))));
-- Req text: While OP_MODE DRC shall always satisfy Heatup | Load_Follow
LTLSPEC NAME PWR-0200_Load_Follow_0 := (! ((G ((! OP_MODE) | (Heatup | Load_Follow))) & (F ((! (! OP_MODE)) & ((! Heatup) & Load_Follow)))));

View File

@ -0,0 +1,49 @@
-- DRCSpec
MODULE main
VAR
Cold_Shutdown: boolean;
Heatup: boolean;
Load_Follow: boolean;
OP_MODE: boolean;
SCRAM: boolean;
DEFINE
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_OP_MODE_0 := (! ((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & ((! OP_MODE) & (! (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_OP_MODE_1 := (! (((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & (F (((! OP_MODE) & (X (! OP_MODE))) & (! (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))))) & ((! OP_MODE) | (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_OP_MODE_2 := (! (((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & (F ((OP_MODE & (! (X (! OP_MODE)))) & (! (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))))) & ((! OP_MODE) | (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_Heatup_0 := (! ((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & ((! (! OP_MODE)) & ((G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))) & (F ((Heatup & (! Load_Follow)) & ((! SCRAM) & (! Cold_Shutdown))))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_Heatup_1 := (! (((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & (F ((! (OP_MODE | (X (! OP_MODE)))) & (X ((G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))) & (F ((Heatup & (! Load_Follow)) & ((! SCRAM) & (! Cold_Shutdown))))))))) & ((! OP_MODE) | (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_Load_Follow_0 := (! ((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & ((! (! OP_MODE)) & ((G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))) & (F (((! Heatup) & Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_Load_Follow_1 := (! (((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & (F ((! (OP_MODE | (X (! OP_MODE)))) & (X ((G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))) & (F (((! Heatup) & Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))))) & ((! OP_MODE) | (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_SCRAM_0 := (! ((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & ((! (! OP_MODE)) & ((G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))) & (F ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_SCRAM_1 := (! (((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & (F ((! (OP_MODE | (X (! OP_MODE)))) & (X ((G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))) & (F ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))))) & ((! OP_MODE) | (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_Cold_Shutdown_0 := (! ((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & ((! (! OP_MODE)) & ((G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))) & (F ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))));
-- Req text: When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)
LTLSPEC NAME PWR-0201_Cold_Shutdown_1 := (! (((G ((OP_MODE | (X (! OP_MODE))) | (X (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))) & (F ((! (OP_MODE | (X (! OP_MODE)))) & (X ((G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))) & (F ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown))))))))) & ((! OP_MODE) | (G ((Heatup | Load_Follow) & ((! SCRAM) & (! Cold_Shutdown)))))));

View File

@ -0,0 +1,23 @@
-- DRCSpec
MODULE main
VAR
Heatup: boolean;
Load_Follow: boolean;
OP_MODE: boolean;
DEFINE
-- Req text: While !OP_MODE DRC shall always satisfy (Heatup | Load_Follow)
LTLSPEC NAME PWR-0202_OP_MODE_0 := (! ((G (OP_MODE | (Heatup | Load_Follow))) & (F (OP_MODE & (! (Heatup | Load_Follow))))));
-- Req text: While !OP_MODE DRC shall always satisfy (Heatup | Load_Follow)
LTLSPEC NAME PWR-0202_Heatup_0 := (! ((G (OP_MODE | (Heatup | Load_Follow))) & (F ((! OP_MODE) & (Heatup & (! Load_Follow))))));
-- Req text: While !OP_MODE DRC shall always satisfy (Heatup | Load_Follow)
LTLSPEC NAME PWR-0202_Load_Follow_0 := (! ((G (OP_MODE | (Heatup | Load_Follow))) & (F ((! OP_MODE) & ((! Heatup) & Load_Follow)))));

View File

@ -0,0 +1,145 @@
-- DRCSpec
MODULE main
VAR
STARTUP:boolean;
Cold_Shutdown: boolean;
Heatup: boolean;
OP_MODE: boolean;
SCRAM: boolean;
DEFINE
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_0 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! Cold_Shutdown) | (! STARTUP))) & (((! SCRAM) & (X SCRAM)) & (! (X (OP_MODE & Heatup)))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_1 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! Cold_Shutdown) | (! STARTUP))) & (((! SCRAM) & (X SCRAM)) & (! (X (OP_MODE & Heatup)))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_2 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & ((! SCRAM) & (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_3 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM & (! (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_4 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X (((! SCRAM) & (X SCRAM)) & (! (X (OP_MODE & Heatup))))) & (SCRAM | (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_5 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X (((! SCRAM) & (X SCRAM)) & (! (X (OP_MODE & Heatup))))) & (SCRAM | (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_6 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((! (Cold_Shutdown & STARTUP)) & ((! (X ((! Cold_Shutdown) | (! STARTUP)))) & ((! SCRAM) & (X SCRAM)))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_7 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((! (Cold_Shutdown & STARTUP)) & ((! (X ((! Cold_Shutdown) | (! STARTUP)))) & ((! SCRAM) & (X SCRAM)))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_8 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((((! SCRAM) & (X SCRAM)) -> ((! SCRAM) & (X SCRAM))) U (! (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_9 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((((! SCRAM) & (X SCRAM)) -> ((! SCRAM) & (X SCRAM))) U (! (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_10 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (SCRAM & (! ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_11 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! Cold_Shutdown) | (! STARTUP))) & (((! SCRAM) & (X SCRAM)) & (! (X (OP_MODE & Heatup)))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_12 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! Cold_Shutdown) | (! STARTUP))) & (((! SCRAM) & (X SCRAM)) & (! (X (OP_MODE & Heatup)))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_13 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & ((! SCRAM) & (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_14 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM & (! (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_15 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X (((! SCRAM) & (X SCRAM)) & (! (X (OP_MODE & Heatup))))) & (SCRAM | (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_16 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X (((! SCRAM) & (X SCRAM)) & (! (X (OP_MODE & Heatup))))) & (SCRAM | (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_17 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((! (Cold_Shutdown & STARTUP)) & ((! (X ((! Cold_Shutdown) | (! STARTUP)))) & ((! SCRAM) & (X SCRAM)))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_18 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((! (Cold_Shutdown & STARTUP)) & ((! (X ((! Cold_Shutdown) | (! STARTUP)))) & ((! SCRAM) & (X SCRAM)))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_19 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((((! SCRAM) & (X SCRAM)) -> ((! SCRAM) & (X SCRAM))) U (! (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_20 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((((! SCRAM) & (X SCRAM)) -> ((! SCRAM) & (X SCRAM))) U (! (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_21 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F (((! (! SCRAM)) & (X SCRAM)) & (! (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_SCRAM_22 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F (((! SCRAM) & (! (X SCRAM))) & (! (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Cold_Shutdown_0 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) & (! (! STARTUP))) & (! (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Cold_Shutdown_1 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((! (Cold_Shutdown & STARTUP)) & ((X ((! Cold_Shutdown) & (! (! STARTUP)))) & (! ((! SCRAM) & (X SCRAM))))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Cold_Shutdown_2 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((Cold_Shutdown & STARTUP) & (! ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Cold_Shutdown_3 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) & (! (! STARTUP))) & (! (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Cold_Shutdown_4 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((! (Cold_Shutdown & STARTUP)) & ((X ((! Cold_Shutdown) & (! (! STARTUP)))) & (! ((! SCRAM) & (X SCRAM))))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Cold_Shutdown_5 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((Cold_Shutdown & STARTUP) & (! ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_STARTUP_0 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! (! Cold_Shutdown)) & (! STARTUP)) & (! (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_STARTUP_1 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((! (Cold_Shutdown & STARTUP)) & ((X ((! (! Cold_Shutdown)) & (! STARTUP))) & (! ((! SCRAM) & (X SCRAM))))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_STARTUP_2 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((Cold_Shutdown & STARTUP) & (! ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_STARTUP_3 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! (! Cold_Shutdown)) & (! STARTUP)) & (! (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_STARTUP_4 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((! (Cold_Shutdown & STARTUP)) & ((X ((! (! Cold_Shutdown)) & (! STARTUP))) & (! ((! SCRAM) & (X SCRAM))))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_STARTUP_5 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U (((Cold_Shutdown & STARTUP) & (! ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & (! ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_OP_MODE_0 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! Cold_Shutdown) | (! STARTUP))) & ((! ((! SCRAM) & (X SCRAM))) & (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_OP_MODE_1 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X ((! ((! SCRAM) & (X SCRAM))) & (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_OP_MODE_2 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! Cold_Shutdown) | (! STARTUP))) & ((! ((! SCRAM) & (X SCRAM))) & (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_OP_MODE_3 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X ((! ((! SCRAM) & (X SCRAM))) & (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Heatup_0 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! Cold_Shutdown) | (! STARTUP))) & ((! ((! SCRAM) & (X SCRAM))) & (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Heatup_1 := (! ((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) & (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X ((! ((! SCRAM) & (X SCRAM))) & (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Heatup_2 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! Cold_Shutdown) | (! STARTUP))) & ((! ((! SCRAM) & (X SCRAM))) & (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));
-- Req text: While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup
LTLSPEC NAME PWR-2001_Heatup_3 := (! (((G (((! SCRAM) | (X SCRAM)) | (X ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & (F ((! ((! SCRAM) | (X SCRAM))) & (X (((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & ((! ((! SCRAM) & (X SCRAM))) U ((! ((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM))))) & ((X ((! ((! SCRAM) & (X SCRAM))) & (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM))))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))))) & (SCRAM | ((((! SCRAM) & (X SCRAM)) V (((Cold_Shutdown & STARTUP) | ((X ((! Cold_Shutdown) | (! STARTUP))) | ((! SCRAM) & (X SCRAM)))) | ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (SCRAM | (X (! SCRAM)))))) & (((! Cold_Shutdown) | (! STARTUP)) | (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup))))))));

View File

@ -0,0 +1,113 @@
-- DRCSpec
MODULE main
VAR
t_dot_exceeded:boolean;
Heatup: boolean;
SCRAM: boolean;
DEFINE
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_0 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (! t_dot_exceeded)) & ((Heatup & (X (! Heatup))) & (! (X SCRAM))))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_1 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (! t_dot_exceeded)) & ((Heatup & (X (! Heatup))) & (! (X SCRAM))))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_2 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! (! Heatup)) & (X Heatup)))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_3 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) & (! (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_4 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) & (! (X SCRAM)))) & ((! Heatup) | (X Heatup)))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_5 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) & (! (X SCRAM)))) & ((! Heatup) | (X Heatup)))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_6 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_dot_exceeded) & ((! (X (! t_dot_exceeded))) & (Heatup & (X (! Heatup))))) & (! ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_7 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_dot_exceeded) & ((! (X (! t_dot_exceeded))) & (Heatup & (X (! Heatup))))) & (! ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_8 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & (((Heatup & (X (! Heatup))) -> (Heatup & (X (! Heatup)))) U (! ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_9 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & (((Heatup & (X (! Heatup))) -> (Heatup & (X (! Heatup)))) U (! ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_10 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! Heatup) & (! (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_11 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (! t_dot_exceeded)) & ((Heatup & (X (! Heatup))) & (! (X SCRAM))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_12 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (! t_dot_exceeded)) & ((Heatup & (X (! Heatup))) & (! (X SCRAM))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_13 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! (! Heatup)) & (X Heatup)))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_14 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) & (! (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_15 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) & (! (X SCRAM)))) & ((! Heatup) | (X Heatup)))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_16 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) & (! (X SCRAM)))) & ((! Heatup) | (X Heatup)))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_17 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_dot_exceeded) & ((! (X (! t_dot_exceeded))) & (Heatup & (X (! Heatup))))) & (! ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_18 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_dot_exceeded) & ((! (X (! t_dot_exceeded))) & (Heatup & (X (! Heatup))))) & (! ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_19 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & (((Heatup & (X (! Heatup))) -> (Heatup & (X (! Heatup)))) U (! ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_20 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & (((Heatup & (X (! Heatup))) -> (Heatup & (X (! Heatup)))) U (! ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_21 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F (((! Heatup) & (X (! Heatup))) & (! (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_Heatup_22 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((Heatup & (! (X (! Heatup)))) & (! (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_t_dot_exceeded_0 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) & (! ((Heatup & (X (! Heatup))) | (X SCRAM))))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_t_dot_exceeded_1 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_dot_exceeded) & ((X (! t_dot_exceeded)) & (! (Heatup & (X (! Heatup)))))) & (! ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_t_dot_exceeded_2 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((t_dot_exceeded & (! ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & (! ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_t_dot_exceeded_3 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) & (! ((Heatup & (X (! Heatup))) | (X SCRAM))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_t_dot_exceeded_4 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_dot_exceeded) & ((X (! t_dot_exceeded)) & (! (Heatup & (X (! Heatup)))))) & (! ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_t_dot_exceeded_5 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((t_dot_exceeded & (! ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & (! ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_SCRAM_0 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (! t_dot_exceeded)) & ((! (Heatup & (X (! Heatup)))) & (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_SCRAM_1 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((! (Heatup & (X (! Heatup)))) & (X SCRAM))) & ((! Heatup) | (X Heatup)))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_SCRAM_2 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (! t_dot_exceeded)) & ((! (Heatup & (X (! Heatup)))) & (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));
-- Req text: While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3001_SCRAM_3 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup)))))) & ((X ((! (Heatup & (X (! Heatup)))) & (X SCRAM))) & ((! Heatup) | (X Heatup)))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_dot_exceeded | ((X (! t_dot_exceeded)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & ((! Heatup) | (X Heatup))))) & ((! t_dot_exceeded) | ((Heatup & (X (! Heatup))) | (X SCRAM)))))));

View File

@ -0,0 +1,28 @@
-- DRCSpec
MODULE main
VAR
t_max_exceeded:boolean;
SCRAM: boolean;
DEFINE
-- Req text: if t_max_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3002_t_max_exceeded_0 := (! ((G ((t_max_exceeded | (X (! t_max_exceeded))) | (X (X SCRAM)))) & ((! t_max_exceeded) & (! (X SCRAM)))));
-- Req text: if t_max_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3002_t_max_exceeded_1 := (! (((G ((t_max_exceeded | (X (! t_max_exceeded))) | (X (X SCRAM)))) & (F (((! t_max_exceeded) & (X (! t_max_exceeded))) & (! (X (X SCRAM)))))) & ((! t_max_exceeded) | (X SCRAM))));
-- Req text: if t_max_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3002_t_max_exceeded_2 := (! (((G ((t_max_exceeded | (X (! t_max_exceeded))) | (X (X SCRAM)))) & (F ((t_max_exceeded & (! (X (! t_max_exceeded)))) & (! (X (X SCRAM)))))) & ((! t_max_exceeded) | (X SCRAM))));
-- Req text: if t_max_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3002_SCRAM_0 := (! ((G ((t_max_exceeded | (X (! t_max_exceeded))) | (X (X SCRAM)))) & ((! (! t_max_exceeded)) & (X SCRAM))));
-- Req text: if t_max_exceeded DRC shall at the next timepoint satisfy SCRAM
LTLSPEC NAME PWR-3002_SCRAM_1 := (! (((G ((t_max_exceeded | (X (! t_max_exceeded))) | (X (X SCRAM)))) & (F ((! (t_max_exceeded | (X (! t_max_exceeded)))) & (X (X SCRAM))))) & ((! t_max_exceeded) | (X SCRAM))));

View File

@ -0,0 +1,125 @@
-- DRCSpec
MODULE main
VAR
t_power_min:boolean;
Heatup: boolean;
Load_Follow: boolean;
DEFINE
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_0 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (! t_power_min)) & ((! (Heatup & (X (! Heatup)))) & (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_1 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (! t_power_min)) & ((Heatup & (X (! Heatup))) & (! (X (Load_Follow & (! Heatup))))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_2 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (! t_power_min)) & ((Heatup & (X (! Heatup))) & (! (X (Load_Follow & (! Heatup))))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_3 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! (! Heatup)) & (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_4 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) & (! (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_5 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((! (Heatup & (X (! Heatup)))) & (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_6 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) & (! (X (Load_Follow & (! Heatup)))))) & ((! Heatup) | (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_7 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) & (! (X (Load_Follow & (! Heatup)))))) & ((! Heatup) | (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_8 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_power_min) & ((! (X (! t_power_min))) & (Heatup & (X (! Heatup))))) & (! ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_9 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_power_min) & ((! (X (! t_power_min))) & (Heatup & (X (! Heatup))))) & (! ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_10 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & (((Heatup & (X (! Heatup))) -> (Heatup & (X (! Heatup)))) U (! ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_11 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & (((Heatup & (X (! Heatup))) -> (Heatup & (X (! Heatup)))) U (! ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_12 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! Heatup) & (! (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_13 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (! t_power_min)) & ((! (Heatup & (X (! Heatup)))) & (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_14 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (! t_power_min)) & ((Heatup & (X (! Heatup))) & (! (X (Load_Follow & (! Heatup))))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_15 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (! t_power_min)) & ((Heatup & (X (! Heatup))) & (! (X (Load_Follow & (! Heatup))))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_16 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! (! Heatup)) & (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_17 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) & (! (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_18 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((! (Heatup & (X (! Heatup)))) & (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_19 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) & (! (X (Load_Follow & (! Heatup)))))) & ((! Heatup) | (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_20 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((Heatup & (X (! Heatup))) & (! (X (Load_Follow & (! Heatup)))))) & ((! Heatup) | (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_21 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_power_min) & ((! (X (! t_power_min))) & (Heatup & (X (! Heatup))))) & (! ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_22 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_power_min) & ((! (X (! t_power_min))) & (Heatup & (X (! Heatup))))) & (! ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_23 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & (((Heatup & (X (! Heatup))) -> (Heatup & (X (! Heatup)))) U (! ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_24 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & (((Heatup & (X (! Heatup))) -> (Heatup & (X (! Heatup)))) U (! ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_25 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F (((! Heatup) & (X (! Heatup))) & (! (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Heatup_26 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((Heatup & (! (X (! Heatup)))) & (! (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_t_power_min_0 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) & (! ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_t_power_min_1 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_power_min) & ((X (! t_power_min)) & (! (Heatup & (X (! Heatup)))))) & (! ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_t_power_min_2 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((t_power_min & (! ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & (! ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_t_power_min_3 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) & (! ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_t_power_min_4 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U (((! t_power_min) & ((X (! t_power_min)) & (! (Heatup & (X (! Heatup)))))) & (! ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_t_power_min_5 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((t_power_min & (! ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & (! ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Load_Follow_0 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (! t_power_min)) & ((! (Heatup & (X (! Heatup)))) & (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Load_Follow_1 := (! ((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & ((! (! Heatup)) & ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((! (Heatup & (X (! Heatup)))) & (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Load_Follow_2 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (! t_power_min)) & ((! (Heatup & (X (! Heatup)))) & (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));
-- Req text: While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)
LTLSPEC NAME PWR-3003_Load_Follow_3 := (! (((G ((Heatup | (X (! Heatup))) | (X (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (F ((! (Heatup | (X (! Heatup)))) & (X ((((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! (Heatup & (X (! Heatup)))) U ((! (t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup)))))) & ((X ((! (Heatup & (X (! Heatup)))) & (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup)))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))))) & ((! Heatup) | (((Heatup & (X (! Heatup))) V ((t_power_min | ((X (! t_power_min)) | (Heatup & (X (! Heatup))))) | ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & ((! Heatup) | (X Heatup))))) & ((! t_power_min) | ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup)))))))));

View File

@ -0,0 +1,147 @@
{
"_comment": "Generated by parse_smv.py. Review and edit variable roles before synthesis.",
"spec_name": "DRC",
"variables": {
"Cold_Shutdown": {
"role": "conflict",
"input_reasons": [
"DRCSpec_PWR-2001: condition in \"While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup\""
],
"output_reasons": [
"DRCSpec_PWR-0000: satisfaction in \"DRC shall initially satisfy (Cold_Shutdown & !SCRAM)\"",
"DRCSpec_PWR-0201: satisfaction in \"When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)\""
]
},
"Heatup": {
"role": "conflict",
"input_reasons": [
"DRCSpec_PWR-3001: condition in \"While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM\"",
"DRCSpec_PWR-3003: condition in \"While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)\""
],
"output_reasons": [
"DRCSpec_PWR-0200: satisfaction in \"While OP_MODE DRC shall always satisfy Heatup | Load_Follow\"",
"DRCSpec_PWR-0201: satisfaction in \"When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)\"",
"DRCSpec_PWR-0202: satisfaction in \"While !OP_MODE DRC shall always satisfy (Heatup | Load_Follow)\"",
"DRCSpec_PWR-2001: satisfaction in \"While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup\"",
"DRCSpec_PWR-3003: satisfaction in \"While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)\""
]
},
"Load_Follow": {
"role": "output",
"input_reasons": [],
"output_reasons": [
"DRCSpec_PWR-0200: satisfaction in \"While OP_MODE DRC shall always satisfy Heatup | Load_Follow\"",
"DRCSpec_PWR-0201: satisfaction in \"When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)\"",
"DRCSpec_PWR-0202: satisfaction in \"While !OP_MODE DRC shall always satisfy (Heatup | Load_Follow)\"",
"DRCSpec_PWR-3003: satisfaction in \"While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)\""
]
},
"OP_MODE": {
"role": "conflict",
"input_reasons": [
"DRCSpec_PWR-0200: condition in \"While OP_MODE DRC shall always satisfy Heatup | Load_Follow\"",
"DRCSpec_PWR-0201: condition in \"When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)\"",
"DRCSpec_PWR-0202: condition in \"While !OP_MODE DRC shall always satisfy (Heatup | Load_Follow)\""
],
"output_reasons": [
"DRCSpec_PWR-0100: satisfaction in \"If SCRAM DRC shall immediately satisfy !OP_MODE\"",
"DRCSpec_PWR-2001: satisfaction in \"While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup\""
]
},
"SCRAM": {
"role": "conflict",
"input_reasons": [
"DRCSpec_PWR-0100: condition in \"If SCRAM DRC shall immediately satisfy !OP_MODE\"",
"DRCSpec_PWR-0102: condition in \"If SCRAM DRC shall always satisfy SCRAM\"",
"DRCSpec_PWR-2001: condition in \"While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup\""
],
"output_reasons": [
"DRCSpec_PWR-0000: satisfaction in \"DRC shall initially satisfy (Cold_Shutdown & !SCRAM)\"",
"DRCSpec_PWR-0102: satisfaction in \"If SCRAM DRC shall always satisfy SCRAM\"",
"DRCSpec_PWR-0201: satisfaction in \"When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)\"",
"DRCSpec_PWR-3001: satisfaction in \"While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM\"",
"DRCSpec_PWR-3002: satisfaction in \"if t_max_exceeded DRC shall at the next timepoint satisfy SCRAM\""
]
},
"STARTUP": {
"role": "input",
"input_reasons": [
"DRCSpec_PWR-2001: condition in \"While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup\""
],
"output_reasons": []
},
"t_dot_exceeded": {
"role": "input",
"input_reasons": [
"DRCSpec_PWR-3001: condition in \"While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM\""
],
"output_reasons": []
},
"t_max_exceeded": {
"role": "input",
"input_reasons": [
"DRCSpec_PWR-3002: condition in \"if t_max_exceeded DRC shall at the next timepoint satisfy SCRAM\""
],
"output_reasons": []
},
"t_power_min": {
"role": "input",
"input_reasons": [
"DRCSpec_PWR-3003: condition in \"While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)\""
],
"output_reasons": []
}
},
"requirements": [
{
"req_id": "DRCSpec_PWR-0000",
"fretish": "DRC shall initially satisfy (Cold_Shutdown & !SCRAM)",
"ltl": "(Cold_Shutdown & !SCRAM)"
},
{
"req_id": "DRCSpec_PWR-0100",
"fretish": "If SCRAM DRC shall immediately satisfy !OP_MODE",
"ltl": "G((SCRAM) -> X(!OP_MODE))"
},
{
"req_id": "DRCSpec_PWR-0102",
"fretish": "If SCRAM DRC shall always satisfy SCRAM",
"ltl": "G(SCRAM)"
},
{
"req_id": "DRCSpec_PWR-0200",
"fretish": "While OP_MODE DRC shall always satisfy Heatup | Load_Follow",
"ltl": "G((OP_MODE) -> (Heatup | Load_Follow))"
},
{
"req_id": "DRCSpec_PWR-0201",
"fretish": "When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)",
"ltl": "G((OP_MODE) -> X(G((Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown))))"
},
{
"req_id": "DRCSpec_PWR-0202",
"fretish": "While !OP_MODE DRC shall always satisfy (Heatup | Load_Follow)",
"ltl": "G((!OP_MODE) -> ((Heatup | Load_Follow)))"
},
{
"req_id": "DRCSpec_PWR-2001",
"fretish": "While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup",
"ltl": "G(((!SCRAM) & (Cold_Shutdown & STARTUP)) -> X(OP_MODE & Heatup))"
},
{
"req_id": "DRCSpec_PWR-3001",
"fretish": "While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM",
"ltl": "G(((Heatup) & (t_dot_exceeded)) -> X(SCRAM))"
},
{
"req_id": "DRCSpec_PWR-3002",
"fretish": "if t_max_exceeded DRC shall at the next timepoint satisfy SCRAM",
"ltl": "G((t_max_exceeded) -> X(SCRAM))"
},
{
"req_id": "DRCSpec_PWR-3003",
"fretish": "While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)",
"ltl": "G(((Heatup) & (t_power_min)) -> X((Load_Follow & !Heatup)))"
}
]
}

View File

@ -0,0 +1,143 @@
# DRC Spec Redesign -- Matching Figure 1 Hybrid Automaton
## Naming Convention
**Format: `DRC_XNNN_name`** where X is a category letter:
| Prefix | Category | Purpose |
|--------|----------|---------|
| `DRC_A___` | Architecture | Mode validity, structural constraints |
| `DRC_I___` | Initialization | Initial conditions |
| `DRC_S___` | Stay | Self-loop / remain-in-mode |
| `DRC_T___` | Transition | Mode-to-mode edges |
## Variable Mapping
### Outputs
| Variable | Type | Description |
|----------|------|-------------|
| `control_mode` | integer | Current discrete state (0-3) |
### Internal (enum constants)
| Variable | Type | Assignment | Description |
|----------|------|------------|-------------|
| `q_shutdown` | integer | 0 | Cold Shutdown mode |
| `q_heatup` | integer | 1 | Heatup mode |
| `q_operation` | integer | 2 | Power Operation mode |
| `q_scram` | integer | 3 | SCRAM mode |
### Inputs (boolean predicates over continuous state)
| Variable | Type | Description | Maps to |
|----------|------|-------------|---------|
| `t_avg_above_min` | boolean | T_avg > T_min | Guard: Shutdown -> Heatup |
| `t_avg_in_range` | boolean | T_avg in [T_op +/- delta] | Guard: Heatup -> Operation |
| `p_above_crit` | boolean | P > P_crit | Guard: Heatup -> Operation |
| `inv1_holds` | boolean | Invariant 1 OK | Safety: Heatup |
| `inv2_holds` | boolean | Invariant 2 OK | Safety: Operation |
| `manual_reset` | boolean | Operator reset command | Guard: SCRAM -> Shutdown |
## FRETish Requirements
### Architecture
```
DRC_A001_MODE_VALID:
DRC shall always satisfy
control_mode = q_shutdown | control_mode = q_heatup | control_mode = q_operation | control_mode = q_scram
```
### Initialization
```
DRC_I001_INIT_SHUTDOWN:
DRC shall immediately satisfy control_mode = q_shutdown
```
### Stay Conditions (self-loops)
```
DRC_S001_SHUTDOWN_STAY:
Whenever control_mode = q_shutdown & !t_avg_above_min
DRC shall at the next timepoint satisfy control_mode = q_shutdown
DRC_S002_HEATUP_STAY:
Whenever control_mode = q_heatup & inv1_holds & !(t_avg_in_range & p_above_crit)
DRC shall at the next timepoint satisfy control_mode = q_heatup
DRC_S003_OPERATION_STAY:
Whenever control_mode = q_operation & inv2_holds
DRC shall at the next timepoint satisfy control_mode = q_operation
DRC_S004_SCRAM_STAY:
Whenever control_mode = q_scram & !manual_reset
DRC shall at the next timepoint satisfy control_mode = q_scram
```
### Transitions (edges in Figure 1)
```
DRC_T001_SHUTDOWN_TO_HEATUP:
Upon control_mode = q_shutdown & t_avg_above_min
DRC shall at the next timepoint satisfy control_mode = q_heatup
DRC_T002_HEATUP_TO_OPERATION:
Upon control_mode = q_heatup & t_avg_in_range & p_above_crit
DRC shall at the next timepoint satisfy control_mode = q_operation
DRC_T003_HEATUP_TO_SCRAM:
Upon control_mode = q_heatup & !inv1_holds
DRC shall at the next timepoint satisfy control_mode = q_scram
DRC_T004_OPERATION_TO_SCRAM:
Upon control_mode = q_operation & !inv2_holds
DRC shall at the next timepoint satisfy control_mode = q_scram
DRC_T005_SCRAM_TO_SHUTDOWN:
Upon control_mode = q_scram & manual_reset
DRC shall at the next timepoint satisfy control_mode = q_shutdown
```
## Transition Priority Note
DRC_S002 and DRC_T003 overlap when `control_mode = q_heatup & !inv1_holds &
!(t_avg_in_range & p_above_crit)`. Both fire -- S002 says stay in heatup,
T003 says go to scram. T003 should win (safety takes priority). To resolve:
**Option A:** Strengthen S002 to include inv1_holds (already done above).
When inv1 fails, S002 doesn't fire, only T003 does.
**Option B:** Add explicit priority requirement:
```
DRC_A002_SCRAM_PRIORITY:
Whenever control_mode = q_heatup & !inv1_holds
DRC shall at the next timepoint satisfy control_mode = q_scram
```
Similarly, DRC_S003 and DRC_T004: when `control_mode = q_operation & !inv2_holds`,
S003 doesn't fire (requires inv2_holds), only T004 fires. This is already
correct in the spec above.
## Key Differences from Original DRC Spec
1. **Single integer mode variable** instead of 5 independent boolean outputs
- Mutual exclusivity is automatic
- No vacuous satisfaction of scoped requirements
2. **Guard conditions as boolean inputs** instead of output variables
- `t_avg_above_min` replaces continuous T_avg comparison
- These are computed by the tactical (continuous) layer
3. **Complete transition coverage** -- every mode has explicit stay + transition rules
- Original spec had no "stay" requirements, allowing trivial mode avoidance
4. **SCRAM is recoverable** (via manual_reset) instead of permanent latch
- Matches Figure 1 which shows SCRAM -> Cold Shutdown recovery
- Original PWR-0102 "If SCRAM always SCRAM" made op_mode unreachable
5. **Invariant violations as inputs** -- the environment reports invariant status
- Original spec had sensor triggers (t_dot_exceeded) as inputs, which is the
same concept but more directly connected to the automaton structure
## Boolean Abstraction for Synthesis
For ltlsynt, this translates directly:
- Inputs (6): t_avg_above_min, t_avg_in_range, p_above_crit, inv1_holds, inv2_holds, manual_reset
- Outputs (4): in_shutdown, in_heatup, in_operation, in_scram (with exclusivity)
- Environment assumptions: physical constraints on input combinations
- Guarantees: mode transitions from FRET requirements above

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
# Liveness constraints for DRC synthesis
#
# F(heatup): prevent trivially never entering heatup
# The environment can always force a scram during heatup (by asserting
# t_dot_exceeded), which permanently prevents op_mode. This is a latent
# conflict in the FRET requirements -- another FRET limitation finding.
#
# For now, we only require heatup to demonstrate that the scoped
# requirements activate meaningfully.
F(heatup)

View File

@ -0,0 +1,69 @@
{
"_comment": "Boolean abstraction of LPC lift-mode controller. Assumes -> Guarantees form.",
"spec_name": "LPC_mini",
"source_file": "specs/LPC_mini_reqts_and_vars.json",
"inputs": [
"r_a",
"r_b",
"r_c",
"r_d",
"r_e",
"r_f"
],
"outputs": [
"m_tb",
"m_stb",
"m_swb",
"m_wb"
],
"assumptions": [
"G((r_a | r_b | r_c | r_d | r_e | r_f) & (!r_a | !r_b) & (!r_a | !r_c) & (!r_a | !r_d) & (!r_a | !r_e) & (!r_a | !r_f) & (!r_b | !r_c) & (!r_b | !r_d) & (!r_b | !r_e) & (!r_b | !r_f) & (!r_c | !r_d) & (!r_c | !r_e) & (!r_c | !r_f) & (!r_d | !r_e) & (!r_d | !r_f) & (!r_e | !r_f))",
"r_f",
"G(r_a -> (X(r_a) | X(r_b)))",
"G(r_b -> (X(r_a) | X(r_b) | X(r_c)))",
"G(r_c -> (X(r_b) | X(r_c) | X(r_d)))",
"G(r_d -> (X(r_c) | X(r_d) | X(r_e)))",
"G(r_e -> (X(r_d) | X(r_e) | X(r_f)))",
"G(r_f -> (X(r_e) | X(r_f)))"
],
"guarantees": [
"G((m_tb | m_stb | m_swb | m_wb) & (!m_tb | !m_stb) & (!m_tb | !m_swb) & (!m_tb | !m_wb) & (!m_stb | !m_swb) & (!m_stb | !m_wb) & (!m_swb | !m_wb))",
"m_wb",
"G((m_wb & (r_e | r_f)) -> X(m_wb))",
"G((m_wb & (r_a | r_b | r_c | r_d)) -> X(m_swb))",
"G((m_swb & (r_d | r_e)) -> X(m_swb))",
"G((m_swb & r_f) -> X(m_wb))",
"G((m_swb & (r_a | r_b)) -> X(m_stb))",
"G((m_stb & (r_b | r_c)) -> X(m_stb))",
"G((m_stb & (r_d | r_e | r_f)) -> X(m_swb))",
"G((m_stb & r_a) -> X(m_tb))",
"G((m_tb & r_a) -> X(m_tb))",
"G((m_tb & !r_a) -> X(m_stb))"
],
"conjoined_ltl": "((G((r_a | r_b | r_c | r_d | r_e | r_f) & (!r_a | !r_b) & (!r_a | !r_c) & (!r_a | !r_d) & (!r_a | !r_e) & (!r_a | !r_f) & (!r_b | !r_c) & (!r_b | !r_d) & (!r_b | !r_e) & (!r_b | !r_f) & (!r_c | !r_d) & (!r_c | !r_e) & (!r_c | !r_f) & (!r_d | !r_e) & (!r_d | !r_f) & (!r_e | !r_f))) & (r_f) & (G(r_a -> (X(r_a) | X(r_b)))) & (G(r_b -> (X(r_a) | X(r_b) | X(r_c)))) & (G(r_c -> (X(r_b) | X(r_c) | X(r_d)))) & (G(r_d -> (X(r_c) | X(r_d) | X(r_e)))) & (G(r_e -> (X(r_d) | X(r_e) | X(r_f)))) & (G(r_f -> (X(r_e) | X(r_f))))) -> ((G((m_tb | m_stb | m_swb | m_wb) & (!m_tb | !m_stb) & (!m_tb | !m_swb) & (!m_tb | !m_wb) & (!m_stb | !m_swb) & (!m_stb | !m_wb) & (!m_swb | !m_wb))) & (m_wb) & (G((m_wb & (r_e | r_f)) -> X(m_wb))) & (G((m_wb & (r_a | r_b | r_c | r_d)) -> X(m_swb))) & (G((m_swb & (r_d | r_e)) -> X(m_swb))) & (G((m_swb & r_f) -> X(m_wb))) & (G((m_swb & (r_a | r_b)) -> X(m_stb))) & (G((m_stb & (r_b | r_c)) -> X(m_stb))) & (G((m_stb & (r_d | r_e | r_f)) -> X(m_swb))) & (G((m_stb & r_a) -> X(m_tb))) & (G((m_tb & r_a) -> X(m_tb))) & (G((m_tb & !r_a) -> X(m_stb))))",
"abstraction_notes": {
"speed_regions": {
"r_a": "speed <= 20 (hover zone)",
"r_b": "20 < speed <= 30",
"r_c": "30 < speed <= 40",
"r_d": "40 < speed <= 90",
"r_e": "90 < speed <= 100",
"r_f": "speed > 100"
},
"modes": {
"m_tb": "thrust_borne",
"m_stb": "semi_thrust_borne",
"m_swb": "semi_wing_borne",
"m_wb": "wing_borne"
},
"skipped_requirements": [
"LPC_REACH_HOVER_06 (bounded temporal F[0,6])",
"LPC_REACH_HOVER_12 (bounded temporal F[0,12])",
"LPC_KIAS_DERIVATIVE (absorbed into adjacency constraint)",
"LPC_KIAS_KGS (absorbed - single speed variable)",
"LPC_INIT_KIAS (absorbed into initial region)",
"LPC_KIAS_0 (trivially satisfied)",
"LPC_INIT_HOVER_MODE (absorbed - hover = region A)"
]
}
}

View File

@ -0,0 +1,153 @@
{
"_comment": "Generated from FRET JSON export. Ready for ltlsynt synthesis.",
"spec_name": "PWR_Hybrid_DRC",
"source_file": "specs/fretRequirementsVariables.json",
"inputs": [
"startup",
"t_dot_exceeded",
"t_max_exceeded",
"t_power_min"
],
"outputs": [
"cold_shutdown",
"heatup",
"load_follow",
"op_mode",
"scram"
],
"requirements": [
{
"req_id": "PWR-0100",
"fulltext": "If SCRAM DRC shall immediately satisfy !OP_MODE",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "((G (((! scram) & (X scram)) -> (X (! op_mode)))) & (scram -> (! op_mode)))",
"ltl_original": "((G (((! SCRAM) & (X SCRAM)) -> (X (! OP_MODE)))) & (SCRAM -> (! OP_MODE)))",
"variables": [
"SCRAM",
"OP_MODE"
]
},
{
"req_id": "PWR-0202",
"fulltext": "While !OP_MODE DRC shall always satisfy (Heatup | Load_Follow)",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "(G ((! op_mode) -> (heatup | load_follow)))",
"ltl_original": "(G ((! OP_MODE) -> (Heatup | Load_Follow)))",
"variables": [
"OP_MODE",
"Heatup",
"Load_Follow"
]
},
{
"req_id": "PWR-0201",
"fulltext": "When OP_MODE DRC shall always satisfy (Heatup | Load_Follow) & !(!Heatup & !Load_Follow) & !(SCRAM | Cold_Shutdown)",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "((G (((! op_mode) & (X op_mode)) -> (X (G ((heatup | load_follow) & (! (scram | cold_shutdown))))))) & (op_mode -> (G ((heatup | load_follow) & (! (scram | cold_shutdown))))))",
"ltl_original": "((G (((! OP_MODE) & (X OP_MODE)) -> (X (G ((Heatup | Load_Follow) & (! (SCRAM | Cold_Shutdown))))))) & (OP_MODE -> (G ((Heatup | Load_Follow) & (! (SCRAM | Cold_Shutdown))))))",
"variables": [
"OP_MODE",
"Heatup",
"Load_Follow",
"SCRAM",
"Cold_Shutdown"
]
},
{
"req_id": "PWR-0200",
"fulltext": "While OP_MODE DRC shall always satisfy Heatup | Load_Follow",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "(G (op_mode -> (heatup | load_follow)))",
"ltl_original": "(G (OP_MODE -> (Heatup | Load_Follow)))",
"variables": [
"OP_MODE",
"Heatup",
"Load_Follow"
]
},
{
"req_id": "PWR-3002",
"fulltext": "if t_max_exceeded DRC shall at the next timepoint satisfy SCRAM",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "((G (((! t_max_exceeded) & (X t_max_exceeded)) -> (X (X scram)))) & (t_max_exceeded -> (X scram)))",
"ltl_original": "((G (((! t_max_exceeded) & (X t_max_exceeded)) -> (X (X SCRAM)))) & (t_max_exceeded -> (X SCRAM)))",
"variables": [
"t_max_exceeded",
"SCRAM"
]
},
{
"req_id": "PWR-3001",
"fulltext": "While Heatup if t_dot_exceeded DRC shall at the next timepoint satisfy SCRAM",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "((G ((! ((! heatup) & (X heatup))) | (X (((heatup & (X (! heatup))) V (((! t_dot_exceeded) & ((X t_dot_exceeded) & (! (heatup & (X (! heatup)))))) -> ((X ((heatup & (X (! heatup))) | (X scram))) & (! (heatup & (X (! heatup))))))) & (t_dot_exceeded -> ((heatup & (X (! heatup))) | (X scram))))))) & (heatup -> (((heatup & (X (! heatup))) V (((! t_dot_exceeded) & ((X t_dot_exceeded) & (! (heatup & (X (! heatup)))))) -> ((X ((heatup & (X (! heatup))) | (X scram))) & (! (heatup & (X (! heatup))))))) & (t_dot_exceeded -> ((heatup & (X (! heatup))) | (X scram))))))",
"ltl_original": "((G ((! ((! Heatup) & (X Heatup))) | (X (((Heatup & (X (! Heatup))) V (((! t_dot_exceeded) & ((X t_dot_exceeded) & (! (Heatup & (X (! Heatup)))))) -> ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & (! (Heatup & (X (! Heatup))))))) & (t_dot_exceeded -> ((Heatup & (X (! Heatup))) | (X SCRAM))))))) & (Heatup -> (((Heatup & (X (! Heatup))) V (((! t_dot_exceeded) & ((X t_dot_exceeded) & (! (Heatup & (X (! Heatup)))))) -> ((X ((Heatup & (X (! Heatup))) | (X SCRAM))) & (! (Heatup & (X (! Heatup))))))) & (t_dot_exceeded -> ((Heatup & (X (! Heatup))) | (X SCRAM))))))",
"variables": [
"Heatup",
"t_dot_exceeded",
"SCRAM"
]
},
{
"req_id": "PWR-2001",
"fulltext": "While !SCRAM If Cold_Shutdown & STARTUP DRC shall at the next timepoint satisfy OP_MODE & Heatup",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "((G ((! (scram & (X (! scram)))) | (X ((((! scram) & (X scram)) V (((! (cold_shutdown & startup)) & ((X (cold_shutdown & startup)) & (! ((! scram) & (X scram))))) -> ((X (((! scram) & (X scram)) | (X (op_mode & heatup)))) & (! ((! scram) & (X scram)))))) & ((cold_shutdown & startup) -> (((! scram) & (X scram)) | (X (op_mode & heatup)))))))) & ((! scram) -> ((((! scram) & (X scram)) V (((! (cold_shutdown & startup)) & ((X (cold_shutdown & startup)) & (! ((! scram) & (X scram))))) -> ((X (((! scram) & (X scram)) | (X (op_mode & heatup)))) & (! ((! scram) & (X scram)))))) & ((cold_shutdown & startup) -> (((! scram) & (X scram)) | (X (op_mode & heatup)))))))",
"ltl_original": "((G ((! (SCRAM & (X (! SCRAM)))) | (X ((((! SCRAM) & (X SCRAM)) V (((! (Cold_Shutdown & STARTUP)) & ((X (Cold_Shutdown & STARTUP)) & (! ((! SCRAM) & (X SCRAM))))) -> ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (! ((! SCRAM) & (X SCRAM)))))) & ((Cold_Shutdown & STARTUP) -> (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))) & ((! SCRAM) -> ((((! SCRAM) & (X SCRAM)) V (((! (Cold_Shutdown & STARTUP)) & ((X (Cold_Shutdown & STARTUP)) & (! ((! SCRAM) & (X SCRAM))))) -> ((X (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))) & (! ((! SCRAM) & (X SCRAM)))))) & ((Cold_Shutdown & STARTUP) -> (((! SCRAM) & (X SCRAM)) | (X (OP_MODE & Heatup)))))))",
"variables": [
"SCRAM",
"Cold_Shutdown",
"STARTUP",
"OP_MODE",
"Heatup"
]
},
{
"req_id": "PWR-3003",
"fulltext": "While Heatup if t_power_min DRC shall at the next timepoint satisfy (Load_Follow & !Heatup)",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "((G ((! ((! heatup) & (X heatup))) | (X (((heatup & (X (! heatup))) V (((! t_power_min) & ((X t_power_min) & (! (heatup & (X (! heatup)))))) -> ((X ((heatup & (X (! heatup))) | (X (load_follow & (! heatup))))) & (! (heatup & (X (! heatup))))))) & (t_power_min -> ((heatup & (X (! heatup))) | (X (load_follow & (! heatup))))))))) & (heatup -> (((heatup & (X (! heatup))) V (((! t_power_min) & ((X t_power_min) & (! (heatup & (X (! heatup)))))) -> ((X ((heatup & (X (! heatup))) | (X (load_follow & (! heatup))))) & (! (heatup & (X (! heatup))))))) & (t_power_min -> ((heatup & (X (! heatup))) | (X (load_follow & (! heatup))))))))",
"ltl_original": "((G ((! ((! Heatup) & (X Heatup))) | (X (((Heatup & (X (! Heatup))) V (((! t_power_min) & ((X t_power_min) & (! (Heatup & (X (! Heatup)))))) -> ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & (! (Heatup & (X (! Heatup))))))) & (t_power_min -> ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))) & (Heatup -> (((Heatup & (X (! Heatup))) V (((! t_power_min) & ((X t_power_min) & (! (Heatup & (X (! Heatup)))))) -> ((X ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))) & (! (Heatup & (X (! Heatup))))))) & (t_power_min -> ((Heatup & (X (! Heatup))) | (X (Load_Follow & (! Heatup))))))))",
"variables": [
"Heatup",
"t_power_min",
"Load_Follow"
]
},
{
"req_id": "PWR-0000",
"fulltext": "DRC shall initially satisfy (Cold_Shutdown & !SCRAM)",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "(cold_shutdown & (! scram))",
"ltl_original": "(Cold_Shutdown & (! SCRAM))",
"variables": [
"Cold_Shutdown",
"SCRAM"
]
},
{
"req_id": "PWR-0102",
"fulltext": "If SCRAM DRC shall always satisfy SCRAM",
"project": "PWR_Hybrid",
"component": "DRC",
"ltl": "((G (((! scram) & (X scram)) -> (X (G scram)))) & (scram -> (G scram)))",
"ltl_original": "((G (((! SCRAM) & (X SCRAM)) -> (X (G SCRAM)))) & (SCRAM -> (G SCRAM)))",
"variables": [
"SCRAM"
]
}
],
"liveness_constraints": [
"F(heatup)"
],
"conjoined_ltl": "(((G (((! scram) & (X scram)) -> (X (! op_mode)))) & (scram -> (! op_mode)))) & ((G ((! op_mode) -> (heatup | load_follow)))) & (((G (((! op_mode) & (X op_mode)) -> (X (G ((heatup | load_follow) & (! (scram | cold_shutdown))))))) & (op_mode -> (G ((heatup | load_follow) & (! (scram | cold_shutdown))))))) & ((G (op_mode -> (heatup | load_follow)))) & (((G (((! t_max_exceeded) & (X t_max_exceeded)) -> (X (X scram)))) & (t_max_exceeded -> (X scram)))) & (((G ((! ((! heatup) & (X heatup))) | (X (((heatup & (X (! heatup))) V (((! t_dot_exceeded) & ((X t_dot_exceeded) & (! (heatup & (X (! heatup)))))) -> ((X ((heatup & (X (! heatup))) | (X scram))) & (! (heatup & (X (! heatup))))))) & (t_dot_exceeded -> ((heatup & (X (! heatup))) | (X scram))))))) & (heatup -> (((heatup & (X (! heatup))) V (((! t_dot_exceeded) & ((X t_dot_exceeded) & (! (heatup & (X (! heatup)))))) -> ((X ((heatup & (X (! heatup))) | (X scram))) & (! (heatup & (X (! heatup))))))) & (t_dot_exceeded -> ((heatup & (X (! heatup))) | (X scram))))))) & (((G ((! (scram & (X (! scram)))) | (X ((((! scram) & (X scram)) V (((! (cold_shutdown & startup)) & ((X (cold_shutdown & startup)) & (! ((! scram) & (X scram))))) -> ((X (((! scram) & (X scram)) | (X (op_mode & heatup)))) & (! ((! scram) & (X scram)))))) & ((cold_shutdown & startup) -> (((! scram) & (X scram)) | (X (op_mode & heatup)))))))) & ((! scram) -> ((((! scram) & (X scram)) V (((! (cold_shutdown & startup)) & ((X (cold_shutdown & startup)) & (! ((! scram) & (X scram))))) -> ((X (((! scram) & (X scram)) | (X (op_mode & heatup)))) & (! ((! scram) & (X scram)))))) & ((cold_shutdown & startup) -> (((! scram) & (X scram)) | (X (op_mode & heatup)))))))) & (((G ((! ((! heatup) & (X heatup))) | (X (((heatup & (X (! heatup))) V (((! t_power_min) & ((X t_power_min) & (! (heatup & (X (! heatup)))))) -> ((X ((heatup & (X (! heatup))) | (X (load_follow & (! heatup))))) & (! (heatup & (X (! heatup))))))) & (t_power_min -> ((heatup & (X (! heatup))) | (X (load_follow & (! heatup))))))))) & (heatup -> (((heatup & (X (! heatup))) V (((! t_power_min) & ((X t_power_min) & (! (heatup & (X (! heatup)))))) -> ((X ((heatup & (X (! heatup))) | (X (load_follow & (! heatup))))) & (! (heatup & (X (! heatup))))))) & (t_power_min -> ((heatup & (X (! heatup))) | (X (load_follow & (! heatup))))))))) & ((cold_shutdown & (! scram))) & (((G (((! scram) & (X scram)) -> (X (G scram)))) & (scram -> (G scram)))) & (F(heatup))"
}

4
fret-pipeline/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.DS_Store
__pycache__/
*.pyc
.claude/

99
fret-pipeline/CLAUDE.md Normal file
View File

@ -0,0 +1,99 @@
# 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`.

110
fret-pipeline/README.md Normal file
View File

@ -0,0 +1,110 @@
# FRET-to-Synthesis Pipeline
A deterministic pipeline for converting FRET natural-language requirements into
synthesized reactive controllers, with automatic state machine visualization.
```
pwr_hybrid_3.json FRET export (source of truth)
|
v
scripts/fret_to_synth.py Auto-discover modes, encode as booleans
|
v
specs/synthesis_config_v3.json ltlsynt-ready config
|
v
scripts/synthesize.sh Run ltlsynt (reactive synthesis)
|
v
circuits/*.aag Synthesized controller (AIGER circuit)
|
v
scripts/trace_aiger.py Exhaustive eval, guard extraction, DOT
|
v
diagrams/*_states.dot/png/svg State machine with guard conditions
```
## Quick Start
```bash
# 1. Convert FRET export to synthesis config
python3 scripts/fret_to_synth.py pwr_hybrid_3.json specs/synthesis_config_v3.json
# 2. Synthesize the controller
bash scripts/synthesize.sh specs/synthesis_config_v3.json circuits
# 3. Trace and visualize
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
```
## Prerequisites
- **Python 3.10+** (no external packages required)
- **[Spot](https://spot.lre.epita.fr/)** for `ltlsynt` (`brew install spot`)
- **[Graphviz](https://graphviz.org/)** for `dot` (`brew install graphviz`)
## FRET Naming Conventions
The pipeline auto-discovers mode variables and environment inputs from your FRET
export. To make this work, follow these naming rules in FRET:
### Mode variables: `control_* = q_*`
Any variable whose name starts with `control_` is treated as a discrete mode
variable. Its values must start with `q_`. Examples:
```
control_mode = q_shutdown (a reactor operating mode)
control_pump = q_running (a pump state)
control_valve = q_open (a valve position)
```
The script discovers these by regex-scanning the LTL formulas. Multiple control
groups are supported -- each gets its own set of boolean outputs and its own
mutual exclusion constraint.
### Everything else is an environment input
Variables that don't match `control_*` or `q_*` are classified as environment
inputs (uncontrollable). These are typically continuous predicates abstracted
to booleans:
```
t_avg_above_min (temperature predicate)
inv1_holds (safety invariant)
manual_reset (operator action)
```
### Mutual exclusion encoding
FRET uses a single integer variable (`control_mode`) that inherently can only
hold one value at a time. But ltlsynt works with independent boolean
propositions. When we decompose `control_mode` into separate booleans
(`in_mode_shutdown`, `in_mode_heatup`, etc.), we lose the single-valued
constraint -- the synthesizer could assert multiple modes simultaneously.
The mutual exclusion constraint is added automatically by `fret_to_synth.py`
to restore this invariant. **It is a synthesis encoding artifact, NOT a missing
FRET requirement.** You do not need to write it in FRET.
## Directory Structure
```
fret_processing/
pwr_hybrid_3.json FRET JSON export
specs/
synthesis_config_v3.json Generated synthesis config
circuits/
PWR_HYBRID_3_DRC.aag Synthesized AIGER circuit
diagrams/
*_states.dot/png/svg State machine diagrams
scripts/
fret_to_synth.py FRET-to-ltlsynt converter
synthesize.sh ltlsynt wrapper
trace_aiger.py Circuit tracer + visualizer
aag2dot.py Gate-level circuit diagram
visualize.sh Visualization wrapper
.archive/ Old/superseded files
```

View File

View File

@ -0,0 +1,42 @@
aag 27 6 2 4 19
2
4
6
8
10
12
14 42
16 55
18
20
22
24
18 15 17
20 14 17
22 15 16
24 14 16
26 4 6
28 8 20
30 26 28
32 12 24
34 3 18
36 10 22
38 31 33
40 35 37
42 38 40
44 5 20
46 6 28
48 13 16
50 23 45
52 47 49
54 50 52
i0 t_avg_above_min
i1 inv1_holds
i2 p_above_crit
i3 t_avg_in_range
i4 inv2_holds
i5 manual_reset
o0 in_mode_shutdown
o1 in_mode_heatup
o2 in_mode_operation
o3 in_mode_scram

View File

View File

@ -0,0 +1,24 @@
digraph Controller {
rankdir=LR;
bgcolor="white";
node [shape=Mrecord, style="filled,rounded", fontname="Helvetica-Bold", fontsize=12, penwidth=1.5];
edge [fontname="Helvetica", fontsize=9];
s00 [label="MODE_SHUTDOWN", fillcolor="#A8D8EA"];
s01 [label="MODE_OPERATION", fillcolor="#77DD77"];
s10 [label="MODE_HEATUP", fillcolor="#FFFACD"];
s11 [label="MODE_SCRAM", fillcolor="#FF6B6B"];
init [shape=point, width=0.25, color="black"];
init -> s00 [penwidth=2.0];
s00 -> s00 [label="!t_avg_above_min", penwidth=1.2, color="#4A90D9", fontcolor="#4A90D9", style="bold"];
s00 -> s10 [label="t_avg_above_min", penwidth=1.2, color="#228B22", fontcolor="#228B22"];
s01 -> s01 [label="inv2_holds", penwidth=1.2, color="#4A90D9", fontcolor="#4A90D9", style="bold"];
s01 -> s11 [label="!inv2_holds", penwidth=1.2, color="#CC0000", fontcolor="#CC0000", style="bold"];
s10 -> s01 [label="inv1_holds & p_above_crit & t_avg_in_range", penwidth=1.2, color="#228B22", fontcolor="#228B22"];
s10 -> s10 [label="(inv1_holds & !t_avg_in_range) | (inv1_holds & !p_above_crit)", penwidth=1.2, color="#4A90D9", fontcolor="#4A90D9", style="bold"];
s10 -> s11 [label="!inv1_holds", penwidth=1.2, color="#CC0000", fontcolor="#CC0000", style="bold"];
s11 -> s00 [label="manual_reset", penwidth=1.2, color="#228B22", fontcolor="#228B22"];
s11 -> s11 [label="!manual_reset", penwidth=1.2, color="#4A90D9", fontcolor="#4A90D9", style="bold"];
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 14.1.4 (20260321.0153)
-->
<!-- Title: Controller Pages: 1 -->
<svg width="948pt" height="149pt"
viewBox="0.00 0.00 948.00 149.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 144.75)">
<title>Controller</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-144.75 943.5,-144.75 943.5,4 -4,4"/>
<!-- s00 -->
<g id="node1" class="node">
<title>s00</title>
<path fill="#a8d8ea" stroke="black" stroke-width="1.5" d="M67,-0.5C67,-0.5 173.75,-0.5 173.75,-0.5 179.75,-0.5 185.75,-6.5 185.75,-12.5 185.75,-12.5 185.75,-24.5 185.75,-24.5 185.75,-30.5 179.75,-36.5 173.75,-36.5 173.75,-36.5 67,-36.5 67,-36.5 61,-36.5 55,-30.5 55,-24.5 55,-24.5 55,-12.5 55,-12.5 55,-6.5 61,-0.5 67,-0.5"/>
<text xml:space="preserve" text-anchor="middle" x="120.38" y="-13.6" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="12.00">MODE_SHUTDOWN</text>
</g>
<!-- s00&#45;&gt;s00 -->
<g id="edge2" class="edge">
<title>s00&#45;&gt;s00</title>
<path fill="none" stroke="#4a90d9" stroke-width="1.2" d="M105.2,-36.9C102.87,-46.42 107.92,-55 120.38,-55 127.18,-55 131.78,-52.43 134.17,-48.55"/>
<polygon fill="#4a90d9" stroke="#4a90d9" stroke-width="1.2" points="137.63,-49.05 135.33,-38.71 130.68,-48.23 137.63,-49.05"/>
<text xml:space="preserve" text-anchor="middle" x="120.38" y="-56.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#4a90d9">!t_avg_above_min</text>
</g>
<!-- s10 -->
<g id="node3" class="node">
<title>s10</title>
<path fill="#fffacd" stroke="black" stroke-width="1.5" d="M307.25,-31.5C307.25,-31.5 391.5,-31.5 391.5,-31.5 397.5,-31.5 403.5,-37.5 403.5,-43.5 403.5,-43.5 403.5,-55.5 403.5,-55.5 403.5,-61.5 397.5,-67.5 391.5,-67.5 391.5,-67.5 307.25,-67.5 307.25,-67.5 301.25,-67.5 295.25,-61.5 295.25,-55.5 295.25,-55.5 295.25,-43.5 295.25,-43.5 295.25,-37.5 301.25,-31.5 307.25,-31.5"/>
<text xml:space="preserve" text-anchor="middle" x="349.38" y="-44.6" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="12.00">MODE_HEATUP</text>
</g>
<!-- s00&#45;&gt;s10 -->
<g id="edge3" class="edge">
<title>s00&#45;&gt;s10</title>
<path fill="none" stroke="#228b22" stroke-width="1.2" d="M186.42,-27.38C216.86,-31.54 253.02,-36.48 283.44,-40.63"/>
<polygon fill="#228b22" stroke="#228b22" stroke-width="1.2" points="282.62,-44.05 293,-41.94 283.56,-37.12 282.62,-44.05"/>
<text xml:space="preserve" text-anchor="middle" x="240.5" y="-40.67" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#228b22">t_avg_above_min</text>
</g>
<!-- s01 -->
<g id="node2" class="node">
<title>s01</title>
<path fill="#77dd77" stroke="black" stroke-width="1.5" d="M635.25,-76.5C635.25,-76.5 740.5,-76.5 740.5,-76.5 746.5,-76.5 752.5,-82.5 752.5,-88.5 752.5,-88.5 752.5,-100.5 752.5,-100.5 752.5,-106.5 746.5,-112.5 740.5,-112.5 740.5,-112.5 635.25,-112.5 635.25,-112.5 629.25,-112.5 623.25,-106.5 623.25,-100.5 623.25,-100.5 623.25,-88.5 623.25,-88.5 623.25,-82.5 629.25,-76.5 635.25,-76.5"/>
<text xml:space="preserve" text-anchor="middle" x="687.88" y="-89.6" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="12.00">MODE_OPERATION</text>
</g>
<!-- s01&#45;&gt;s01 -->
<g id="edge4" class="edge">
<title>s01&#45;&gt;s01</title>
<path fill="none" stroke="#4a90d9" stroke-width="1.2" d="M668.65,-112.9C665.7,-122.42 672.1,-131 687.88,-131 696.5,-131 702.32,-128.43 705.35,-124.55"/>
<polygon fill="#4a90d9" stroke="#4a90d9" stroke-width="1.2" points="708.8,-125.11 706.83,-114.7 701.88,-124.07 708.8,-125.11"/>
<text xml:space="preserve" text-anchor="middle" x="687.88" y="-132.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#4a90d9">inv2_holds</text>
</g>
<!-- s11 -->
<g id="node4" class="node">
<title>s11</title>
<path fill="#ff6b6b" stroke="black" stroke-width="1.5" d="M847.75,-30.5C847.75,-30.5 927.5,-30.5 927.5,-30.5 933.5,-30.5 939.5,-36.5 939.5,-42.5 939.5,-42.5 939.5,-54.5 939.5,-54.5 939.5,-60.5 933.5,-66.5 927.5,-66.5 927.5,-66.5 847.75,-66.5 847.75,-66.5 841.75,-66.5 835.75,-60.5 835.75,-54.5 835.75,-54.5 835.75,-42.5 835.75,-42.5 835.75,-36.5 841.75,-30.5 847.75,-30.5"/>
<text xml:space="preserve" text-anchor="middle" x="887.62" y="-43.6" font-family="Helvetica,sans-Serif" font-weight="bold" font-size="12.00">MODE_SCRAM</text>
</g>
<!-- s01&#45;&gt;s11 -->
<g id="edge5" class="edge">
<title>s01&#45;&gt;s11</title>
<path fill="none" stroke="#cc0000" stroke-width="1.2" d="M753.08,-79.57C775.74,-74.29 801.19,-68.37 823.74,-63.13"/>
<polygon fill="#cc0000" stroke="#cc0000" stroke-width="1.2" points="824.53,-66.54 833.48,-60.86 822.94,-59.72 824.53,-66.54"/>
<text xml:space="preserve" text-anchor="middle" x="794.12" y="-75.45" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cc0000">!inv2_holds</text>
</g>
<!-- s10&#45;&gt;s01 -->
<g id="edge6" class="edge">
<title>s10&#45;&gt;s01</title>
<path fill="none" stroke="#228b22" stroke-width="1.2" d="M403.91,-59.65C409.84,-60.66 415.79,-61.63 421.5,-62.5 485.16,-72.15 557.78,-80.74 610.93,-86.58"/>
<polygon fill="#228b22" stroke="#228b22" stroke-width="1.2" points="610.52,-90.06 620.84,-87.66 611.28,-83.1 610.52,-90.06"/>
<text xml:space="preserve" text-anchor="middle" x="513.38" y="-87.06" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#228b22">inv1_holds &amp; p_above_crit &amp; t_avg_in_range</text>
</g>
<!-- s10&#45;&gt;s10 -->
<g id="edge7" class="edge">
<title>s10&#45;&gt;s10</title>
<path fill="none" stroke="#4a90d9" stroke-width="1.2" d="M329.68,-67.9C326.65,-77.42 333.21,-86 349.38,-86 358.21,-86 364.18,-83.43 367.28,-79.55"/>
<polygon fill="#4a90d9" stroke="#4a90d9" stroke-width="1.2" points="370.73,-80.12 368.8,-69.7 363.82,-79.05 370.73,-80.12"/>
<text xml:space="preserve" text-anchor="middle" x="349.38" y="-87.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#4a90d9">(inv1_holds &amp; !t_avg_in_range) | (inv1_holds &amp; !p_above_crit)</text>
</g>
<!-- s10&#45;&gt;s11 -->
<g id="edge8" class="edge">
<title>s10&#45;&gt;s11</title>
<path fill="none" stroke="#cc0000" stroke-width="1.2" d="M404.25,-49.4C504.09,-49.21 717.35,-48.82 823.66,-48.62"/>
<polygon fill="#cc0000" stroke="#cc0000" stroke-width="1.2" points="823.35,-52.12 833.34,-48.6 823.33,-45.12 823.35,-52.12"/>
<text xml:space="preserve" text-anchor="middle" x="687.88" y="-50.18" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#cc0000">!inv1_holds</text>
</g>
<!-- s11&#45;&gt;s00 -->
<g id="edge9" class="edge">
<title>s11&#45;&gt;s00</title>
<path fill="none" stroke="#228b22" stroke-width="1.2" d="M835.1,-45.48C829.25,-45.15 823.37,-44.81 817.75,-44.5 633.66,-34.27 587.77,-28.7 403.5,-22.5 334.03,-20.16 254.89,-19.19 198.14,-18.78"/>
<polygon fill="#228b22" stroke="#228b22" stroke-width="1.2" points="198.22,-15.28 188.2,-18.72 198.18,-22.28 198.22,-15.28"/>
<text xml:space="preserve" text-anchor="middle" x="513.38" y="-32.71" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#228b22">manual_reset</text>
</g>
<!-- s11&#45;&gt;s11 -->
<g id="edge10" class="edge">
<title>s11&#45;&gt;s11</title>
<path fill="none" stroke="#4a90d9" stroke-width="1.2" d="M870.71,-66.9C868.11,-76.42 873.75,-85 887.62,-85 895.22,-85 900.34,-82.43 903,-78.55"/>
<polygon fill="#4a90d9" stroke="#4a90d9" stroke-width="1.2" points="906.46,-79.08 904.3,-68.71 899.52,-78.16 906.46,-79.08"/>
<text xml:space="preserve" text-anchor="middle" x="887.62" y="-86.2" font-family="Helvetica,sans-Serif" font-size="9.00" fill="#4a90d9">!manual_reset</text>
</g>
<!-- init -->
<g id="node5" class="node">
<title>init</title>
<ellipse fill="black" stroke="black" stroke-width="1.5" cx="9" cy="-18.5" rx="9" ry="9"/>
</g>
<!-- init&#45;&gt;s00 -->
<g id="edge1" class="edge">
<title>init&#45;&gt;s00</title>
<path fill="none" stroke="black" stroke-width="2" d="M18.58,-18.5C24.26,-18.5 32.33,-18.5 41.45,-18.5"/>
<polygon fill="black" stroke="black" stroke-width="2" points="41.4,-22 51.4,-18.5 41.4,-15 41.4,-22"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -0,0 +1,63 @@
# aag2dot.py -- Gate-Level Circuit Diagram
## Purpose
Converts an ASCII AIGER (`.aag`) file into a Graphviz DOT representation
showing the raw gate-level circuit topology. Unlike `trace_aiger.py` which
shows the behavioral state machine, this shows the actual hardware structure:
AND gates, latches, and wiring.
## Usage
```bash
python3 scripts/aag2dot.py circuits/SPEC.aag | dot -Tsvg -o diagrams/SPEC_gates.svg
```
## How It Works
### `parse_aag(text)`
Same AIGER parsing logic as `trace_aiger.py` (see that documentation for
format details). Returns a dictionary of inputs, latches, outputs, and AND
gates.
### `lit_node(lit)`
Maps an AIGER literal to a Graphviz node ID and negation flag:
- Literal `14` -> `("n7", False)` -- variable 7, positive
- Literal `15` -> `("n7", True)` -- variable 7, negated
### `to_dot(aag)`
Generates the DOT string with:
- **Input nodes** (light blue boxes): environment signals
- **Latch nodes** (yellow rounded boxes): state registers
- **AND gate nodes** (white circles): combinational logic
- **Output nodes** (green boxes): controller outputs
- **Solid edges**: positive connections
- **Dashed red edges** with `~` label: negated connections
- **Feedback edges** (constraint=false): latch next-state wiring, drawn
backward to show the feedback loop
## When to Use
The gate-level view is useful for:
- Verifying the circuit structure matches expectations
- Understanding how the synthesizer encoded the state transitions
- Debugging unexpected behavior by tracing signals through gates
- Presentations where you want to show "this is real hardware"
For understanding the controller's behavior (which mode transitions to
which, under what conditions), use `trace_aiger.py` instead.
## Future Improvements
- **Signal propagation highlighting**: Color-code paths from a specific
input to the outputs it affects.
- **Latch grouping**: Visually group latches and their feedback logic
into subclusters.
- **Gate count summary**: Print statistics (number of each gate type,
circuit depth, fan-in/fan-out).

View File

@ -0,0 +1,135 @@
# fret_to_synth.py -- FRET Export to Synthesis Config
## Purpose
Converts a FRET JSON export into a synthesis configuration file that
`ltlsynt` (from the Spot library) can consume. Handles the critical encoding
step: FRET's multi-valued mode variables become independent boolean
propositions with automatically generated mutual exclusion constraints.
## Usage
```bash
python3 scripts/fret_to_synth.py <fret_export.json> [output.json]
```
If `output.json` is omitted, writes to `specs/synthesis_config_v3.json`.
## How It Works
### Step 1: Mode Discovery (`discover_modes`)
Regex-scans all `ftInfAUExpanded` (and fallback `ft`) LTL formulas in the
FRET export for patterns matching:
```
(control_GROUPNAME = q_VALUENAME)
```
Returns a dictionary of mode groups:
```python
{
"control_mode": ["q_heatup", "q_operation", "q_scram", "q_shutdown"],
"control_pump": ["q_off", "q_running"], # if present
}
```
This is fully automatic -- no hardcoded variable lists. Adding a new mode in
FRET and re-exporting is all that's needed.
### Step 2: Boolean Encoding (`build_mode_map`)
For each mode group, creates boolean proposition names:
```
control_mode = q_shutdown --> in_mode_shutdown
control_mode = q_heatup --> in_mode_heatup
control_pump = q_off --> in_pump_off
```
The naming rule is: `in_{group_suffix}_{value_suffix}`, where the group
suffix strips `control_` and the value suffix strips `q_`.
Returns a string replacement map used by `encode_ltl` to transform the
FRET LTL formulas.
### Step 3: Variable Classification (`classify_variables`)
Every variable in the FRET semantics is classified:
- **Mode variables** (`control_*`, `q_*`): handled by boolean encoding, excluded
from explicit input/output lists.
- **Everything else**: classified as an environment input. These are typically
continuous-domain predicates that have been abstracted to boolean
(e.g., `t_avg_above_min`, `inv1_holds`).
### Step 4: LTL Encoding (`encode_ltl`)
Simple string replacement of `(control_X = q_Y)` with the corresponding
boolean name. A sanity check ensures no `control_` or `q_` references survive
the transformation -- if a mode value appears in the LTL but wasn't discovered
in Step 1, the script raises an error rather than producing a silent bug.
### Step 5: Mutual Exclusion (`mutual_exclusion_ltl`)
For each mode group, generates an "exactly one active" LTL constraint:
```
G( (a & !b & !c & !d) | (!a & b & !c & !d) | (!a & !b & c & !d) | (!a & !b & !c & d) )
```
This is conjoined with the requirement formulas in the final output.
**Why this is needed:** FRET's `control_mode = q_X` is a single integer
variable -- it inherently holds one value. After decomposition into independent
booleans, the synthesizer could assert `in_mode_heatup = true` AND
`in_mode_scram = true` simultaneously and still satisfy every requirement.
The mutual exclusion constraint prevents this. It is a synthesis encoding
artifact, not a gap in the FRET specifications.
### Step 6: LTL Formula Selection
The script prefers `ftInfAUExpanded` from FRET's semantics object. This is
the future-time LTL formula with:
- Infinite-horizon semantics (no LAST boundary terms)
- Expanded AU (always-until) operators
Fallback is `ft` (the raw future-time formula, which may contain LAST
operators). The `ftInfAUExpanded` form produces cleaner synthesis results
because ltlsynt works over infinite traces.
## Output Format
The generated JSON contains:
| Field | Description |
|---|---|
| `spec_name` | `{PROJECT}_{COMPONENT}` from the FRET export |
| `mode_groups` | Discovered control groups, their values, and boolean names |
| `inputs` | Environment (uncontrollable) variables |
| `outputs` | System (controllable) boolean mode propositions |
| `requirements` | Each FRET requirement with original and encoded LTL |
| `structural_constraints` | Auto-generated mutual exclusion constraints |
| `conjoined_ltl` | All formulas AND'd together, ready for ltlsynt |
## Future Improvements
- **Multi-valued non-mode variables**: Currently assumes all non-mode variables
are boolean. If FRET exports integer-valued environment variables (e.g.,
`power_level = 3`), the encoding would need range-based boolean decomposition.
- **Environment assumptions**: No mechanism yet for adding assumptions about the
environment (e.g., "t_max_exceeded cannot persist forever"). These would need
to be separated from guarantees in the ltlsynt call (`--ins` assumptions vs.
`--outs` guarantees). This is important for liveness properties.
- **Liveness constraints**: The old synthesis config had a manual `F(heatup)`
liveness constraint. Currently there is no automatic detection of which
requirements imply liveness vs. safety. A future version could parse FRET's
timing semantics to classify these.
- **Partial observability**: All environment variables are currently assumed
fully observable. Real reactor instrumentation has sensor noise and delays.
Extending the pipeline to handle partial observability would require
belief-state synthesis.

View File

@ -0,0 +1,123 @@
# 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 <synthesis_config.json> [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
<input literals> One per line, even numbers (2, 4, 6, ...)
<latch definitions> current_lit next_lit (state registers)
<output literals> Which literals are outputs
<AND gates> lhs rhs0 rhs1 (lhs = rhs0 AND rhs1)
<symbol table> 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.

View File

@ -0,0 +1,190 @@
# trace_aiger.py -- Circuit Tracer and State Machine Visualizer
## Purpose
Takes a synthesized AIGER circuit and produces a complete state machine
analysis: full transition tables, reachability analysis, and a Graphviz DOT
diagram with human-readable guard condition labels. Every label is derived
from exhaustive circuit evaluation -- no manual annotation, no probabilistic
inference.
## Usage
```bash
python3 scripts/trace_aiger.py <circuit.aag> [output_dir]
dot -Tpng diagrams/SPEC_states.dot -o diagrams/SPEC_states.png
```
The script is generic -- it works with any `.aag` file, not just the PWR
reactor controller.
## How It Works
### Phase 1: Parse (`parse_aag`)
Reads the ASCII AIGER file and extracts:
- **Input literals**: the environment signals (even numbers)
- **Latch pairs**: `(current_literal, next_state_literal)` for each state bit
- **Output literals**: which computed values are controller outputs
- **AND gates**: the combinational logic `(lhs, rhs0, rhs1)`
- **Symbol table**: human-readable names for inputs/outputs
Returns a dictionary that `eval_circuit` can simulate.
### Phase 2: Simulate (`eval_circuit`)
Evaluates the circuit for one clock cycle given specific latch values (current
state) and input values (environment signals).
**How it works:**
1. Initialize a literal-value table with constant 0/1
2. Set input literals and their negations: `val[lit] = v; val[lit ^ 1] = 1 - v`
3. Set latch literals the same way
4. Evaluate AND gates in order: `val[lhs] = val[rhs0] & val[rhs1]`
5. Read output values and next-state latch values from the table
The `^ 1` trick exploits AIGER's literal encoding: even literals are positive,
odd literals are negated. XOR-ing with 1 flips between positive and negative.
This means we never need explicit negation logic -- every gate's inputs are
already in the table, whether positive or negated.
**Critical assumption:** AND gates are listed in topological order in the AIGER
file, so evaluating them sequentially guarantees all inputs are computed before
they're needed. This is a property of the AIGER format specification.
### Phase 3: Enumerate
For every combination of latch state and input values:
- `2^L` latch states (L = number of latches)
- `2^I` input combinations (I = number of inputs)
- Total: `2^(L+I)` evaluations
For the PWR reactor: 2 latches, 6 inputs = 256 evaluations. Trivial.
For each evaluation, records:
- Which outputs are active (determines the "mode")
- What the next latch state is (determines the transition)
Results are stored in:
- `transitions[src_state][dst_state]` = set of input tuples
- `state_modes[state]` = set of mode labels
### Phase 4: Reachability Analysis
Starting from the initial state (all latches = 0), performs a breadth-first
search through the transition graph to identify which states are actually
reachable during operation. Unreachable states are grayed out in the diagram.
### Phase 5: Guard Extraction (`extract_guard`)
This is the core algorithm that makes the diagram human-readable. Given a set
of input combinations that all produce the same transition, it finds a minimal
boolean expression describing exactly that set.
**Simple case -- single conjunction:**
For each input variable, check if it's fixed (always 0 or always 1) or
don't-care (both 0 and 1 appear) across all combos. If the fixed variables
alone perfectly predict the combo count (`2^(don't-cares) == combo count`),
the guard is a single AND of the fixed variables.
Example: the shutdown-to-heatup edge has 32 combos. In all 32,
`t_avg_above_min = 1`. The other 5 inputs vary freely: `2^5 = 32`. So the
guard is simply `t_avg_above_min`.
**Complex case -- cube covering:**
When a single conjunction can't explain the combo set, the algorithm uses
greedy cube covering:
1. Pick a sample combo from the uncovered set
2. Start with all variables fixed to the sample's values (a point cube)
3. Try relaxing each variable (making it don't-care), one at a time
4. Accept the relaxation only if the expanded cube is a strict subset of the
edge's combos (`trial_set <= combo_set`) -- this prevents the cube from
"leaking" into other transitions
5. Repeat relaxation until no more variables can be freed
6. Record this cube, remove its combos from the uncovered set, go to step 1
7. OR all the cubes together
**What is a "cube"?** A conjunction where some variables are fixed and the
rest are don't-care. Example: `inv1_holds & !t_avg_in_range` fixes 2 of 6
variables, so it covers `2^4 = 16` input combinations. The term comes from
digital logic (Karnaugh maps), where a cube is a rectangular group of cells.
**Correctness guarantee:** The subset check `trial_set <= combo_set` on line
176 ensures that every cube covers ONLY combos belonging to this edge. The
check tests set containment, not size -- even one foreign combo causes
rejection. The union of all cubes exactly equals the original combo set.
**Optimality caveat:** The greedy algorithm does not guarantee a minimal
number of cubes. The order in which variables are relaxed can affect the
result. For guaranteed minimality, a Quine-McCluskey or Espresso algorithm
would be needed. In practice, with 6 inputs, the greedy result is typically
optimal or off by at most one cube.
### Phase 6: DOT Generation
Produces a Graphviz DOT file with:
- **State nodes** labeled with human-readable mode names (stripping `in_`
prefix, uppercasing)
- **Edge labels** showing the extracted guard conditions
- **Color coding:**
- State fill: blue (initial), yellow (transitory), green (operation),
red (scram/emergency), gray (unreachable)
- Edge color: blue (self-loop/stay), green (normal transition),
red (scram transition)
- Edge width: thicker for edges with more input combinations
Color assignment uses keyword heuristics on the output variable names
(e.g., "scram" in the name -> red). This is cosmetic and does not affect
correctness.
## Scaling Considerations
The exhaustive enumeration approach has complexity `O(2^(L+I) * A)` where
`A` is the number of AND gates. This is perfectly tractable for small
controllers:
| Latches | Inputs | Evaluations | Feasible? |
|---|---|---|---|
| 2 | 6 | 256 | Instant |
| 3 | 8 | 2,048 | Instant |
| 4 | 10 | 16,384 | < 1 second |
| 5 | 12 | 131,072 | ~ seconds |
| 8 | 16 | 16M | ~ minutes |
| 10 | 20 | 1B | Impractical |
For controllers with more than ~12 latches, a symbolic (BDD-based) analysis
would be needed instead of exhaustive enumeration.
## Future Improvements
- **Symbolic analysis**: Replace exhaustive enumeration with BDD-based
reachability for large controllers. Libraries like `dd` (Python) or
direct use of Spot's automata operations could handle this.
- **Guard minimization**: Replace the greedy cube-covering algorithm with
Espresso or Quine-McCluskey for guaranteed minimal expressions. The Python
`pyeda` library provides `espresso_exprs()` for this.
- **Trace simulation**: Add a mode that simulates specific input sequences
step-by-step, showing the controller's response. Useful for validating
against specific scenarios (e.g., "what happens if t_avg_above_min is
asserted, then inv1_holds drops?").
- **Cross-reference with FRET requirements**: Annotate each edge with which
FRET requirement(s) it satisfies. This would provide traceability from the
synthesized controller back to the natural-language specifications.
- **Multi-output modes**: Currently assumes each state has exactly one active
output (mode). If the controller has overlapping outputs, the labeling
would need to handle composite states.
- **Interactive HTML output**: Generate an interactive diagram (e.g., using
D3.js or vis.js) instead of static SVG, allowing users to click states
and see the full transition table for that state.

View File

@ -0,0 +1,43 @@
# visualize.sh -- AIGER Visualization Wrapper
## Purpose
Convenience wrapper that renders an AIGER circuit as SVG/PNG using either
`aigtodot` + Graphviz or Yosys. Handles tool detection and output directory
creation.
## Usage
```bash
bash scripts/visualize.sh <circuit.aag> [output_dir] [dot|yosys]
```
- `circuit.aag`: the AIGER file to visualize
- `output_dir`: where to write images (default: `diagrams/`)
- Method: `dot` (default) or `yosys`
## Methods
### `dot` (default)
Requires `aigtodot` (from the [AIGER tools](https://github.com/arminbiere/aiger))
and `graphviz`. Produces a gate-level schematic.
Note: if `aigtodot` is not installed, use `aag2dot.py` instead:
```bash
python3 scripts/aag2dot.py circuits/SPEC.aag | dot -Tpng -o diagrams/SPEC.png
```
### `yosys`
Requires [Yosys](https://github.com/YosysHQ/yosys) and `graphviz`. Produces
a higher-level schematic with recognized logic patterns (muxes, registers, etc.)
drawn as compound symbols rather than individual gates.
## Future Improvements
- **Auto-detect available tools**: Fall back gracefully between aigtodot,
aag2dot.py, and yosys depending on what's installed.
- **State machine mode**: Add an option to invoke `trace_aiger.py` and render
the behavioral state machine instead of the gate-level view.

File diff suppressed because it is too large Load Diff

View File

View File

@ -0,0 +1,167 @@
#!/usr/bin/env python3
"""Convert an ASCII AIGER (.aag) file to Graphviz DOT format.
Usage: python3 scripts/aag2dot.py circuits/spec.aag | dot -Tsvg -o diagrams/spec.svg
"""
import sys
from pathlib import Path
def parse_aag(text: str) -> dict:
lines = text.strip().split('\n')
header = lines[0].split()
assert header[0] == 'aag'
max_var = int(header[1])
n_inputs = int(header[2])
n_latches = int(header[3])
n_outputs = int(header[4])
n_ands = int(header[5])
idx = 1
inputs = []
for i in range(n_inputs):
inputs.append(int(lines[idx]))
idx += 1
latches = []
for i in range(n_latches):
parts = lines[idx].split()
latches.append((int(parts[0]), int(parts[1])))
idx += 1
outputs = []
for i in range(n_outputs):
outputs.append(int(lines[idx]))
idx += 1
ands = []
for i in range(n_ands):
parts = lines[idx].split()
ands.append((int(parts[0]), int(parts[1]), int(parts[2])))
idx += 1
# Symbol table
input_names = {}
output_names = {}
latch_names = {}
while idx < len(lines):
line = lines[idx]
if line.startswith('i'):
parts = line.split(' ', 1)
input_names[int(parts[0][1:])] = parts[1]
elif line.startswith('o'):
parts = line.split(' ', 1)
output_names[int(parts[0][1:])] = parts[1]
elif line.startswith('l'):
parts = line.split(' ', 1)
latch_names[int(parts[0][1:])] = parts[1]
elif line.startswith('c'):
break
idx += 1
return {
'inputs': inputs,
'latches': latches,
'outputs': outputs,
'ands': ands,
'input_names': input_names,
'output_names': output_names,
'latch_names': latch_names,
}
def lit_node(lit: int) -> tuple[str, bool]:
"""Return (node_id, is_negated) for a literal."""
var = lit >> 1
negated = lit & 1
return f'n{var}', bool(negated)
def to_dot(aag: dict) -> str:
lines = ['digraph aiger {']
lines.append(' rankdir=LR;')
lines.append(' node [shape=record];')
lines.append('')
# Constant 0
lines.append(' n0 [label="0", shape=circle, style=filled, fillcolor=gray90];')
# Inputs
lines.append(' { rank=source;')
for i, inp in enumerate(aag['inputs']):
var = inp >> 1
name = aag['input_names'].get(i, f'i{i}')
lines.append(f' n{var} [label="{name}", shape=box, style=filled, fillcolor=lightblue];')
lines.append(' }')
# Latches
for i, (latch_lit, next_lit) in enumerate(aag['latches']):
var = latch_lit >> 1
name = aag['latch_names'].get(i, f'L{i}')
lines.append(f' n{var} [label="{name}", shape=box, style="filled,rounded", fillcolor=lightyellow];')
# AND gates
for lhs, rhs0, rhs1 in aag['ands']:
var = lhs >> 1
lines.append(f' n{var} [label="&", shape=circle, style=filled, fillcolor=white];')
# Outputs
lines.append(' { rank=sink;')
for i, out_lit in enumerate(aag['outputs']):
name = aag['output_names'].get(i, f'o{i}')
lines.append(f' out_{i} [label="{name}", shape=box, style=filled, fillcolor=lightgreen];')
lines.append(' }')
lines.append('')
# AND gate edges
for lhs, rhs0, rhs1 in aag['ands']:
lhs_var = lhs >> 1
for rhs in [rhs0, rhs1]:
src_node, negated = lit_node(rhs)
style = 'style=dashed, color=red' if negated else ''
label = 'label="~"' if negated else ''
attrs = ', '.join(filter(None, [style, label]))
if attrs:
lines.append(f' {src_node} -> n{lhs_var} [{attrs}];')
else:
lines.append(f' {src_node} -> n{lhs_var};')
# Latch feedback edges
for i, (latch_lit, next_lit) in enumerate(aag['latches']):
latch_var = latch_lit >> 1
src_node, negated = lit_node(next_lit)
style = 'style=dashed, color=red' if negated else ''
label = 'label="~"' if negated else ''
extra = 'constraint=false, '
attrs = ', '.join(filter(None, [extra + style, label]))
lines.append(f' {src_node} -> n{latch_var} [{attrs}];')
# Output edges
for i, out_lit in enumerate(aag['outputs']):
src_node, negated = lit_node(out_lit)
style = 'style=dashed, color=red' if negated else ''
label = 'label="~"' if negated else ''
attrs = ', '.join(filter(None, [style, label]))
if attrs:
lines.append(f' {src_node} -> out_{i} [{attrs}];')
else:
lines.append(f' {src_node} -> out_{i};')
lines.append('}')
return '\n'.join(lines)
def main():
if len(sys.argv) < 2:
print(f'Usage: {sys.argv[0]} <file.aag>', file=sys.stderr)
sys.exit(1)
text = Path(sys.argv[1]).read_text()
aag = parse_aag(text)
print(to_dot(aag))
if __name__ == '__main__':
main()

View File

@ -0,0 +1,258 @@
#!/usr/bin/env python3
"""Convert FRET JSON export to ltlsynt synthesis config.
Automatically detects:
- Mode variables: any variable matching `control_* = q_*` in the LTL.
Each control group (e.g. control_mode) gets its own set of boolean
outputs (e.g. in_mode_shutdown, in_mode_heatup) with a mutual
exclusion constraint.
- Environment inputs: variables that appear only in conditions
(pre_condition / regular_condition) and are not mode variables.
- System outputs: the boolean mode propositions derived from control_*.
Naming convention in FRET:
- Mode variables MUST start with "control_" (e.g. control_mode, control_pump)
- Mode values MUST start with "q_" (e.g. q_shutdown, q_heatup)
- All other variables are classified by their FRET role.
Usage: python3 scripts/fret_to_synth.py <fret_export.json> [output.json]
"""
import json
import re
import sys
from collections import defaultdict
from pathlib import Path
def discover_modes(requirements):
"""Scan all LTL formulas for (control_X = q_Y) patterns.
Returns a dict: { "control_X": ["q_Y", "q_Z", ...] }
Each key is a mode group, values are the discovered mode values.
"""
# Match patterns like (control_mode = q_shutdown), (control_pump = q_off)
pattern = re.compile(r'\((\s*control_\w+)\s*=\s*(q_\w+)\s*\)')
mode_groups = defaultdict(set)
for req in requirements:
sem = req["semantics"]
for field in ("ftInfAUExpanded", "ft", "ftExpanded"):
ltl = sem.get(field, "")
if ltl:
for match in pattern.finditer(ltl):
ctrl_var = match.group(1).strip()
mode_val = match.group(2).strip()
mode_groups[ctrl_var].add(mode_val)
# Sort mode values for deterministic output
return {k: sorted(v) for k, v in sorted(mode_groups.items())}
def build_mode_map(mode_groups):
"""Build the string replacement map and output variable list.
For a single control group like control_mode with values
[q_heatup, q_operation, q_scram, q_shutdown], produces:
- replacements: {"(control_mode = q_heatup)": "in_mode_heatup", ...}
- outputs: ["in_mode_heatup", "in_mode_operation", ...]
For multiple groups, the boolean name includes the group suffix:
control_mode -> in_mode_X
control_pump -> in_pump_X
"""
replacements = {}
outputs_by_group = {}
for ctrl_var, mode_vals in mode_groups.items():
# Derive group suffix: control_mode -> mode, control_pump -> pump
suffix = ctrl_var.replace("control_", "", 1)
group_outputs = []
for qval in mode_vals:
# q_shutdown -> shutdown
val_name = qval.replace("q_", "", 1)
bool_name = f"in_{suffix}_{val_name}"
replacements[f"({ctrl_var} = {qval})"] = bool_name
group_outputs.append(bool_name)
outputs_by_group[ctrl_var] = group_outputs
return replacements, outputs_by_group
def classify_variables(requirements, mode_groups):
"""Classify non-mode variables as environment inputs.
A variable is an environment input if:
- It is NOT a control_* or q_* variable (those are handled by mode encoding)
- It appears in any requirement's semantics.variables
All mode propositions are system outputs (handled separately).
"""
# Collect all known mode-related variable names to exclude
mode_var_names = set()
for ctrl_var, mode_vals in mode_groups.items():
mode_var_names.add(ctrl_var)
mode_var_names.update(mode_vals)
# Collect all variables referenced across requirements
all_vars = set()
for req in requirements:
sem = req["semantics"]
for v in sem.get("variables", []):
all_vars.add(v)
# Everything that's not a mode variable is an environment input
env_inputs = sorted(all_vars - mode_var_names)
return env_inputs
def encode_ltl(formula, replacements):
"""Replace all (control_X = q_Y) with boolean mode propositions."""
result = formula
for pattern, replacement in replacements.items():
result = result.replace(pattern, replacement)
# Sanity check: no control_ or q_ references should remain
leftover = re.findall(r'control_\w+|q_\w+', result)
if leftover:
raise ValueError(
f"Unhandled mode references in LTL: {leftover}\n"
f" Formula: {result}\n"
f" Known replacements: {list(replacements.keys())}"
)
return result
def mutual_exclusion_ltl(group_outputs):
"""Generate LTL for exactly-one-active constraint over a mode group.
Produces: G( (a & !b & !c & !d) | (!a & b & !c & !d) | ... )
"""
clauses = []
for i, m in enumerate(group_outputs):
parts = []
for j, n in enumerate(group_outputs):
if i == j:
parts.append(n)
else:
parts.append(f"(! {n})")
clauses.append(f"({' & '.join(parts)})")
exactly_one = " | ".join(clauses)
return f"G ({exactly_one})"
def main():
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <fret_export.json> [output.json]", file=sys.stderr)
sys.exit(1)
input_path = Path(sys.argv[1])
output_path = Path(sys.argv[2]) if len(sys.argv) > 2 else Path("specs/synthesis_config_v3.json")
with open(input_path) as f:
fret_data = json.load(f)
requirements = fret_data["requirements"]
project = requirements[0]["project"]
component = requirements[0]["semantics"]["component_name"]
# --- Auto-discover everything ---
mode_groups = discover_modes(requirements)
replacements, outputs_by_group = build_mode_map(mode_groups)
env_inputs = classify_variables(requirements, mode_groups)
all_outputs = [out for group in outputs_by_group.values() for out in group]
print(f"Discovered {len(mode_groups)} mode group(s):")
for ctrl_var, modes in mode_groups.items():
print(f" {ctrl_var}: {modes}")
print(f" -> booleans: {outputs_by_group[ctrl_var]}")
print(f"Environment inputs: {env_inputs}")
print(f"System outputs: {all_outputs}")
print()
# --- Encode requirements ---
encoded_reqs = []
for req in requirements:
reqid = req["reqid"]
fulltext = req["fulltext"]
sem = req["semantics"]
# Prefer ftInfAUExpanded (cleanest infinite-horizon LTL)
raw_ltl = sem.get("ftInfAUExpanded") or sem.get("ft")
if not raw_ltl:
print(f"WARNING: No LTL for {reqid}, skipping", file=sys.stderr)
continue
encoded = encode_ltl(raw_ltl, replacements)
encoded_reqs.append({
"req_id": reqid,
"fulltext": fulltext,
"project": project,
"component": component,
"ltl": encoded,
"ltl_original": raw_ltl,
"condition_type": sem.get("condition", "unknown"),
})
# --- Build structural constraints (one mutex per mode group) ---
structural = []
for ctrl_var, group_outs in outputs_by_group.items():
mutex = mutual_exclusion_ltl(group_outs)
structural.append({
"name": f"mutex_{ctrl_var}",
"description": f"Exactly one {ctrl_var} value active at all times",
"ltl": mutex,
})
# --- Conjoin all formulas ---
all_formulas = [r["ltl"] for r in encoded_reqs]
all_formulas += [s["ltl"] for s in structural]
conjoined = " & ".join(f"({f})" for f in all_formulas)
# --- Write config ---
config = {
"_comment": (
f"Generated from {input_path.name} by fret_to_synth.py. "
f"Boolean mode encoding with auto-discovered mode groups. "
f"Mutual exclusion constraints are synthesis artifacts — they enforce "
f"the single-valued semantics of control_* variables after decomposition "
f"into independent booleans. They are NOT needed in FRET itself, where "
f"control_mode = q_X is inherently single-valued."
),
"spec_name": f"{project}_{component}",
"source_file": str(input_path),
"mode_groups": {
ctrl_var: {
"values": modes,
"booleans": outputs_by_group[ctrl_var],
}
for ctrl_var, modes in mode_groups.items()
},
"inputs": env_inputs,
"outputs": all_outputs,
"requirements": encoded_reqs,
"structural_constraints": structural,
"conjoined_ltl": conjoined,
}
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, "w") as f:
json.dump(config, f, indent=2)
print(f"Synthesis config written to: {output_path}")
print(f" Requirements: {len(encoded_reqs)}")
print(f" Structural constraints: {len(structural)}")
print(f" Conjoined formula length: {len(conjoined)} chars")
print("\nEncoded requirements:")
for r in encoded_reqs:
print(f" {r['req_id']} [{r['condition_type']}]:")
print(f" {r['ltl'][:120]}{'...' if len(r['ltl']) > 120 else ''}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,80 @@
#!/usr/bin/env bash
# Synthesize a controller from a FRET synthesis config using ltlsynt (Spot).
#
# Usage: ./scripts/synthesize.sh specs/synthesis_config.json [output_dir]
#
# Reads the synthesis_config.json produced by parse_fret_json.py and
# runs ltlsynt to produce an AIGER circuit.
set -euo pipefail
CONFIG="${1:?Usage: $0 <synthesis_config.json> [output_dir]}"
OUTPUT_DIR="${2:-circuits}"
if ! command -v ltlsynt &>/dev/null; then
echo "Error: ltlsynt not found. Install with: brew install spot"
exit 1
fi
mkdir -p "$OUTPUT_DIR"
# Extract synthesis parameters from config
eval "$(python3 -c "
import json, sys, shlex
config = json.load(open(sys.argv[1]))
inputs = config['inputs']
outputs = config['outputs']
ltl = config.get('conjoined_ltl')
spec_name = config['spec_name']
if not ltl:
print('echo \"Error: no conjoined LTL formula in config\"; exit 1')
sys.exit(0)
if not outputs:
print('echo \"Error: no output variables defined\"; exit 1')
sys.exit(0)
print(f'SPEC_NAME={shlex.quote(spec_name)}')
print(f'INPUTS={shlex.quote(\",\".join(inputs))}')
print(f'OUTPUTS={shlex.quote(\",\".join(outputs))}')
print(f'LTL_FORMULA={shlex.quote(ltl)}')
" "$CONFIG")"
AAG_FILE="$OUTPUT_DIR/${SPEC_NAME}.aag"
echo "=== ltlsynt Reactive Synthesis ==="
echo "Spec: $SPEC_NAME"
echo "Inputs: $INPUTS"
echo "Outputs: $OUTPUTS"
echo "Formula: ${LTL_FORMULA:0:200}..."
echo ""
echo "Running ltlsynt..."
# Run ltlsynt
# -f: LTL formula
# --ins: uncontrollable (input/environment) propositions
# --outs: controllable (output/system) propositions
# --aiger: output as AIGER circuit
# --simplify=bwoa-sat: best simplification
SYNTH_OUTPUT=$(ltlsynt -f "$LTL_FORMULA" --ins="$INPUTS" --outs="$OUTPUTS" --aiger=both+ud+dc --simplify=bwoa-sat 2>&1) || true
if echo "$SYNTH_OUTPUT" | head -1 | grep -q "^REALIZABLE"; then
echo ""
echo "Result: REALIZABLE"
# Strip the REALIZABLE line and write the AIGER circuit
echo "$SYNTH_OUTPUT" | tail -n +2 > "$AAG_FILE"
LINES=$(wc -l < "$AAG_FILE")
echo "Circuit written to: $AAG_FILE ($LINES lines)"
elif echo "$SYNTH_OUTPUT" | head -1 | grep -q "^UNREALIZABLE"; then
echo ""
echo "Result: UNREALIZABLE"
echo "The specification cannot be implemented as a controller."
echo "$SYNTH_OUTPUT"
exit 1
else
echo ""
echo "Error: unexpected ltlsynt output:"
echo "$SYNTH_OUTPUT"
exit 1
fi

View File

@ -0,0 +1,388 @@
#!/usr/bin/env python3
"""Enumerate all states and transitions of a synthesized AIGER controller.
Generic AIGER parser reads any .aag file and produces:
1. A full transition table
2. State-to-mode mapping
3. A Graphviz DOT file for the state machine with guard condition labels
Usage: python3 scripts/trace_aiger.py <circuit.aag> [output_dir]
"""
import sys
from itertools import product
from pathlib import Path
from collections import defaultdict
def parse_aag(path):
"""Parse an ASCII AIGER file, return circuit definition."""
lines = Path(path).read_text().strip().split('\n')
header = lines[0].split()
assert header[0] == 'aag'
n_inputs = int(header[2])
n_latches = int(header[3])
n_outputs = int(header[4])
n_ands = int(header[5])
idx = 1
input_lits = []
for _ in range(n_inputs):
input_lits.append(int(lines[idx])); idx += 1
latch_pairs = [] # (current_lit, next_lit)
for _ in range(n_latches):
parts = lines[idx].split()
latch_pairs.append((int(parts[0]), int(parts[1]))); idx += 1
output_lits = []
for _ in range(n_outputs):
output_lits.append(int(lines[idx])); idx += 1
ands = []
for _ in range(n_ands):
parts = lines[idx].split()
ands.append((int(parts[0]), int(parts[1]), int(parts[2]))); idx += 1
input_names = {}
output_names = {}
while idx < len(lines):
line = lines[idx]
if line.startswith('i'):
parts = line.split(' ', 1)
input_names[int(parts[0][1:])] = parts[1]
elif line.startswith('o'):
parts = line.split(' ', 1)
output_names[int(parts[0][1:])] = parts[1]
elif line.startswith('c'):
break
idx += 1
return {
'input_lits': input_lits,
'input_names': [input_names.get(i, f'i{i}') for i in range(n_inputs)],
'latch_lits': [lp[0] for lp in latch_pairs],
'latch_next_lits': [lp[1] for lp in latch_pairs],
'output_lits': output_lits,
'output_names': [output_names.get(i, f'o{i}') for i in range(n_outputs)],
'ands': ands,
}
def eval_circuit(circ, latch_vals, input_vals):
"""Evaluate circuit for given latch and input values. Returns (outputs, next_latches)."""
val = {0: 0, 1: 1}
for lit, v in zip(circ['input_lits'], input_vals):
val[lit] = v; val[lit ^ 1] = 1 - v
for lit, v in zip(circ['latch_lits'], latch_vals):
val[lit] = v; val[lit ^ 1] = 1 - v
for lhs, rhs0, rhs1 in circ['ands']:
val[lhs] = val[rhs0] & val[rhs1]
val[lhs ^ 1] = 1 - val[lhs]
outputs = {name: val[lit] for name, lit in zip(circ['output_names'], circ['output_lits'])}
next_latches = tuple(val[nl] for nl in circ['latch_next_lits'])
return outputs, next_latches
def mode_label(outputs):
active = [name for name, val in outputs.items() if val]
return "+".join(active) if active else "NONE"
def output_display_name(name):
"""Derive a human-readable state label from an output variable name.
Strips common prefixes like 'in_' and uppercases the result.
E.g. 'in_shutdown' -> 'SHUTDOWN', 'is_active' -> 'ACTIVE'.
"""
for prefix in ('in_', 'is_', 'at_'):
if name.startswith(prefix):
return name[len(prefix):].upper()
return name.upper()
def extract_guard(input_combos, input_names):
"""Build a minimal boolean guard expression from a set of input combinations.
For each input variable, check if it is fixed to 0, fixed to 1, or don't-care
across all combos that trigger this edge. Fixed variables become guard terms.
If multiple distinct fixed-variable patterns exist, they are OR'd together.
Returns a human-readable string like "inv1_holds & !p_above_crit" or "always".
"""
n_inputs = len(input_names)
n_total = 2 ** n_inputs
combos = list(input_combos)
if len(combos) == n_total:
return "always"
if len(combos) == 0:
return "never"
# For each input variable, determine if it's fixed or don't-care
fixed = {} # var_index -> value (0 or 1), only if fixed across ALL combos
for i in range(n_inputs):
vals = set(c[i] for c in combos)
if len(vals) == 1:
fixed[i] = vals.pop()
# Check if the fixed variables alone fully explain the combo set.
# Count how many combos the fixed vars predict: 2^(number of don't-care vars)
n_dontcare = n_inputs - len(fixed)
predicted = 2 ** n_dontcare
if predicted == len(combos):
# The fixed variables perfectly partition this edge — single conjunction
if not fixed:
return "always"
terms = []
for i in sorted(fixed):
name = input_names[i]
if fixed[i] == 1:
terms.append(name)
else:
terms.append(f"!{name}")
return " & ".join(terms)
# Multiple patterns needed — group combos by their fixed-variable signature
# Strategy: iteratively find the largest single-conjunction cube that covers
# a subset of remaining combos, and OR the cubes together.
combo_set = set(combos)
remaining = set(combos)
all_possible = list(product([0, 1], repeat=n_inputs))
cubes = []
while remaining:
# Pick an arbitrary combo and try to build the largest cube containing it
sample = next(iter(remaining))
# Greedy: start with all vars fixed to sample values, relax one at a time.
# A cube is valid only if every combo it covers belongs to this edge.
cur_fixed = {i: sample[i] for i in range(n_inputs)}
cur_set = {sample}
changed = True
while changed:
changed = False
for i in list(cur_fixed):
# Try relaxing variable i
trial_fixed = {k: v for k, v in cur_fixed.items() if k != i}
trial_set = set()
for c in all_possible:
if all(c[k] == v for k, v in trial_fixed.items()):
trial_set.add(c)
# Only relax if the cube stays entirely within the edge's combos
if trial_set <= combo_set and len(trial_set) > len(cur_set):
cur_fixed = trial_fixed
cur_set = trial_set
changed = True
# Build terms for this cube
terms = []
for i in sorted(cur_fixed):
name = input_names[i]
if cur_fixed[i] == 1:
terms.append(name)
else:
terms.append(f"!{name}")
cubes.append(" & ".join(terms) if terms else "always")
remaining -= cur_set
if len(cubes) == 1:
return cubes[0]
# Wrap each multi-term cube in parens when OR-ing
parts = []
for c in cubes:
if " & " in c:
parts.append(f"({c})")
else:
parts.append(c)
return " | ".join(parts)
def state_color(state, init_latches, reachable, mode_names):
"""Assign a fill color based on state semantics.
Heuristics (checked in order):
- Initial state: light blue
- Any active output containing 'scram' or 'emergency': salmon/red
- Any active output containing 'shutdown' or 'trip': light coral / orange
- Any active output containing 'operation' or 'run' or 'power': light green
- Otherwise (transitory / heatup / startup): light yellow
- Unreachable: gray
"""
if state not in reachable:
return "gray90"
# Lowercase set of active mode keywords
modes_lower = " ".join(mode_names).lower()
if state == init_latches:
return "\"#A8D8EA\"" # light blue
if any(kw in modes_lower for kw in ('scram', 'emergency')):
return "\"#FF6B6B\"" # red
if any(kw in modes_lower for kw in ('shutdown', 'trip')):
return "\"#FFB347\"" # orange
if any(kw in modes_lower for kw in ('operation', 'run', 'power', 'normal')):
return "\"#77DD77\"" # green
# Transitory / heatup / startup / other
return "\"#FFFACD\"" # light yellow
def edge_color(src, dst, dst_modes):
"""Assign edge color based on transition type."""
modes_lower = " ".join(dst_modes).lower()
if src == dst:
return "\"#4A90D9\"", "bold" # blue for self-loops
if any(kw in modes_lower for kw in ('scram', 'emergency')):
return "\"#CC0000\"", "bold" # red for scram transitions
return "\"#228B22\"", "" # green for normal transitions
def main():
aag_path = sys.argv[1] if len(sys.argv) > 1 else "circuits/PWR_Hybrid_DRC.aag"
out_dir = Path(sys.argv[2]) if len(sys.argv) > 2 else Path("diagrams")
out_dir.mkdir(parents=True, exist_ok=True)
circ = parse_aag(aag_path)
n_latches = len(circ['latch_lits'])
n_inputs = len(circ['input_lits'])
n_total_inputs = 2 ** n_inputs
basename = Path(aag_path).stem
print("=" * 100)
print(f"Synthesized Controller Trace: {basename}")
print(f" Inputs ({n_inputs}): {circ['input_names']}")
print(f" Latches: {n_latches}")
print(f" Outputs ({len(circ['output_names'])}): {circ['output_names']}")
print("=" * 100)
init_latches = tuple(0 for _ in range(n_latches))
init_inputs = tuple(0 for _ in range(n_inputs))
init_out, init_ns = eval_circuit(circ, init_latches, init_inputs)
print(f"\nInitial state: latches={init_latches}")
print(f"Initial outputs (all inputs 0): {mode_label(init_out)}")
for k, v in init_out.items():
print(f" {k}={v}", end="")
print("\n")
# Build header
inp_hdr = " ".join(f"{n[:5]:>5}" for n in circ['input_names'])
out_hdr = " ".join(f"{n[:6]:>6}" for n in circ['output_names'])
l_hdr = " ".join(f"L{i}" for i in range(n_latches))
nl_hdr = " ".join(f"nL{i}" for i in range(n_latches))
header = f"{l_hdr} | {inp_hdr} | {out_hdr} | {nl_hdr} | mode"
print(header)
print("-" * len(header))
# transitions[src][dst] = set of input combo tuples
transitions = defaultdict(lambda: defaultdict(set))
state_modes = defaultdict(set)
all_latch_states = list(product([0, 1], repeat=n_latches))
all_input_combos = list(product([0, 1], repeat=n_inputs))
for ls in all_latch_states:
for iv in all_input_combos:
outputs, ns = eval_circuit(circ, ls, iv)
ml = mode_label(outputs)
state_modes[ls].add(ml)
transitions[ls][ns].add(iv)
l_str = " ".join(f"{v:>2}" for v in ls)
i_str = " ".join(f"{v:>5}" for v in iv)
o_str = " ".join(f"{v:>6}" for v in outputs.values())
n_str = " ".join(f"{v:>3}" for v in ns)
print(f"{l_str} | {i_str} | {o_str} | {n_str} | {ml}")
# Reachability
print("\n" + "=" * 80)
print(f"REACHABILITY (from initial state {init_latches})")
print("=" * 80)
frontier = {init_latches}
reachable = set()
while frontier:
s = frontier.pop()
if s in reachable: continue
reachable.add(s)
for ns in transitions[s]:
if ns not in reachable:
frontier.add(ns)
for s in sorted(all_latch_states):
modes = sorted(state_modes[s])
tag = "REACHABLE" if s in reachable else "UNREACHABLE"
print(f" State {s}: modes={modes} [{tag}]")
# Transition summary with guard labels
print("\n" + "=" * 80)
print("STATE TRANSITION SUMMARY")
print("=" * 80)
for s in sorted(reachable):
print(f"\nFrom state {s} — modes: {sorted(state_modes[s])}")
for ns in sorted(transitions[s]):
guard = extract_guard(transitions[s][ns], circ['input_names'])
n = len(transitions[s][ns])
print(f" -> {ns} [{n}/{n_total_inputs} combos] guard: {guard}")
# Build output display name mapping
out_display = {name: output_display_name(name) for name in circ['output_names']}
# Generate DOT
dot = ['digraph Controller {',
' rankdir=LR;',
' bgcolor="white";',
' node [shape=Mrecord, style="filled,rounded", fontname="Helvetica-Bold", fontsize=12, penwidth=1.5];',
' edge [fontname="Helvetica", fontsize=9];', '']
for s in sorted(all_latch_states):
modes = sorted(state_modes[s])
# Build display label: show human-readable output names
display_modes = []
for m in modes:
if m == "NONE":
display_modes.append("NONE")
else:
parts = m.split("+")
display_modes.append(" + ".join(out_display.get(p, p.upper()) for p in parts))
label = " | ".join(display_modes)
sid = "s" + "".join(str(v) for v in s)
color = state_color(s, init_latches, reachable, modes)
dot.append(f' {sid} [label="{label}", fillcolor={color}];')
init_id = "s" + "".join(str(v) for v in init_latches)
dot += ['', ' init [shape=point, width=0.25, color="black"];', f' init -> {init_id} [penwidth=2.0];', '']
for s in sorted(reachable):
sid = "s" + "".join(str(v) for v in s)
for ns in sorted(transitions[s]):
nsid = "s" + "".join(str(v) for v in ns)
guard = extract_guard(transitions[s][ns], circ['input_names'])
# Determine destination modes for coloring
dst_modes = sorted(state_modes[ns])
color, style = edge_color(s, ns, dst_modes)
n = len(transitions[s][ns])
pw = "2.0" if n > n_total_inputs // 2 else "1.2"
# Escape guard for DOT label
dot_guard = guard.replace('"', '\\"')
style_attr = f', style="{style}"' if style else ''
dot.append(f' {sid} -> {nsid} [label="{dot_guard}", penwidth={pw}, color={color}, fontcolor={color}{style_attr}];')
dot.append('}')
dot_path = out_dir / f"{basename}_states.dot"
dot_path.write_text('\n'.join(dot))
print(f"\nDOT written to: {dot_path}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Visualize an AIGER circuit as SVG using aigtodot + graphviz, or yosys.
#
# Usage: ./scripts/visualize.sh circuits/DRC.aag [output_dir] [method]
#
# Methods:
# dot - aigtodot + graphviz (default, requires aiger tools + graphviz)
# yosys - yosys show command (requires yosys + graphviz)
set -euo pipefail
AAG_FILE="${1:?Usage: $0 <circuit.aag> [output_dir] [dot|yosys]}"
OUTPUT_DIR="${2:-diagrams}"
METHOD="${3:-dot}"
BASENAME=$(basename "$AAG_FILE" .aag)
mkdir -p "$OUTPUT_DIR"
case "$METHOD" in
dot)
if ! command -v aigtodot &>/dev/null; then
echo "Error: aigtodot not found."
echo "Install AIGER tools: https://github.com/arminbiere/aiger"
echo " git clone https://github.com/arminbiere/aiger && cd aiger && ./configure.sh && make"
exit 1
fi
if ! command -v dot &>/dev/null; then
echo "Error: graphviz not found. Install with: brew install graphviz"
exit 1
fi
echo "Generating DOT from AIGER..."
aigtodot "$AAG_FILE" | dot -Tsvg -o "$OUTPUT_DIR/${BASENAME}.svg"
echo "SVG written to: $OUTPUT_DIR/${BASENAME}.svg"
# Also generate PNG for quick viewing
aigtodot "$AAG_FILE" | dot -Tpng -o "$OUTPUT_DIR/${BASENAME}.png"
echo "PNG written to: $OUTPUT_DIR/${BASENAME}.png"
;;
yosys)
if ! command -v yosys &>/dev/null; then
echo "Error: yosys not found. Install with: brew install yosys"
exit 1
fi
if ! command -v dot &>/dev/null; then
echo "Error: graphviz not found. Install with: brew install graphviz"
exit 1
fi
echo "Generating schematic with Yosys..."
yosys -p "read_aiger $AAG_FILE; show -format svg -prefix $OUTPUT_DIR/${BASENAME}"
echo "SVG written to: $OUTPUT_DIR/${BASENAME}.svg"
;;
*)
echo "Unknown method: $METHOD (use 'dot' or 'yosys')"
exit 1
;;
esac
echo ""
echo "Open with: open $OUTPUT_DIR/${BASENAME}.svg"

View File

View File

@ -0,0 +1,144 @@
{
"_comment": "Generated from pwr_hybrid_3.json by fret_to_synth.py. Boolean mode encoding with auto-discovered mode groups. Mutual exclusion constraints are synthesis artifacts \u2014 they enforce the single-valued semantics of control_* variables after decomposition into independent booleans. They are NOT needed in FRET itself, where control_mode = q_X is inherently single-valued.",
"spec_name": "PWR_HYBRID_3_DRC",
"source_file": "pwr_hybrid_3.json",
"mode_groups": {
"control_mode": {
"values": [
"q_heatup",
"q_operation",
"q_scram",
"q_shutdown"
],
"booleans": [
"in_mode_heatup",
"in_mode_operation",
"in_mode_scram",
"in_mode_shutdown"
]
}
},
"inputs": [
"inv1_holds",
"inv2_holds",
"manual_reset",
"p_above_crit",
"t_avg_above_min",
"t_avg_in_range"
],
"outputs": [
"in_mode_heatup",
"in_mode_operation",
"in_mode_scram",
"in_mode_shutdown"
],
"requirements": [
{
"req_id": "DRC_S004_SCRAM_STAY",
"fulltext": "Whenever control_mode = q_scram & !manual_reset DRC shall at the next timepoint satisfy control_mode = q_scram",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "(G ((in_mode_scram & (! manual_reset)) -> (X in_mode_scram)))",
"ltl_original": "(G (((control_mode = q_scram) & (! manual_reset)) -> (X (control_mode = q_scram))))",
"condition_type": "holding"
},
{
"req_id": "DRC_T001_SHUTDOWN_TO_HEATUP",
"fulltext": "Upon control_mode = q_shutdown & t_avg_above_min DRC shall at the next timepoint satisfy control_mode = q_heatup",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "((G (((! (in_mode_shutdown & t_avg_above_min)) & (X (in_mode_shutdown & t_avg_above_min))) -> (X (X in_mode_heatup)))) & ((in_mode_shutdown & t_avg_above_min) -> (X in_mode_heatup)))",
"ltl_original": "((G (((! ((control_mode = q_shutdown) & t_avg_above_min)) & (X ((control_mode = q_shutdown) & t_avg_above_min))) -> (X (X (control_mode = q_heatup))))) & (((control_mode = q_shutdown) & t_avg_above_min) -> (X (control_mode = q_heatup))))",
"condition_type": "regular"
},
{
"req_id": "DRC_T002_HEATUP_TO_OPERATION",
"fulltext": "Upon control_mode = q_heatup & t_avg_in_range & p_above_crit & inv1_holds DRC shall at the next timepoint satisfy control_mode = q_operation",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "((G (((! (((in_mode_heatup & t_avg_in_range) & p_above_crit) & inv1_holds)) & (X (((in_mode_heatup & t_avg_in_range) & p_above_crit) & inv1_holds))) -> (X (X in_mode_operation)))) & ((((in_mode_heatup & t_avg_in_range) & p_above_crit) & inv1_holds) -> (X in_mode_operation)))",
"ltl_original": "((G (((! ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds)) & (X ((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds))) -> (X (X (control_mode = q_operation))))) & (((((control_mode = q_heatup) & t_avg_in_range) & p_above_crit) & inv1_holds) -> (X (control_mode = q_operation))))",
"condition_type": "regular"
},
{
"req_id": "DRC_A001_MODE_VALID",
"fulltext": "DRC shall always satisfy control_mode = q_shutdown | control_mode = q_heatup | control_mode = q_operation | control_mode = q_scram",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "(G (((in_mode_shutdown | in_mode_heatup) | in_mode_operation) | in_mode_scram))",
"ltl_original": "(G ((((control_mode = q_shutdown) | (control_mode = q_heatup)) | (control_mode = q_operation)) | (control_mode = q_scram)))",
"condition_type": "null"
},
{
"req_id": "DRC_T003_HEATUP_TO_SCRAM",
"fulltext": "Upon control_mode = q_heatup & !inv1_holds DRC shall at the next timepoint satisfy control_mode = q_scram",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "((G (((! (in_mode_heatup & (! inv1_holds))) & (X (in_mode_heatup & (! inv1_holds)))) -> (X (X in_mode_scram)))) & ((in_mode_heatup & (! inv1_holds)) -> (X in_mode_scram)))",
"ltl_original": "((G (((! ((control_mode = q_heatup) & (! inv1_holds))) & (X ((control_mode = q_heatup) & (! inv1_holds)))) -> (X (X (control_mode = q_scram))))) & (((control_mode = q_heatup) & (! inv1_holds)) -> (X (control_mode = q_scram))))",
"condition_type": "regular"
},
{
"req_id": "DRC_T004_OPERATION_TO_SCRAM",
"fulltext": "Upon control_mode = q_operation & !inv2_holds DRC shall at the next timepoint satisfy control_mode = q_scram",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "((G (((! (in_mode_operation & (! inv2_holds))) & (X (in_mode_operation & (! inv2_holds)))) -> (X (X in_mode_scram)))) & ((in_mode_operation & (! inv2_holds)) -> (X in_mode_scram)))",
"ltl_original": "((G (((! ((control_mode = q_operation) & (! inv2_holds))) & (X ((control_mode = q_operation) & (! inv2_holds)))) -> (X (X (control_mode = q_scram))))) & (((control_mode = q_operation) & (! inv2_holds)) -> (X (control_mode = q_scram))))",
"condition_type": "regular"
},
{
"req_id": "DRC_T005_SCRAM_TO_SHUTDOWN",
"fulltext": "Upon control_mode = q_scram & manual_reset DRC shall at the next timepoint satisfy control_mode = q_shutdown",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "((G (((! (in_mode_scram & manual_reset)) & (X (in_mode_scram & manual_reset))) -> (X (X in_mode_shutdown)))) & ((in_mode_scram & manual_reset) -> (X in_mode_shutdown)))",
"ltl_original": "((G (((! ((control_mode = q_scram) & manual_reset)) & (X ((control_mode = q_scram) & manual_reset))) -> (X (X (control_mode = q_shutdown))))) & (((control_mode = q_scram) & manual_reset) -> (X (control_mode = q_shutdown))))",
"condition_type": "regular"
},
{
"req_id": "DRC_S001_SHUTDOWN_STAY",
"fulltext": "Whenever control_mode = q_shutdown & !t_avg_above_min DRC shall at the next timepoint satisfy control_mode = q_shutdown",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "(G ((in_mode_shutdown & (! t_avg_above_min)) -> (X in_mode_shutdown)))",
"ltl_original": "(G (((control_mode = q_shutdown) & (! t_avg_above_min)) -> (X (control_mode = q_shutdown))))",
"condition_type": "holding"
},
{
"req_id": "DRC_S002_HEATUP_STAY",
"fulltext": "Whenever control_mode = q_heatup & inv1_holds & !(t_avg_in_range & p_above_crit) DRC shall at the next timepoint satisfy control_mode = q_heatup",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "(G (((in_mode_heatup & inv1_holds) & (! (t_avg_in_range & p_above_crit))) -> (X in_mode_heatup)))",
"ltl_original": "(G ((((control_mode = q_heatup) & inv1_holds) & (! (t_avg_in_range & p_above_crit))) -> (X (control_mode = q_heatup))))",
"condition_type": "holding"
},
{
"req_id": "DRC_S003_OPERATION_STAY",
"fulltext": "Whenever control_mode = q_operation & inv2_holds DRC shall at the next timepoint satisfy control_mode = q_operation ",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "(G ((in_mode_operation & inv2_holds) -> (X in_mode_operation)))",
"ltl_original": "(G (((control_mode = q_operation) & inv2_holds) -> (X (control_mode = q_operation))))",
"condition_type": "holding"
},
{
"req_id": "DRC_I001_INIT_SHUTDOWN",
"fulltext": "DRC shall immediately satisfy control_mode = q_shutdown",
"project": "PWR_HYBRID_3",
"component": "DRC",
"ltl": "in_mode_shutdown",
"ltl_original": "(control_mode = q_shutdown)",
"condition_type": "null"
}
],
"structural_constraints": [
{
"name": "mutex_control_mode",
"description": "Exactly one control_mode value active at all times",
"ltl": "G ((in_mode_heatup & (! in_mode_operation) & (! in_mode_scram) & (! in_mode_shutdown)) | ((! in_mode_heatup) & in_mode_operation & (! in_mode_scram) & (! in_mode_shutdown)) | ((! in_mode_heatup) & (! in_mode_operation) & in_mode_scram & (! in_mode_shutdown)) | ((! in_mode_heatup) & (! in_mode_operation) & (! in_mode_scram) & in_mode_shutdown))"
}
],
"conjoined_ltl": "((G ((in_mode_scram & (! manual_reset)) -> (X in_mode_scram)))) & (((G (((! (in_mode_shutdown & t_avg_above_min)) & (X (in_mode_shutdown & t_avg_above_min))) -> (X (X in_mode_heatup)))) & ((in_mode_shutdown & t_avg_above_min) -> (X in_mode_heatup)))) & (((G (((! (((in_mode_heatup & t_avg_in_range) & p_above_crit) & inv1_holds)) & (X (((in_mode_heatup & t_avg_in_range) & p_above_crit) & inv1_holds))) -> (X (X in_mode_operation)))) & ((((in_mode_heatup & t_avg_in_range) & p_above_crit) & inv1_holds) -> (X in_mode_operation)))) & ((G (((in_mode_shutdown | in_mode_heatup) | in_mode_operation) | in_mode_scram))) & (((G (((! (in_mode_heatup & (! inv1_holds))) & (X (in_mode_heatup & (! inv1_holds)))) -> (X (X in_mode_scram)))) & ((in_mode_heatup & (! inv1_holds)) -> (X in_mode_scram)))) & (((G (((! (in_mode_operation & (! inv2_holds))) & (X (in_mode_operation & (! inv2_holds)))) -> (X (X in_mode_scram)))) & ((in_mode_operation & (! inv2_holds)) -> (X in_mode_scram)))) & (((G (((! (in_mode_scram & manual_reset)) & (X (in_mode_scram & manual_reset))) -> (X (X in_mode_shutdown)))) & ((in_mode_scram & manual_reset) -> (X in_mode_shutdown)))) & ((G ((in_mode_shutdown & (! t_avg_above_min)) -> (X in_mode_shutdown)))) & ((G (((in_mode_heatup & inv1_holds) & (! (t_avg_in_range & p_above_crit))) -> (X in_mode_heatup)))) & ((G ((in_mode_operation & inv2_holds) -> (X in_mode_operation)))) & (in_mode_shutdown) & (G ((in_mode_heatup & (! in_mode_operation) & (! in_mode_scram) & (! in_mode_shutdown)) | ((! in_mode_heatup) & in_mode_operation & (! in_mode_scram) & (! in_mode_shutdown)) | ((! in_mode_heatup) & (! in_mode_operation) & in_mode_scram & (! in_mode_shutdown)) | ((! in_mode_heatup) & (! in_mode_operation) & (! in_mode_scram) & in_mode_shutdown)))"
}

132
plant-model/CLAUDE.md Normal file
View File

@ -0,0 +1,132 @@
# CLAUDE.md
Guidance for Claude Code (and any AI agent) working in this subdirectory.
See also: the parent repo's `CLAUDE.md` (living-documentation rule — update
this file when new knowledge is created) and `claude_memory/` for session
notes that haven't yet earned a place here.
## What this is
A 10-state point kinetic equation (PKE) model of a PWR coupled with
lumped-parameter thermal-hydraulics, plus mode-specific continuous
controllers. Implements the *plant* and the *tactical* layer of the HAHACS
methodology — see `../thesis/3-research-approach/approach.tex` sections on
transitory, stabilizing, and expulsory modes.
The model is being developed for hybrid-systems reachability analysis. The
end goal is barrier-certificate and reachability methods (in `../reachability/`)
to prove each continuous mode satisfies its obligations under bounded
`Q_sg(t)` variations.
## Naming convention (thesis-aligned)
Continuous state and control-theory notation matches the thesis:
| Symbol | Meaning |
|---|---|
| `t` | time [s] |
| `x` | continuous state vector, `[n; C1..C6; T_f; T_c; T_cold]` |
| `plant` | parameter struct from `pke_params()` (was `p` — renamed to avoid collision with `p_i` predicates) |
| `u` | control input: external rod reactivity [dk/k] |
| `Q_sg` | bounded disturbance: SG heat removal [W], as a function handle `Q_sg(t)` |
| `ref` | reference/setpoint struct (e.g. `ref.T_avg`) |
`T_avg = T_c` (algebraic alias); `T_hot = 2*T_c - T_cold` (linear coolant
profile assumption).
## Running
From inside MATLAB:
```matlab
main % runs the default closed-loop scenario
```
From a terminal (figures appear as their own windows):
```bash
matlab -nodesktop -nosplash -r "main" # drops at >> prompt; `exit` to quit
matlab -r "main" & # full IDE, backgrounded
matlab -batch "main" # headless sanity check (no figures shown)
```
`main.m` configures the scenario (plant, `Q_sg`, ref, tspan), picks a
controller, and calls `pke_solver`. Tested on MATLAB R2025b; works on any
MATLAB with `ode15s` (R2020b or newer).
## Architecture
```
plant-model/
pke_params.m plant parameters and derived steady state
pke_initial_conditions.m analytic equilibrium x0 from plant
pke_th_rhs.m dynamics: dx/dt = f(t, x, plant, Q_sg, u)
pke_solver.m closed-loop driver; takes a controller fn handle
plot_pke_results.m 4-panel results plot
load_profile.m canned Q_sg demand shapes
main.m entry point — scenario config + run
controllers/
ctrl_null.m u = 0 (baseline, no feedback)
ctrl_operation.m stabilizing: P on T_avg
(future: ctrl_heatup, ctrl_scram, ctrl_shutdown)
```
**Controller contract:**
```matlab
u = ctrl_<mode>(t, x, plant, ref)
```
Pure function. Returns scalar `u` (external rod reactivity in `dk/k`). All
four signature args are required even if unused — lets the solver swap
controllers by function handle without caring which one it is.
**Solver contract:**
```matlab
[t, X, U] = pke_solver(plant, Q_sg, ctrl_fn, ref, tspan)
```
Builds the closed-loop RHS internally, calls `ode15s`, then reconstructs the
control trajectory `U` by re-evaluating `ctrl_fn` at each returned time step.
For event-driven or hysteretic controllers, this reconstruction may miss
interior solver evaluations — revisit if / when that matters.
## Key design decisions
- **`Q_sg` is the disturbance, never an actuator.** Cold leg temperature is
a dynamic state resulting from SG heat removal — the reachability
formulation needs `Q_sg ∈ [Q_min, Q_max]` as a bounded disturbance, not a
control input.
- **`u` is explicit.** `pke_th_rhs` takes `u` directly instead of reading
`p.rho_ext(t)` from the params struct. This decouples plant from
controller and matches the thesis's `f(x, u)` formulation.
- **Controller gains live in the controller file.** Rough-out phase — we'll
lift to a config struct once we're tuning more than one mode. The gain
in `ctrl_operation` (`Kp = 1e-4 /K`) is chosen to roughly double the
effective moderator coefficient, not for precision tracking.
- **`ode15s` is required** because the system is stiff: `Lambda` (~10⁻⁴ s)
vs thermal time constants (~10100 s).
## Conventions
- One function per file, each file has a single responsibility.
- Internal model uses SI (W, kg, °C); all printed/plotted temperatures in °F.
- Reference setpoints in SI (so `ref.T_avg` is in °C).
- Controllers are pure functions — no persistent state. If a mode ever
needs integral action, augment `x` rather than hiding state in globals.
## For reachability work (next chapter)
- `pke_th_rhs(t, x, plant, Q_sg, u)` is the `ẋ = f(x, u)` with `Q_sg` as the
disturbance `w`. For a given mode, substitute `u = ctrl_<mode>(t, x, plant, ref)`
to get the closed-loop `ẋ = f_cl(x, w)`.
- Linearize around `x0` from `pke_initial_conditions(plant)` for `A, B, B_w`
matrices when a linear reach set is enough.
- Safe regions come from the FRET spec's guards (see
`../fret-pipeline/specs/synthesis_config_v3.json`) — these define
`X_entry`, `X_exit`, `X_safe` per the thesis approach.
- Do NOT try to verify the whole hybrid system at once. Pick one mode,
compute its reach set, discharge the per-mode obligation. The
compositionality argument in the thesis is what makes this tractable.

92
plant-model/README.md Normal file
View File

@ -0,0 +1,92 @@
# plant-model
PWR plant model (point kinetics + lumped thermal-hydraulics) and
mode-specific continuous controllers for the HAHACS preliminary example.
## Overview
A 10-state coupled neutronics + thermal-hydraulics model in MATLAB:
- 6 delayed neutron precursor groups (U-235 thermal fission, Keepin)
- Lumped fuel, core coolant, and SG/cold-leg thermal nodes
- Steam generator heat removal `Q_sg(t)` as the bounded disturbance input
- Doppler and moderator temperature reactivity feedback
- External rod reactivity `u` as the controllable input
State vector: `x = [n; C1..C6; T_f; T_c; T_cold]` (10 states). See
`CLAUDE.md` for the naming convention.
## Quick Start
Open MATLAB in this directory and run:
```matlab
main
```
The default scenario runs two simulations of a 100% → 80% SG demand step:
once with `ctrl_null` (plant feedback only) and once with `ctrl_operation`
(proportional rod reactivity on T_avg error), and plots the comparison.
## Files
| File | Role |
|------|------|
| `main.m` | Entry point — scenario config and run |
| `pke_params.m` | Plant parameters and steady-state derivation |
| `pke_th_rhs.m` | Dynamics `ẋ = f(t, x, plant, Q_sg, u)` |
| `pke_initial_conditions.m` | Analytic steady-state `x0` |
| `pke_solver.m` | Closed-loop driver — takes a controller function handle |
| `plot_pke_results.m` | 4-panel results plot |
| `load_profile.m` | SG heat demand shapes |
| `controllers/ctrl_null.m` | `u = 0` baseline |
| `controllers/ctrl_operation.m` | Stabilizing mode: P on `T_avg` |
## Controllers
Controllers share a single signature:
```matlab
u = ctrl_<mode>(t, x, plant, ref)
```
Returns scalar `u` (external rod reactivity in `dk/k`). The solver swaps
controllers via function handle:
```matlab
[t, X, U] = pke_solver(plant, Q_sg, @ctrl_operation, ref, tspan);
```
Additional modes (`ctrl_heatup`, `ctrl_scram`, `ctrl_shutdown`) will land in
`controllers/` following the same signature.
## Running Different Scenarios
Swap `Q_sg` in `main.m`:
```matlab
% Step down to 90% at t = 10s
Q_sg = @(t) plant.P0 * (1.0 - 0.1 * (t >= 10));
% Interpolated time series
t_data = [0, 100, 200, 300];
q_data = [1.0, 0.85, 0.9, 1.0] * plant.P0;
Q_sg = @(t) interp1(t_data, q_data, t, 'linear', 'extrap');
```
Swap the controller:
```matlab
[t, X, U] = pke_solver(plant, Q_sg, @ctrl_null, [], tspan);
```
Change the reference (for modes that use one):
```matlab
ref.T_avg = plant.T_c0 + 5; % track 5 C above nominal
```
## Requirements
MATLAB (R2020b or newer, tested on R2025b). Uses `ode15s` from base MATLAB
— no toolboxes required.

88
plant-model/context.md Normal file
View File

@ -0,0 +1,88 @@
# PKE Playground — LLM Context
This document provides context for an LLM working on this codebase. It explains the model, design decisions, and where the project is headed.
## What This Is
A point kinetic equation (PKE) model coupled with lumped-parameter thermal-hydraulics, implemented in MATLAB/Octave. The model represents a simplified PWR (pressurized water reactor) core and primary loop.
## Why It Exists
This is a workable plant model being developed for **hybrid systems reachability analysis**. The end goal is to use barrier certificate methods to prove that under bounded variations in steam generator (SG) heat removal, the reactor stays within a defined safe operating region (bounded temperatures, power levels, etc.).
The model needs to be:
- Physically motivated (not just a toy system)
- Clean and state-space oriented (explicit state vector, clear inputs/outputs)
- Structured so that `Q_sg(t)` is a bounded disturbance input for reachability tools
## The Model
### State Vector (10 states)
```
y = [n; C1; C2; C3; C4; C5; C6; T_f; T_c; T_cold]
```
- `n` — normalized neutron population (1.0 = nominal)
- `C1..C6` — six delayed neutron precursor group concentrations (Keepin U-235 thermal fission data)
- `T_f` — lumped fuel temperature [C]
- `T_c` — average core coolant temperature [C]
- `T_cold` — cold leg / SG outlet coolant temperature [C]
### Algebraic Outputs
- `T_hot = 2*T_c - T_cold` (linear coolant temperature profile through the core)
- `T_avg = T_c`
### Equations
**Neutronics:**
```
dn/dt = (rho - beta) / Lambda * n + sum(lambda_i * C_i)
dC_i/dt = beta_i / Lambda * n - lambda_i * C_i
```
**Thermal-hydraulics (three lumped nodes):**
```
M_f*c_f * dT_f/dt = P0*n - hA*(T_f - T_c) [fuel]
M_c*c_c * dT_c/dt = hA*(T_f - T_c) - 2*W*c_c*(T_c - T_cold) [core coolant]
M_sg*c_c * dT_cold/dt = W*c_c*(T_hot - T_cold) - Q_sg(t) [SG/cold leg]
```
**Reactivity feedback:**
```
rho = rho_ext(t) + alpha_f*(T_f - T_f0) + alpha_c*(T_c - T_c0)
```
### Why Q_sg Is the Input (Not T_cold)
In a real PWR, the steam generator removes heat from the primary loop based on secondary-side demand. The cold leg temperature is a *result* of that heat removal, not a boundary condition you get to set. Treating `Q_sg(t)` as the external input and letting `T_cold` be a dynamic state is physically correct and maps naturally to the reachability problem: "given that SG demand is somewhere in [Q_min, Q_max], what states can the reactor reach?"
### Why T_hot = 2*T_c - T_cold
This comes from the linear coolant temperature profile assumption through the core. If coolant enters at `T_cold` and exits at `T_hot`, and the average is `T_c`, then `T_c = (T_hot + T_cold) / 2`, so `T_hot = 2*T_c - T_cold`. This avoids needing a separate hot leg state while still tracking both temperatures.
### Why ode15s
The PKE system is stiff. The prompt neutron generation time `Lambda` (~10^-4 s) is orders of magnitude smaller than the thermal time constants (~10-100 s) and precursor decay constants (~0.01-3 s^-1). An explicit solver would need extremely small timesteps; `ode15s` handles this naturally.
## File Structure
Each file has one purpose:
| File | Purpose |
|------|---------|
| `pke_solver.m` | Main driver script — scenario config, solve, print |
| `pke_params.m` | All plant parameters and steady-state derivation |
| `pke_th_rhs.m` | ODE right-hand side `f(t, y)` — this is the dynamics |
| `pke_initial_conditions.m` | Analytic steady-state initial condition |
| `load_profile.m` | SG heat demand time series (swappable) |
| `plot_pke_results.m` | 4-panel results plotting |
## For Future Reachability Work
- `pke_th_rhs.m` is your `dx/dt = f(x, w)` where `w = Q_sg`
- Linearize around the steady state from `pke_params.m` to get `A`, `B` matrices
- The safe region will be a polytope or sublevel set on `[n, T_f, T_hot, T_cold]` (or a subset)
- `Q_sg` is the bounded disturbance: `Q_sg in [Q_min, Q_max]` around `P0`
- Barrier certificate `B(x)` would certify that trajectories starting in the safe set stay there for all admissible `Q_sg(t)`

View File

@ -0,0 +1,13 @@
function u = ctrl_null(t, x, plant, ref)
% CTRL_NULL No-op controller. Returns u = 0.
%
% Use for unforced-plant simulations (feedback-only response to Q_sg) or
% as a baseline to compare against closed-loop modes.
%
% Signature matches all other controllers:
% u = ctrl_<mode>(t, x, plant, ref)
% so it can be dropped into pke_solver as a function handle.
u = 0;
end

View File

@ -0,0 +1,31 @@
function u = ctrl_operation(t, x, plant, ref)
% CTRL_OPERATION Stabilizing mode controller: hold T_avg at ref.T_avg.
%
% Proportional feedback on external reactivity (rod worth) driven by
% temperature error:
% u = Kp * (ref.T_avg - T_avg)
%
% Sign check: when T_avg > ref.T_avg, error < 0, u < 0 rods insert,
% power drops, T_avg falls. Correct polarity for a PWR.
%
% Gain Kp is a rough-out value. Scale reasoning:
% - alpha_c ~ -1e-4 /K means the moderator already supplies 1e-4/K of
% restoring reactivity per Kelvin of temperature error.
% - Kp = 1e-4 /K roughly doubles the effective moderator coefficient
% it damps transients without overwhelming the intrinsic feedback.
% - Real PWR rod controllers use much smaller gains with a deadband.
% We can retune or switch to PI once we care about steady-state offset.
%
% Inputs:
% t - time [s] (unused in this controller, kept for signature)
% x - state vector (10 x 1)
% plant - parameter struct (unused here; reserved for future gain-scheduling)
% ref - struct with field .T_avg = target average coolant temperature [C]
Kp = 1e-4; % [dk/k per K]
T_avg = x(9);
e = ref.T_avg - T_avg;
u = Kp * e;
end

View File

@ -0,0 +1,26 @@
function f = load_profile(t)
% LOAD_PROFILE Returns fractional SG heat demand at time t.
%
% Output is in [0, 1] where 1.0 = 100% of nominal power P0.
% Multiply by P0 to get Q_sg in watts: Q_sg = @(t) P0 * load_profile(t)
%
% Default profile (load-following):
% 0 - 30s: hold at 100%
% 30 - 130s: ramp 100% -> 80%
% 130 - 350s: hold at 80%
% 350 - 450s: ramp 80% -> 100%
% 450+: hold at 100%
if t < 30
f = 1.0;
elseif t < 130
f = 1.0 - 0.2 * (t - 30) / 100;
elseif t < 350
f = 0.8;
elseif t < 450
f = 0.8 + 0.2 * (t - 350) / 100;
else
f = 1.0;
end
end

50
plant-model/main.m Normal file
View File

@ -0,0 +1,50 @@
%% main.m closed-loop entry point
%
% Scenario: a 100% 80% SG demand step. Compare the plant's intrinsic
% feedback response (ctrl_null) against the stabilizing operation-mode
% controller (ctrl_operation) holding T_avg at the nominal setpoint.
%
% Controller signature (thesis naming):
% u = ctrl_<mode>(t, x, plant, ref)
% where x is the continuous state vector and u is the external rod reactivity.
clear; clc; close all;
addpath('controllers');
%% ===== Plant =====
plant = pke_params();
%% ===== Scenario =====
% SG heat removal: step down to 80% at t = 30s, hold.
Q_sg = @(t) plant.P0 * (1.0 - 0.2 * (t >= 30));
% Reference for the operation-mode controller.
ref = struct();
ref.T_avg = plant.T_c0; % hold T_avg at steady-state value
% Simulation window.
tspan = [0, 600];
%% ===== Baseline: unforced feedback response =====
fprintf('\n----- Run 1: ctrl_null (plant feedback only) -----\n');
[t1, X1, U1] = pke_solver(plant, Q_sg, @ctrl_null, [], tspan);
%% ===== Closed loop: operation mode =====
fprintf('\n----- Run 2: ctrl_operation (P on T_avg) -----\n');
[t2, X2, U2] = pke_solver(plant, Q_sg, @ctrl_operation, ref, tspan);
%% ===== Plots =====
plot_pke_results(t1, X1, U1, plant, Q_sg, 'ctrl_null (baseline)');
plot_pke_results(t2, X2, U2, plant, Q_sg, 'ctrl_operation (P on T_avg)');
%% ===== Quick comparison figure =====
CtoF = @(T) T*9/5 + 32;
figure('Position', [100 50 1000 450], 'Name', 'T_avg comparison');
plot(t1, CtoF(X1(:,9)), 'b-', 'LineWidth', 1.5); hold on;
plot(t2, CtoF(X2(:,9)), 'r-', 'LineWidth', 1.5);
yline(CtoF(plant.T_c0), 'k--', 'LineWidth', 1.0);
xlabel('Time [s]'); ylabel('T_{avg} [F]');
legend('ctrl\_null', 'ctrl\_operation', 'setpoint', 'Location', 'best');
title('T_{avg} tracking: baseline vs stabilizing controller');
grid on;

View File

@ -0,0 +1,12 @@
function x0 = pke_initial_conditions(plant)
% PKE_INITIAL_CONDITIONS Steady-state initial condition vector.
%
% Returns x0 = [n0; C1..C6; T_f0; T_c0; T_cold0] (10 x 1)
% Precursor concentrations are the analytic equilibrium values at n = 1.
n0 = 1.0;
C0 = (plant.beta_i ./ (plant.lambda_i * plant.Lambda)) * n0;
x0 = [n0; C0; plant.T_f0; plant.T_c0; plant.T_cold0];
end

86
plant-model/pke_params.m Normal file
View File

@ -0,0 +1,86 @@
function p = pke_params()
% PKE_PARAMS Returns the parameter struct for the coupled PKE + T/H model.
%
% All plant parameters, kinetic data, and steady-state conditions live here.
% Modify this file to change the reactor you're modeling.
p = struct();
% --- Neutronics ---
% Prompt neutron generation time for a typical PWR with enriched UO2 fuel
% and a water-moderated thermal spectrum. Literature range: 1e-5 to 5e-4 s;
% 1e-4 is a standard mid-range value (Duderstadt & Hamilton, Ch. 6).
p.Lambda = 1e-4; % prompt neutron generation time [s]
% 6-group delayed neutron data for U-235 thermal fission (Keepin et al.,
% Phys. Rev. 107, 1957). These are the canonical values used in virtually
% all PKE models. Total beta_eff ~ 650 pcm.
p.beta_i = [0.000215; 0.001424; 0.001274; 0.002568; 0.000748; 0.000273];
p.lambda_i = [0.0124; 0.0305; 0.111; 0.301; 1.14; 3.01];
p.beta = sum(p.beta_i);
% --- Thermal-hydraulic ---
% 1000 MWth is a round number representative of a 2-loop PWR (e.g.,
% Westinghouse 2-loop class). Actual plants range ~1800-3400 MWth for
% 2-loop to 4-loop designs.
p.P0 = 1000e6; % nominal thermal power [W]
% Fuel mass: representative of total UO2 inventory in the core.
% A typical 4-loop PWR has ~100,000 kg UO2; scaled down for 1000 MWth.
p.M_f = 50000; % fuel mass [kg]
% UO2 specific heat at operating temperatures (~400-800 C). Published
% values range 250-350 J/kg-K (MATPRO / Fink correlation); 300 is a
% standard lumped value for transient analysis.
p.c_f = 300; % fuel specific heat [J/kg-K]
% Coolant mass in the core region. Based on core volume fraction of
% water in a PWR (~40% moderator-to-fuel ratio) and active core volume.
p.M_c = 20000; % coolant mass in core [kg]
% Pressurized water specific heat at ~15.5 MPa, ~300 C. NIST/IAPWS
% gives cp ~ 5.4-5.5 kJ/kg-K in this range.
p.c_c = 5450; % coolant specific heat [J/kg-K]
% Lumped fuel-to-coolant heat transfer coefficient x area. Chosen so that
% the steady-state fuel-to-coolant dT = P0/hA = 20 C, which is in the
% right ballpark for the average pellet-to-bulk-coolant temperature drop
% in a lumped single-node fuel model.
p.hA = 5e7; % fuel-to-coolant heat transfer coeff * area [W/K]
% Primary coolant mass flow rate. Typical PWR: ~4000-6000 kg/s per loop.
% 5000 kg/s gives core dT = P0/(W*c_c) ~ 36.7 C, consistent with a
% ~35-38 C core rise in operating PWRs.
p.W = 5000; % coolant mass flow rate [kg/s]
% Coolant mass in SG + hot/cold leg piping. Represents the ex-core primary
% inventory that participates in the loop transport delay. Larger than M_c
% because the SG tubes and piping hold significant volume.
p.M_sg = 30000; % coolant mass in SG + hot/cold leg piping [kg]
% --- Reactivity feedback coefficients ---
% Doppler coefficient: fuel temperature feedback, predominantly from
% U-238 resonance broadening. Typical BOL range: -2 to -3 pcm/K
% (Todreas & Kazimi). -2.5 pcm/K is a standard mid-cycle value.
p.alpha_f = -2.5e-5; % fuel (Doppler) [dk/k per K]
% Moderator temperature coefficient: captures water density change with
% temperature and its effect on neutron moderation/absorption. Typical
% range: -5 to -50 pcm/K depending on boron concentration and burnup.
% -10 pcm/K is moderate (mid-cycle, moderate boron).
p.alpha_c = -1.0e-4; % coolant (moderator) [dk/k per K]
% --- Steady-state (derived from energy balance at P0, n=1) ---
% Q_sg = P0, all dT/dt = 0
% T_hot - T_cold = P0 / (W*c_c)
% T_c = (T_hot + T_cold) / 2
% T_f = T_c + P0 / hA
% Cold leg temperature of 290 C (554 F) is typical for a PWR at full
% power (Westinghouse plants: ~288-293 C depending on design).
p.T_cold0 = 290; % inlet coolant [C]
p.dT_core = p.P0 / (p.W * p.c_c); % core delta-T [C]
p.T_hot0 = p.T_cold0 + p.dT_core;
p.T_c0 = (p.T_hot0 + p.T_cold0) / 2; % avg coolant [C]
p.T_f0 = p.T_c0 + p.P0 / p.hA; % fuel [C]
end

60
plant-model/pke_solver.m Normal file
View File

@ -0,0 +1,60 @@
function [t, X, U] = pke_solver(plant, Q_sg, ctrl_fn, ref, tspan)
% PKE_SOLVER Solve the coupled PKE + T/H system in closed loop with a mode controller.
%
% Inputs:
% plant - parameter struct from pke_params()
% Q_sg - function handle Q_sg(t) returning SG heat removal [W]
% ctrl_fn - function handle u = ctrl_fn(t, x, plant, ref)
% ref - struct of per-mode setpoints (e.g. ref.T_avg); [] if unused
% tspan - [t_start, t_end] in seconds
%
% Outputs:
% t - time vector (M x 1) from the ODE solver
% X - state matrix (M x 10): columns are [n, C1..C6, T_f, T_c, T_cold]
% U - control input trajectory (M x 1): u evaluated at each (t(k), X(k,:))
CtoF = @(T) T * 9/5 + 32;
%% ===== Print Steady-State =====
fprintf('=== Steady-State Conditions ===\n');
fprintf(' beta = %.5f (%.1f pcm)\n', plant.beta, plant.beta*1e5);
fprintf(' Lambda = %.1e s\n', plant.Lambda);
fprintf(' P0 = %.0f MWth\n', plant.P0/1e6);
fprintf(' T_cold = %.1f F\n', CtoF(plant.T_cold0));
fprintf(' T_avg = %.1f F\n', CtoF(plant.T_c0));
fprintf(' T_hot = %.1f F\n', CtoF(plant.T_hot0));
fprintf(' T_fuel = %.1f F\n', CtoF(plant.T_f0));
fprintf(' Core dT = %.1f F\n', plant.dT_core * 9/5);
fprintf('================================\n\n');
%% ===== Solve closed-loop =====
x0 = pke_initial_conditions(plant);
options = odeset('RelTol', 1e-8, 'AbsTol', 1e-10);
rhs = @(t, x) pke_th_rhs(t, x, plant, Q_sg, ctrl_fn(t, x, plant, ref));
[t, X] = ode15s(rhs, tspan, x0, options);
%% ===== Reconstruct control trajectory =====
M = length(t);
U = zeros(M, 1);
for k = 1:M
U(k) = ctrl_fn(t(k), X(k,:).', plant, ref);
end
%% ===== Print Final State =====
n = X(end, 1); T_f = X(end, 8); T_c = X(end, 9); T_cold = X(end, 10);
T_hot = 2*T_c - T_cold;
rho_tot = U(end) ...
+ plant.alpha_f*(T_f - plant.T_f0) ...
+ plant.alpha_c*(T_c - plant.T_c0);
fprintf('=== Final State (t = %.0f s) ===\n', t(end));
fprintf(' Power = %.1f MWth (%.3f x nominal)\n', n*plant.P0/1e6, n);
fprintf(' T_fuel = %.1f F\n', CtoF(T_f));
fprintf(' T_hot = %.1f F\n', CtoF(T_hot));
fprintf(' T_avg = %.1f F\n', CtoF(T_c));
fprintf(' T_cold = %.1f F\n', CtoF(T_cold));
fprintf(' u = %.4f $ (external reactivity from controller)\n', U(end)/plant.beta);
fprintf(' rho = %.4f $ (total, incl. T-feedback)\n', rho_tot/plant.beta);
end

49
plant-model/pke_th_rhs.m Normal file
View File

@ -0,0 +1,49 @@
function dxdt = pke_th_rhs(t, x, plant, Q_sg, u)
% PKE_TH_RHS ODE right-hand side for coupled PKE + thermal-hydraulics.
%
% State x = [n; C1..C6; T_f; T_c; T_cold] (10 x 1)
%
% Inputs:
% t - time [s]
% x - continuous state vector (10 x 1)
% plant - parameter struct from pke_params()
% Q_sg - function handle Q_sg(t) returning SG heat removal [W]
% u - external reactivity (rod worth) [dk/k], scalar
%
% The controller is responsible for computing u; this function treats u
% as a given input. Q_sg is the bounded disturbance.
n = x(1);
C = x(2:7);
T_f = x(8);
T_c = x(9);
T_cold = x(10);
T_hot = 2 * T_c - T_cold;
Q_sg_val = Q_sg(t);
% --- Reactivity with feedback ---
% rho = u + alpha_f*(T_f - T_f0) + alpha_c*(T_c - T_c0)
rho = u ...
+ plant.alpha_f * (T_f - plant.T_f0) ...
+ plant.alpha_c * (T_c - plant.T_c0);
% --- Neutronics ---
dndt = (rho - plant.beta) / plant.Lambda * n + plant.lambda_i' * C;
dCdt = (plant.beta_i / plant.Lambda) * n - plant.lambda_i .* C;
% --- Thermal-hydraulics ---
% Fuel node: fission power in, heat transfer to coolant out
dTf_dt = (plant.P0 * n - plant.hA * (T_f - T_c)) / (plant.M_f * plant.c_f);
% Core coolant: heat from fuel in, bulk enthalpy flow out
dTc_dt = (plant.hA * (T_f - T_c) - 2*plant.W*plant.c_c*(T_c - T_cold)) ...
/ (plant.M_c * plant.c_c);
% SG/loop node: hot leg enthalpy in, SG heat removal out
dTcold_dt = (plant.W * plant.c_c * (T_hot - T_cold) - Q_sg_val) ...
/ (plant.M_sg * plant.c_c);
dxdt = [dndt; dCdt; dTf_dt; dTc_dt; dTcold_dt];
end

View File

@ -0,0 +1,76 @@
function plot_pke_results(t, X, U, plant, Q_sg, plot_title)
% PLOT_PKE_RESULTS Standard 4-panel plot of PKE + T/H simulation results.
%
% Inputs:
% t - time vector from ODE solver
% X - state matrix (M x 10): [n, C1..C6, T_f, T_c, T_cold]
% U - control input trajectory (M x 1): scalar u at each time
% plant - parameter struct from pke_params()
% Q_sg - function handle Q_sg(t) used in the simulation
% plot_title - (optional) string used in the figure name and first subplot
if nargin < 6 || isempty(plot_title)
plot_title = 'PKE + T/H closed-loop';
end
% --- Extract states ---
n = X(:, 1);
T_f = X(:, 8);
T_c = X(:, 9);
T_cold = X(:, 10);
T_hot = 2 * T_c - T_cold;
% --- Convert temperatures to Fahrenheit for display ---
CtoF = @(T) T * 9/5 + 32;
T_f_F = CtoF(T_f);
T_c_F = CtoF(T_c);
T_cold_F = CtoF(T_cold);
T_hot_F = CtoF(T_hot);
% --- Derived quantities ---
power_MW = n * plant.P0 / 1e6;
Q_sg_MW = arrayfun(Q_sg, t) / 1e6;
rho_fb = plant.alpha_f * (T_f - plant.T_f0) + plant.alpha_c * (T_c - plant.T_c0);
rho_tot = U + rho_fb;
% --- Plot ---
figure('Position', [100 50 1000 950], 'Name', plot_title);
% Power & SG demand
subplot(4, 1, 1);
plot(t, power_MW, 'b-', 'LineWidth', 1.5); hold on;
plot(t, Q_sg_MW, 'r--', 'LineWidth', 1.2);
xlabel('Time [s]'); ylabel('Power [MW_{th}]');
legend('Reactor Power', 'Q_{sg}', 'Location', 'east');
title(sprintf('%s Power and SG Heat Demand', plot_title));
grid on;
% Reactivity: controller u, feedback, total
subplot(4, 1, 2);
plot(t, U / plant.beta, 'k-', 'LineWidth', 1.5); hold on;
plot(t, rho_fb / plant.beta, 'b-.', 'LineWidth', 1.2);
plot(t, rho_tot / plant.beta, 'm:', 'LineWidth', 1.5);
xlabel('Time [s]'); ylabel('\rho [$]');
legend('u (controller)', 'Feedback', 'Total', 'Location', 'east');
title('Reactivity');
grid on;
% Coolant temperatures
subplot(4, 1, 3);
plot(t, T_hot_F, 'r-', 'LineWidth', 1.5); hold on;
plot(t, T_c_F, 'm--', 'LineWidth', 1.2);
plot(t, T_cold_F, 'b-', 'LineWidth', 1.5);
xlabel('Time [s]'); ylabel('Temperature [F]');
legend('T_{hot}', 'T_{avg}', 'T_{cold}', 'Location', 'east');
title('Coolant Temperatures');
grid on;
% Fuel temperature
subplot(4, 1, 4);
plot(t, T_f_F, 'Color', [0.85 0.33 0.1], 'LineWidth', 1.5);
xlabel('Time [s]'); ylabel('Temperature [F]');
title('Fuel Temperature');
grid on;
end

@ -0,0 +1 @@
Subproject commit bb00a946f828176b76858d8f3774723f6bd77292

1
thesis Submodule

@ -0,0 +1 @@
Subproject commit e9ed9e252ea2ee74bbef3019d17e92e7bf164bf9