Theorem: Regex.VM.stepChar_spec.mem_next_iff
Proof state before:
case h_1
nfa : NFA
c : Char
pos : String.Pos
next : SparseSet nfa.nodes.size
saveSlots : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
target : Fin nfa.nodes.size
matched' : Option (Array (Option String.Pos))
next' : SparseSet nfa.nodes.size
saveSlots' : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
inv : ∀ (i j : Fin nfa.nodes.size), i ∈ next → ↑j ∈ nfa.εStep ↑i → j ∈ next
c'✝ : Char
target'✝ : ℕ
heq✝ : nfa[target] = Node.char c'✝ target'✝
h :
  (if c = c'✝ then
      let_fun isLt := ⋯;
      let currentSave := saveSlots.get ↑target ⋯;
      exploreεClosure nfa pos next currentSave none saveSlots ⟨target'✝, isLt⟩ #[]
    else (none, next, saveSlots)) =
    (matched', next', saveSlots')
⊢ ∀ (j : Fin nfa.nodes.size), j ∈ next' ↔ j ∈ next ∨ ∃ i ∈ nfa.charStep (↑target) c, ↑j ∈ nfa.εClosure i

case h_2
nfa : NFA
c : Char
pos : String.Pos
next : SparseSet nfa.nodes.size
saveSlots : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
target : Fin nfa.nodes.size
matched' : Option (Array (Option String.Pos))
next' : SparseSet nfa.nodes.size
saveSlots' : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
inv : ∀ (i j : Fin nfa.nodes.size), i ∈ next → ↑j ∈ nfa.εStep ↑i → j ∈ next
cs✝ : Data.Classes
target'✝ : ℕ
heq✝ : nfa[target] = Node.sparse cs✝ target'✝
h :
  (if c ∈ cs✝ then
      let_fun isLt := ⋯;
      let currentSave := saveSlots.get ↑target ⋯;
      exploreεClosure nfa pos next currentSave none saveSlots ⟨target'✝, isLt⟩ #[]
    else (none, next, saveSlots)) =
    (matched', next', saveSlots')
⊢ ∀ (j : Fin nfa.nodes.size), j ∈ next' ↔ j ∈ next ∨ ∃ i ∈ nfa.charStep (↑target) c, ↑j ∈ nfa.εClosure i

case h_3
nfa : NFA
c : Char
pos : String.Pos
next : SparseSet nfa.nodes.size
saveSlots : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
target : Fin nfa.nodes.size
matched' : Option (Array (Option String.Pos))
next' : SparseSet nfa.nodes.size
saveSlots' : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
inv : ∀ (i j : Fin nfa.nodes.size), i ∈ next → ↑j ∈ nfa.εStep ↑i → j ∈ next
x✝¹ : ∀ (c' : Char) (target' : ℕ), nfa[target] = Node.char c' target' → False
x✝ : ∀ (cs : Data.Classes) (target' : ℕ), nfa[target] = Node.sparse cs target' → False
h : (none, next, saveSlots) = (matched', next', saveSlots')
⊢ ∀ (j : Fin nfa.nodes.size), j ∈ next' ↔ j ∈ next ∨ ∃ i ∈ nfa.charStep (↑target) c, ↑j ∈ nfa.εClosure i
Tactic:
next c' target' hn =>
  simp at hn
  split at h
  next hc =>
    simp at h
    have mem_next_iff := exploreεClosure_spec.mem_next_iff h inv
    intro j
    apply Iff.intro
    . intro hj
      cases (mem_next_iff j).mp hj with
      | inl hj => exact .inl hj
      | inr hj =>
        refine .inr ⟨target', ?_, hj⟩
        simp [charStep, Node.charStep, hn, hc]
    . intro hj
      cases hj with
      | inl hj => exact (mem_next_iff j).mpr (.inl hj)
      | inr hj =>
        simp [charStep, Node.charStep, hn, hc] at hj
        exact (mem_next_iff j).mpr (.inr hj)
  next hc =>
    have : ∀ i, ¬i ∈ nfa.charStep target c := by
      intro i
      simp [charStep, Node.charStep, hn, hc]
    simp at h
    simp [h, this]
Proof state after:
case h_2
nfa : NFA
c : Char
pos : String.Pos
next : SparseSet nfa.nodes.size
saveSlots : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
target : Fin nfa.nodes.size
matched' : Option (Array (Option String.Pos))
next' : SparseSet nfa.nodes.size
saveSlots' : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
inv : ∀ (i j : Fin nfa.nodes.size), i ∈ next → ↑j ∈ nfa.εStep ↑i → j ∈ next
cs✝ : Data.Classes
target'✝ : ℕ
heq✝ : nfa[target] = Node.sparse cs✝ target'✝
h :
  (if c ∈ cs✝ then
      let_fun isLt := ⋯;
      let currentSave := saveSlots.get ↑target ⋯;
      exploreεClosure nfa pos next currentSave none saveSlots ⟨target'✝, isLt⟩ #[]
    else (none, next, saveSlots)) =
    (matched', next', saveSlots')
⊢ ∀ (j : Fin nfa.nodes.size), j ∈ next' ↔ j ∈ next ∨ ∃ i ∈ nfa.charStep (↑target) c, ↑j ∈ nfa.εClosure i

case h_3
nfa : NFA
c : Char
pos : String.Pos
next : SparseSet nfa.nodes.size
saveSlots : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
target : Fin nfa.nodes.size
matched' : Option (Array (Option String.Pos))
next' : SparseSet nfa.nodes.size
saveSlots' : Data.Vec (Array (Option String.Pos)) nfa.nodes.size
inv : ∀ (i j : Fin nfa.nodes.size), i ∈ next → ↑j ∈ nfa.εStep ↑i → j ∈ next
x✝¹ : ∀ (c' : Char) (target' : ℕ), nfa[target] = Node.char c' target' → False
x✝ : ∀ (cs : Data.Classes) (target' : ℕ), nfa[target] = Node.sparse cs target' → False
h : (none, next, saveSlots) = (matched', next', saveSlots')
⊢ ∀ (j : Fin nfa.nodes.size), j ∈ next' ↔ j ∈ next ∨ ∃ i ∈ nfa.charStep (↑target) c, ↑j ∈ nfa.εClosure i