-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Formula/RatAddSound.lean
theorem existsRatHint_of_ratHintsExhaustive {n : Nat} (f : DefaultFormula n)
    (f_readyForRatAdd : ReadyForRatAdd f) (pivot : Literal (PosFin n))
    (ratHints : Array (Nat × Array Nat))
    (ratHintsExhaustive_eq_true : ratHintsExhaustive f pivot ratHints = true) (c' : DefaultClause n)
    (c'_in_f : c' ∈ toList f) (negPivot_in_c' : Literal.negate pivot ∈ Clause.toList c') :
    ∃ i : Fin ratHints.size, f.clauses[ratHints[i].1]! = some c'

Proof state:
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.negate)
          (Array.range f.clauses.size) =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negate ∈ Clause.toList c'
i : Nat
hi : i < f.clauses.toList.length
c'_in_f : f.clauses.toList[i] = some c'
i_in_bounds : i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : i < f.clauses.size
i_eq_range_i : i = (Array.range f.clauses.size)[i]
⊢ i ∈
    (Array.filter
        (fun i =>
          match f.clauses[i]! with
          | none => false
          | some c => c.contains pivot.negate)
        (Array.range f.clauses.size)).toList

Tactic:
rw [i_eq_range_i]

Result:
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.negate)
          (Array.range f.clauses.size) =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negate ∈ Clause.toList c'
i : Nat
hi : i < f.clauses.toList.length
c'_in_f : f.clauses.toList[i] = some c'
i_in_bounds : i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : i < f.clauses.size
i_eq_range_i : i = (Array.range f.clauses.size)[i]
⊢ (Array.range f.clauses.size)[i] ∈
    (Array.filter
        (fun i =>
          match f.clauses[i]! with
          | none => false
          | some c => c.contains pivot.negate)
        (Array.range f.clauses.size)).toList

Proof state:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.ReadyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true : f.ratHintsExhaustive pivot ratHints = true
c' : DefaultClause n
c'_in_f : c' ∈ f.toList
negPivot_in_c' : pivot.negate ∈ Clause.toList c'
⊢ ∃ i, f.clauses[ratHints[i].fst]! = some c'

Tactic:
simp only [toList, f_readyForRatAdd.2.1, Array.toList_toArray, List.map, List.append_nil, f_readyForRatAdd.1,
  List.mem_filterMap, id_eq, exists_eq_right] at c'_in_f

Result:
n : Nat
f : DefaultFormula n
f_readyForRatAdd : f.ReadyForRatAdd
pivot : Literal (PosFin n)
ratHints : Array (Nat × Array Nat)
ratHintsExhaustive_eq_true : f.ratHintsExhaustive pivot ratHints = true
c' : DefaultClause n
negPivot_in_c' : pivot.negate ∈ Clause.toList c'
c'_in_f : some c' ∈ f.clauses.toList
⊢ ∃ i, f.clauses[ratHints[i].fst]! = some c'

Proof state:
case right
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.negate)
          (Array.range f.clauses.size) =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negate ∈ Clause.toList c'
i : Nat
hi : i < f.clauses.toList.length
c'_in_f : f.clauses.toList[i] = some c'
i_in_bounds : i < (Array.range f.clauses.size).size
i_lt_f_clauses_size : i < f.clauses.size
i_eq_range_i : i = (Array.range f.clauses.size)[i]
⊢ (match f.clauses[(Array.range f.clauses.size)[i]]! with
    | none => false
    | some c => c.contains pivot.negate) =
    true

Tactic:
rw [Array.getElem_toList] at c'_in_f

Result:
case right
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.negate)
          (Array.range f.clauses.size) =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negate ∈ Clause.toList c'
i : Nat
hi : i < f.clauses.toList.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_eq_range_i : i = (Array.range f.clauses.size)[i]
⊢ (match f.clauses[(Array.range f.clauses.size)[i]]! with
    | none => false
    | some c => c.contains pivot.negate) =
    true

Proof state:
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.negate)
          (Array.range f.clauses.size) =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negate ∈ Clause.toList c'
i : Nat
hi : i < f.clauses.toList.length
c'_in_f : f.clauses.toList[i] = some c'
i_in_bounds : i < (Array.range f.clauses.size).size
⊢ i < f.clauses.size

Tactic:
rw [Array.size_range] at i_in_bounds

Result:
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.negate)
          (Array.range f.clauses.size) =
        Array.map (fun x => x.fst) ratHints) =
    true
c' : DefaultClause n
negPivot_in_c' : pivot.negate ∈ Clause.toList c'
i : Nat
hi : i < f.clauses.toList.length
c'_in_f : f.clauses.toList[i] = some c'
i_in_bounds : i < f.clauses.size
⊢ i < f.clauses.size