internlm/Lean-Github huggingface dataset:
Theorem: LRAT.DefaultFormula.existsRatHint_of_ratHintsExhaustive
Proof state before:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
⊢ ↑i = (Array.range f.clauses.size)[↑i]
Tactic:
have f_clauses_rw : f.clauses = { data := f.clauses.data } := rfl
Proof state after:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
f_clauses_rw : f.clauses = { data := f.clauses.data }
⊢ ↑i = (Array.range f.clauses.size)[↑i]
Theorem: LRAT.DefaultFormula.existsRatHint_of_ratHintsExhaustive
Proof state before:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
f_clauses_rw : f.clauses = { data := f.clauses.data }
⊢ ↑i = (Array.range f.clauses.size)[↑i]
Tactic:
rw [Array.range_idx]
Proof state after:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
f_clauses_rw : f.clauses = { data := f.clauses.data }
⊢ ↑i < f.clauses.size
Theorem: LRAT.DefaultFormula.existsRatHint_of_ratHintsExhaustive
Proof state before:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
f_clauses_rw : f.clauses = { data := f.clauses.data }
⊢ ↑i < f.clauses.size
Tactic:
conv => rhs; rw [f_clauses_rw, Array.size]
Proof state after:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
f_clauses_rw : f.clauses = { data := f.clauses.data }
⊢ ↑i < { data := f.clauses.data }.data.length
Theorem: LRAT.DefaultFormula.existsRatHint_of_ratHintsExhaustive
Proof state before:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
f_clauses_rw : f.clauses = { data := f.clauses.data }
⊢ ↑i < { data := f.clauses.data }.data.length
Tactic:
exact i.2
Proof state after:
no goals
Theorem: LRAT.DefaultFormula.existsRatHint_of_ratHintsExhaustive
Proof state before:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
h : ↑i ∈ (Array.map (fun x => x.fst) ratHints).data
j : Fin (Array.map (fun x => x.fst) ratHints).data.length
h' : (Array.map (fun x => x.fst) ratHints).data.get j = ↑i
⊢ ↑j < ratHints.size
Tactic:
have j_property := j.2
Proof state after:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
h : ↑i ∈ (Array.map (fun x => x.fst) ratHints).data
j : Fin (Array.map (fun x => x.fst) ratHints).data.length
h' : (Array.map (fun x => x.fst) ratHints).data.get j = ↑i
j_property : ↑j < (Array.map (fun x => x.fst) ratHints).data.length
⊢ ↑j < ratHints.size
Theorem: LRAT.DefaultFormula.existsRatHint_of_ratHintsExhaustive
Proof state before:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
h : ↑i ∈ (Array.map (fun x => x.fst) ratHints).data
j : Fin (Array.map (fun x => x.fst) ratHints).data.length
h' : (Array.map (fun x => x.fst) ratHints).data.get j = ↑i
j_property : ↑j < (Array.map (fun x => x.fst) ratHints).data.length
⊢ ↑j < ratHints.size
Tactic:
simp only [Array.map_data, List.length_map] at j_property
Proof state after:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
h : ↑i ∈ (Array.map (fun x => x.fst) ratHints).data
j : Fin (Array.map (fun x => x.fst) ratHints).data.length
h' : (Array.map (fun x => x.fst) ratHints).data.get j = ↑i
j_property : ↑j < ratHints.data.length
⊢ ↑j < ratHints.size
Theorem: LRAT.DefaultFormula.existsRatHint_of_ratHintsExhaustive
Proof state before:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
h : ↑i ∈ (Array.map (fun x => x.fst) ratHints).data
j : Fin (Array.map (fun x => x.fst) ratHints).data.length
h' : (Array.map (fun x => x.fst) ratHints).data.get j = ↑i
j_property : ↑j < ratHints.data.length
⊢ ↑j < ratHints.size
Tactic:
dsimp at *
Proof state after:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
h : ↑i ∈ (Array.map (fun x => x.fst) ratHints).data
j : Fin (Array.map (fun x => x.fst) ratHints).data.length
h' : (Array.map (fun x => x.fst) ratHints).data.get j = ↑i
j_property : ↑j < ratHints.size
⊢ ↑j < ratHints.size
Theorem: LRAT.DefaultFormula.existsRatHint_of_ratHintsExhaustive
Proof state before:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.readyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true :
  decide
      (Array.filter
          (fun i =>
            match f.clauses[i]! with
            | none => false
            | some c => c.contains pivot.negateLiteral)
          (Array.range f.clauses.size) 0 =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negateLiteral ∈ Clause.toList c'
i : Fin f.clauses.data.length
c'_in_f : f.clauses[↑i] = some c'
i_in_bounds : ↑i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : ↑i < f.clauses.size
h : ↑i ∈ (Array.map (fun x => x.fst) ratHints).data
j : Fin (Array.map (fun x => x.fst) ratHints).data.length
h' : (Array.map (fun x => x.fst) ratHints).data.get j = ↑i
j_property : ↑j < ratHints.size
⊢ ↑j < ratHints.size
Tactic:
omega
Proof state after:
no goals
Theorem: LRAT.DefaultFormula.performRatCheck_success_of_performRatCheck_fold_success
Proof state before:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
⊢ (f.performRatCheck p ratHints[i]).snd = true
Tactic:
let motive (idx : Nat) (acc : DefaultFormula n × Bool) : Prop :=
  acc.1 = f ∧ (acc.2 = true → ∀ i : Fin idx, (performRatCheck f p ratHints[i]!).2)
Proof state after:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
⊢ (f.performRatCheck p ratHints[i]).snd = true
Theorem: LRAT.DefaultFormula.performRatCheck_success_of_performRatCheck_fold_success
Proof state before:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
⊢ (f.performRatCheck p ratHints[i]).snd = true
Tactic:
have h_base : motive 0 (f, true) := by
  constructor
  . rfl
  . intro _ i
    exact Fin.elim0 i
Proof state after:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
h_base : motive 0 (f, true)
⊢ (f.performRatCheck p ratHints[i]).snd = true
Theorem: LRAT.DefaultFormula.performRatCheck_success_of_performRatCheck_fold_success
Proof state before:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
h_base : motive 0 (f, true)
⊢ (f.performRatCheck p ratHints[i]).snd = true
Tactic:
let fold_fn (acc : DefaultFormula n × Bool) (ratHint : Nat × Array Nat) :=
  if acc.2 = true then performRatCheck acc.1 p ratHint else (acc.1, false)
Proof state after:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
h_base : motive 0 (f, true)
fold_fn : DefaultFormula n × Bool → Nat × Array Nat → DefaultFormula n × Bool :=
  fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
⊢ (f.performRatCheck p ratHints[i]).snd = true
Theorem: LRAT.DefaultFormula.performRatCheck_success_of_performRatCheck_fold_success
Proof state before:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
h_base : motive 0 (f, true)
fold_fn : DefaultFormula n × Bool → Nat × Array Nat → DefaultFormula n × Bool :=
  fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
⊢ (f.performRatCheck p ratHints[i]).snd = true
Tactic:
have fold_fn_def (acc : DefaultFormula n × Bool) (ratHint : Nat × Array Nat) :
  fold_fn acc ratHint = if acc.2 = true then performRatCheck acc.1 p ratHint else (acc.1, false) := rfl
Proof state after:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
h_base : motive 0 (f, true)
fold_fn : DefaultFormula n × Bool → Nat × Array Nat → DefaultFormula n × Bool :=
  fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
fold_fn_def :
  ∀ (acc : DefaultFormula n × Bool) (ratHint : Nat × Array Nat),
    fold_fn acc ratHint = if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
⊢ (f.performRatCheck p ratHints[i]).snd = true
Theorem: LRAT.DefaultFormula.performRatCheck_success_of_performRatCheck_fold_success
Proof state before:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
h_base : motive 0 (f, true)
fold_fn : DefaultFormula n × Bool → Nat × Array Nat → DefaultFormula n × Bool :=
  fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
fold_fn_def :
  ∀ (acc : DefaultFormula n × Bool) (ratHint : Nat × Array Nat),
    fold_fn acc ratHint = if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
⊢ (f.performRatCheck p ratHints[i]).snd = true
Tactic:
have h_inductive (idx : Fin ratHints.size) (acc : DefaultFormula n × Bool) (ih : motive idx.1 acc) :
  motive (idx.1 + 1) (fold_fn acc ratHints[idx]) := by
  constructor
  . simp only [Fin.getElem_fin, fold_fn_def, ih.1]
    split
    . rw [performRatCheck_preserves_formula]
      exact hf
    . rfl
  . intro h i
    rw [fold_fn_def] at h
    split at h
    . next acc_eq_true =>
      have i_lt_or_eq_idx : i.1 < idx.1 ∨ i.1 = idx.1 := by
        omega
      rcases i_lt_or_eq_idx with i_lt_idx | i_eq_idx
      . exact ih.2 acc_eq_true ⟨i.1, i_lt_idx⟩
      . simp only [getElem!, i_eq_idx, idx.2, Fin.getElem_fin, dite_true]
        simp only [Fin.getElem_fin, ih.1] at h
        exact h
    . simp only at h
Proof state after:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
h_base : motive 0 (f, true)
fold_fn : DefaultFormula n × Bool → Nat × Array Nat → DefaultFormula n × Bool :=
  fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
fold_fn_def :
  ∀ (acc : DefaultFormula n × Bool) (ratHint : Nat × Array Nat),
    fold_fn acc ratHint = if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
h_inductive :
  ∀ (idx : Fin ratHints.size) (acc : DefaultFormula n × Bool),
    motive (↑idx) acc → motive (↑idx + 1) (fold_fn acc ratHints[idx])
⊢ (f.performRatCheck p ratHints[i]).snd = true
Theorem: LRAT.DefaultFormula.performRatCheck_success_of_performRatCheck_fold_success
Proof state before:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
h_base : motive 0 (f, true)
fold_fn : DefaultFormula n × Bool → Nat × Array Nat → DefaultFormula n × Bool :=
  fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
fold_fn_def :
  ∀ (acc : DefaultFormula n × Bool) (ratHint : Nat × Array Nat),
    fold_fn acc ratHint = if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
h_inductive :
  ∀ (idx : Fin ratHints.size) (acc : DefaultFormula n × Bool),
    motive (↑idx) acc → motive (↑idx + 1) (fold_fn acc ratHints[idx])
⊢ (f.performRatCheck p ratHints[i]).snd = true
Tactic:
have h := (Array.foldl_induction motive h_base h_inductive).2 performRatCheck_fold_success i
Proof state after:
n : Nat
f : DefaultFormula n
hf : f.ratUnits = #[] ∧ f.assignments.size = n
p : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
i : Fin ratHints.size
performRatCheck_fold_success :
  (Array.foldl (fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false))
        (f, true) ratHints 0).snd =
    true
motive : Nat → DefaultFormula n × Bool → Prop :=
  fun idx acc => acc.fst = f ∧ (acc.snd = true → ∀ (i : Fin idx), (f.performRatCheck p ratHints[i]!).snd = true)
h_base : motive 0 (f, true)
fold_fn : DefaultFormula n × Bool → Nat × Array Nat → DefaultFormula n × Bool :=
  fun acc ratHint => if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
fold_fn_def :
  ∀ (acc : DefaultFormula n × Bool) (ratHint : Nat × Array Nat),
    fold_fn acc ratHint = if acc.snd = true then acc.fst.performRatCheck p ratHint else (acc.fst, false)
h_inductive :
  ∀ (idx : Fin ratHints.size) (acc : DefaultFormula n × Bool),
    motive (↑idx) acc → motive (↑idx + 1) (fold_fn acc ratHints[idx])
h : (f.performRatCheck p ratHints[i]!).snd = true
⊢ (f.performRatCheck p ratHints[i]).snd = true