-- 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 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
⊢ (go aig (discr.ite lhs rhs) atomHandler).val.aig.decls[idx] = aig.decls[idx]

Tactic:
have := go_le_size atomHandler rhs (go (go aig discr atomHandler).val.aig lhs atomHandler).val.aig

Result:
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]

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

Tactic:
cases g with
| and =>
  simp only [go]
  rw [AIG.LawfulOperator.decl_eq (f := mkAndCached), rih, lih]
| xor =>
  simp only [go]
  rw [AIG.LawfulOperator.decl_eq (f := mkXorCached), rih, lih]
| beq =>
  simp only [go]
  rw [AIG.LawfulOperator.decl_eq (f := mkBEqCached), rih, lih]
| or =>
  simp only [go]
  rw [AIG.LawfulOperator.decl_eq (f := mkOrCached), rih, lih]

Result:
no goals

Proof state:
case gate
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
g : Gate
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 (BoolExpr.gate g lhs rhs) atomHandler).val.aig.decls.size
⊢ (go aig (BoolExpr.gate g lhs rhs) atomHandler).val.aig.decls[idx] = aig.decls[idx]

Tactic:
have := go_le_size atomHandler lhs aig

Result:
case gate
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
g : Gate
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 (BoolExpr.gate g lhs rhs) atomHandler).val.aig.decls.size
this : aig.decls.size ≤ (go aig lhs atomHandler).val.aig.decls.size
⊢ (go aig (BoolExpr.gate g lhs rhs) atomHandler).val.aig.decls[idx] = aig.decls[idx]

Proof state:
α β : Type
inst✝² : Hashable β
inst✝¹ : DecidableEq β
atomHandler : AIG β → α → Entrypoint β
inst✝ : LawfulOperator β (fun x => α) atomHandler
idx : Nat
g : Gate
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 (BoolExpr.gate g lhs rhs) atomHandler).val.aig.decls.size
this✝ : aig.decls.size ≤ (go aig lhs atomHandler).val.aig.decls.size
this :
  (go aig lhs atomHandler).val.aig.decls.size ≤ (go (go aig lhs atomHandler).val.aig rhs atomHandler).val.aig.decls.size
⊢ idx < aig.decls.size

Tactic:
omega

Result:
no goals