Skip to content

[Lean Squad] feat(formal-verification): AlphaFilter Lean spec + Deadzone sorry elimination#10

Merged
dsyme merged 1 commit intomainfrom
lean-squad/fv-alphafilter-deadzone-run7-03a4472311-bcebc3f30b6d3bd8
Apr 4, 2026
Merged

[Lean Squad] feat(formal-verification): AlphaFilter Lean spec + Deadzone sorry elimination#10
dsyme merged 1 commit intomainfrom
lean-squad/fv-alphafilter-deadzone-run7-03a4472311-bcebc3f30b6d3bd8

Conversation

@github-actions
Copy link
Copy Markdown

@github-actions github-actions Bot commented Apr 4, 2026

Overview

This PR delivers two completed tasks and contributes to a third:

  • Task 5 (Proof Assistance): Eliminates the 2 remaining sorry in Deadzone.lean — the range-bound theorems deadzone_le_one and deadzone_ge_neg_one are now fully proved. Deadzone.lean now has 12 proved theorems and 0 sorry.

  • Task 2 (Informal Spec): Adds a precise informal specification for AlphaFilter::update documenting pre/postconditions, no-overshoot safety property, and open questions for maintainers.

  • Task 4+5 (Lean Spec + Proofs): Adds AlphaFilter.lean with 9 proved theorems and 3 documented sorry.


Changes

formal-verification/lean/FVSquad/Deadzone.lean

Proves the two theorems that previously required sorry:

deadzone_le_one (negative branch): When x < 0 and |x| > dz, the output is (x + dz)/(1 − dz) < 0 ≤ 1. Key steps: |x| = −x via Rat.abs_of_nonpos, then x < −dz via Rat.neg_lt_neg_iff, then show x + dz < 0 using the same pattern as deadzone_neg.

deadzone_ge_neg_one: Full case split: (1) in-deadzone → output = 0 ≥ −1; (2) positive branch → output > 0 ≥ −1; (3) negative branch → uses −(1−dz) ≤ x+dz (from −1 ≤ x, add dz) and the calc chain −1 = −(1−dz)·(1−dz)⁻¹ ≤ (x+dz)·(1−dz)⁻¹.

formal-verification/specs/alphafilter_informal.md (new)

Informal specification for AlphaFilter::updateCalculation:

  • Core update: new = (1−α)·old + α·sample (convex blend)
  • No-overshoot safety property: min(state, sample) ≤ new_state ≤ max(state, sample)
  • Fixed point, boundary cases (α=0, α=1), multi-step convergence formula
  • Concrete examples table, edge cases, open questions for maintainers

formal-verification/lean/FVSquad/AlphaFilter.lean (new)

Lean 4 model over Rat:

Proved (9 theorems):

  • alphaUpdate_fixed: sample = state → no change
  • alphaUpdate_alpha_zero: α=0 → state frozen
  • alphaUpdate_alpha_one: α=1 → state = sample immediately
  • alphaUpdate_le_sample / alphaUpdate_ge_state: no-overshoot upper/lower bound (upward case)
  • alphaUpdate_no_overshoot_up: combined state ≤ new_state ≤ sample
  • alphaUpdate_le_state: upper bound downward case (new_state ≤ state)
  • alphaUpdate_mono_sample: monotone in sample input
  • alphaIterate_formula (base case): state₀ = target + (state₀ − target) · (1−α)⁰

3 sorry remain (documented):

  • alphaUpdate_ge_sample: needs multiply-by-nonpositive lemma (mul_le_mul_of_nonpos_right, not in stdlib without Mathlib)
  • alphaUpdate_mono_state: ring step — (s₁−s₂)·(1−α) ≤ 0
  • alphaIterate_formula (inductive step): ring manipulation

Verification Status

🔄 Partial verification: lake build passed with Lean 4.29.0. 3 sorry remain in AlphaFilter.lean (listed in summary table). Deadzone.lean is now fully proved (0 sorry).

lake build — Build completed successfully (8 jobs)
Lean (version 4.29.0, x86_64-unknown-linux-gnu)

Key Correctness Properties Proved

The no-overshoot upward case is the key safety property: when state ≤ sample, the filter output strictly remains in [state, sample] — it never overshoots. This is critical for autopilot rate/attitude controllers where filter transients could destabilise the aircraft.

theorem alphaUpdate_no_overshoot_up (state alpha sample : Rat)
    (h_le : state ≤ sample) (ha0 : 0 ≤ alpha) (ha1 : alpha ≤ 1) :
    state ≤ alphaUpdate state alpha sample ∧ alphaUpdate state alpha sample ≤ sample

🔬 This PR was created by Lean Squad automated formal verification.

Generated by 📐 Lean Squad, see workflow run. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/lean-squad.md@4b17e80c4ba005a7d9b3507ca5facf9d1fce3b66

…mination

Task 2 (Informal Spec): formal-verification/specs/alphafilter_informal.md
  - Precise pre/postconditions for AlphaFilter::update (first-order IIR filter)
  - Documents the no-overshoot safety property (key autopilot invariant)
  - Concrete examples, edge cases, open questions

Task 4+5 (Lean spec + proofs): formal-verification/lean/FVSquad/AlphaFilter.lean
  - Lean 4 model of alphaUpdate over Rat
  - 9 theorems proved: fixed_point, alpha_zero, alpha_one,
    no_overshoot_up (both bounds), no_overshoot_down upper bound,
    mono_sample, iterated zero case
  - 3 sorry remain: alphaUpdate_ge_sample (mul-by-nonpositive),
    alphaUpdate_mono_state (ring step), alphaIterate_formula succ case

Task 5 (Proof Assistance): formal-verification/lean/FVSquad/Deadzone.lean
  - Eliminated both remaining sorry from deadzone_le_one (negative branch)
    and deadzone_ge_neg_one by direct Rat arithmetic proofs
  - Deadzone now has 12 proved theorems, 0 sorry

lake build: passed (Lean 4.29.0), 3 sorry remain in AlphaFilter.lean

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dsyme dsyme merged commit e8d594b into main Apr 4, 2026
github-actions Bot added a commit that referenced this pull request Apr 14, 2026
…ility critique update (run35)

Task 5 (Proof Assistance): Add ExpoDeadzone.lean — formal specification and proofs
for the combined expo(deadzone(v, dz), e) RC input pipeline.

8 theorems proved (0 sorry, lake build passes):
- expodz_in_dz: inside-deadzone input → exactly 0
- expodz_in_range: output always ∈ [-1, 1] (unconditional)
- expodz_zero: zero input → zero output for dz ≥ 0
- expodz_at_one / expodz_at_neg_one: ±1 are fixed points for dz ∈ [0, 1)
- expodz_e0: e=0 (linear expo) reduces to pure deadzone
- expodz_cubic: e=1 (full cubic expo) gives (deadzone v dz)³
- expodz_no_dz: dz=0 recovers exactly expoRat (no-deadzone degeneration)

Proofs compose expo_* and deadzone_* theorems from prior Lean files,
demonstrating compositional verification of the two-stage RC pipeline.
Also registers ExpoDeadzone + MedianFilter + SuperExpo in FVSquad.lean.

Task 7 (Proof Utility Critique): Update CRITIQUE.md to reflect current state:
- 15 targets, 172 theorems, 166 proved, 6 sorry (WrapAngle wrapRat only)
- Add SuperExpo, MedianFilter, ExpoDeadzone rows to proved-theorems table
- Update gaps: add expodz_odd as next high-priority target
- Add positive findings #10-12 (MedianFilter spike rejection, superexpo
  denom-positive safety, expo+deadzone composition correctness)
- Update Known Sorry-Guarded section (14 files, 0 sorry except WrapAngle)

> ✅ Proofs verified: lake build passed with Lean 4.29.0. 0 sorry in new file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
github-actions Bot added a commit that referenced this pull request Apr 14, 2026
…ility critique update (run35)

Task 5 (Proof Assistance): Add ExpoDeadzone.lean — formal specification and proofs
for the combined expo(deadzone(v, dz), e) RC input pipeline.

8 theorems proved (0 sorry, lake build passes):
- expodz_in_dz: inside-deadzone input → exactly 0
- expodz_in_range: output always ∈ [-1, 1] (unconditional)
- expodz_zero: zero input → zero output for dz ≥ 0
- expodz_at_one / expodz_at_neg_one: ±1 are fixed points for dz ∈ [0, 1)
- expodz_e0: e=0 (linear expo) reduces to pure deadzone
- expodz_cubic: e=1 (full cubic expo) gives (deadzone v dz)³
- expodz_no_dz: dz=0 recovers exactly expoRat (no-deadzone degeneration)

Proofs compose expo_* and deadzone_* theorems from prior Lean files,
demonstrating compositional verification of the two-stage RC pipeline.
Also registers ExpoDeadzone + MedianFilter + SuperExpo in FVSquad.lean.

Task 7 (Proof Utility Critique): Update CRITIQUE.md to reflect current state:
- 15 targets, 172 theorems, 166 proved, 6 sorry (WrapAngle wrapRat only)
- Add SuperExpo, MedianFilter, ExpoDeadzone rows to proved-theorems table
- Update gaps: add expodz_odd as next high-priority target
- Add positive findings #10-12 (MedianFilter spike rejection, superexpo
  denom-positive safety, expo+deadzone composition correctness)
- Update Known Sorry-Guarded section (14 files, 0 sorry except WrapAngle)

> ✅ Proofs verified: lake build passed with Lean 4.29.0. 0 sorry in new file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant