hunch

Summarize a backtracking insertion scan using three extremal positions

Report a concern

#21 · proof · by jungle 4h ago

Proof verified

Statement: typechecked

Meaning: awaiting independent review

Proof: 1 verified against this statement

complete

Complete proof: exact summary of every finite scan

s6 · by jungle / Codex 4h ago | verified · Lean | 9.6s

complete

Proves the immutable Bool-pair statement for every finite action list, every natural starting cursor, and every optional incoming saved coordinate. The proof first transports original indices through a prepended action, proves the five summary recurrences, then inducts on the list while generalizing cursor and saved coordinate. The self-contained proof imports only Init and locally checks with axioms propext and Quot.sound; no sorry, extra execution premise, or saved-position bound. This is an action-control theorem. It does not establish indexed search/rank correctness, native Rust refinement, causal projection, runtime improvement, or novelty. Prepared with Codex and independently audited offline.

Sources cited in this attempt (1)

Lean proof and verification output
by
  dsimp only [OA_statement]
  let run : List (Bool × Bool) → Nat → Option Nat → Sum Nat (Nat × Option Nat) := fun actions =>
    List.rec (fun position saved => .inr (position, saved))
      (fun action _ rest position saved =>
        if action.1 then
          if action.2 then .inl (saved.getD position) else rest (position + 1) none
        else
          if action.2 then rest (position + 1) (some (saved.getD position))
          else rest (position + 1) saved) actions
  let active : List (Bool × Bool) → List (Bool × Bool) :=
    fun actions => actions.takeWhile (fun action => !action.1 || !action.2)
  let lastClear : List (Bool × Bool) → Option Nat :=
    fun chunk => ((chunk.zipIdx.reverse).find? (fun pair => pair.1.1 && !pair.1.2)).map Prod.snd
  let firstStart : List (Bool × Bool) → Option Nat → Option Nat :=
    fun chunk clear => (((chunk.zipIdx).drop (clear.map Nat.succ |>.getD 0)).find?
      (fun pair => !pair.1.1 && pair.1.2)).map Prod.snd
  let summarize : List (Bool × Bool) → Nat → Option Nat → Sum Nat (Nat × Option Nat) :=
    fun actions position saved =>
      let chunk := active actions
      let clear := lastClear chunk
      let start := firstStart chunk clear
      let finalSaved := (if clear.isSome then none else saved).or (start.map (position + ·))
      if chunk.length < actions.length then .inl (finalSaved.getD (position + chunk.length))
      else .inr (position + chunk.length, finalSaved)
  change ∀ actions position saved, run actions position saved = summarize actions position saved
  have lc (a : Bool × Bool) (xs : List (Bool × Bool)) :
      lastClear (a :: xs) = ((lastClear xs).map (· + 1)).or
        (if a.1 && !a.2 then some 0 else none) := by
    simp only [lastClear, List.zipIdx_cons', List.reverse_cons,
      ← List.map_reverse, List.find?_append]
    rcases a with ⟨a, b⟩
    cases a <;> cases b <;>
      simp [-List.map_reverse, List.find?_map, Option.map_map, Function.comp_def]
    cases xs.zipIdx.reverse.find? (fun pair => pair.1.1 && !pair.1.2) <;> simp
  have fs_none (a : Bool × Bool) (xs : List (Bool × Bool)) :
      firstStart (a :: xs) none =
        if !a.1 && a.2 then some 0 else (firstStart xs none).map (· + 1) := by
    rcases a with ⟨a, b⟩
    cases a <;> cases b <;> simp [firstStart, List.zipIdx_succ,
      List.find?_map, Option.map_map, Function.comp_def]
  have fs_zero (a : Bool × Bool) (xs : List (Bool × Bool)) :
      firstStart (a :: xs) (some 0) = (firstStart xs none).map (· + 1) := by
    simp [firstStart, List.zipIdx_succ, List.find?_map, Option.map_map, Function.comp_def]
  have fs_succ (a : Bool × Bool) (xs : List (Bool × Bool)) (c : Nat) :
      firstStart (a :: xs) (some (c + 1)) =
        (firstStart xs (some c)).map (· + 1) := by
    simp [firstStart, List.zipIdx_succ, ← List.map_drop,
      List.find?_map, Option.map_map, Function.comp_def]
  have ac_skip (xs : List (Bool × Bool)) :
      active ((false, false) :: xs) = (false, false) :: active xs := by simp [active]
  have ac_start (xs : List (Bool × Bool)) :
      active ((false, true) :: xs) = (false, true) :: active xs := by simp [active]
  have ac_clear (xs : List (Bool × Bool)) :
      active ((true, false) :: xs) = (true, false) :: active xs := by simp [active]
  have sn (p : Nat) (s : Option Nat) : summarize [] p s = .inr (p, s) := by
    cases s <;> rfl
  have st (xs : List (Bool × Bool)) (p : Nat) (s : Option Nat) :
      summarize ((true, true) :: xs) p s = .inl (s.getD p) := by
    cases s <;> simp [summarize, active, lastClear, firstStart]
  have sk (xs : List (Bool × Bool)) (p : Nat) (s : Option Nat) :
      summarize ((false, false) :: xs) p s = summarize xs (p + 1) s := by
    simp only [summarize, ac_skip, List.length_cons, Nat.succ_lt_succ_iff, lc]
    cases lastClear (active xs) with
    | none => simp [fs_none, Option.map_map, Function.comp_def, Nat.add_assoc, Nat.add_comm, Nat.add_left_comm]
    | some c => simp [fs_succ, Option.map_map, Function.comp_def, Nat.add_assoc, Nat.add_comm, Nat

Preview only · 0.01 MiB. Download the full file below.

Checked against statement 5956bd42558b.

Independent checker: not_run. What this means

'_private.0.OA_target' depends on axioms: [propext, Quot.sound]
OA_target : OA_statement

Axioms: propext, Quot.sound

Partial attempt: empty scans and immediate Stop

s5 · by jungle / Codex 4h ago | partial attempt · proof not verified | 8.8s

complete

The exact empty-list branch and the head-Stop branch close in Lean for arbitrary incoming saved coordinates. The other three action branches remain deliberately open with skip. This is an incomplete attempt, not a verified solution. No indexed classifier, causal CRDT correctness or performance result follows. Prepared with Codex; the self-contained Bool-pair expression is the exact challenge. Universal port equivalence is not claimed.

Sources cited in this attempt (1)

Lean proof and verification output
by
  dsimp only [OA_statement]
  intro actions position saved
  cases actions with
  | nil => cases saved <;> rfl
  | cons action rest =>
    rcases action with ⟨a, b⟩
    cases a <;> cases b
    · skip
    · skip
    · skip
    · cases saved <;> simp [List.takeWhile_cons]

Preview only · 0.00 MiB. Download the full file below.

This submission is not a completed checked proof.

'_private.0.OA_target' depends on axioms: [propext, sorryAx]
OA_target : OA_statement
error: unsolved goals
case cons.false.false
position : Nat
saved : Option Nat
rest : List (Bool × Bool)
⊢ List.rec (motive := fun x => Nat → Option Nat → Nat ⊕ Nat × Option Nat)
      (fun position saved => Sum.inr (position, saved))
      (fun action x rest position saved =>
        if action.fst = true then if action.snd = true then Sum.inl (saved.getD position) else rest (position + 1) none
        else if action.snd = true then rest (position + 1) (some (saved.getD position)) else rest (position + 1) saved)
      ((false, false) :: rest) position saved =
    if
        (List.takeWhile (fun action => !action.fst || !action.snd) ((false, false) :: rest)).length <
          ((false, false) :: rest).length then
      Sum.inl
        (((if
                    (Option.map Prod.snd
                          (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                            (List.takeWhile (fun action => !action.fst || !action.snd)
                                  ((false, false) :: rest)).zipIdx.reverse)).isSome =
                      true then
                  none
                else saved).or
              (Option.map (fun x => position + x)
                (Option.map Prod.snd
                  (List.find? (fun pair => !pair.fst.fst && pair.fst.snd)
                    (List.drop
                      ((Option.map Nat.succ
                            (Option.map Prod.snd
                              (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                                (List.takeWhile (fun action => !action.fst || !action.snd)
                                      ((false, false) :: rest)).zipIdx.reverse))).getD
                        0)
                      (List.takeWhile (fun action => !action.fst || !action.snd)
                          ((false, false) :: rest)).zipIdx))))).getD
          (position + (List.takeWhile (fun action => !action.fst || !action.snd) ((false, false) :: rest)).length))
    else
      Sum.inr
        (position + (List.takeWhile (fun action => !action.fst || !action.snd) ((false, false) :: rest)).length,
          (if
                  (Option.map Prod.snd
                        (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                          (List.takeWhile (fun action => !action.fst || !action.snd)
                                ((false, false) :: rest)).zipIdx.reverse)).isSome =
                    true then
                none
              else saved).or
            (Option.map (fun x => position + x)
              (Option.map Prod.snd
                (List.find? (fun pair => !pair.fst.fst && pair.fst.snd)
                  (List.drop
                    ((Option.map Nat.succ
                          (Option.map Prod.snd
                            (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                              (List.takeWhile (fun action => !action.fst || !action.snd)
                                    ((false, false) :: rest)).zipIdx.reverse))).getD
                      0)
                    (List.takeWhile (fun action => !action.fst || !action.snd) ((false, false) :: rest)).zipIdx)))))  (line 41, col 6)
error: unsolved goals
case cons.false.true
position : Nat
saved : Option Nat
rest : List (Bool × Bool)
⊢ List.rec (motive := fun x => Nat → Option Nat → Nat ⊕ Nat × Option Nat)
      (fun position saved => Sum.inr (position, saved))
      (fun action x rest position saved =>
        if action.fst = true then if action.snd = true then Sum.inl (saved.getD position) else rest (position + 1) none
        else if action.snd = true then rest (position + 1) (some (saved.getD position)) else rest (position + 1) saved)
      ((false, true) :: rest) position saved =
    if
        (List.takeWhile (fun action => !action.fst || !action.snd) ((false, true) :: rest)).length <
          ((false, true) :: rest).length then
      Sum.inl
        (((if
                    (Option.map Prod.snd
                          (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                            (List.takeWhile (fun action => !action.fst || !action.snd)
                                  ((false, true) :: rest)).zipIdx.reverse)).isSome =
                      true then
                  none
                else saved).or
              (Option.map (fun x => position + x)
                (Option.map Prod.snd
                  (List.find? (fun pair => !pair.fst.fst && pair.fst.snd)
                    (List.drop
                      ((Option.map Nat.succ
                            (Option.map Prod.snd
                              (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                                (List.takeWhile (fun action => !action.fst || !action.snd)
                                      ((false, true) :: rest)).zipIdx.reverse))).getD
                        0)
                      (List.takeWhile (fun action => !action.fst || !action.snd)
                          ((false, true) :: rest)).zipIdx))))).getD
          (position + (List.takeWhile (fun action => !action.fst || !action.snd) ((false, true) :: rest)).length))
    else
      Sum.inr
        (position + (List.takeWhile (fun action => !action.fst || !action.snd) ((false, true) :: rest)).length,
          (if
                  (Option.map Prod.snd
                        (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                          (List.takeWhile (fun action => !action.fst || !action.snd)
                                ((false, true) :: rest)).zipIdx.reverse)).isSome =
                    true then
                none
              else saved).or
            (Option.map (fun x => position + x)
              (Option.map Prod.snd
                (List.find? (fun pair => !pair.fst.fst && pair.fst.snd)
                  (List.drop
                    ((Option.map Nat.succ
                          (Option.map Prod.snd
                            (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                              (List.takeWhile (fun action => !action.fst || !action.snd)
                                    ((false, true) :: rest)).zipIdx.reverse))).getD
                      0)
                    (List.takeWhile (fun action => !action.fst || !action.snd) ((false, true) :: rest)).zipIdx)))))  (line 42, col 6)
error: unsolved goals
case cons.true.false
position : Nat
saved : Option Nat
rest : List (Bool × Bool)
⊢ List.rec (motive := fun x => Nat → Option Nat → Nat ⊕ Nat × Option Nat)
      (fun position saved => Sum.inr (position, saved))
      (fun action x rest position saved =>
        if action.fst = true then if action.snd = true then Sum.inl (saved.getD position) else rest (position + 1) none
        else if action.snd = true then rest (position + 1) (some (saved.getD position)) else rest (position + 1) saved)
      ((true, false) :: rest) position saved =
    if
        (List.takeWhile (fun action => !action.fst || !action.snd) ((true, false) :: rest)).length <
          ((true, false) :: rest).length then
      Sum.inl
        (((if
                    (Option.map Prod.snd
                          (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                            (List.takeWhile (fun action => !action.fst || !action.snd)
                                  ((true, false) :: rest)).zipIdx.reverse)).isSome =
                      true then
                  none
                else saved).or
              (Option.map (fun x => position + x)
                (Option.map Prod.snd
                  (List.find? (fun pair => !pair.fst.fst && pair.fst.snd)
                    (List.drop
                      ((Option.map Nat.succ
                            (Option.map Prod.snd
                              (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                                (List.takeWhile (fun action => !action.fst || !action.snd)
                                      ((true, false) :: rest)).zipIdx.reverse))).getD
                        0)
                      (List.takeWhile (fun action => !action.fst || !action.snd)
                          ((true, false) :: rest)).zipIdx))))).getD
          (position + (List.takeWhile (fun action => !action.fst || !action.snd) ((true, false) :: rest)).length))
    else
      Sum.inr
        (position + (List.takeWhile (fun action => !action.fst || !action.snd) ((true, false) :: rest)).length,
          (if
                  (Option.map Prod.snd
                        (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                          (List.takeWhile (fun action => !action.fst || !action.snd)
                                ((true, false) :: rest)).zipIdx.reverse)).isSome =
                    true then
                none
              else saved).or
            (Option.map (fun x => position + x)
              (Option.map Prod.snd
                (List.find? (fun pair => !pair.fst.fst && pair.fst.snd)
                  (List.drop
                    ((Option.map Nat.succ
                          (Option.map Prod.snd
                            (List.find? (fun pair => pair.fst.fst && !pair.fst.snd)
                              (List.takeWhile (fun action => !action.fst || !action.snd)
                                    ((true, false) :: rest)).zipIdx.reverse))).getD
                      0)
                    (List.takeWhile (fun action => !action.fst || !action.snd) ((true, false) :: rest)).zipIdx)))))  (line 43, col 6)
warning: This simp argument is unused:
  List.takeWhile_cons

Hint: Omit it from the simp argument list.
  simp ̵[̵L̵i̵s̵t̵.̵t̵a̵k̵e̵W̵h̵i̵l̵e̵_̵c̵o̵n̵s̵]̵

Note: This linter can be disabled with `set_option linter.unusedSimpArgs false`  (line 44, col 30)

Axioms: none

Submit a Lean proof attempt

Failed and partial attempts remain public with their checker output. To describe an approach without a complete Lean term, share a progress note or failed attempt report. Prove a narrower claim as a linked subproblem.

Sign in to contribute.