-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/RatAddSound.lean
theorem sat_of_confirmRupHint_of_insertRat_fold {n : Nat} (f : DefaultFormula n)
    (hf : f.ratUnits = #[] ∧ AssignmentsInvariant f) (c : DefaultClause n) (rupHints : Array Nat)
    (p : PosFin n → Bool) (pf : p ⊨ f) :
    let fc := insertRatUnits f (negate c)
    let confirmRupHint_fold_res := rupHints.foldl (confirmRupHint fc.1.clauses) (fc.1.assignments, [], false, false) 0 rupHints.size
    confirmRupHint_fold_res.2.2.1 = true → p ⊨ c

Proof state:
case neg.intro.intro
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.AssignmentsInvariant
c : DefaultClause n
rupHints : Array Nat
p : PosFin n → Bool
pf : p ⊨ f
fc : DefaultFormula n × Bool := f.insertRatUnits c.negate
confirmRupHint_fold_res : Array Assignment × CNF.Clause (PosFin n) × Bool × Bool :=
  Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints
confirmRupHint_success : confirmRupHint_fold_res.snd.snd.fst = true
motive : Nat → Array Assignment × CNF.Clause (PosFin n) × Bool × Bool → Prop := fc.fst.ConfirmRupHintFoldEntailsMotive
h_base : motive 0 (fc.fst.assignments, [], false, false)
h_inductive :
  ∀ (idx : Fin rupHints.size) (acc : Array Assignment × CNF.Clause (PosFin n) × Bool × Bool),
    motive (↑idx) acc →
      fc.fst.ConfirmRupHintFoldEntailsMotive (↑idx + 1) (confirmRupHint fc.fst.clauses acc rupHints[idx])
left✝ : (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst.size = n
h1 :
  Limplies (PosFin n) fc.fst
    (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst
h2 :
  (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).snd.snd.fst = true →
    Incompatible (PosFin n)
      (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst fc.fst
fc_incompatible_confirmRupHint_fold_res :
  Incompatible (PosFin n) fc.fst
    (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst
pc :
  ∀ (x : PosFin n),
    ((x, false) ∈ Clause.toList c → decide (p x = false) = false) ∧
      ((x, true) ∈ Clause.toList c → decide (p x = true) = false)
unsat_c : DefaultClause n
unsat_c_in_fc : unsat_c ∈ fc.fst.toList
p_unsat_c : ¬(p ⊨ unsat_c)
⊢ False

Tactic:
have unsat_c_in_fc := mem_of_insertRatUnits f (negate c) unsat_c unsat_c_in_fc

Result:
case neg.intro.intro
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.AssignmentsInvariant
c : DefaultClause n
rupHints : Array Nat
p : PosFin n → Bool
pf : p ⊨ f
fc : DefaultFormula n × Bool := f.insertRatUnits c.negate
confirmRupHint_fold_res : Array Assignment × CNF.Clause (PosFin n) × Bool × Bool :=
  Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints
confirmRupHint_success : confirmRupHint_fold_res.snd.snd.fst = true
motive : Nat → Array Assignment × CNF.Clause (PosFin n) × Bool × Bool → Prop := fc.fst.ConfirmRupHintFoldEntailsMotive
h_base : motive 0 (fc.fst.assignments, [], false, false)
h_inductive :
  ∀ (idx : Fin rupHints.size) (acc : Array Assignment × CNF.Clause (PosFin n) × Bool × Bool),
    motive (↑idx) acc →
      fc.fst.ConfirmRupHintFoldEntailsMotive (↑idx + 1) (confirmRupHint fc.fst.clauses acc rupHints[idx])
left✝ : (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst.size = n
h1 :
  Limplies (PosFin n) fc.fst
    (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst
h2 :
  (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).snd.snd.fst = true →
    Incompatible (PosFin n)
      (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst fc.fst
fc_incompatible_confirmRupHint_fold_res :
  Incompatible (PosFin n) fc.fst
    (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst
pc :
  ∀ (x : PosFin n),
    ((x, false) ∈ Clause.toList c → decide (p x = false) = false) ∧
      ((x, true) ∈ Clause.toList c → decide (p x = true) = false)
unsat_c : DefaultClause n
unsat_c_in_fc✝ : unsat_c ∈ fc.fst.toList
p_unsat_c : ¬(p ⊨ unsat_c)
unsat_c_in_fc : unsat_c ∈ List.map Clause.unit c.negate ∨ unsat_c ∈ f.toList
⊢ False

Proof state:
case intro.intro
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.AssignmentsInvariant
c : DefaultClause n
rupHints : Array Nat
p : PosFin n → Bool
pf : p ⊨ f
fc : DefaultFormula n × Bool := f.insertRatUnits c.negate
confirmRupHint_fold_res : Array Assignment × CNF.Clause (PosFin n) × Bool × Bool :=
  Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints
confirmRupHint_success : confirmRupHint_fold_res.snd.snd.fst = true
motive : Nat → Array Assignment × CNF.Clause (PosFin n) × Bool × Bool → Prop := fc.fst.ConfirmRupHintFoldEntailsMotive
h_base : motive 0 (fc.fst.assignments, [], false, false)
h_inductive :
  ∀ (idx : Fin rupHints.size) (acc : Array Assignment × CNF.Clause (PosFin n) × Bool × Bool),
    motive (↑idx) acc →
      fc.fst.ConfirmRupHintFoldEntailsMotive (↑idx + 1) (confirmRupHint fc.fst.clauses acc rupHints[idx])
left✝ : (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst.size = n
h1 :
  Limplies (PosFin n) fc.fst
    (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst
h2 :
  (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).snd.snd.fst = true →
    Incompatible (PosFin n)
      (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst fc.fst
fc_incompatible_confirmRupHint_fold_res :
  Incompatible (PosFin n) fc.fst
    (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst
⊢ p ⊨ c

Tactic:
have fc_unsat :=
  unsat_of_limplies_and_incompatible (PosFin n) fc.1 confirmRupHint_fold_res.1 h1 fc_incompatible_confirmRupHint_fold_res p

Result:
case intro.intro
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.AssignmentsInvariant
c : DefaultClause n
rupHints : Array Nat
p : PosFin n → Bool
pf : p ⊨ f
fc : DefaultFormula n × Bool := f.insertRatUnits c.negate
confirmRupHint_fold_res : Array Assignment × CNF.Clause (PosFin n) × Bool × Bool :=
  Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints
confirmRupHint_success : confirmRupHint_fold_res.snd.snd.fst = true
motive : Nat → Array Assignment × CNF.Clause (PosFin n) × Bool × Bool → Prop := fc.fst.ConfirmRupHintFoldEntailsMotive
h_base : motive 0 (fc.fst.assignments, [], false, false)
h_inductive :
  ∀ (idx : Fin rupHints.size) (acc : Array Assignment × CNF.Clause (PosFin n) × Bool × Bool),
    motive (↑idx) acc →
      fc.fst.ConfirmRupHintFoldEntailsMotive (↑idx + 1) (confirmRupHint fc.fst.clauses acc rupHints[idx])
left✝ : (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst.size = n
h1 :
  Limplies (PosFin n) fc.fst
    (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst
h2 :
  (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).snd.snd.fst = true →
    Incompatible (PosFin n)
      (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst fc.fst
fc_incompatible_confirmRupHint_fold_res :
  Incompatible (PosFin n) fc.fst
    (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst
fc_unsat : ¬(p ⊨ fc.fst)
⊢ p ⊨ c