-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/RupAddSound.lean
theorem reduce_postcondition {n : Nat} (c : DefaultClause n) (assignment : Array Assignment) :
    (reduce c assignment = reducedToEmpty → Incompatible (PosFin n) c assignment) ∧
    (∀ l : Literal (PosFin n), reduce c assignment = reducedToUnit l → ∀ (p : (PosFin n) → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l)

Proof state:
case intro.right.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := List.toArray c.clause
c_clause_rw : c.clause = c_arr.toList
motive : Nat → ReduceResult (PosFin n) → Prop := ReducePostconditionInductionMotive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.toList
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ p ⊨ c_arr[idx]

Tactic:
rw [hidx]

Result:
case intro.right.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := List.toArray c.clause
c_clause_rw : c.clause = c_arr.toList
motive : Nat → ReduceResult (PosFin n) → Prop := ReducePostconditionInductionMotive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.toList
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ p ⊨ (i, false)

Proof state:
case intro.left.inl.h.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := List.toArray c.clause
c_clause_rw : c.clause = c_arr.toList
motive : Nat → ReduceResult (PosFin n) → Prop := ReducePostconditionInductionMotive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToEmpty
p : PosFin n → Bool
i : PosFin n
pc1 : (i, false) ∈ c_arr.toList
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
h1 : ¬(p ⊨ (i, false))
⊢ False

Tactic:
exact h1 <| of_decide_eq_true pc2

Result:
no goals

Proof state:
case intro.right
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := List.toArray c.clause
c_clause_rw : c.clause = c_arr.toList
motive : Nat → ReduceResult (PosFin n) → Prop := ReducePostconditionInductionMotive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
pc :
  ∃ a,
    (a, false) ∈ Clause.toList c ∧ decide (p a = false) = true ∨
      (a, true) ∈ Clause.toList c ∧ decide (p a = true) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

Tactic:
rcases pc with ⟨i, ⟨pc1, pc2⟩ | ⟨pc1, pc2⟩⟩

Result:
case intro.right.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := List.toArray c.clause
c_clause_rw : c.clause = c_arr.toList
motive : Nat → ReduceResult (PosFin n) → Prop := ReducePostconditionInductionMotive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ Clause.toList c
pc2 : decide (p i = false) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

case intro.right.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := List.toArray c.clause
c_clause_rw : c.clause = c_arr.toList
motive : Nat → ReduceResult (PosFin n) → Prop := ReducePostconditionInductionMotive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ Clause.toList c
pc2 : decide (p i = true) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])