Theorem: LRAT.DefaultFormula.ratAdd_result
Proof state before:
n : Nat
f : DefaultFormula n
c : DefaultClause n
p : Literal (PosFin n)
rupHints : Array Nat
ratHints : Array (Nat × Array Nat)
f_readyForRatAdd : f.readyForRatAdd
_pc : p ∈ Clause.toList c
h✝³ : f.ratHintsExhaustive p ratHints = true
h✝² : ¬(f.insertRupUnits c.negate).snd = true
h✝¹ : ¬((f.insertRupUnits c.negate).fst.performRupCheck rupHints).2.2.snd = true
h✝ : ¬((f.insertRupUnits c.negate).fst.performRupCheck rupHints).2.2.fst = true
performRatCheck_fold_success :
  (Array.foldl (fun x ratHint => if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
        (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).snd =
    true
fc : DefaultFormula n := (f.insertRupUnits c.negate).fst
fc_assignments_size : (f.insertRupUnits c.negate).fst.assignments.size = n
performRupCheck_res : DefaultFormula n := ((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst
h_performRupCheck_res : performRupCheck_res.ratUnits = #[] ∧ performRupCheck_res.assignments.size = n
⊢ {
            clauses :=
              (Array.foldl
                    (fun x ratHint =>
                      if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
                    (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).1.clauses,
            rupUnits :=
              (Array.foldl
                    (fun x ratHint =>
                      if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
                    (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).1.rupUnits,
            ratUnits :=
              (Array.foldl
                    (fun x ratHint =>
                      if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
                    (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).1.ratUnits,
            assignments :=
              restoreAssignments
                (Array.foldl
                      (fun x ratHint =>
                        if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
                      (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).1.assignments
                ((f.insertRupUnits c.negate).fst.performRupCheck rupHints).2.fst }.clearRupUnits.insert
      c =
    f.insert c
Tactic:
have insertRupUnits_rw : (insertRupUnits f (negate c)).1 =
  ⟨(insertRupUnits f (negate c)).1.clauses, (insertRupUnits f (negate c)).1.rupUnits,
   (insertRupUnits f (negate c)).1.ratUnits, (insertRupUnits f (negate c)).1.assignments⟩ := rfl
Proof state after:
n : Nat
f : DefaultFormula n
c : DefaultClause n
p : Literal (PosFin n)
rupHints : Array Nat
ratHints : Array (Nat × Array Nat)
f_readyForRatAdd : f.readyForRatAdd
_pc : p ∈ Clause.toList c
h✝³ : f.ratHintsExhaustive p ratHints = true
h✝² : ¬(f.insertRupUnits c.negate).snd = true
h✝¹ : ¬((f.insertRupUnits c.negate).fst.performRupCheck rupHints).2.2.snd = true
h✝ : ¬((f.insertRupUnits c.negate).fst.performRupCheck rupHints).2.2.fst = true
performRatCheck_fold_success :
  (Array.foldl (fun x ratHint => if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
        (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).snd =
    true
fc : DefaultFormula n := (f.insertRupUnits c.negate).fst
fc_assignments_size : (f.insertRupUnits c.negate).fst.assignments.size = n
performRupCheck_res : DefaultFormula n := ((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst
h_performRupCheck_res : performRupCheck_res.ratUnits = #[] ∧ performRupCheck_res.assignments.size = n
insertRupUnits_rw :
  (f.insertRupUnits c.negate).fst =
    { clauses := (f.insertRupUnits c.negate).fst.clauses, rupUnits := (f.insertRupUnits c.negate).fst.rupUnits,
      ratUnits := (f.insertRupUnits c.negate).fst.ratUnits, assignments := (f.insertRupUnits c.negate).fst.assignments }
⊢ {
            clauses :=
              (Array.foldl
                    (fun x ratHint =>
                      if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
                    (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).1.clauses,
            rupUnits :=
              (Array.foldl
                    (fun x ratHint =>
                      if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
                    (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).1.rupUnits,
            ratUnits :=
              (Array.foldl
                    (fun x ratHint =>
                      if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
                    (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).1.ratUnits,
            assignments :=
              restoreAssignments
                (Array.foldl
                      (fun x ratHint =>
                        if x.snd = true then x.fst.performRatCheck p.negateLiteral ratHint else (x.fst, false))
                      (((f.insertRupUnits c.negate).fst.performRupCheck rupHints).fst, true) ratHints 0).1.assignments
                ((f.insertRupUnits c.negate).fst.performRupCheck rupHints).2.fst }.clearRupUnits.insert
      c =
    f.insert c