-- 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, 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
i_in_bounds : i.val < f.assignments.size
ib_ne_c : ¬(i, b) = (l, false)
hb' : hasAssignment b f.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)

Tactic:
rcases hf with hf | hf

Result:
case inl
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
i_in_bounds : i.val < f.assignments.size
ib_ne_c : ¬(i, b) = (l, false)
hb' : hasAssignment b f.assignments[i.val] = true
hf : some (unit (i, b)) ∈ f.clauses.toList
⊢ (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)

case inr
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
i_in_bounds : i.val < f.assignments.size
ib_ne_c : ¬(i, b) = (l, false)
hb' : hasAssignment b f.assignments[i.val] = true
hf :
  (∃ 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, 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)
⊢ (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)

Tactic:
apply Or.inl ∘ Or.inr

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_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, false)
⊢ { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
      assignments := f.assignments.modify l.val addNegAssignment }.ReadyForRupAdd

Tactic:
have hsize : (Array.modify f.assignments l.1 addNegAssignment).size = n := by
  rw [Array.size_modify, f_readyForRupAdd.2.1]

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
⊢ { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
      assignments := f.assignments.modify l.val addNegAssignment }.ReadyForRupAdd

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)
hb' : hasAssignment b f.assignments[i.val] = true
⊢ unit (i, b) ∈
    { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
        assignments := f.assignments.modify l.val addPosAssignment }.toList

Tactic:
specialize hf 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, 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
i_in_bounds : i.val < f.assignments.size
ib_ne_c : ¬(i, b) = (l, true)
hb' : hasAssignment b f.assignments[i.val] = true
hf : unit (i, b) ∈ f.toList
⊢ unit (i, b) ∈
    { clauses := f.clauses.push (some c), rupUnits := f.rupUnits, ratUnits := f.ratUnits,
        assignments := f.assignments.modify l.val addPosAssignment }.toList