-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/RatAddResult.lean
theorem nodup_insertRatUnits {n : Nat} (f : DefaultFormula n)
    (hf : f.ratUnits = #[] ∧ f.assignments.size = n) (units : CNF.Clause (PosFin n)) :
    ∀ i : Fin (f.insertRatUnits units).1.ratUnits.size, ∀ j : Fin (f.insertRatUnits units).1.ratUnits.size,
      i ≠ j → (f.insertRatUnits units).1.ratUnits[i] ≠ (f.insertRatUnits units).1.ratUnits[j]

Proof state:
case pos
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRatUnits units).fst.ratUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRatUnits units).fst.ratUnits[i] = (li, bi)
hj : (f.insertRatUnits units).fst.ratUnits[j] = (li, bi)
k : Fin (f.insertRatUnits units).fst.ratUnits.size
b : Bool
left✝² : ∃ x, (f.insertRatUnits units).fst.ratUnits[k] = (⟨li.val, ⋯⟩, b)
left✝¹ : (f.insertRatUnits units).fst.assignments[li.val] = addAssignment b f.assignments[li.val]
left✝ : hasAssignment b f.assignments[li.val] = false
h4 :
  ∀ (k_1 : Fin (f.insertRatUnits units).fst.ratUnits.size),
    ¬k_1 = k → ¬(f.insertRatUnits units).fst.ratUnits[k_1].fst.val = li.val
h✝ : i = k
⊢ False

Tactic:
next i_eq_k =>
have j_ne_k : j ≠ k := by rw [← i_eq_k]; exact i_ne_j.symm
specialize h4 j j_ne_k
simp +decide only [hj] at h4

Result:
no goals

Proof state:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRatUnits units).fst.ratUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRatUnits units).fst.ratUnits[i] = (li, bi)
hj : (f.insertRatUnits units).fst.ratUnits[j] = (li, bi)
k1 k2 : Fin (f.insertRatUnits units).fst.ratUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRatUnits units).fst.ratUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRatUnits units).fst.ratUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRatUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
bi_eq_true : bi = true
i_ne_k1 : ¬i = k1
i_ne_k2 : ¬i = k2
h5 : ¬(f.insertRatUnits units).fst.ratUnits[i].fst.val = li.val
⊢ False

Tactic:
simp only [hi, not_true] at h5

Result:
no goals

Proof state:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRatUnits units).fst.ratUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRatUnits units).fst.ratUnits[i] = (li, bi)
hj : (f.insertRatUnits units).fst.ratUnits[j] = (li, bi)
k1 k2 : Fin (f.insertRatUnits units).fst.ratUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRatUnits units).fst.ratUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRatUnits units).fst.ratUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRatUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
h5 :
  ∀ (k : Fin (f.insertRatUnits units).fst.ratUnits.size),
    ¬k = k1 → ¬k = k2 → ¬(f.insertRatUnits units).fst.ratUnits[k].fst.val = li.val
bi_eq_true : bi = true
i_eq_k1 : i = k1
j_ne_k1 : j ≠ k1
⊢ False

Tactic:
by_cases j = k2

Result:
case pos
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRatUnits units).fst.ratUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRatUnits units).fst.ratUnits[i] = (li, bi)
hj : (f.insertRatUnits units).fst.ratUnits[j] = (li, bi)
k1 k2 : Fin (f.insertRatUnits units).fst.ratUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRatUnits units).fst.ratUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRatUnits units).fst.ratUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRatUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
h5 :
  ∀ (k : Fin (f.insertRatUnits units).fst.ratUnits.size),
    ¬k = k1 → ¬k = k2 → ¬(f.insertRatUnits units).fst.ratUnits[k].fst.val = li.val
bi_eq_true : bi = true
i_eq_k1 : i = k1
j_ne_k1 : j ≠ k1
h✝ : j = k2
⊢ False

case neg
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRatUnits units).fst.ratUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRatUnits units).fst.ratUnits[i] = (li, bi)
hj : (f.insertRatUnits units).fst.ratUnits[j] = (li, bi)
k1 k2 : Fin (f.insertRatUnits units).fst.ratUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRatUnits units).fst.ratUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRatUnits units).fst.ratUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRatUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
h5 :
  ∀ (k : Fin (f.insertRatUnits units).fst.ratUnits.size),
    ¬k = k1 → ¬k = k2 → ¬(f.insertRatUnits units).fst.ratUnits[k].fst.val = li.val
bi_eq_true : bi = true
i_eq_k1 : i = k1
j_ne_k1 : j ≠ k1
h✝ : ¬j = k2
⊢ False

Proof state:
case mk.mk.refl.inl.intro
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRatUnits units).fst.ratUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRatUnits units).fst.ratUnits[i] = (li, bi)
hj : (f.insertRatUnits units).fst.ratUnits[j] = (li, bi)
left✝ : (f.insertRatUnits units).fst.assignments[li.val] = f.assignments[li.val]
h2 : ¬(li, bi).fst.val = li.val
⊢ False

Tactic:
contradiction

Result:
no goals

Proof state:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRatUnits units).fst.ratUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRatUnits units).fst.ratUnits[i] = (li, bi)
hj : (f.insertRatUnits units).fst.ratUnits[j] = (li, bi)
k1 k2 : Fin (f.insertRatUnits units).fst.ratUnits.size
li_gt_zero : li.val > 0
h1 : (f.insertRatUnits units).fst.ratUnits[k1] = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRatUnits units).fst.ratUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRatUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
h5 :
  ∀ (k : Fin (f.insertRatUnits units).fst.ratUnits.size),
    ¬k = k1 → ¬k = k2 → ¬(f.insertRatUnits units).fst.ratUnits[k].fst.val = li.val
bi_eq_false : bi = false
i_eq_k2 : i = k2
j_ne_k2 : j ≠ k2
j_eq_k1 : j = k1
⊢ False

Tactic:
rw [← j_eq_k1, hj, bi_eq_false] at h1

Result:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
units : CNF.Clause (PosFin n)
i j : Fin (f.insertRatUnits units).fst.ratUnits.size
i_ne_j : i ≠ j
li : PosFin n
bi : Bool
hi : (f.insertRatUnits units).fst.ratUnits[i] = (li, bi)
hj : (f.insertRatUnits units).fst.ratUnits[j] = (li, bi)
k1 k2 : Fin (f.insertRatUnits units).fst.ratUnits.size
li_gt_zero : li.val > 0
h1 : (li, false) = (⟨li.val, ⋯⟩, true)
h2 : (f.insertRatUnits units).fst.ratUnits[k2] = (⟨li.val, ⋯⟩, false)
h3 : (f.insertRatUnits units).fst.assignments[li.val] = both
h4 : f.assignments[li.val] = unassigned
h5 :
  ∀ (k : Fin (f.insertRatUnits units).fst.ratUnits.size),
    ¬k = k1 → ¬k = k2 → ¬(f.insertRatUnits units).fst.ratUnits[k].fst.val = li.val
bi_eq_false : bi = false
i_eq_k2 : i = k2
j_ne_k2 : j ≠ k2
j_eq_k1 : j = k1
⊢ False