-- 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]
⊢ (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

Tactic:
rw [Array.mem_toList]

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)

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 < ratHints.size

Tactic:
have j_property := j.2

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
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 < (Array.map (fun x => x.fst) ratHints).toList.length
⊢ ↑j < ratHints.size

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 < f.clauses.size

Tactic:
simpa using hi

Result:
no goals

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[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

Tactic:
omega

Result:
no goals

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[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]
⊢ pivot.negate ∈ c'.toList

Tactic:
simpa [Clause.toList] using negPivot_in_c'

Result:
no goals