-- 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 ∈ (Array.map (fun x => x.fst) ratHints).toList

Tactic:
rw [← of_decide_eq_true ratHintsExhaustive_eq_true]

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 ∈
    (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 :
  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.range f.clauses.size ∧
    (match f.clauses[(Array.range f.clauses.size)[i]]! with
      | none => false
      | some c => c.contains pivot.negate) =
      true

Tactic:
constructor

Result:
case left
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.range f.clauses.size

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

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
h : i ∈ (Array.map (fun x => x.fst) ratHints).toList
j : Fin (Array.map (fun x => x.fst) ratHints).toList.length
h' : (Array.map (fun x => x.fst) ratHints).toList.get j = i
j_property : ↑j < ratHints.toList.length
⊢ ↑j < ratHints.size

Tactic:
dsimp at *

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[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).toList
j : Fin (Array.map (fun x => x.fst) ratHints).toList.length
h' : (Array.map (fun x => x.fst) ratHints)[↑j] = i
j_property : ↑j < ratHints.size
⊢ ↑j < ratHints.size