Tag the finite lattice carrier types with `@[aesop safe cases]`
(`AboveBelow`, `Sign`) so aesop performs the dominant proof step in this
framework -- case-splitting a lattice element -- automatically. Combined
with the existing `@[simp]` operation lemmas, this collapses the recurring
"case-split then reduce" proofs to a bare `aesop`:
* AboveBelow's six lattice axioms drop their explicit `rcases`
* Sign/Constant `plus_mono₂`/`minus_mono₂` become `by aesop`
* Constant `plus_valid`/`minus_valid` shrink to a 2-line `rcases <;> simp_all`
* `not_mk_lt_mk` is reexpressed via `le_cases`
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The six lattice axioms (sup/inf comm/assoc, absorption) all close with a
uniform `rcases <;> aesop`, removing the per-lemma simp-lemma lists that had
to be kept in sync with the Max/Min definitions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce `tr₁ ++< he >++ tr₂` scoped notation for `Trace.concat`
(precedence 65, right-associative, mirroring `++`) and use it
throughout Properties.lean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This requires a few pieces:
* Make node tags use `Fin n` intead of natural numbers. This makes
it possible to build a finite lattice over AST nodes, and also
ensure automatic, total indexing from CFG nodes into the AST that
created them. For this, use the elaborator to derive the ordering
statements etc. where possible.
* Adjust the forward framework to enable proofs that don't just state
correctness on the environment, but also on an arbitrary additional
state accumulated from traversing the trace.
* State the reaching definition analysis's correctness in terms
of this new framework.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This makes a finite-height proof for any `Fin n -> a` lattice
immediate, and precludes the need for IterProd and Prod altogether.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Convert every theorem to lemma (mathlib's default) except the headline results a
reader of each module seeks out: analyze_correct (Forward/Sign/Constant),
aFix_eq/aFix_le (Fixedpoint), trace (Language), and Stmt.cfg_sufficient
(Language/Properties). lemma and theorem are interchangeable keywords, so no
references change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Spa/Lattice.lean: add the missing space in the PointedLTSeries binder list
((f t : α) (n : ℕ)).
- Spa/Lattice/Unit.lean: use rfl instead of refl _, and split the ~200-column
longestChain record literal across lines, one field per line.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the ad-hoc truncation `evalB`/`evalB_mono` in
Spa/Analysis/Forward/Adapters.lean with `evalBasicStmt`/`evalBasicStmt_mono`.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The `inst*` prefix is reserved for compiler-generated instance names; writing it
by hand is non-idiomatic. Rename the recursive instances in Spa/Lattice/IterProd.lean
to descriptive lowerCamelCase matching the file's `def fixedHeight`:
instLattice -> lattice, instDecidableEq -> decidableEq, instFiniteHeight -> finiteHeight.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce a finite-height lattice instance for Bool, then build the
reaching-definitions analysis on top of the forward framework:
* Spa/Lattice/Bool.lean: FiniteHeightLattice Bool (the two-element
lattice false ≤ true), making FiniteMap A Bool ks a finite-height
"power set" lattice for free.
* Spa/Analysis/Reaching.lean: DefSet prog = FiniteMap prog.State Bool
prog.states as the per-variable lattice of definition sites, with a
StmtEvaluator whose transfer function performs a strong update
(assignment to k at node s sets k's def-set to {s}).
The analysis computes a least fixed point and produces correct
reaching-definitions sets. Soundness (relating def-sets to actual
execution provenance) is deferred; not yet exposed in Spa.lean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Derive c.head < c 1 from the series' StrictMono instance and Fin.one_pos'
instead of unfolding c.step with manual Fin.succ index arithmetic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Wrap the forward-analysis framework in a Spa.Forward namespace so its
generic names (analyze, result, joinAll, variablesAt, ...) no longer
sit flat in Spa, matching the ConstAnalysis/SignAnalysis convention.
- Merge the split Graph namespace in Graphs.lean by relocating buildCfg.
- Use nested namespace Spa / Fixedpoint instead of Spa.Fixedpoint.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce [spa_e| ... ] for Expr and [spa| ... ] for Stmt, scoped to the
Spa namespace via a dedicated syntax category and macro_rules. This removes
the deeply nested .andThen / .basic (.assign ...) boilerplate when writing
programs; Main.lean's test programs are rewritten to use it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>