Theorem: LRAT.DefaultFormula.reduce_postcondition (LeanSAT/LRAT/Formula/RupAddSound.lean)

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
⊢ (c.reduce assignment = reducedToEmpty → incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      c.reduce assignment = reducedToUnit l → ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l
Tactic:
let c_arr := Array.mk c.clause
State after:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
⊢ (c.reduce assignment = reducedToEmpty → incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      c.reduce assignment = reducedToUnit l → ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
⊢ (c.reduce assignment = reducedToEmpty → incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      c.reduce assignment = reducedToUnit l → ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l
Tactic:
have c_clause_rw : c.clause = c_arr.data := rfl
State after:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
⊢ (c.reduce assignment = reducedToEmpty → incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      c.reduce assignment = reducedToUnit l → ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
⊢ (c.reduce assignment = reducedToEmpty → incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      c.reduce assignment = reducedToUnit l → ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l
Tactic:
rw [reduce, c_clause_rw, ← Array.foldl_eq_foldl_data]
State after:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l
Tactic:
let motive := reduce_postcondition_induction_motive c_arr assignment
State after:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l
Tactic:
have h_base : motive 0 reducedToEmpty := by
  simp only [reduce_postcondition_induction_motive, Fin.getElem_fin, forall_exists_index, and_imp, Prod.forall,
    forall_const, false_implies, implies_true, and_true, motive]
  intro p
  apply Or.inl
  intro i i_lt_zero
  exfalso
  exact Nat.not_lt_zero i.1 i_lt_zero
State after:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l
Tactic:
have h_inductive (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)) (ih : motive idx.1 res) :
  motive (idx.1 + 1) (reduce_fold_fn assignment res c_arr[idx]) := reduce_fold_fn_preserves_induction_motive idx res ih
State after:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l
Tactic:
rcases Array.foldl_induction motive h_base h_inductive with ⟨h1, h2⟩
State after:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l

State before:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
⊢ (Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty →
      incompatible (PosFin n) c assignment) ∧
    ∀ (l : Literal (PosFin n)),
      Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
        ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l
Tactic:
constructor
State after:
case intro.left
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
⊢ Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty → incompatible (PosFin n) c assignment

case intro.right
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
⊢ ∀ (l : Literal (PosFin n)),
    Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
⊢ motive 0 reducedToEmpty
Tactic:
simp only [reduce_postcondition_induction_motive, Fin.getElem_fin, forall_exists_index, and_imp, Prod.forall,
  forall_const, false_implies, implies_true, and_true, motive]
State after:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
⊢ ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < 0 → ¬(p ⊨ c_arr[↑i])) ∨ ¬(p ⊨ assignment)

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
⊢ ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < 0 → ¬(p ⊨ c_arr[↑i])) ∨ ¬(p ⊨ assignment)
Tactic:
intro p
State after:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
p : PosFin n → Bool
⊢ (∀ (i : Fin c_arr.size), ↑i < 0 → ¬(p ⊨ c_arr[↑i])) ∨ ¬(p ⊨ assignment)

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
p : PosFin n → Bool
⊢ (∀ (i : Fin c_arr.size), ↑i < 0 → ¬(p ⊨ c_arr[↑i])) ∨ ¬(p ⊨ assignment)
Tactic:
apply Or.inl
State after:
case h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
p : PosFin n → Bool
⊢ ∀ (i : Fin c_arr.size), ↑i < 0 → ¬(p ⊨ c_arr[↑i])

State before:
case h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
p : PosFin n → Bool
⊢ ∀ (i : Fin c_arr.size), ↑i < 0 → ¬(p ⊨ c_arr[↑i])
Tactic:
intro i i_lt_zero
State after:
case h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
p : PosFin n → Bool
i : Fin c_arr.size
i_lt_zero : ↑i < 0
⊢ ¬(p ⊨ c_arr[↑i])

State before:
case h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
p : PosFin n → Bool
i : Fin c_arr.size
i_lt_zero : ↑i < 0
⊢ ¬(p ⊨ c_arr[↑i])
Tactic:
exfalso
State after:
case h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
p : PosFin n → Bool
i : Fin c_arr.size
i_lt_zero : ↑i < 0
⊢ False

State before:
case h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
p : PosFin n → Bool
i : Fin c_arr.size
i_lt_zero : ↑i < 0
⊢ False
Tactic:
exact Nat.not_lt_zero i.1 i_lt_zero
State after:
no goals

State before:
case intro.left
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
⊢ Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty → incompatible (PosFin n) c assignment
Tactic:
intro h p
State after:
case intro.left
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
⊢ ¬(p ⊨ c) ∨ ¬(p ⊨ assignment)

State before:
case intro.left
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
⊢ ¬(p ⊨ c) ∨ ¬(p ⊨ assignment)
Tactic:
specialize h1 h p
State after:
case intro.left
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
⊢ ¬(p ⊨ c) ∨ ¬(p ⊨ assignment)

State before:
case intro.left
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
⊢ ¬(p ⊨ c) ∨ ¬(p ⊨ assignment)
Tactic:
rcases h1 with h1 | h1
State after:
case intro.left.inl
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
⊢ ¬(p ⊨ c) ∨ ¬(p ⊨ assignment)

case intro.left.inr
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ¬(p ⊨ assignment)
⊢ ¬(p ⊨ c) ∨ ¬(p ⊨ assignment)

State before:
case intro.left.inr
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ¬(p ⊨ assignment)
⊢ ¬(p ⊨ c) ∨ ¬(p ⊨ assignment)
Tactic:
. exact Or.inr h1
State after:
no goals

State before:
case intro.left.inl
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
⊢ ¬(p ⊨ c) ∨ ¬(p ⊨ assignment)
Tactic:
apply Or.inl
State after:
case intro.left.inl.h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
⊢ ¬(p ⊨ c)

State before:
case intro.left.inl.h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
⊢ ¬(p ⊨ c)
Tactic:
intro pc
State after:
case intro.left.inl.h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
pc : p ⊨ c
⊢ False

State before:
case intro.left.inl.h
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
pc :
  ∃ a,
    (a, false) ∈ Clause.toList c ∧ decide (p a = false) = true ∨
      (a, true) ∈ Clause.toList c ∧ decide (p a = true) = true
⊢ False
Tactic:
rcases pc with ⟨i, ⟨pc1, pc2⟩ | ⟨pc1, pc2⟩⟩
State after:
case intro.left.inl.h.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ Clause.toList c
pc2 : decide (p i = false) = true
⊢ False

case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ Clause.toList c
pc2 : decide (p i = true) = true
⊢ False

State before:
case intro.left.inl.h.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ Clause.toList c
pc2 : decide (p i = false) = true
⊢ False

case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ Clause.toList c
pc2 : decide (p i = true) = true
⊢ False
Tactic:
. simp only [Clause.toList, DefaultClause.toList] at pc1
  rw [c_clause_rw] at pc1
  have idx_exists : ∃ idx : Fin c_arr.size, c_arr[idx] = (i, false) := by
    rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
    rw [← Array.getElem_fin_eq_data_get] at hidx
    exact Exists.intro idx hidx
  rcases idx_exists with ⟨idx, hidx⟩
  specialize h1 idx idx.2
  rw [hidx] at h1
  exact h1 $ of_decide_eq_true pc2
State after:
case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ Clause.toList c
pc2 : decide (p i = true) = true
⊢ False

State before:
case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ Clause.toList c
pc2 : decide (p i = true) = true
⊢ False
Tactic:
. simp only [Clause.toList, DefaultClause.toList] at pc1
  rw [c_clause_rw] at pc1
  have idx_exists : ∃ idx : Fin c_arr.size, c_arr[idx] = (i, true) := by
    rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
    rw [← Array.getElem_fin_eq_data_get] at hidx
    exact Exists.intro idx hidx
  rcases idx_exists with ⟨idx, hidx⟩
  specialize h1 idx idx.2
  rw [hidx] at h1
  exact h1 $ of_decide_eq_true pc2
State after:
no goals

State before:
case intro.left.inl.h.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ Clause.toList c
pc2 : decide (p i = false) = true
⊢ False
Tactic:
simp only [Clause.toList, DefaultClause.toList] at pc1
State after:
case intro.left.inl.h.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c.clause
pc2 : decide (p i = false) = true
⊢ False

State before:
case intro.left.inl.h.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c.clause
pc2 : decide (p i = false) = true
⊢ False
Tactic:
rw [c_clause_rw] at pc1
State after:
case intro.left.inl.h.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
⊢ False

State before:
case intro.left.inl.h.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
⊢ False
Tactic:
have idx_exists : ∃ idx : Fin c_arr.size, c_arr[idx] = (i, false) := by
  rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
  rw [← Array.getElem_fin_eq_data_get] at hidx
  exact Exists.intro idx hidx
State after:
case intro.left.inl.h.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx_exists : ∃ idx, c_arr[idx] = (i, false)
⊢ False

State before:
case intro.left.inl.h.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx_exists : ∃ idx, c_arr[idx] = (i, false)
⊢ False
Tactic:
rcases idx_exists with ⟨idx, hidx⟩
State after:
case intro.left.inl.h.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ False

State before:
case intro.left.inl.h.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ False
Tactic:
specialize h1 idx idx.2
State after:
case intro.left.inl.h.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
h1 : ¬(p ⊨ c_arr[idx])
⊢ False

State before:
case intro.left.inl.h.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
h1 : ¬(p ⊨ c_arr[idx])
⊢ False
Tactic:
rw [hidx] at h1
State after:
case intro.left.inl.h.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
h1 : ¬(p ⊨ (i, false))
⊢ False

State before:
case intro.left.inl.h.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
h1 : ¬(p ⊨ (i, false))
⊢ False
Tactic:
exact h1 $ of_decide_eq_true pc2
State after:
no goals

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
⊢ ∃ idx, c_arr[idx] = (i, false)
Tactic:
rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
State after:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.data.length
hidx : c_arr.data.get idx = (i, false)
⊢ ∃ idx, c_arr[idx] = (i, false)

State before:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.data.length
hidx : c_arr.data.get idx = (i, false)
⊢ ∃ idx, c_arr[idx] = (i, false)
Tactic:
rw [← Array.getElem_fin_eq_data_get] at hidx
State after:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.data.length
hidx : c_arr[idx] = (i, false)
⊢ ∃ idx, c_arr[idx] = (i, false)

State before:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.data.length
hidx : c_arr[idx] = (i, false)
⊢ ∃ idx, c_arr[idx] = (i, false)
Tactic:
exact Exists.intro idx hidx
State after:
no goals

State before:
case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ Clause.toList c
pc2 : decide (p i = true) = true
⊢ False
Tactic:
simp only [Clause.toList, DefaultClause.toList] at pc1
State after:
case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c.clause
pc2 : decide (p i = true) = true
⊢ False

State before:
case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c.clause
pc2 : decide (p i = true) = true
⊢ False
Tactic:
rw [c_clause_rw] at pc1
State after:
case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
⊢ False

State before:
case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
⊢ False
Tactic:
have idx_exists : ∃ idx : Fin c_arr.size, c_arr[idx] = (i, true) := by
  rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
  rw [← Array.getElem_fin_eq_data_get] at hidx
  exact Exists.intro idx hidx
State after:
case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx_exists : ∃ idx, c_arr[idx] = (i, true)
⊢ False

State before:
case intro.left.inl.h.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx_exists : ∃ idx, c_arr[idx] = (i, true)
⊢ False
Tactic:
rcases idx_exists with ⟨idx, hidx⟩
State after:
case intro.left.inl.h.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
⊢ False

State before:
case intro.left.inl.h.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
⊢ False
Tactic:
specialize h1 idx idx.2
State after:
case intro.left.inl.h.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
h1 : ¬(p ⊨ c_arr[idx])
⊢ False

State before:
case intro.left.inl.h.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
h1 : ¬(p ⊨ c_arr[idx])
⊢ False
Tactic:
rw [hidx] at h1
State after:
case intro.left.inl.h.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
h1 : ¬(p ⊨ (i, true))
⊢ False

State before:
case intro.left.inl.h.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
h1 : ¬(p ⊨ (i, true))
⊢ False
Tactic:
exact h1 $ of_decide_eq_true pc2
State after:
no goals

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
⊢ ∃ idx, c_arr[idx] = (i, true)
Tactic:
rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
State after:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.data.length
hidx : c_arr.data.get idx = (i, true)
⊢ ∃ idx, c_arr[idx] = (i, true)

State before:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.data.length
hidx : c_arr.data.get idx = (i, true)
⊢ ∃ idx, c_arr[idx] = (i, true)
Tactic:
rw [← Array.getElem_fin_eq_data_get] at hidx
State after:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.data.length
hidx : c_arr[idx] = (i, true)
⊢ ∃ idx, c_arr[idx] = (i, true)

State before:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.data.length
hidx : c_arr[idx] = (i, true)
⊢ ∃ idx, c_arr[idx] = (i, true)
Tactic:
exact Exists.intro idx hidx
State after:
no goals

State before:
case intro.left.inr
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
h : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToEmpty
p : PosFin n → Bool
h1 : ¬(p ⊨ assignment)
⊢ ¬(p ⊨ c) ∨ ¬(p ⊨ assignment)
Tactic:
exact Or.inr h1
State after:
no goals

State before:
case intro.right
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
⊢ ∀ (l : Literal (PosFin n)),
    Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → p ⊨ c → p ⊨ l
Tactic:
intro l hl p hp pc
State after:
case intro.right
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
pc : p ⊨ c
⊢ p ⊨ l

State before:
case intro.right
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
pc : p ⊨ c
⊢ p ⊨ l
Tactic:
apply h2 l hl p hp
State after:
case intro.right
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
pc : p ⊨ c
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
pc :
  ∃ a,
    (a, false) ∈ Clause.toList c ∧ decide (p a = false) = true ∨
      (a, true) ∈ Clause.toList c ∧ decide (p a = true) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
rcases pc with ⟨i, ⟨pc1, pc2⟩ | ⟨pc1, pc2⟩⟩
State after:
case intro.right.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ Clause.toList c
pc2 : decide (p i = false) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

case intro.right.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ Clause.toList c
pc2 : decide (p i = true) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ Clause.toList c
pc2 : decide (p i = false) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
simp only [Clause.toList, DefaultClause.toList] at pc1
State after:
case intro.right.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c.clause
pc2 : decide (p i = false) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c.clause
pc2 : decide (p i = false) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
rw [c_clause_rw] at pc1
State after:
case intro.right.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
have idx_exists : ∃ idx : Fin c_arr.size, c_arr[idx] = (i, false) := by
  rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
  rw [← Array.getElem_fin_eq_data_get] at hidx
  exact Exists.intro idx hidx
State after:
case intro.right.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx_exists : ∃ idx, c_arr[idx] = (i, false)
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right.intro.inl.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx_exists : ∃ idx, c_arr[idx] = (i, false)
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
rcases idx_exists with ⟨idx, hidx⟩
State after:
case intro.right.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
apply Exists.intro idx ∘ And.intro idx.2
State after:
case intro.right.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ p ⊨ c_arr[idx]

State before:
case intro.right.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ p ⊨ c_arr[idx]
Tactic:
rw [hidx]
State after:
case intro.right.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ p ⊨ (i, false)

State before:
case intro.right.intro.inl.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, false)
⊢ p i = false
Tactic:
exact of_decide_eq_true pc2
State after:
no goals

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
⊢ ∃ idx, c_arr[idx] = (i, false)
Tactic:
rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
State after:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.data.length
hidx : c_arr.data.get idx = (i, false)
⊢ ∃ idx, c_arr[idx] = (i, false)

State before:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.data.length
hidx : c_arr.data.get idx = (i, false)
⊢ ∃ idx, c_arr[idx] = (i, false)
Tactic:
rw [← Array.getElem_fin_eq_data_get] at hidx
State after:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.data.length
hidx : c_arr[idx] = (i, false)
⊢ ∃ idx, c_arr[idx] = (i, false)

State before:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, false) ∈ c_arr.data
pc2 : decide (p i = false) = true
idx : Fin c_arr.data.length
hidx : c_arr[idx] = (i, false)
⊢ ∃ idx, c_arr[idx] = (i, false)
Tactic:
exact Exists.intro idx hidx
State after:
no goals

State before:
case intro.right.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ Clause.toList c
pc2 : decide (p i = true) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
simp only [Clause.toList, DefaultClause.toList] at pc1
State after:
case intro.right.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c.clause
pc2 : decide (p i = true) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c.clause
pc2 : decide (p i = true) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
rw [c_clause_rw] at pc1
State after:
case intro.right.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
have idx_exists : ∃ idx : Fin c_arr.size, c_arr[idx] = (i, true) := by
  rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
  rw [← Array.getElem_fin_eq_data_get] at hidx
  exact Exists.intro idx hidx
State after:
case intro.right.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx_exists : ∃ idx, c_arr[idx] = (i, true)
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right.intro.inr.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx_exists : ∃ idx, c_arr[idx] = (i, true)
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
rcases idx_exists with ⟨idx, hidx⟩
State after:
case intro.right.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])

State before:
case intro.right.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
⊢ ∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])
Tactic:
apply Exists.intro idx ∘ And.intro idx.2
State after:
case intro.right.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
⊢ p ⊨ c_arr[idx]

State before:
case intro.right.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
⊢ p ⊨ c_arr[idx]
Tactic:
rw [hidx]
State after:
case intro.right.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
⊢ p ⊨ (i, true)

State before:
case intro.right.intro.inr.intro.intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.size
hidx : c_arr[idx] = (i, true)
⊢ p i = true
Tactic:
exact of_decide_eq_true pc2
State after:
no goals

State before:
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
⊢ ∃ idx, c_arr[idx] = (i, true)
Tactic:
rcases List.get_of_mem pc1 with ⟨idx, hidx⟩
State after:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.data.length
hidx : c_arr.data.get idx = (i, true)
⊢ ∃ idx, c_arr[idx] = (i, true)

State before:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.data.length
hidx : c_arr.data.get idx = (i, true)
⊢ ∃ idx, c_arr[idx] = (i, true)
Tactic:
rw [← Array.getElem_fin_eq_data_get] at hidx
State after:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.data.length
hidx : c_arr[idx] = (i, true)
⊢ ∃ idx, c_arr[idx] = (i, true)

State before:
case intro
n : Nat
c : DefaultClause n
assignment : Array Assignment
c_arr : Array (Literal (PosFin n)) := { data := c.clause }
c_clause_rw : c.clause = c_arr.data
motive : Nat → ReduceResult (PosFin n) → Prop := reduce_postcondition_induction_motive c_arr assignment
h_base : motive 0 reducedToEmpty
h_inductive :
  ∀ (idx : Fin c_arr.size) (res : ReduceResult (PosFin n)),
    motive (↑idx) res → motive (↑idx + 1) (reduce_fold_fn assignment res c_arr[idx])
h1 :
  Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToEmpty →
    ∀ (p : PosFin n → Bool), (∀ (i : Fin c_arr.size), ↑i < c_arr.size → ¬(p ⊨ c_arr[i])) ∨ ¬(p ⊨ assignment)
h2 :
  ∀ (l : Literal (PosFin n)),
    Array.foldl (fun b => reduce_fold_fn assignment b) reducedToEmpty c_arr 0 = reducedToUnit l →
      ∀ (p : PosFin n → Bool), p ⊨ assignment → (∃ i, ↑i < c_arr.size ∧ (p ⊨ c_arr[i])) → p ⊨ l
l : Literal (PosFin n)
hl : Array.foldl (reduce_fold_fn assignment) reducedToEmpty c_arr 0 = reducedToUnit l
p : PosFin n → Bool
hp : p ⊨ assignment
i : PosFin n
pc1 : (i, true) ∈ c_arr.data
pc2 : decide (p i = true) = true
idx : Fin c_arr.data.length
hidx : c_arr[idx] = (i, true)
⊢ ∃ idx, c_arr[idx] = (i, true)
Tactic:
exact Exists.intro idx hidx
State after:
no goals