-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/RupAddSound.lean
theorem sat_of_confirmRupHint_insertRup_fold {n : Nat} (f : DefaultFormula n)
    (f_readyForRupAdd : ReadyForRupAdd f) (c : DefaultClause n) (rupHints : Array Nat)
    (p : PosFin n → Bool) (pf : p ⊨ f) :
    let fc := insertRupUnits 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.inl.intro.inl.intro.intro.inr.intro
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
c : DefaultClause n
rupHints : Array Nat
p : PosFin n → Bool
pf : p ⊨ f
fc : DefaultFormula n × Bool := f.insertRupUnits 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
v : PosFin n
unsat_c_eq : Clause.unit (v, false) = unsat_c
v' : PosFin n
v'_in_c : (v', true) ∈ c.toList
v'_eq_v : v' = v
p_unsat_c :
  ∀ (x : PosFin n),
    ((x, false) ∈ Clause.toList (Clause.unit (v, false)) → ¬p x = false) ∧
      ((x, true) ∈ Clause.toList (Clause.unit (v, false)) → ¬p x = true)
⊢ False

Tactic:
specialize p_unsat_c v

Result:
case neg.intro.intro.inl.intro.inl.intro.intro.inr.intro
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
c : DefaultClause n
rupHints : Array Nat
p : PosFin n → Bool
pf : p ⊨ f
fc : DefaultFormula n × Bool := f.insertRupUnits 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
v : PosFin n
unsat_c_eq : Clause.unit (v, false) = unsat_c
v' : PosFin n
v'_in_c : (v', true) ∈ c.toList
v'_eq_v : v' = v
p_unsat_c :
  ((v, false) ∈ Clause.toList (Clause.unit (v, false)) → ¬p v = false) ∧
    ((v, true) ∈ Clause.toList (Clause.unit (v, false)) → ¬p v = true)
⊢ False

Proof state:
case intro.intro
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
c : DefaultClause n
rupHints : Array Nat
p : PosFin n → Bool
pf : p ⊨ f
fc : DefaultFormula n × Bool := f.insertRupUnits 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
⊢ p ⊨ c

Tactic:
have fc_incompatible_confirmRupHint_fold_res := (h2 confirmRupHint_success)

Result:
case intro.intro
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
c : DefaultClause n
rupHints : Array Nat
p : PosFin n → Bool
pf : p ⊨ f
fc : DefaultFormula n × Bool := f.insertRupUnits 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)
    (Array.foldl (confirmRupHint fc.fst.clauses) (fc.fst.assignments, [], false, false) rupHints).fst fc.fst
⊢ p ⊨ c