-- Mathlib/.lake/packages/lean4/src/lean/Std/Tactic/BVDecide/Bitblast/BVExpr/Circuit/Impl/Expr.lean
theorem bitblast.go_decl_eq (aig : AIG BVBit) (expr : BVExpr w) :
    ∀ (idx : Nat) (h1) (h2), (go aig expr).val.aig.decls[idx]'h2 = aig.decls[idx]'h1

Proof state:
case shiftRight.h2
w idx m✝ n✝ : Nat
lhs : BVExpr m✝
rhs : BVExpr n✝
lih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig lhs).val.aig.decls.size),
    (go aig lhs).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig rhs).val.aig.decls.size),
    (go aig rhs).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (lhs.shiftRight rhs)).val.aig.decls.size
this✝¹ this✝ : aig.decls.size ≤ (go aig lhs).val.aig.decls.size
this : (go aig lhs).val.aig.decls.size ≤ (go (go aig lhs).val.aig rhs).val.aig.decls.size
⊢ aig.decls.size ≤ (go (go aig lhs).1.aig rhs).val.aig.decls.size

Tactic:
apply Nat.le_trans <;> assumption

Result:
no goals

Proof state:
case arithShiftRight
w idx m✝ n✝ : Nat
lhs : BVExpr m✝
rhs : BVExpr n✝
lih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig lhs).val.aig.decls.size),
    (go aig lhs).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig rhs).val.aig.decls.size),
    (go aig rhs).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (lhs.arithShiftRight rhs)).val.aig.decls.size
this✝¹ this✝ : aig.decls.size ≤ (go aig lhs).val.aig.decls.size
this : (go aig lhs).val.aig.decls.size ≤ (go (go aig lhs).val.aig rhs).val.aig.decls.size
⊢ (go (go aig lhs).1.aig rhs).1.aig.decls[idx] = aig.decls[idx]

case arithShiftRight.h1
w idx m✝ n✝ : Nat
lhs : BVExpr m✝
rhs : BVExpr n✝
lih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig lhs).val.aig.decls.size),
    (go aig lhs).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig rhs).val.aig.decls.size),
    (go aig rhs).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (lhs.arithShiftRight rhs)).val.aig.decls.size
this✝¹ this✝ : aig.decls.size ≤ (go aig lhs).val.aig.decls.size
this : (go aig lhs).val.aig.decls.size ≤ (go (go aig lhs).val.aig rhs).val.aig.decls.size
⊢ idx < (go (go aig lhs).1.aig rhs).1.aig.decls.size

Tactic:
rw [rih, lih]

Result:
case arithShiftRight.h2
w idx m✝ n✝ : Nat
lhs : BVExpr m✝
rhs : BVExpr n✝
lih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig lhs).val.aig.decls.size),
    (go aig lhs).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig rhs).val.aig.decls.size),
    (go aig rhs).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (lhs.arithShiftRight rhs)).val.aig.decls.size
this✝¹ this✝ : aig.decls.size ≤ (go aig lhs).val.aig.decls.size
this : (go aig lhs).val.aig.decls.size ≤ (go (go aig lhs).val.aig rhs).val.aig.decls.size
⊢ idx < (go aig lhs).val.aig.decls.size

case arithShiftRight.h2
w idx m✝ n✝ : Nat
lhs : BVExpr m✝
rhs : BVExpr n✝
lih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig lhs).val.aig.decls.size),
    (go aig lhs).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig rhs).val.aig.decls.size),
    (go aig rhs).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (lhs.arithShiftRight rhs)).val.aig.decls.size
this✝¹ this✝ : aig.decls.size ≤ (go aig lhs).val.aig.decls.size
this : (go aig lhs).val.aig.decls.size ≤ (go (go aig lhs).val.aig rhs).val.aig.decls.size
⊢ idx < (go (go aig lhs).1.aig rhs).val.aig.decls.size

Proof state:
w : Nat
aig : AIG BVBit
expr : BVExpr w
⊢ ∀ (idx : Nat) (h1 : idx < aig.decls.size) (h2 : idx < (go aig expr).val.aig.decls.size),
    (go aig expr).val.aig.decls[idx] = aig.decls[idx]

Tactic:
intros idx h1 h2

Result:
w : Nat
aig : AIG BVBit
expr : BVExpr w
idx : Nat
h1 : idx < aig.decls.size
h2 : idx < (go aig expr).val.aig.decls.size
⊢ (go aig expr).val.aig.decls[idx] = aig.decls[idx]

Proof state:
case arithShiftRight
w idx m✝ n✝ : Nat
lhs : BVExpr m✝
rhs : BVExpr n✝
lih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig lhs).val.aig.decls.size),
    (go aig lhs).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig rhs).val.aig.decls.size),
    (go aig rhs).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (lhs.arithShiftRight rhs)).val.aig.decls.size
⊢ (go aig (lhs.arithShiftRight rhs)).val.aig.decls[idx] = aig.decls[idx]

Tactic:
dsimp only [go]

Result:
case arithShiftRight
w idx m✝ n✝ : Nat
lhs : BVExpr m✝
rhs : BVExpr n✝
lih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig lhs).val.aig.decls.size),
    (go aig lhs).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig rhs).val.aig.decls.size),
    (go aig rhs).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (lhs.arithShiftRight rhs)).val.aig.decls.size
⊢ (blastArithShiftRight (go (go aig lhs).1.aig rhs).1.aig
            { n := n✝, target := (go aig lhs).1.vec.cast ⋯,
              distance := (go (go aig lhs).1.aig rhs).1.vec }).aig.decls[idx] =
    aig.decls[idx]

Proof state:
case replicate.h2
w idx w✝ n : Nat
inner : BVExpr w✝
ih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig inner).val.aig.decls.size),
    (go aig inner).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (replicate n inner)).val.aig.decls.size
⊢ idx < (go aig inner).val.aig.decls.size

Tactic:
have := (go aig inner).property

Result:
case replicate.h2
w idx w✝ n : Nat
inner : BVExpr w✝
ih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig inner).val.aig.decls.size),
    (go aig inner).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (replicate n inner)).val.aig.decls.size
this : aig.decls.size ≤ (go aig inner).val.aig.decls.size
⊢ idx < (go aig inner).val.aig.decls.size

Proof state:
case zeroExtend
w✝¹ idx w✝ w : Nat
inner : BVExpr w✝
ih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig inner).val.aig.decls.size),
    (go aig inner).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (zeroExtend w inner)).val.aig.decls.size
⊢ (go aig (zeroExtend w inner)).val.aig.decls[idx] = aig.decls[idx]

Tactic:
dsimp only [go]

Result:
case zeroExtend
w✝¹ idx w✝ w : Nat
inner : BVExpr w✝
ih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig inner).val.aig.decls.size),
    (go aig inner).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (zeroExtend w inner)).val.aig.decls.size
⊢ (blastZeroExtend (go aig inner).1.aig { w := w✝, vec := (go aig inner).1.vec }).aig.decls[idx] = aig.decls[idx]

Proof state:
case shiftRight.h2
w idx m✝ n✝ : Nat
lhs : BVExpr m✝
rhs : BVExpr n✝
lih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig lhs).val.aig.decls.size),
    (go aig lhs).val.aig.decls[idx] = aig.decls[idx]
rih :
  ∀ (aig : AIG BVBit) (h1 : idx < aig.decls.size) (h2 : idx < (go aig rhs).val.aig.decls.size),
    (go aig rhs).val.aig.decls[idx] = aig.decls[idx]
aig : AIG BVBit
h1 : idx < aig.decls.size
h2 : idx < (go aig (lhs.shiftRight rhs)).val.aig.decls.size
this✝¹ this✝ : aig.decls.size ≤ (go aig lhs).val.aig.decls.size
this : (go aig lhs).val.aig.decls.size ≤ (go (go aig lhs).val.aig rhs).val.aig.decls.size
⊢ idx < (go aig lhs).val.aig.decls.size

Tactic:
omega

Result:
no goals