-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/LRAT/Internal/Convert.lean
theorem CNF.Clause.mem_lrat_of_mem (clause : CNF.Clause (PosFin n)) (h1 : l ∈ clause)
    (h2 : DefaultClause.ofArray clause.toArray = some lratClause) : l ∈ lratClause.clause

Proof state:
case cons.h_2.isFalse.isFalse.head
n : Nat
l : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
acc✝¹ : Option (DefaultClause n)
acc✝ : DefaultClause n
heq✝ :
  List.foldr
      (fun l acc =>
        match acc with
        | none => none
        | some acc => acc.insert l)
      (some DefaultClause.empty) tl =
    some acc✝
h✝¹ : ¬List.contains acc✝.clause (l.fst, !l.snd) = true
h✝ : ¬List.contains acc✝.clause l = true
h2 :
  (let clause := l :: acc✝.clause;
    let_fun nodupkey := ⋯;
    let_fun nodup := ⋯;
    some { clause := clause, nodupkey := nodupkey, nodup := nodup }) =
    some lratClause
⊢ l ∈ lratClause.clause

Tactic:
simp only [← Option.some.inj h2]

Result:
case cons.h_2.isFalse.isFalse.head
n : Nat
l : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
acc✝¹ : Option (DefaultClause n)
acc✝ : DefaultClause n
heq✝ :
  List.foldr
      (fun l acc =>
        match acc with
        | none => none
        | some acc => acc.insert l)
      (some DefaultClause.empty) tl =
    some acc✝
h✝¹ : ¬List.contains acc✝.clause (l.fst, !l.snd) = true
h✝ : ¬List.contains acc✝.clause l = true
h2 :
  (let clause := l :: acc✝.clause;
    let_fun nodupkey := ⋯;
    let_fun nodup := ⋯;
    some { clause := clause, nodupkey := nodupkey, nodup := nodup }) =
    some lratClause
⊢ l ∈ l :: acc✝.clause

Proof state:
case cons
n : Nat
l hd : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
h1 : l ∈ hd :: tl
h2 :
  List.foldr
      (fun l acc =>
        match acc with
        | none => none
        | some acc => acc.insert l)
      (some DefaultClause.empty) { toList := hd :: tl }.toList =
    some lratClause
⊢ l ∈ lratClause.clause

Tactic:
dsimp only [List.foldr] at h2

Result:
case cons
n : Nat
l hd : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
h1 : l ∈ hd :: tl
h2 :
  (match
      List.foldr
        (fun l acc =>
          match acc with
          | none => none
          | some acc => acc.insert l)
        (some DefaultClause.empty) tl with
    | none => none
    | some acc => acc.insert hd) =
    some lratClause
⊢ l ∈ lratClause.clause

Proof state:
case cons.h_2.isFalse.isTrue.head
n : Nat
l : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
acc✝¹ : Option (DefaultClause n)
acc✝ : DefaultClause n
heq✝ :
  List.foldr
      (fun l acc =>
        match acc with
        | none => none
        | some acc => acc.insert l)
      (some DefaultClause.empty) tl =
    some acc✝
h2 : some acc✝ = some acc✝
h✝ : ¬List.contains acc✝.clause (l.fst, !l.snd) = true
h : List.contains acc✝.clause l = true
⊢ l ∈ acc✝.clause

Tactic:
exact List.mem_of_elem_eq_true h

Result:
no goals

Proof state:
case cons.h_2.isFalse.isFalse.tail
n : Nat
l hd : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
acc✝¹ : Option (DefaultClause n)
acc✝ : DefaultClause n
heq✝ :
  List.foldr
      (fun l acc =>
        match acc with
        | none => none
        | some acc => acc.insert l)
      (some DefaultClause.empty) tl =
    some acc✝
h✝¹ : ¬List.contains acc✝.clause (hd.fst, !hd.snd) = true
h✝ : ¬List.contains acc✝.clause hd = true
h2 : some { clause := hd :: acc✝.clause, nodupkey := ⋯, nodup := ⋯ } = some lratClause
a✝ : List.Mem l tl
⊢ l ∈ lratClause.clause

Tactic:
simp only [← Option.some.inj h2]

Result:
case cons.h_2.isFalse.isFalse.tail
n : Nat
l hd : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
acc✝¹ : Option (DefaultClause n)
acc✝ : DefaultClause n
heq✝ :
  List.foldr
      (fun l acc =>
        match acc with
        | none => none
        | some acc => acc.insert l)
      (some DefaultClause.empty) tl =
    some acc✝
h✝¹ : ¬List.contains acc✝.clause (hd.fst, !hd.snd) = true
h✝ : ¬List.contains acc✝.clause hd = true
h2 : some { clause := hd :: acc✝.clause, nodupkey := ⋯, nodup := ⋯ } = some lratClause
a✝ : List.Mem l tl
⊢ l ∈ hd :: acc✝.clause

Proof state:
case cons
n : Nat
l hd : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
h1 : l ∈ hd :: tl
h2 : DefaultClause.ofArray (hd :: tl).toArray = some lratClause
⊢ l ∈ lratClause.clause

Tactic:
unfold DefaultClause.ofArray at h2

Result:
case cons
n : Nat
l hd : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
h1 : l ∈ hd :: tl
h2 :
  (let fold_fn := fun l acc =>
      match acc with
      | none => none
      | some acc => acc.insert l;
    Array.foldr fold_fn (some DefaultClause.empty) (hd :: tl).toArray) =
    some lratClause
⊢ l ∈ lratClause.clause

Proof state:
case cons.h_2.isFalse.isTrue
n : Nat
l hd : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
h1 : l ∈ hd :: tl
acc✝¹ : Option (DefaultClause n)
acc✝ : DefaultClause n
heq✝ :
  List.foldr
      (fun l acc =>
        match acc with
        | none => none
        | some acc => acc.insert l)
      (some DefaultClause.empty) tl =
    some acc✝
h✝¹ : ¬List.contains acc✝.clause (hd.fst, !hd.snd) = true
h✝ : List.contains acc✝.clause hd = true
h2 : some acc✝ = some lratClause
⊢ l ∈ lratClause.clause

Tactic:
rename_i h

Result:
case cons.h_2.isFalse.isTrue
n : Nat
l hd : Literal (PosFin n)
tl : List (Literal (PosFin n))
ih :
  ∀ {lratClause : DefaultClause n}, l ∈ tl → DefaultClause.ofArray tl.toArray = some lratClause → l ∈ lratClause.clause
lratClause : DefaultClause n
h1 : l ∈ hd :: tl
acc✝¹ : Option (DefaultClause n)
acc✝ : DefaultClause n
heq✝ :
  List.foldr
      (fun l acc =>
        match acc with
        | none => none
        | some acc => acc.insert l)
      (some DefaultClause.empty) tl =
    some acc✝
h✝ : ¬List.contains acc✝.clause (hd.fst, !hd.snd) = true
h : List.contains acc✝.clause hd = true
h2 : some acc✝ = some lratClause
⊢ l ∈ lratClause.clause