Section 10: Advanced Rewrites & Verification
Status: Not Started Goal: Complete the algebraic optimization pipeline with distributivity (Ring law), multiplicative inverse, and comprehensive verification that the entire semantic optimization pipeline is correct, performant, and regression-free.
Success Criteria:
- Distributivity fires:
a*c + b*c → (a+b)*cwhen profitable (fewer operations) - Distributivity does NOT fire when unprofitable (e.g., when factoring increases live ranges)
- Multiplicative inverse:
x * recip(x) → 1for types withInvtrait and nonzero proof - Genuine lowered TRMC fixtures cross block boundaries, pass the PL-7–PL-11 calculus gate, and contain no self-recursive call after normalization
- Full test matrix: every type × law × pattern combination tested
-
diagnostics/dual-exec-verify.shpasses on all algebraic test programs -
ORI_CHECK_LEAKS=1clean on all test programs -
/code-journeypasses with escalating complexity
Depends on: Section 09 (normalization framework).
10.1 Distributivity with Cost Model
File(s): compiler/ori_arc/src/aims/normalize/algebra.rs
Distributivity rewrites factor common subexpressions: a*c + b*c → (a+b)*c. This reduces operation count (2 multiplications + 1 addition → 1 addition + 1 multiplication) but increases the live range of the intermediate (a+b) result. A cost model gates the rewrite.
- Detect pattern (indirect through ArcVarId def chains — all operators are PrimOp in ARC IR):
- Outer:
Let { dst: d, value: PrimOp { op: Binary(Add), args: [mul1_dst, mul2_dst] } } mul1_dstdefined by:Let { value: PrimOp { op: Binary(Mul), args: [a, c1] } }mul2_dstdefined by:Let { value: PrimOp { op: Binary(Mul), args: [b, c2] } }- Where
c1 == c2(same ArcVarId) ANDMulhasDistributesOver { inner: Add }law for this type
- Outer:
- Also detect left-distributed:
c*a + c*b → c*(a+b)depending onside: left/right/both - Cost model: count operations before and after. Only apply if post-rewrite has fewer operations (2 mul + 1 add → 1 add + 1 mul = saves 1 multiplication)
- Live range consideration: the factored common factor
cmust be live at both uses. If it’s already live (same variable), factoring is free. If it requires an extra load/retain, cost may increase — gate on this. - Rewrite: create new intermediate
Let { dst: sum_var, value: PrimOp { op: Binary(Add), args: [a, b] } }then replace outer withLet { dst: d, value: PrimOp { op: Binary(Mul), args: [sum_var, c] } } - Reverse factoring (expansion):
c*(a+b) → c*a + c*b— useful when expansion enables other optimizations (e.g., constant folding onc*a). Only apply with explicit cost benefit. - Write tests:
a*c + b*c → (a+b)*cfor int (two muls → one)a*c + b*cwhere c is different variables → NOT factoreda*c + b*d→ NOT factored (different factors)- Cost model test: case where factoring would increase live range → NOT applied
- Verify:
timeout 150 cargo t -p ori_arcpasses
Matrix dimensions:
-
Types: int (Mul distributes over Add)
-
Patterns: right-factor, left-factor, both sides, no common factor, nested factoring
-
Semantic pin:
a*c + b*cproduces ARC IR with 1 Mul + 1 Add (not 2 Mul + 1 Add) -
Negative pin:
a*c + b*dis NOT factored -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (10.1) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-10.1 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 10.1: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
10.2 Multiplicative Inverse
File(s): library/std/prelude.ori (NEW trait), compiler/ori_arc/src/aims/normalize/algebra.rs
Add Inv/Recip trait for types with multiplicative inverse. Gate on nonzero precondition.
-
Add to prelude.ori:
pub trait Inv { @inv (self) -> Self // Precondition: self != Zero::zero() // Law: self.inv() * self == One::one() } -
Implement for
float(using current parser syntaximpl Trait for Type):impl Inv for float { @inv (self) -> float = 1.0 / self } -
Do NOT implement for
int— integer division loses precision,invis meaningless -
Add
Inverselaw toMultrait algebra block:inverse: Inv::inv(multiplicative inverse) -
impl Mul for floatcan declarelaws [commutative, inverse]— theinverselaw asserts the mathematical property exists. BUT the normalization rewritex * inv(x) → 1.0must be guarded by finite-nonzero proof (see precondition below) -
Normalization: detect
x * inv(x) → One::one()(1.0 for float) -
Precondition: only fire if
xis provably a finite nonzero value. For now, conservative: only fire ifxis a literal that is nonzero AND finite (not NaN, not Inf, not -Inf). The guard must exclude ALL of: zero, NaN, Inf, -Inf.NaN * inv(NaN)=NaN * NaN=NaN(not 1.0) — UNSOUND without guardInf * inv(Inf)=Inf * 0.0=NaN(not 1.0) — UNSOUND without guard-Inf * inv(-Inf)=-Inf * -0.0=NaN(not 1.0) — UNSOUND without guard0.0 * inv(0.0)=0.0 * Inf=NaN(not 1.0) — UNSOUND without guard-0.0 * inv(-0.0)=-0.0 * -Inf=NaN(not 1.0) — UNSOUND without guard Future: integrate with range metadata and non-NaN/non-Inf proofs from type-level contracts.
-
Write tests:
x * (1.0 / x) → 1.0where x is literal nonzero finite constant (e.g.,2.0)x * (1.0 / x)where x is variable → NOT optimized (can’t prove finite nonzero)0.0 * (1.0 / 0.0)→ NOT optimized (zero)NaN * (1.0 / NaN)→ NOT optimized (NaN guard)Inf * (1.0 / Inf)→ NOT optimized (Inf guard)
-
Verify:
timeout 150 ./test-all.shpasses -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (10.2) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-10.2 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 10.2: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
10.2a TRMC Cross-Block Admission and Must-Fire Activation
Transferred from: plans/completed/aims-burden-tracking/ section s-45be9b5e. This is semantic normalization work, not provenance-ledger or physical-RC retirement work.
File(s): compiler/ori_arc/src/aims/normalize/{rewrite,detect,verify,lift}.rs, compiler/ori_arc/src/pipeline/aims_pipeline/trmc.rs, compiler/ori_llvm/tests/aot/trmc.rs, compiler/ori_llvm/tests/aot/fixtures/trmc/, compiler/aims-proof/proofs/07-pipeline/, compiler/aims-proof/lean/AimsProof/
Real lowered TRMC candidates place the recursive Apply and wrapping Construct in different blocks because checked arithmetic and calls introduce normal, overflow, and unwind edges. Detection, rollback, and the PL-7–PL-11 proof family exist, but check_admission retains a v1 same-block restriction. Synthetic same-block unit tests therefore pass while production AOT fixtures can remain recursively compiled.
- Establish calculus coverage before changing Rust: state the cross-block context-region obligation in scratch Lean against PL-8, PL-9, and PL-10. If the current theorem hypotheses do not cover it, extend compiled Lean first, keep zero
sorry, and synchronize the.proof,aims-rules.md,arc.md, and Annex E AIMS surfaces in the same change. - Lift only the same-block rejection in
check_admission. Admit a region only whenopen_block/close_block, dominance/post-dominance, hole position,Applyordering, normal edges, and unwind edges satisfy the proven hypothesis. Preserve every other admission check and the singlenormalize_with_trmcpath. - Keep PL-10 verification and rollback fail-closed. An injected malformed or inadmissible cross-block region must restore the pre-rewrite function and re-run the required downstream analysis; no partially rewritten CFG may escape.
- Add must-fire evidence on real lowered source: a deep-recursion fixture that requires loop conversion, an ARC-IR shape pin with context-hole threading and no self-recursive
Apply, and an optimized-assembly pin with no self-call in the function body. - Add must-not-fire coverage for branching/non-context recursion and a hole-position matrix covering first, last, and interior constructor fields. Reconcile any historical fixture whose name claims TRMC but whose body contains no TRMC shape.
- Require
verify_trmc_burden_balanceor its post-bytecode logical-event successor to report zero errors, evaluator/VM/LLVM debug/release/AOT observable parity, exact cleanup/unwind correspondence,ORI_CHECK_LEAKS=1zero leaks, and the full test suite green. - Re-bless snapshots only after classifying each changed output against the proven PL-9/PL-10 shape; behavioral success without a rewrite-fired pin is insufficient.
Banned approaches: a second cross-block TRMC implementation; weakening a theorem; same-block-only synthetic evidence; unconditional snapshot blessing; or using behavior parity as proof that the optimization fired.
-
/tpr-reviewpassed and all findings resolved. -
/impl-hygiene-reviewpassed after TPR. - Subsection close-out (10.2a) — run the required
/improve-tooling,/sync-claude, and repo-hygiene checks; record the transferred burden section as delivered here.
10.3 Full Test Matrix
File(s): Tests across tests/spec/algebra/, compiler/ori_llvm/tests/aot/, tests/valgrind/
Build a comprehensive test matrix covering every type × law × pattern combination across all sections.
- Identity elimination matrix:
| Type | Operator | Identity | Left | Right | Both |
|---|---|---|---|---|---|
| int | Add | 0 | x | x | x |
| int | Mul | 1 | x | x | x |
| str | Add | "" | x | x | x |
| [T] | Add | [] | x | x | x |
| int | BitAnd | -1 (all set) | x | x | x |
| int | BitOr | 0 | x | x | x |
| int | BitXor | 0 | x | x | x |
| float | Add | (excluded) | - | - | - |
| float | Mul | (excluded) | - | - | - |
Note: &&/|| are NOT PrimOps (short-circuit control flow). No ARC IR identity elimination possible.
- Involutive matrix:
| Type | Operator | Test |
|---|---|---|
| int | Neg | -(-x) → x |
| bool | Not | !!b → b |
| int | BitNot | ~~n → n |
- Commutative ordering matrix:
| Type | Operator | Before | After |
|---|---|---|---|
| int | Add | 3 + x | x + 3 |
| int | Mul | 5 * y | y * 5 |
| int | BitAnd | -1 & x | x & -1 |
| int | BitOr | 0 | x | x | 0 |
Note: &&/|| are NOT PrimOps — they produce control-flow IR, not commutable operands.
- Associativity matrix:
| Type | Operator | Input | Canonical |
|---|---|---|---|
| int | Add | (a+b)+c | a+(b+c) |
| int | Mul | (a*b)*c | a*(b*c) |
| str | Add | (s1+s2)+s3 | s1+(s2+s3) |
- Inverse matrix:
| Type | Operator | Input | Result |
|---|---|---|---|
| int | Add/Neg | x+(-x) | 0 |
| int | Add/Neg | (-x)+x | 0 |
- Distributivity matrix:
| Type | Outer | Inner | Input | Result |
|---|---|---|---|---|
| int | Mul | Add | ac+bc | (a+b)*c |
-
Verify:
timeout 150 cargo st tests/spec/algebra/passes -
Verify:
timeout 150 cargo t -p ori_llvm(AOT tests) passes -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (10.3) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-10.3 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 10.3: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
10.4 Dual-Exec Parity Verification
Verify that the normalization pass preserves behavioral equivalence between interpreter and LLVM paths.
-
Run
diagnostics/dual-exec-verify.sh tests/spec/algebra/— all programs produce identical output in eval vs AOT -
Run
diagnostics/dual-exec-verify.sh tests/spec/expressions/— existing expression tests still produce identical output -
Any mismatch → investigate and fix before proceeding
-
Track results in a verification report
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (10.4) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-10.4 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 10.4: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
10.5 Code Journey & Safety
-
Run
/code-journeywith algebraic programs (matrix arithmetic, vector operations, numeric algorithms) -
All CRITICAL findings triaged
-
Run
ORI_CHECK_LEAKS=1on all algebraic test programs — zero leaks -
Run
diagnostics/valgrind-aot.sh tests/spec/algebra/— zero memory errors -
Stress test: program with 1000+ algebraic operations → normalization pass completes in < 100ms
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (10.5) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-10.5 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 10.5: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
10.6 Documentation
-
Update CLAUDE.md with new commands/flags:
ORI_DUMP_AFTER_ALGEBRA=1— dump ARC IR after algebraic normalizationalgebra {}syntax in trait definitionslaws []syntax in impl blocksZero/One/Invtraits
-
Update
.claude/rules/ori-syntax.mdwith algebra/laws syntax: addalgebra,laws,supportsto context-sensitive keyword list; addalgebra {}block in trait definition syntax; addlaws []in impl syntax; addZero/One/Invin prelude traits -
Update
docs/ori_lang/v2026/spec/operator-rules.mdwith algebraic law semantics -
Update
docs/ori_lang/v2026/spec/grammar.ebnfwithalgebraandlawsgrammar rules -
Add architecture overview to
compiler/ori_arc/src/aims/normalize/algebra.rsmodule docs -
Document in the module docs:
BinaryOp::And/Or/Coalesceare intercepted before PrimOp emission and lowered to control-flow IR — they NEVER appear asPrimOp::Binary(And)etc. in ARC IR. Only bitwiseBitAnd/BitOr/BitXorreach PrimOp. -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (10.6) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-10.6 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 10.6: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
10.R Third Party Review Findings
- None.
10.N Completion Checklist
- Distributivity with cost model implemented and tested
- Multiplicative inverse implemented for float with nonzero guard
- Cross-block TRMC calculus coverage, admission lift, rollback, must-fire, and must-not-fire matrix complete
- Full test matrix covers all type × law × pattern combinations
- Cross-executor parity verified; dual-exec eval/LLVM is one leg of the evaluator/VM/LLVM debug/release/AOT and affected native/WASM/JIT matrix
-
ORI_CHECK_LEAKS=1clean on all algebraic programs - Valgrind clean on all algebraic programs
- Code journey passes
- Stress test passes (1000+ ops, < 100ms)
- All documentation updated (CLAUDE.md, spec, grammar, rules)
- Plan annotation cleanup: all
semantic-optimization-pipelineannotations removed from code — rungrep -rn "semantic-optimization-pipeline" compiler/ library/to verify zero hits -
timeout 150 ./test-all.shgreen (debug AND release —cargo b --release && timeout 150 ./test-all.sh) -
timeout 150 ./clippy-all.shgreen - Plan sync — update all plan metadata:
- All sections
status→complete -
00-overview.mdall mission success criteria checked, status →complete -
index.mdall section statuses updated - Cross-plan links updated (roadmap items resolved)
- All sections
-
/tpr-reviewpassed (final, full-section) -
/impl-hygiene-reviewpassed -
/improve-toolingretrospective completed — MANDATORY at section close, after both reviews are clean. Reflect on the section’s debugging journey (whichdiagnostics/scripts you ran, which command sequences you repeated, where you added ad-hocdbg!/tracingcalls, where output was hard to interpret) and identify any tool/log/diagnostic improvement that would have made this section materially easier OR that would help the next section touching this area. Implement every accepted improvement NOW (zero deferral) and commit each via SEPARATE/commit-push. The retrospective is mandatory even when nothing felt painful — that is exactly when blind spots accumulate. See.claude/skills/improve-tooling/SKILL.md“Retrospective Mode” for the full protocol.
Exit Criteria: The full semantic optimization pipeline is operational: one backend-neutral AIMS fact plan exists, LLVM metadata projects from it, derived methods are normalized, runtime identities are fixed, algebraic laws are consumed, and normalization applies distributivity/inverse only under proved gates. ./test-all.sh passes with zero failures.
Evaluator, VM, LLVM debug/release/AOT, and affected native/JIT consumers preserve behavior and cleanup parity. Valgrind/leak checks are clean, and documentation reflects the shared carrier plus target projections.