Theorem: LRAT.DefaultFormula.confirmRupHint_preserves_invariant
Proof state before:
case intro.isFalse.inr.inr.intro
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
rupHints : Array Nat
i : Fin rupHints.size
acc : Array Assignment × List (Literal (PosFin n)) × Bool × Bool
hsize : acc.fst.size = n
ih : f.derivedLits_invariant f_assignments_size acc.fst hsize acc.snd.fst
hsize' : (confirmRupHint f.clauses acc rupHints[i]).fst.size = n
h✝ : ¬(acc.2.2.snd || acc.2.2.fst) = true
c : DefaultClause n
rupHint_clause_eq_c : f.clauses[rupHints[↑i]]? = some (some c)
⊢ f.derivedLits_invariant f_assignments_size
    (match c.reduce acc.fst with
      | ReduceResult.encounteredBoth => (acc.fst, acc.2.fst, true, false)
      | ReduceResult.reducedToEmpty => (acc.fst, acc.2.fst, true, false)
      | ReduceResult.reducedToUnit (l, b) =>
        if hasAssignment b acc.fst[l.val]! = true then (acc.fst, acc.2.fst, false, false)
        else (acc.fst.modify l.val (addAssignment b), (l, b) :: acc.2.fst, false, false)
      | ReduceResult.reducedToNonunit => (acc.fst, acc.2.fst, false, true)).fst
    ⋯
    (match c.reduce acc.fst with
        | ReduceResult.encounteredBoth => (acc.fst, acc.2.fst, true, false)
        | ReduceResult.reducedToEmpty => (acc.fst, acc.2.fst, true, false)
        | ReduceResult.reducedToUnit (l, b) =>
          if hasAssignment b acc.fst[l.val]! = true then (acc.fst, acc.2.fst, false, false)
          else (acc.fst.modify l.val (addAssignment b), (l, b) :: acc.2.fst, false, false)
        | ReduceResult.reducedToNonunit => (acc.fst, acc.2.fst, false, true)).snd.fst
Tactic:
have reduce_c_options : reduce c acc.1 = ReduceResult.encounteredBoth ∨ reduce c acc.1 = ReduceResult.reducedToEmpty ∨
  (∃ l : Literal (PosFin n), reduce c acc.1 = ReduceResult.reducedToUnit l) ∨ reduce c acc.1 = ReduceResult.reducedToNonunit := by
  match reduce c acc.fst with
  | ReduceResult.encounteredBoth => exact Or.inl rfl
  | ReduceResult.reducedToEmpty => exact (Or.inr ∘ Or.inl) rfl
  | ReduceResult.reducedToUnit l => exact (Or.inr ∘ Or.inr ∘ Or.inl ∘ Exists.intro l) rfl
  | ReduceResult.reducedToNonunit => exact (Or.inr ∘ Or.inr ∘ Or.inr) rfl
Proof state after:
case intro.isFalse.inr.inr.intro
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
rupHints : Array Nat
i : Fin rupHints.size
acc : Array Assignment × List (Literal (PosFin n)) × Bool × Bool
hsize : acc.fst.size = n
ih : f.derivedLits_invariant f_assignments_size acc.fst hsize acc.snd.fst
hsize' : (confirmRupHint f.clauses acc rupHints[i]).fst.size = n
h✝ : ¬(acc.2.2.snd || acc.2.2.fst) = true
c : DefaultClause n
rupHint_clause_eq_c : f.clauses[rupHints[↑i]]? = some (some c)
reduce_c_options :
  c.reduce acc.fst = ReduceResult.encounteredBoth ∨
    c.reduce acc.fst = ReduceResult.reducedToEmpty ∨
      (∃ l, c.reduce acc.fst = ReduceResult.reducedToUnit l) ∨ c.reduce acc.fst = ReduceResult.reducedToNonunit
⊢ f.derivedLits_invariant f_assignments_size
    (match c.reduce acc.fst with
      | ReduceResult.encounteredBoth => (acc.fst, acc.2.fst, true, false)
      | ReduceResult.reducedToEmpty => (acc.fst, acc.2.fst, true, false)
      | ReduceResult.reducedToUnit (l, b) =>
        if hasAssignment b acc.fst[l.val]! = true then (acc.fst, acc.2.fst, false, false)
        else (acc.fst.modify l.val (addAssignment b), (l, b) :: acc.2.fst, false, false)
      | ReduceResult.reducedToNonunit => (acc.fst, acc.2.fst, false, true)).fst
    ⋯
    (match c.reduce acc.fst with
        | ReduceResult.encounteredBoth => (acc.fst, acc.2.fst, true, false)
        | ReduceResult.reducedToEmpty => (acc.fst, acc.2.fst, true, false)
        | ReduceResult.reducedToUnit (l, b) =>
          if hasAssignment b acc.fst[l.val]! = true then (acc.fst, acc.2.fst, false, false)
          else (acc.fst.modify l.val (addAssignment b), (l, b) :: acc.2.fst, false, false)
        | ReduceResult.reducedToNonunit => (acc.fst, acc.2.fst, false, true)).snd.fst