-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/Bitblast/BoolExpr/Circuit.lean
theorem go_decl_eq (idx) (aig : AIG β) (h : idx < aig.decls.size) (hbounds) :
    (ofBoolExprCached.go aig expr atomHandler).val.aig.decls[idx]'hbounds = aig.decls[idx]

Proof state:
case not
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
expr : BoolExpr α
ih :
  ∀ (aig : AIG β) (h : idx < aig.decls.size) (hbounds : idx < (go aig expr atomHandler).val.aig.decls.size),
    (go aig expr atomHandler).val.aig.decls[idx] = aig.decls[idx]
aig : AIG β
h : idx < aig.decls.size
hbounds : idx < (go aig expr.not atomHandler).val.aig.decls.size
⊢ ((go aig expr atomHandler).1.aig.mkNotCached (go aig expr atomHandler).1.ref).aig.decls[idx] = aig.decls[idx]

Tactic:
have := go_le_size atomHandler expr aig

Result:
case not
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
expr : BoolExpr α
ih :
  ∀ (aig : AIG β) (h : idx < aig.decls.size) (hbounds : idx < (go aig expr atomHandler).val.aig.decls.size),
    (go aig expr atomHandler).val.aig.decls[idx] = aig.decls[idx]
aig : AIG β
h : idx < aig.decls.size
hbounds : idx < (go aig expr.not atomHandler).val.aig.decls.size
this : aig.decls.size ≤ (go aig expr atomHandler).val.aig.decls.size
⊢ ((go aig expr atomHandler).1.aig.mkNotCached (go aig expr atomHandler).1.ref).aig.decls[idx] = aig.decls[idx]

Proof state:
case not
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
expr : BoolExpr α
aig : AIG β
h : idx < aig.decls.size
hbounds : idx < (go aig expr.not atomHandler).val.aig.decls.size
this : aig.decls.size ≤ (go aig expr atomHandler).val.aig.decls.size
ih : (go aig expr atomHandler).val.aig.decls[idx] = aig.decls[idx]
⊢ ((go aig expr atomHandler).1.aig.mkNotCached (go aig expr atomHandler).1.ref).aig.decls[idx] = aig.decls[idx]

Tactic:
rw [AIG.LawfulOperator.decl_eq (f := mkNotCached)]

Result:
case not
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
expr : BoolExpr α
aig : AIG β
h : idx < aig.decls.size
hbounds : idx < (go aig expr.not atomHandler).val.aig.decls.size
this : aig.decls.size ≤ (go aig expr atomHandler).val.aig.decls.size
ih : (go aig expr atomHandler).val.aig.decls[idx] = aig.decls[idx]
⊢ (go aig expr atomHandler).1.aig.decls[idx] = aig.decls[idx]

case not.h1
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
expr : BoolExpr α
aig : AIG β
h : idx < aig.decls.size
hbounds : idx < (go aig expr.not atomHandler).val.aig.decls.size
this : aig.decls.size ≤ (go aig expr atomHandler).val.aig.decls.size
ih : (go aig expr atomHandler).val.aig.decls[idx] = aig.decls[idx]
⊢ idx < (go aig expr atomHandler).1.aig.decls.size

Proof state:
case not
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
expr : BoolExpr α
aig : AIG β
h : idx < aig.decls.size
hbounds : idx < (go aig expr.not atomHandler).val.aig.decls.size
this : aig.decls.size ≤ (go aig expr atomHandler).val.aig.decls.size
ih : (go aig expr atomHandler).val.aig.decls[idx] = aig.decls[idx]
⊢ (go aig expr atomHandler).1.aig.decls[idx] = aig.decls[idx]

case not.h1
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
expr : BoolExpr α
aig : AIG β
h : idx < aig.decls.size
hbounds : idx < (go aig expr.not atomHandler).val.aig.decls.size
this : aig.decls.size ≤ (go aig expr atomHandler).val.aig.decls.size
ih : (go aig expr atomHandler).val.aig.decls[idx] = aig.decls[idx]
⊢ idx < (go aig expr atomHandler).1.aig.decls.size

Tactic:
assumption

Result:
no goals

Proof state:
case ite
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
discr lhs rhs : BoolExpr α
dih :
  ∀ (aig : AIG β) (h : idx < aig.decls.size) (hbounds : idx < (go aig discr atomHandler).val.aig.decls.size),
    (go aig discr atomHandler).val.aig.decls[idx] = aig.decls[idx]
lih :
  ∀ (aig : AIG β) (h : idx < aig.decls.size) (hbounds : idx < (go aig lhs atomHandler).val.aig.decls.size),
    (go aig lhs atomHandler).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG β) (h : idx < aig.decls.size) (hbounds : idx < (go aig rhs atomHandler).val.aig.decls.size),
    (go aig rhs atomHandler).val.aig.decls[idx] = aig.decls[idx]
aig : AIG β
h : idx < aig.decls.size
hbounds : idx < (go aig (discr.ite lhs rhs) atomHandler).val.aig.decls.size
this✝¹ : aig.decls.size ≤ (go aig discr atomHandler).val.aig.decls.size
this✝ :
  (go aig discr atomHandler).val.aig.decls.size ≤
    (go (go aig discr atomHandler).val.aig lhs atomHandler).val.aig.decls.size
this :
  (go (go aig discr atomHandler).val.aig lhs atomHandler).val.aig.decls.size ≤
    (go (go (go aig discr atomHandler).val.aig lhs atomHandler).val.aig rhs atomHandler).val.aig.decls.size
⊢ (go aig (discr.ite lhs rhs) atomHandler).val.aig.decls[idx] = aig.decls[idx]

Tactic:
specialize dih aig (by omega) (by omega)

Result:
case ite
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
discr lhs rhs : BoolExpr α
lih :
  ∀ (aig : AIG β) (h : idx < aig.decls.size) (hbounds : idx < (go aig lhs atomHandler).val.aig.decls.size),
    (go aig lhs atomHandler).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG β) (h : idx < aig.decls.size) (hbounds : idx < (go aig rhs atomHandler).val.aig.decls.size),
    (go aig rhs atomHandler).val.aig.decls[idx] = aig.decls[idx]
aig : AIG β
h : idx < aig.decls.size
hbounds : idx < (go aig (discr.ite lhs rhs) atomHandler).val.aig.decls.size
this✝¹ : aig.decls.size ≤ (go aig discr atomHandler).val.aig.decls.size
this✝ :
  (go aig discr atomHandler).val.aig.decls.size ≤
    (go (go aig discr atomHandler).val.aig lhs atomHandler).val.aig.decls.size
this :
  (go (go aig discr atomHandler).val.aig lhs atomHandler).val.aig.decls.size ≤
    (go (go (go aig discr atomHandler).val.aig lhs atomHandler).val.aig rhs atomHandler).val.aig.decls.size
dih : (go aig discr atomHandler).val.aig.decls[idx] = aig.decls[idx]
⊢ (go aig (discr.ite lhs rhs) atomHandler).val.aig.decls[idx] = aig.decls[idx]