-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/Lemmas.lean
theorem deleteOne_preserves_strongAssignmentsInvariant {n : Nat} (f : DefaultFormula n) (id : Nat) :
    StrongAssignmentsInvariant f → StrongAssignmentsInvariant (deleteOne f id)

Proof state:
n : Nat
f : DefaultFormula n
id : Nat
hsize : f.assignments.size = n
hsize' : (f.deleteOne id).assignments.size = n
i : PosFin n
b : Bool
i_in_bounds : i.val < f.assignments.size
c : DefaultClause n
heq : f.clauses[id]! = some c
l : Literal (PosFin n)
hl : c = { clause := [l], nodupkey := ⋯, nodup := ⋯ }
l_eq_i : l.fst.val = i.val
l_ne_b : l.snd = !b
hb✝ : hasAssignment b (removeAssignment (!b) f.assignments[i.val]) = true
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.set! id none).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)

Tactic:
rcases hf with hf | hf

Result:
case inl
n : Nat
f : DefaultFormula n
id : Nat
hsize : f.assignments.size = n
hsize' : (f.deleteOne id).assignments.size = n
i : PosFin n
b : Bool
i_in_bounds : i.val < f.assignments.size
c : DefaultClause n
heq : f.clauses[id]! = some c
l : Literal (PosFin n)
hl : c = { clause := [l], nodupkey := ⋯, nodup := ⋯ }
l_eq_i : l.fst.val = i.val
l_ne_b : l.snd = !b
hb✝ : hasAssignment b (removeAssignment (!b) f.assignments[i.val]) = true
hb : hasAssignment b f.assignments[i.val] = true
hf : some (unit (i, b)) ∈ f.clauses.toList
⊢ some (unit (i, b)) ∈ (f.clauses.set! id none).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)

case inr
n : Nat
f : DefaultFormula n
id : Nat
hsize : f.assignments.size = n
hsize' : (f.deleteOne id).assignments.size = n
i : PosFin n
b : Bool
i_in_bounds : i.val < f.assignments.size
c : DefaultClause n
heq : f.clauses[id]! = some c
l : Literal (PosFin n)
hl : c = { clause := [l], nodupkey := ⋯, nodup := ⋯ }
l_eq_i : l.fst.val = i.val
l_ne_b : l.snd = !b
hb✝ : hasAssignment b (removeAssignment (!b) f.assignments[i.val]) = true
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.set! id none).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)

Proof state:
case inl.h
n : Nat
f : DefaultFormula n
id : Nat
hsize : f.assignments.size = n
hsize' : (f.deleteOne id).assignments.size = n
i : PosFin n
b : Bool
i_in_bounds : i.val < f.assignments.size
c : DefaultClause n
heq : f.clauses[id]! = some c
l : Literal (PosFin n)
hl : c = { clause := [l], nodupkey := ⋯, nodup := ⋯ }
l_eq_i : l.fst.val = i.val
l_ne_b : l.snd = !b
hb✝ : hasAssignment b (removeAssignment (!b) f.assignments[i.val]) = true
hb : hasAssignment b f.assignments[i.val] = true
hf : some (unit (i, b)) ∈ f.clauses.toList
⊢ some (unit (i, b)) ∈ (if h : id < f.clauses.size then f.clauses.set id none h else f.clauses).toList

Tactic:
split

Result:
case inl.h.isTrue
n : Nat
f : DefaultFormula n
id : Nat
hsize : f.assignments.size = n
hsize' : (f.deleteOne id).assignments.size = n
i : PosFin n
b : Bool
i_in_bounds : i.val < f.assignments.size
c : DefaultClause n
heq : f.clauses[id]! = some c
l : Literal (PosFin n)
hl : c = { clause := [l], nodupkey := ⋯, nodup := ⋯ }
l_eq_i : l.fst.val = i.val
l_ne_b : l.snd = !b
hb✝ : hasAssignment b (removeAssignment (!b) f.assignments[i.val]) = true
hb : hasAssignment b f.assignments[i.val] = true
hf : some (unit (i, b)) ∈ f.clauses.toList
h✝ : id < f.clauses.size
⊢ some (unit (i, b)) ∈ (f.clauses.set id none h✝).toList

case inl.h.isFalse
n : Nat
f : DefaultFormula n
id : Nat
hsize : f.assignments.size = n
hsize' : (f.deleteOne id).assignments.size = n
i : PosFin n
b : Bool
i_in_bounds : i.val < f.assignments.size
c : DefaultClause n
heq : f.clauses[id]! = some c
l : Literal (PosFin n)
hl : c = { clause := [l], nodupkey := ⋯, nodup := ⋯ }
l_eq_i : l.fst.val = i.val
l_ne_b : l.snd = !b
hb✝ : hasAssignment b (removeAssignment (!b) f.assignments[i.val]) = true
hb : hasAssignment b f.assignments[i.val] = true
hf : some (unit (i, b)) ∈ f.clauses.toList
h✝ : ¬id < f.clauses.size
⊢ some (unit (i, b)) ∈ f.clauses.toList

Proof state:
case neg
n : Nat
f : DefaultFormula n
id : Nat
hsize : f.assignments.size = n
hf : ∀ (i : PosFin n) (b : Bool), hasAssignment b f.assignments[i.val] = true → unit (i, b) ∈ f.toList
hsize' : (f.deleteOne id).assignments.size = n
i : PosFin n
b : Bool
hb : hasAssignment b (f.deleteOne id).assignments[i.val] = true
i_in_bounds : i.val < f.assignments.size
c : DefaultClause n
heq : f.clauses[id]! = some c
x✝² : Option (DefaultClause n)
val✝ : DefaultClause n
x✝¹ :
  ∀ (l : Literal (PosFin n)) (nodupkey : ∀ (l_1 : PosFin n), ¬(l_1, true) ∈ [l] ∨ ¬(l_1, false) ∈ [l])
    (nodup : [l].Nodup), val✝ = { clause := [l], nodupkey := nodupkey, nodup := nodup } → False
heq✝ : some c = some val✝
x✝ : Option (DefaultClause n)
l : Literal (PosFin n)
nodupkey✝ : ∀ (l_1 : PosFin n), ¬(l_1, true) ∈ [l] ∨ ¬(l_1, false) ∈ [l]
nodup✝ : [l].Nodup
heq2 : c = { clause := [l], nodupkey := nodupkey✝, nodup := nodup✝ }
hl : ¬l = (l.fst, false) ∧ ¬l = (l.fst, true)
hl2 : l.snd = false
⊢ { clauses := f.clauses.set! id none, rupUnits := f.rupUnits, ratUnits := f.ratUnits,
      assignments := f.assignments.modify l.fst.val (removeAssignment l.snd) } =
    { clauses := f.clauses.set! id none, rupUnits := f.rupUnits, ratUnits := f.ratUnits, assignments := f.assignments }

Tactic:
simp only [← hl2, not_true, false_and] at hl

Result:
no goals