-- Mathlib/.lake/packages/lean4/src/lean/Std/Sat/AIG/Lemmas.lean
theorem denote_mkConst {aig : AIG α} : ⟦(aig.mkConst val), assign⟧ = val

Proof state:
case h_2
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
idx✝ : α
heq✝ : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.atom idx✝
⊢ assign idx✝ = val

Tactic:
next heq =>
rw [mkConst, Array.getElem_push_eq] at heq
contradiction

Result:
no goals

Proof state:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
b✝ : Bool
heq : val = b✝
⊢ b✝ = val

Tactic:
rw [heq]

Result:
no goals

Proof state:
case h_1
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
b✝ : Bool
heq✝ : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.const b✝
⊢ b✝ = val

Tactic:
next heq =>
rw [mkConst, Array.getElem_push_eq] at heq
injection heq with heq
rw [heq]

Result:
no goals

Proof state:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
b✝ : Bool
heq : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.const b✝
⊢ b✝ = val

Tactic:
rw [mkConst, Array.getElem_push_eq] at heq

Result:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
b✝ : Bool
heq : Decl.const val = Decl.const b✝
⊢ b✝ = val

Proof state:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
idx✝ : α
heq : Decl.const val = Decl.atom idx✝
⊢ assign idx✝ = val

Tactic:
contradiction

Result:
no goals

Proof state:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
b✝ : Bool
heq : Decl.const val = Decl.const b✝
⊢ b✝ = val

Tactic:
injection heq with heq

Result:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
b✝ : Bool
heq : val = b✝
⊢ b✝ = val

Proof state:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
idx✝ : α
heq : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.atom idx✝
⊢ assign idx✝ = val

Tactic:
rw [mkConst, Array.getElem_push_eq] at heq

Result:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
idx✝ : α
heq : Decl.const val = Decl.atom idx✝
⊢ assign idx✝ = val

Proof state:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
⊢ (match elem : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] with
    | Decl.const b => b
    | Decl.atom v => assign v
    | Decl.gate lhs rhs linv rinv =>
      let_fun this := ⋯;
      let lval := denote.go lhs (aig.mkConst val).aig.decls assign ⋯ ⋯;
      let rval := denote.go rhs (aig.mkConst val).aig.decls assign ⋯ ⋯;
      (lval ^^ linv) && (rval ^^ rinv)) =
    val

Tactic:
split

Result:
case h_1
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
b✝ : Bool
heq✝ : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.const b✝
⊢ b✝ = val

case h_2
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
idx✝ : α
heq✝ : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.atom idx✝
⊢ assign idx✝ = val

case h_3
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    (lval ^^ linv✝) && (rval ^^ rinv✝)) =
    val

Proof state:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    (lval ^^ linv✝) && (rval ^^ rinv✝)) =
    val

Tactic:
rw [mkConst, Array.getElem_push_eq] at heq

Result:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq : Decl.const val = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    (lval ^^ linv✝) && (rval ^^ rinv✝)) =
    val

Proof state:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
⊢ ⟦assign, aig.mkConst val⟧ = val

Tactic:
unfold denote denote.go

Result:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
⊢ (match elem : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] with
    | Decl.const b => b
    | Decl.atom v => assign v
    | Decl.gate lhs rhs linv rinv =>
      let_fun this := ⋯;
      let lval := denote.go lhs (aig.mkConst val).aig.decls assign ⋯ ⋯;
      let rval := denote.go rhs (aig.mkConst val).aig.decls assign ⋯ ⋯;
      (lval ^^ linv) && (rval ^^ rinv)) =
    val

Proof state:
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq : Decl.const val = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    (lval ^^ linv✝) && (rval ^^ rinv✝)) =
    val

Tactic:
contradiction

Result:
no goals

Proof state:
case h_3
α : Type
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
val : Bool
aig : AIG α
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkConst val).aig.decls[(aig.mkConst val).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkConst val).aig.decls assign ⋯ ⋯;
    (lval ^^ linv✝) && (rval ^^ rinv✝)) =
    val

Tactic:
next heq =>
rw [mkConst, Array.getElem_push_eq] at heq
contradiction

Result:
no goals