-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/RupAddSound.lean
theorem assignmentsInvariant_insertRupUnits_of_assignmentsInvariant {n : Nat} (f : DefaultFormula n) (f_readyForRupAdd : ReadyForRupAdd f)
    (units : CNF.Clause (PosFin n)) :
    AssignmentsInvariant (insertRupUnits f units).1

Proof state:
case pos.h.left
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
h :
  let assignments := (f.insertRupUnits units).fst.assignments;
  let_fun hsize := ⋯;
  let rupUnits := (f.insertRupUnits units).fst.rupUnits;
  InsertUnitInvariant f.assignments ⋯ rupUnits assignments hsize
hsize : (f.insertRupUnits units).fst.assignments.size = n
i : PosFin n
b : Bool
p : PosFin n → Bool
hp :
  ∀ (x : DefaultClause n),
    (some x ∈ (f.insertRupUnits units).fst.clauses.toList ∨
        (∃ a,
            (a, false) ∈ (f.insertRupUnits units).fst.rupUnits.toList ∧ unit (a, false) = x ∨
              (a, true) ∈ (f.insertRupUnits units).fst.rupUnits.toList ∧ unit (a, true) = x) ∨
          ∃ a,
            (a, false) ∈ (f.insertRupUnits units).fst.ratUnits.toList ∧ unit (a, false) = x ∨
              (a, true) ∈ (f.insertRupUnits units).fst.ratUnits.toList ∧ unit (a, true) = x) →
      ∃ a, (a, false) ∈ Clause.toList x ∧ decide (p a = false) = true ∨ (a, true) ∈ Clause.toList x ∧ p a = true
pf : p ⊨ f
j : Fin (f.insertRupUnits units).fst.rupUnits.size
b' : Bool
hb : hasAssignment b (addAssignment b' f.assignments[↑⟨i.val, ⋯⟩]) = true
i_gt_zero : ↑⟨i.val, ⋯⟩ > 0
h1✝ : (f.insertRupUnits units).fst.rupUnits[j] = (⟨↑⟨i.val, ⋯⟩, ⋯⟩, b')
h2 : (f.insertRupUnits units).fst.assignments[↑⟨i.val, ⋯⟩] = addAssignment b' f.assignments[↑⟨i.val, ⋯⟩]
h3 : ¬hasAssignment b' f.assignments[↑⟨i.val, ⋯⟩] = true
h4 :
  ∀ (k : Fin (f.insertRupUnits units).fst.rupUnits.size),
    k ≠ j → (f.insertRupUnits units).fst.rupUnits[k].fst.val ≠ ↑⟨i.val, ⋯⟩
b_eq_b' : b = b'
j_unit : DefaultClause n := unit (f.insertRupUnits units).fst.rupUnits[j]
j_unit_def : j_unit = unit (f.insertRupUnits units).fst.rupUnits[j]
hb' : b' = true
h1 : (f.insertRupUnits units).fst.rupUnits[j] = (i, true)
⊢ (f.insertRupUnits units).fst.rupUnits[j] ∈ (f.insertRupUnits units).fst.rupUnits.toList

Tactic:
apply Array.getElem_mem_toList

Result:
no goals

Proof state:
case inl
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
h :
  let assignments := (f.insertRupUnits units).fst.assignments;
  let_fun hsize := ⋯;
  let rupUnits := (f.insertRupUnits units).fst.rupUnits;
  InsertUnitInvariant f.assignments ⋯ rupUnits assignments hsize
hsize : (f.insertRupUnits units).fst.assignments.size = n
i : PosFin n
b : Bool
hb : hasAssignment b (f.insertRupUnits units).fst.assignments[i.val] = true
p : PosFin n → Bool
c : DefaultClause n
cf : some c ∈ f.clauses.toList
hp : ∃ a, (a, false) ∈ Clause.toList c ∧ decide (p a = false) = true ∨ (a, true) ∈ Clause.toList c ∧ p a = true
⊢ ∃ a, (a, false) ∈ Clause.toList c ∧ decide (p a = false) = true ∨ (a, true) ∈ Clause.toList c ∧ p a = true

Tactic:
exact hp

Result:
no goals

Proof state:
case inl.intro
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
h :
  let assignments := (f.insertRupUnits units).fst.assignments;
  let_fun hsize := ⋯;
  let rupUnits := (f.insertRupUnits units).fst.rupUnits;
  InsertUnitInvariant f.assignments ⋯ rupUnits assignments hsize
hsize : (f.insertRupUnits units).fst.assignments.size = n
i : PosFin n
b : Bool
hb : hasAssignment b f.assignments[↑⟨i.val, ⋯⟩] = true
p : PosFin n → Bool
hp :
  ∀ (x : DefaultClause n),
    (some x ∈ (f.insertRupUnits units).fst.clauses.toList ∨
        (∃ a,
            (a, false) ∈ (f.insertRupUnits units).fst.rupUnits.toList ∧ unit (a, false) = x ∨
              (a, true) ∈ (f.insertRupUnits units).fst.rupUnits.toList ∧ unit (a, true) = x) ∨
          ∃ a,
            (a, false) ∈ (f.insertRupUnits units).fst.ratUnits.toList ∧ unit (a, false) = x ∨
              (a, true) ∈ (f.insertRupUnits units).fst.ratUnits.toList ∧ unit (a, true) = x) →
      ∃ a, (a, false) ∈ Clause.toList x ∧ decide (p a = false) = true ∨ (a, true) ∈ Clause.toList x ∧ p a = true
pf : p ⊨ f
h1 : (f.insertRupUnits units).fst.assignments[↑⟨i.val, ⋯⟩] = f.assignments[↑⟨i.val, ⋯⟩]
h2 :
  ∀ (j : Fin (f.insertRupUnits units).fst.rupUnits.size), (f.insertRupUnits units).fst.rupUnits[j].fst.val ≠ ↑⟨i.val, ⋯⟩
⊢ p ⊨ (i, b)

Tactic:
exact (assignmentsInvariant_of_strongAssignmentsInvariant f f_readyForRupAdd.2).2 i b hb p pf

Result:
no goals

Proof state:
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
h :
  let assignments := (f.insertRupUnits units).fst.assignments;
  let_fun hsize := ⋯;
  let rupUnits := (f.insertRupUnits units).fst.rupUnits;
  InsertUnitInvariant f.assignments ⋯ rupUnits assignments hsize
hsize : (f.insertRupUnits units).fst.assignments.size = n
i : PosFin n
b : Bool
hb : hasAssignment b (f.insertRupUnits units).fst.assignments[i.val] = true
p : PosFin n → Bool
hp :
  ∀ (x : DefaultClause n),
    (some x ∈ (f.insertRupUnits units).fst.clauses.toList ∨
        (∃ a,
            (a, false) ∈ (f.insertRupUnits units).fst.rupUnits.toList ∧ unit (a, false) = x ∨
              (a, true) ∈ (f.insertRupUnits units).fst.rupUnits.toList ∧ unit (a, true) = x) ∨
          ∃ a,
            (a, false) ∈ (f.insertRupUnits units).fst.ratUnits.toList ∧ unit (a, false) = x ∨
              (a, true) ∈ (f.insertRupUnits units).fst.ratUnits.toList ∧ unit (a, true) = x) →
      ∃ a, (a, false) ∈ Clause.toList x ∧ decide (p a = false) = true ∨ (a, true) ∈ Clause.toList x ∧ p a = true
⊢ (f.toList.all fun s => decide ((List.any (Clause.toList s) fun l => decide (p l.fst = l.snd)) = true)) = true

Tactic:
simp only [toList, List.append_assoc, List.any_eq_true, Prod.exists, Bool.exists_bool,
  Bool.decide_coe, List.all_eq_true, List.mem_append, List.mem_filterMap, id_eq, exists_eq_right, List.mem_map]

Result:
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
h :
  let assignments := (f.insertRupUnits units).fst.assignments;
  let_fun hsize := ⋯;
  let rupUnits := (f.insertRupUnits units).fst.rupUnits;
  InsertUnitInvariant f.assignments ⋯ rupUnits assignments hsize
hsize : (f.insertRupUnits units).fst.assignments.size = n
i : PosFin n
b : Bool
hb : hasAssignment b (f.insertRupUnits units).fst.assignments[i.val] = true
p : PosFin n → Bool
hp :
  ∀ (x : DefaultClause n),
    (some x ∈ (f.insertRupUnits units).fst.clauses.toList ∨
        (∃ a,
            (a, false) ∈ (f.insertRupUnits units).fst.rupUnits.toList ∧ unit (a, false) = x ∨
              (a, true) ∈ (f.insertRupUnits units).fst.rupUnits.toList ∧ unit (a, true) = x) ∨
          ∃ a,
            (a, false) ∈ (f.insertRupUnits units).fst.ratUnits.toList ∧ unit (a, false) = x ∨
              (a, true) ∈ (f.insertRupUnits units).fst.ratUnits.toList ∧ unit (a, true) = x) →
      ∃ a, (a, false) ∈ Clause.toList x ∧ decide (p a = false) = true ∨ (a, true) ∈ Clause.toList x ∧ p a = true
⊢ ∀ (x : DefaultClause n),
    (some x ∈ f.clauses.toList ∨
        (∃ a,
            (a, false) ∈ f.rupUnits.toList ∧ unit (a, false) = x ∨ (a, true) ∈ f.rupUnits.toList ∧ unit (a, true) = x) ∨
          ∃ a,
            (a, false) ∈ f.ratUnits.toList ∧ unit (a, false) = x ∨ (a, true) ∈ f.ratUnits.toList ∧ unit (a, true) = x) →
      ∃ a, (a, false) ∈ Clause.toList x ∧ decide (p a = false) = true ∨ (a, true) ∈ Clause.toList x ∧ p a = true