-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/RupAddResult.lean
theorem clear_insert_inductive_case {n : Nat} (f : DefaultFormula n) (f_assignments_size : f.assignments.size = n)
    (units : Array (Literal (PosFin n))) (units_nodup : ∀ i : Fin units.size, ∀ j : Fin units.size, i ≠ j → units[i] ≠ units[j])
    (idx : Fin units.size) (assignments : Array Assignment)
    (ih : ClearInsertInductionMotive f f_assignments_size units idx.1 assignments) :
    ClearInsertInductionMotive f f_assignments_size units (idx.1 + 1) (clearUnit assignments units[idx])

Proof state:
case h.right
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
units : Array (Literal (PosFin n))
units_nodup : ∀ (i j : Fin units.size), i ≠ j → units[i] ≠ units[j]
idx : Fin units.size
assignments : Array Assignment
hsize : assignments.size = n
hsize' : (clearUnit assignments units[idx]).size = n
i : Fin n
j : Fin units.size
j_ge_idx : ↑j ≥ ↑idx
b : Bool
i_gt_zero : ↑i > 0
ih1 : units[↑j] = (⟨↑i, ⋯⟩, b)
ih2 : assignments[↑i] = addAssignment b f.assignments[↑i]
ih3 : ¬hasAssignment b f.assignments[↑i] = true
ih4 : ∀ (k : Fin units.size), ↑k ≥ ↑idx → ¬k = j → ¬units[↑k].fst.val = ↑i
idx_eq_j : idx = j
⊢ ∀ (j : Fin units.size), ↑j ≥ ↑idx + 1 → units[j].fst.val ≠ ↑i

Tactic:
intro k k_ge_idx_add_one

Result:
case h.right
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
units : Array (Literal (PosFin n))
units_nodup : ∀ (i j : Fin units.size), i ≠ j → units[i] ≠ units[j]
idx : Fin units.size
assignments : Array Assignment
hsize : assignments.size = n
hsize' : (clearUnit assignments units[idx]).size = n
i : Fin n
j : Fin units.size
j_ge_idx : ↑j ≥ ↑idx
b : Bool
i_gt_zero : ↑i > 0
ih1 : units[↑j] = (⟨↑i, ⋯⟩, b)
ih2 : assignments[↑i] = addAssignment b f.assignments[↑i]
ih3 : ¬hasAssignment b f.assignments[↑i] = true
ih4 : ∀ (k : Fin units.size), ↑k ≥ ↑idx → ¬k = j → ¬units[↑k].fst.val = ↑i
idx_eq_j : idx = j
k : Fin units.size
k_ge_idx_add_one : ↑k ≥ ↑idx + 1
⊢ units[k].fst.val ≠ ↑i

Proof state:
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
units : Array (Literal (PosFin n))
units_nodup : ∀ (i j : Fin units.size), i ≠ j → units[i] ≠ units[j]
idx : Fin units.size
assignments : Array Assignment
hsize : assignments.size = n
hsize' : (clearUnit assignments units[idx]).size = n
i : Fin n
j1 : Fin units.size
j1_ge_idx : ↑j1 ≥ ↑idx
j2 : Fin units.size
j2_ge_idx : ↑j2 ≥ ↑idx
i_gt_zero : ↑i > 0
ih1 : units[↑j1] = (⟨↑i, ⋯⟩, true)
ih2 : units[↑j2] = (⟨↑i, ⋯⟩, false)
ih3 : assignments[↑i] = both
ih4 : f.assignments[↑i] = unassigned
ih5 : ∀ (k : Fin units.size), ↑k ≥ ↑idx → ¬k = j1 → ¬k = j2 → ¬units[↑k].fst.val = ↑i
idx_eq_j1 : idx = j1
idx_ne_j2 : idx ≠ j2
k : Fin units.size
k_ge_idx_add_one : ↑k ≥ ↑idx + 1
k_ne_j2 : k ≠ j2
h1 : units[k].fst.val = ↑i
h2 : units[↑k].snd = true
k_ne_j1 : k ≠ j1
h3 : ¬units[↑k] = (⟨units[↑k].fst.val, ⋯⟩, units[↑k].snd)
⊢ False

Tactic:
exact h3 rfl

Result:
no goals

Proof state:
case left.a
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
units : Array (Literal (PosFin n))
units_nodup : ∀ (i j : Fin units.size), i ≠ j → units[i] ≠ units[j]
idx : Fin units.size
assignments : Array Assignment
hsize : assignments.size = n
hsize' : (clearUnit assignments units[idx]).size = n
i : Fin n
j1 : Fin units.size
j1_ge_idx : ↑j1 ≥ ↑idx
j2 : Fin units.size
j2_ge_idx : ↑j2 ≥ ↑idx
i_gt_zero : ↑i > 0
ih1 : units[↑j1] = (⟨↑i, ⋯⟩, true)
ih2 : units[↑j2] = (⟨↑i, ⋯⟩, false)
ih3 : assignments[↑i] = both
ih4 : f.assignments[↑i] = unassigned
ih5 : ∀ (k : Fin units.size), ↑k ≥ ↑idx → ¬k = j1 → ¬k = j2 → ¬units[↑k].fst.val = ↑i
idx_ne_j1 : ¬idx = j1
idx_eq_j2 : idx = j2
⊢ (↑idx).succ < (↑j1).succ

Tactic:
apply Nat.succ_lt_succ ∘ Nat.lt_of_le_of_ne j1_ge_idx

Result:
case left.a
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
units : Array (Literal (PosFin n))
units_nodup : ∀ (i j : Fin units.size), i ≠ j → units[i] ≠ units[j]
idx : Fin units.size
assignments : Array Assignment
hsize : assignments.size = n
hsize' : (clearUnit assignments units[idx]).size = n
i : Fin n
j1 : Fin units.size
j1_ge_idx : ↑j1 ≥ ↑idx
j2 : Fin units.size
j2_ge_idx : ↑j2 ≥ ↑idx
i_gt_zero : ↑i > 0
ih1 : units[↑j1] = (⟨↑i, ⋯⟩, true)
ih2 : units[↑j2] = (⟨↑i, ⋯⟩, false)
ih3 : assignments[↑i] = both
ih4 : f.assignments[↑i] = unassigned
ih5 : ∀ (k : Fin units.size), ↑k ≥ ↑idx → ¬k = j1 → ¬k = j2 → ¬units[↑k].fst.val = ↑i
idx_ne_j1 : ¬idx = j1
idx_eq_j2 : idx = j2
⊢ ¬↑idx = ↑j1

Proof state:
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
units : Array (Literal (PosFin n))
units_nodup : ∀ (i j : Fin units.size), i ≠ j → units[i] ≠ units[j]
idx : Fin units.size
assignments : Array Assignment
hsize : assignments.size = n
hsize' : (clearUnit assignments units[idx]).size = n
i : Fin n
j1 : Fin units.size
j1_ge_idx : ↑j1 ≥ ↑idx
j2 : Fin units.size
j2_ge_idx : ↑j2 ≥ ↑idx
i_gt_zero : ↑i > 0
ih1 : units[↑j1] = (⟨↑i, ⋯⟩, true)
ih2 : units[↑j2] = (⟨↑i, ⋯⟩, false)
ih3 : assignments[↑i] = both
ih4 : f.assignments[↑i] = unassigned
ih5 : ∀ (k : Fin units.size), ↑k ≥ ↑idx → ¬k = j1 → ¬k = j2 → ¬units[↑k].fst.val = ↑i
idx_ne_j1 : ¬idx = j1
idx_eq_j2 : idx = j2
k : Fin units.size
k_ge_idx_add_one : ↑k ≥ ↑idx + 1
k_ne_j1 : k ≠ j1
h1 : units[k].fst.val = ↑i
h2 : units[↑k].snd = true
h3 : ¬units[↑k] = (⟨units[↑k].fst.val, ⋯⟩, units[↑k].snd)
⊢ False

Tactic:
exact h3 rfl

Result:
no goals

Proof state:
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
units : Array (Literal (PosFin n))
units_nodup : ∀ (i j : Fin units.size), i ≠ j → units[i] ≠ units[j]
idx : Fin units.size
assignments : Array Assignment
hsize : assignments.size = n
hsize' : (clearUnit assignments units[idx]).size = n
i : Fin n
j1 : Fin units.size
j1_ge_idx : ↑j1 ≥ ↑idx
j2 : Fin units.size
j2_ge_idx : ↑j2 ≥ ↑idx
i_gt_zero : ↑i > 0
ih1 : units[↑j1] = (⟨↑i, ⋯⟩, true)
ih2 : units[↑j2] = (⟨↑i, ⋯⟩, false)
ih3 : assignments[↑i] = both
ih4 : f.assignments[↑i] = unassigned
ih5 : ∀ (k : Fin units.size), ↑k ≥ ↑idx → ¬k = j1 → ¬k = j2 → ¬units[↑k].fst.val = ↑i
idx_ne_j1 : ¬idx = j1
idx_eq_j2 : idx = j2
k : Fin units.size
k_ge_idx_add_one : ↑idx ≥ ↑idx + 1
k_ne_j1 : k ≠ j1
h1 : units[k].fst.val = ↑i
h2 : ¬units[↑k].snd = true
k_eq_idx : k = idx
⊢ False

Tactic:
exact Nat.lt_irrefl idx.1 <| Nat.lt_of_succ_le k_ge_idx_add_one

Result:
no goals

Proof state:
case right.right.left
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
units : Array (Literal (PosFin n))
units_nodup : ∀ (i j : Fin units.size), i ≠ j → units[i] ≠ units[j]
idx : Fin units.size
assignments : Array Assignment
hsize : assignments.size = n
hsize' : (clearUnit assignments units[idx]).size = n
i : Fin n
j : Fin units.size
j_ge_idx : ↑j ≥ ↑idx
b : Bool
i_gt_zero : ↑i > 0
ih1 : units[↑j] = (⟨↑i, ⋯⟩, b)
ih2 : assignments[↑i] = addAssignment b f.assignments[↑i]
ih3 : ¬hasAssignment b f.assignments[↑i] = true
ih4 : ∀ (k : Fin units.size), ↑k ≥ ↑idx → ¬k = j → ¬units[↑k].fst.val = ↑i
idx_ne_j : ¬idx = j
⊢ (assignments.modify units[↑idx].fst.val (removeAssignment units[↑idx].snd))[↑i] = addAssignment b f.assignments[↑i]

Tactic:
specialize ih4 idx (Nat.le_refl idx.1) idx_ne_j

Result:
case right.right.left
n : Nat
f : DefaultFormula n
f_assignments_size : f.assignments.size = n
units : Array (Literal (PosFin n))
units_nodup : ∀ (i j : Fin units.size), i ≠ j → units[i] ≠ units[j]
idx : Fin units.size
assignments : Array Assignment
hsize : assignments.size = n
hsize' : (clearUnit assignments units[idx]).size = n
i : Fin n
j : Fin units.size
j_ge_idx : ↑j ≥ ↑idx
b : Bool
i_gt_zero : ↑i > 0
ih1 : units[↑j] = (⟨↑i, ⋯⟩, b)
ih2 : assignments[↑i] = addAssignment b f.assignments[↑i]
ih3 : ¬hasAssignment b f.assignments[↑i] = true
idx_ne_j : ¬idx = j
ih4 : ¬units[↑idx].fst.val = ↑i
⊢ (assignments.modify units[↑idx].fst.val (removeAssignment units[↑idx].snd))[↑i] = addAssignment b f.assignments[↑i]