Theorem: LRAT.DefaultFormula.clear_insert_inductive_case
Proof state before:
case intro.inr.inr.intro.intro.intro.intro.intro.intro.intro.intro.intro
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
⊢ let_fun i_lt_assignments_size := ⋯;
  let_fun i_lt_f_assignments_size := ⋯;
  let assignments_i := (clearUnit assignments units[idx])[↑i];
  let fassignments_i := f.assignments[↑i];
  (assignments_i = fassignments_i ∧ ∀ (j : Fin units.size), ↑j ≥ ↑idx + 1 → units[j].fst.val ≠ ↑i) ∨
    (∃ j b i_gt_zero,
        ↑j ≥ ↑idx + 1 ∧
          units[j] = (⟨↑i, ⋯⟩, b) ∧
            assignments_i = addAssignment b fassignments_i ∧
              ¬hasAssignment b fassignments_i = true ∧
                ∀ (k : Fin units.size), ↑k ≥ ↑idx + 1 → k ≠ j → units[k].fst.val ≠ ↑i) ∨
      ∃ j1 j2 i_gt_zero,
        ↑j1 ≥ ↑idx + 1 ∧
          ↑j2 ≥ ↑idx + 1 ∧
            units[j1] = (⟨↑i, ⋯⟩, true) ∧
              units[j2] = (⟨↑i, ⋯⟩, false) ∧
                assignments_i = both ∧
                  fassignments_i = unassigned ∧
                    ∀ (k : Fin units.size), ↑k ≥ ↑idx + 1 → k ≠ j1 → k ≠ j2 → units[k].fst.val ≠ ↑i
Tactic:
. by_cases idx = j1
  . next idx_eq_j1 =>
    have idx_ne_j2 : idx ≠ j2 := by
      rw [idx_eq_j1]
      intro j1_eq_j2
      simp only [j1_eq_j2, ih2, Prod.mk.injEq, and_false] at ih1
    refine Or.inr <| Or.inl <| ⟨j2, false, i_gt_zero, ?_⟩
    constructor
    . apply Nat.le_of_lt_succ
      rw [← Nat.succ_eq_add_one]
      apply Nat.succ_lt_succ ∘ Nat.lt_of_le_of_ne j2_ge_idx
      intro idx_eq_j2
      exact idx_ne_j2 (Fin.eq_of_val_eq idx_eq_j2)
    . constructor
      . simp only [Fin.getElem_fin]
        exact ih2
      . constructor
        . simp only [clearUnit, idx_eq_j1, Array.get_eq_getElem, ih1]
          have i_in_bounds : i.1 < assignments.size := hsize ▸ i.2
          rw [Array.get_modify_at_idx i_in_bounds, ih3, ih4]
          decide
        . constructor
          . simp only [hasAssignment, hasNegAssignment, ih4, ite_false, not_false_eq_true]
          . intro k k_ge_idx_add_one k_ne_j2
            intro h1
            by_cases units[k.1].2
            . next h2 =>
              have k_ne_j1 : k ≠ j1 := by
                rw [← idx_eq_j1]
                intro k_eq_idx
                rw [k_eq_idx] at k_ge_idx_add_one
                exact Nat.lt_irrefl idx.1 $ Nat.lt_of_succ_le k_ge_idx_add_one
              have h3 := units_nodup k j1 k_ne_j1
              simp only [Fin.getElem_fin, ih1, ← h1, ← h2, ne_eq] at h3
              exact h3 rfl
            . next h2 =>
              have h3 := units_nodup k j2 k_ne_j2
              simp only [Bool.not_eq_true] at h2
              simp only [Fin.getElem_fin, ih2, ← h1, ← h2, ne_eq] at h3
              exact h3 rfl
  . next idx_ne_j1 =>
    by_cases idx = j2
    . next idx_eq_j2 =>
      refine Or.inr <| Or.inl <| ⟨j1, true, i_gt_zero, ?_⟩
      constructor
      . apply Nat.le_of_lt_succ
        rw [← Nat.succ_eq_add_one]
        apply Nat.succ_lt_succ ∘ Nat.lt_of_le_of_ne j1_ge_idx
        intro idx_eq_j1
        exact idx_ne_j1 (Fin.eq_of_val_eq idx_eq_j1)
      . constructor
        . simp only [Fin.getElem_fin]
          exact ih1
        . constructor
          . simp only [clearUnit, idx_eq_j2, Array.get_eq_getElem, ih2]
            have i_in_bounds : i.1 < assignments.size := hsize ▸ i.2
            rw [Array.get_modify_at_idx i_in_bounds, ih3, ih4]
            decide
          . constructor
            . simp only [hasAssignment, hasNegAssignment, ih4, ite_false, not_false_eq_true]
              decide
            . intro k k_ge_idx_add_one k_ne_j1
              intro h1
              by_cases units[k.1].2
              . next h2 =>
                have h3 := units_nodup k j1 k_ne_j1
                simp only [Fin.getElem_fin, ih1, ← h1, ← h2, ne_eq] at h3
                exact h3 rfl
              . next h2 =>
                have k_ne_j2 : k ≠ j2 := by
                  rw [← idx_eq_j2]
                  intro k_eq_idx
                  rw [k_eq_idx] at k_ge_idx_add_one
                  exact Nat.lt_irrefl idx.1 $ Nat.lt_of_succ_le k_ge_idx_add_one
                have h3 := units_nodup k j2 k_ne_j2
                simp only [Bool.not_eq_true] at h2
                simp only [Fin.getElem_fin, ih2, ← h1, ← h2, ne_eq] at h3
                exact h3 rfl
    . next idx_ne_j2 =>
      refine Or.inr <| Or.inr <| ⟨j1, j2,i_gt_zero, ?_⟩
      constructor
      . apply Nat.le_of_lt_succ
        rw [← Nat.succ_eq_add_one]
        apply Nat.succ_lt_succ ∘ Nat.lt_of_le_of_ne j1_ge_idx
        intro idx_eq_j1
        exact idx_ne_j1 (Fin.eq_of_val_eq idx_eq_j1)
      . constructor
        . apply Nat.le_of_lt_succ
          rw [← Nat.succ_eq_add_one]
          apply Nat.succ_lt_succ ∘ Nat.lt_of_le_of_ne j2_ge_idx
          intro idx_eq_j2
          exact idx_ne_j2 (Fin.eq_of_val_eq idx_eq_j2)
        . constructor
          . simp only [Fin.getElem_fin]
            exact ih1
          . constructor
            . simp only [Fin.getElem_fin]
              exact ih2
            . constructor
              . simp only [clearUnit, Array.get_eq_getElem]
                have idx_res_ne_i : units[idx.1].1.1 ≠ i.1 := by
                  intro h1
                  by_cases units[idx.1].2
                  . next h2 =>
                    have h3 := units_nodup idx j1 idx_ne_j1
                    simp only [Fin.getElem_fin, ih1, ← h1, ← h2, ne_eq] at h3
                    exact h3 rfl
                  . next h2 =>
                    have h3 := units_nodup idx j2 idx_ne_j2
                    simp only [Bool.not_eq_true] at h2
                    simp only [Fin.getElem_fin, ih2, ← h1, ← h2, ne_eq] at h3
                    exact h3 rfl
                have idx_unit_in_bounds : units[idx.1].1.1 < assignments.size := by
                  rw [hsize]; exact units[idx.1].1.2.2
                have i_in_bounds : i.1 < assignments.size := hsize ▸ i.2
                rw [Array.get_modify_unchanged idx_unit_in_bounds i_in_bounds _ idx_res_ne_i]
                exact ih3
              . constructor
                . exact ih4
                . intro k k_ge_idx_add_one
                  exact ih5 k $ Nat.le_of_succ_le k_ge_idx_add_one
Proof state after:
no goals