-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/Lemmas.lean
theorem readyForRupAdd_insert {n : Nat} (f : DefaultFormula n) (c : DefaultClause n) :
    ReadyForRupAdd f → ReadyForRupAdd (insert f c)

Proof state:
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
l : PosFin n
hc : c.isUnit = some (l, true)
hsize : (f.assignments.modify l.val addPosAssignment).size = n
i : PosFin n
b : Bool
hb : hasAssignment b (f.assignments.modify l.val addPosAssignment)[i.val] = true
hf : hasAssignment b f.assignments[i.val] = true → unit (i, b) ∈ f.toList
i_in_bounds : i.val < f.assignments.size
ib_eq_c : (i, b) = (l, true)
⊢ unit (i, b) = c

Tactic:
rw [isUnit_iff, DefaultClause.toList, ← ib_eq_c] at hc

Result:
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
l : PosFin n
hsize : (f.assignments.modify l.val addPosAssignment).size = n
i : PosFin n
b : Bool
hc : c.clause = [(i, b)]
hb : hasAssignment b (f.assignments.modify l.val addPosAssignment)[i.val] = true
hf : hasAssignment b f.assignments[i.val] = true → unit (i, b) ∈ f.toList
i_in_bounds : i.val < f.assignments.size
ib_eq_c : (i, b) = (l, true)
⊢ unit (i, b) = c

Proof state:
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
l : PosFin n
hc : c.isUnit = some (l, true)
hsize : (f.assignments.modify l.val addPosAssignment).size = n
i : PosFin n
b : Bool
hb : hasAssignment b (f.assignments.modify l.val addPosAssignment)[i.val] = true
hf : hasAssignment b f.assignments[i.val] = true → unit (i, b) ∈ f.toList
i_in_bounds : i.val < f.assignments.size
ib_ne_c : ¬(i, b) = (l, true)
l_eq_i : l.val = i.val
b_eq_false : ¬b = true
⊢ b = false

Tactic:
simp only [Bool.not_eq_true] at b_eq_false

Result:
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
l : PosFin n
hc : c.isUnit = some (l, true)
hsize : (f.assignments.modify l.val addPosAssignment).size = n
i : PosFin n
b : Bool
hb : hasAssignment b (f.assignments.modify l.val addPosAssignment)[i.val] = true
hf : hasAssignment b f.assignments[i.val] = true → unit (i, b) ∈ f.toList
i_in_bounds : i.val < f.assignments.size
ib_ne_c : ¬(i, b) = (l, true)
l_eq_i : l.val = i.val
b_eq_false : b = false
⊢ b = false

Proof state:
case h_1
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
heq✝ : c.isUnit = none
i : PosFin n
b : Bool
hb :
  hasAssignment b
      { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
            assignments := f.assignments }.assignments[i.val] =
    true
hf :
  some (unit (i, b)) ∈ f.clauses.toList ∨
    (∃ a,
        (a, false) ∈ f.rupUnits.toList ∧ unit (a, false) = unit (i, b) ∨
          (a, true) ∈ f.rupUnits.toList ∧ unit (a, true) = unit (i, b)) ∨
      ∃ a,
        (a, false) ∈ f.ratUnits.toList ∧ unit (a, false) = unit (i, b) ∨
          (a, true) ∈ f.ratUnits.toList ∧ unit (a, true) = unit (i, b)
⊢ unit (i, b) ∈
    { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
        assignments := f.assignments }.toList

Tactic:
simp only [toList, Array.push_toList, List.append_assoc, List.mem_append, List.mem_filterMap,
  List.mem_singleton, id_eq, exists_eq_right, Option.some.injEq, List.mem_map, Prod.exists, Bool.exists_bool]

Result:
case h_1
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
heq✝ : c.isUnit = none
i : PosFin n
b : Bool
hb :
  hasAssignment b
      { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
            assignments := f.assignments }.assignments[i.val] =
    true
hf :
  some (unit (i, b)) ∈ f.clauses.toList ∨
    (∃ a,
        (a, false) ∈ f.rupUnits.toList ∧ unit (a, false) = unit (i, b) ∨
          (a, true) ∈ f.rupUnits.toList ∧ unit (a, true) = unit (i, b)) ∨
      ∃ a,
        (a, false) ∈ f.ratUnits.toList ∧ unit (a, false) = unit (i, b) ∨
          (a, true) ∈ f.ratUnits.toList ∧ unit (a, true) = unit (i, b)
⊢ (some (unit (i, b)) ∈ f.clauses.toList ∨ unit (i, b) = c) ∨
    (∃ a,
        (a, false) ∈ f.rupUnits.toList ∧ unit (a, false) = unit (i, b) ∨
          (a, true) ∈ f.rupUnits.toList ∧ unit (a, true) = unit (i, b)) ∨
      ∃ a,
        (a, false) ∈ f.ratUnits.toList ∧ unit (a, false) = unit (i, b) ∨
          (a, true) ∈ f.ratUnits.toList ∧ unit (a, true) = unit (i, b)

Proof state:
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
l : PosFin n
hc : c.isUnit = some (l, false)
hsize : (f.assignments.modify l.val addNegAssignment).size = n
i : PosFin n
b : Bool
hb :
  hasAssignment b
      { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
            assignments := f.assignments.modify l.val addNegAssignment }.assignments[i.val] =
    true
hf : hasAssignment b f.assignments[i.val] = true → unit (i, b) ∈ f.toList
i_in_bounds : i.val < f.assignments.size
⊢ unit (i, b) ∈
    { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
        assignments := f.assignments.modify l.val addNegAssignment }.toList

Tactic:
simp only at hb

Result:
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
l : PosFin n
hc : c.isUnit = some (l, false)
hsize : (f.assignments.modify l.val addNegAssignment).size = n
i : PosFin n
b : Bool
hb : hasAssignment b (f.assignments.modify l.val addNegAssignment)[i.val] = true
hf : hasAssignment b f.assignments[i.val] = true → unit (i, b) ∈ f.toList
i_in_bounds : i.val < f.assignments.size
⊢ unit (i, b) ∈
    { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
        assignments := f.assignments.modify l.val addNegAssignment }.toList

Proof state:
case h_1
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
heq✝ : c.isUnit = none
⊢ { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
      assignments := f.assignments }.ReadyForRupAdd

Tactic:
refine ⟨f_readyForRupAdd.1, f_readyForRupAdd.2.1, ?_⟩

Result:
case h_1
n : Nat
f : DefaultFormula n
c : DefaultClause n
f_readyForRupAdd : f.ReadyForRupAdd
x✝ : Option (Literal (PosFin n))
heq✝ : c.isUnit = none
⊢ ∀ (i : PosFin n) (b : Bool),
    hasAssignment b
          { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
                assignments := f.assignments }.assignments[i.val] =
        true →
      unit (i, b) ∈
        { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
            assignments := f.assignments }.toList