-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/RupAddResult.lean
theorem nodup_insertRupUnits {n : Nat} (f : DefaultFormula n) (f_readyForRupAdd : ReadyForRupAdd f)
    (units : CNF.Clause (PosFin n)) :
      ∀ i : Fin (f.insertRupUnits units).1.rupUnits.size, ∀ j : Fin (f.insertRupUnits units).1.rupUnits.size,
      i ≠ j → (f.insertRupUnits units).1.rupUnits[i] ≠ (f.insertRupUnits units).1.rupUnits[j]

Proof state:
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRupUnits units).fst.rupUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRupUnits units).fst.rupUnits[i] = (li, bi)
lj : PosFin n
bj : Bool
hj : (f.insertRupUnits units).fst.rupUnits[j] = (lj, bj)
li_eq_lj : li = lj
bi_eq_bj : bi = bj
k1 k2 : Fin (f.insertRupUnits units).fst.rupUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRupUnits units).fst.rupUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRupUnits units).fst.rupUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRupUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
bi_eq_true : bi = true
i_eq_k1 : i = k1
j_ne_k1 : j ≠ k1
j_ne_k2 : ¬j = k2
h5 : ¬(lj, bj).fst.val = lj.val
⊢ False

Tactic:
simp +decide only at h5

Result:
no goals

Proof state:
case neg
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRupUnits units).fst.rupUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRupUnits units).fst.rupUnits[i] = (li, bi)
lj : PosFin n
bj : Bool
hj : (f.insertRupUnits units).fst.rupUnits[j] = (lj, bj)
li_eq_lj : li = lj
bi_eq_bj : bi = bj
k1 k2 : Fin (f.insertRupUnits units).fst.rupUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRupUnits units).fst.rupUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRupUnits units).fst.rupUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRupUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
h5 :
  ∀ (k : Fin (f.insertRupUnits units).fst.rupUnits.size),
    ¬k = k1 → ¬k = k2 → ¬(f.insertRupUnits units).fst.rupUnits[k].fst.val = li.val
bi_eq_false : bi = false
i_eq_k2 : i = k2
j_ne_k2 : j ≠ k2
h✝ : ¬j = k1
⊢ False

Tactic:
next j_ne_k1 =>
specialize h5 j j_ne_k1 j_ne_k2
rw [hj, li_eq_lj] at h5
simp +decide only at h5

Result:
no goals

Proof state:
case mk.mk.intro
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRupUnits units).fst.rupUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRupUnits units).fst.rupUnits[i] = (li, bi)
lj : PosFin n
bj : Bool
hj : (f.insertRupUnits units).fst.rupUnits[j] = (lj, bj)
li_eq_lj : li = lj
bi_eq_bj : bi = bj
h :
  ((f.insertRupUnits units).fst.assignments[li.val] = f.assignments[li.val] ∧
      ∀ (j : Fin (f.insertRupUnits units).fst.rupUnits.size),
        ¬(f.insertRupUnits units).fst.rupUnits[j].fst.val = li.val) ∨
    (∃ j b,
        (∃ x, (f.insertRupUnits units).fst.rupUnits[j] = (⟨li.val, ⋯⟩, b)) ∧
          (f.insertRupUnits units).fst.assignments[li.val] = addAssignment b f.assignments[li.val] ∧
            hasAssignment b f.assignments[li.val] = false ∧
              ∀ (k : Fin (f.insertRupUnits units).fst.rupUnits.size),
                ¬k = j → ¬(f.insertRupUnits units).fst.rupUnits[k].fst.val = li.val) ∨
      ∃ j1 j2 h,
        (f.insertRupUnits units).fst.rupUnits[j1] = (⟨li.val, ⋯⟩, true) ∧
          (f.insertRupUnits units).fst.rupUnits[j2] = (⟨li.val, ⋯⟩, false) ∧
            (f.insertRupUnits units).fst.assignments[li.val] = both ∧
              f.assignments[li.val] = unassigned ∧
                ∀ (k : Fin (f.insertRupUnits units).fst.rupUnits.size),
                  ¬k = j1 → ¬k = j2 → ¬(f.insertRupUnits units).fst.rupUnits[k].fst.val = li.val
⊢ False

Tactic:
rcases h with ⟨_, h2⟩ | ⟨k, b, _, _, _, h4⟩ | ⟨k1, k2, li_gt_zero, h1, h2, h3, h4, h5⟩

Result:
case mk.mk.intro.inl.intro
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRupUnits units).fst.rupUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRupUnits units).fst.rupUnits[i] = (li, bi)
lj : PosFin n
bj : Bool
hj : (f.insertRupUnits units).fst.rupUnits[j] = (lj, bj)
li_eq_lj : li = lj
bi_eq_bj : bi = bj
left✝ : (f.insertRupUnits units).fst.assignments[li.val] = f.assignments[li.val]
h2 : ∀ (j : Fin (f.insertRupUnits units).fst.rupUnits.size), ¬(f.insertRupUnits units).fst.rupUnits[j].fst.val = li.val
⊢ False

case mk.mk.intro.inr.inl.intro.intro.intro.intro.intro
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRupUnits units).fst.rupUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRupUnits units).fst.rupUnits[i] = (li, bi)
lj : PosFin n
bj : Bool
hj : (f.insertRupUnits units).fst.rupUnits[j] = (lj, bj)
li_eq_lj : li = lj
bi_eq_bj : bi = bj
k : Fin (f.insertRupUnits units).fst.rupUnits.size
b : Bool
left✝² : ∃ x, (f.insertRupUnits units).fst.rupUnits[k] = (⟨li.val, ⋯⟩, b)
left✝¹ : (f.insertRupUnits units).fst.assignments[li.val] = addAssignment b f.assignments[li.val]
left✝ : hasAssignment b f.assignments[li.val] = false
h4 :
  ∀ (k_1 : Fin (f.insertRupUnits units).fst.rupUnits.size),
    ¬k_1 = k → ¬(f.insertRupUnits units).fst.rupUnits[k_1].fst.val = li.val
⊢ False

case mk.mk.intro.inr.inr.intro.intro.intro.intro.intro.intro.intro
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRupUnits units).fst.rupUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRupUnits units).fst.rupUnits[i] = (li, bi)
lj : PosFin n
bj : Bool
hj : (f.insertRupUnits units).fst.rupUnits[j] = (lj, bj)
li_eq_lj : li = lj
bi_eq_bj : bi = bj
k1 k2 : Fin (f.insertRupUnits units).fst.rupUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRupUnits units).fst.rupUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRupUnits units).fst.rupUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRupUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
h5 :
  ∀ (k : Fin (f.insertRupUnits units).fst.rupUnits.size),
    ¬k = k1 → ¬k = k2 → ¬(f.insertRupUnits units).fst.rupUnits[k].fst.val = li.val
⊢ False

Proof state:
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRupUnits units).fst.rupUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRupUnits units).fst.rupUnits[i] = (li, bi)
lj : PosFin n
bj : Bool
hj : (f.insertRupUnits units).fst.rupUnits[j] = (lj, bj)
li_eq_lj : li = lj
bi_eq_bj : bi = bj
k1 k2 : Fin (f.insertRupUnits units).fst.rupUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRupUnits units).fst.rupUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRupUnits units).fst.rupUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRupUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
bi_eq_false : bi = false
i_ne_k2 : ¬i = k2
i_ne_k1 : ¬i = k1
h5 : ¬(f.insertRupUnits units).fst.rupUnits[i].fst.val = li.val
⊢ False

Tactic:
rw [hi] at h5

Result:
n : Nat
f : DefaultFormula n
f_readyForRupAdd : f.ReadyForRupAdd
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRupUnits units).fst.rupUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRupUnits units).fst.rupUnits[i] = (li, bi)
lj : PosFin n
bj : Bool
hj : (f.insertRupUnits units).fst.rupUnits[j] = (lj, bj)
li_eq_lj : li = lj
bi_eq_bj : bi = bj
k1 k2 : Fin (f.insertRupUnits units).fst.rupUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRupUnits units).fst.rupUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRupUnits units).fst.rupUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRupUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
bi_eq_false : bi = false
i_ne_k2 : ¬i = k2
i_ne_k1 : ¬i = k1
h5 : ¬(li, bi).fst.val = li.val
⊢ False