Theorem: AIG.mkGateCached_decl_eq
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig : AIG α
input : aig.GateInput
res : Entrypoint α
hres :
  (match aig, input with
    | { decls := decls, cache := cache, inv := inv }, input =>
      let lhs := input.lhs.ref.gate;
      let rhs := input.rhs.ref.gate;
      let linv := input.lhs.inv;
      let rinv := input.rhs.inv;
      let_fun this := ⋯;
      let_fun this_1 := ⋯;
      let decl := Decl.gate lhs rhs linv rinv;
      match cache.find? decl with
      | some hit => { aig := { decls := decls, cache := cache, inv := inv }, ref := { gate := hit.idx, hgate := ⋯ } }
      | none =>
        match decls[lhs], decls[rhs], linv, rinv with
        | Decl.const true, x, true, x_1 => { decls := decls, cache := cache, inv := inv }.mkConstCached false
        | Decl.const false, x, false, x_1 => { decls := decls, cache := cache, inv := inv }.mkConstCached false
        | x, Decl.const true, x_1, true => { decls := decls, cache := cache, inv := inv }.mkConstCached false
        | x, Decl.const false, x_1, false => { decls := decls, cache := cache, inv := inv }.mkConstCached false
        | Decl.const true, x, false, false =>
          { aig := { decls := decls, cache := cache, inv := inv }, ref := { gate := rhs, hgate := this_1 } }
        | Decl.const false, x, true, false =>
          { aig := { decls := decls, cache := cache, inv := inv }, ref := { gate := rhs, hgate := this_1 } }
        | x, Decl.const true, false, false =>
          { aig := { decls := decls, cache := cache, inv := inv }, ref := { gate := lhs, hgate := this } }
        | x, Decl.const false, false, true =>
          { aig := { decls := decls, cache := cache, inv := inv }, ref := { gate := lhs, hgate := this } }
        | x, x_1, x_2, x_3 =>
          let g := decls.size;
          let cache_1 := Cache.insert decls cache decl;
          let decls_1 := decls.push decl;
          let_fun inv_1 := ⋯;
          { aig := { decls := decls_1, cache := cache_1, inv := inv_1 }, ref := { gate := g, hgate := ⋯ } }) =
    res
⊢ ∀ (idx : Nat) (h1 : idx < res.aig.decls.size) (h2 : idx < aig.decls.size), res.aig.decls[idx] = aig.decls[idx]
Tactic:
dsimp at hres
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig : AIG α
input : aig.GateInput
res : Entrypoint α
hres :
  (match aig.cache.find? (Decl.gate input.lhs.ref.gate input.rhs.ref.gate input.lhs.inv input.rhs.inv) with
    | some hit =>
      { aig := { decls := aig.decls, cache := aig.cache, inv := ⋯ }, ref := { gate := hit.idx, hgate := ⋯ } }
    | none =>
      match aig.decls[input.lhs.ref.gate], aig.decls[input.rhs.ref.gate], input.lhs.inv, input.rhs.inv with
      | Decl.const true, x, true, x_1 => { decls := aig.decls, cache := aig.cache, inv := ⋯ }.mkConstCached false
      | Decl.const false, x, false, x_1 => { decls := aig.decls, cache := aig.cache, inv := ⋯ }.mkConstCached false
      | x, Decl.const true, x_1, true => { decls := aig.decls, cache := aig.cache, inv := ⋯ }.mkConstCached false
      | x, Decl.const false, x_1, false => { decls := aig.decls, cache := aig.cache, inv := ⋯ }.mkConstCached false
      | Decl.const true, x, false, false =>
        { aig := { decls := aig.decls, cache := aig.cache, inv := ⋯ },
          ref := { gate := input.rhs.ref.gate, hgate := ⋯ } }
      | Decl.const false, x, true, false =>
        { aig := { decls := aig.decls, cache := aig.cache, inv := ⋯ },
          ref := { gate := input.rhs.ref.gate, hgate := ⋯ } }
      | x, Decl.const true, false, false =>
        { aig := { decls := aig.decls, cache := aig.cache, inv := ⋯ },
          ref := { gate := input.lhs.ref.gate, hgate := ⋯ } }
      | x, Decl.const false, false, true =>
        { aig := { decls := aig.decls, cache := aig.cache, inv := ⋯ },
          ref := { gate := input.lhs.ref.gate, hgate := ⋯ } }
      | x, x_1, x_2, x_3 =>
        {
          aig :=
            { decls := aig.decls.push (Decl.gate input.lhs.ref.gate input.rhs.ref.gate input.lhs.inv input.rhs.inv),
              cache :=
                Cache.insert aig.decls aig.cache
                  (Decl.gate input.lhs.ref.gate input.rhs.ref.gate input.lhs.inv input.rhs.inv),
              inv := ⋯ },
          ref := { gate := aig.decls.size, hgate := ⋯ } }) =
    res
⊢ ∀ (idx : Nat) (h1 : idx < res.aig.decls.size) (h2 : idx < aig.decls.size), res.aig.decls[idx] = aig.decls[idx]