internlm/Lean-Github huggingface dataset:
Theorem: AIG.denote_mkGate
Proof state before:
case h_1
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
b✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.const b✝
⊢ b✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)

case h_2
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
idx✝ : α
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.atom idx✝
⊢ assign idx✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)

case h_3
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
. next heq =>
  rw [mkGate, Array.get_push_size] at heq
  contradiction
Proof state after:
case h_2
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
idx✝ : α
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.atom idx✝
⊢ assign idx✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)

case h_3
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Theorem: AIG.denote_mkGate
Proof state before:
case h_2
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
idx✝ : α
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.atom idx✝
⊢ assign idx✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)

case h_3
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
. next heq =>
  rw [mkGate, Array.get_push_size] at heq
  contradiction
Proof state after:
case h_3
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Theorem: AIG.denote_mkGate
Proof state before:
case h_3
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
. next heq =>
  rw [mkGate, Array.get_push_size] at heq
  injection heq with heq1 heq2 heq3 heq4
  dsimp
  congr 2
  . unfold denote
    simp only [heq1]
    apply denote.go_eq_of_aig_eq
    apply LawfulOperator.IsPrefix_aig
  . simp [heq3]
  . unfold denote
    simp only [heq2]
    apply denote.go_eq_of_aig_eq
    apply LawfulOperator.IsPrefix_aig
  . simp [heq4]
Proof state after:
no goals
Theorem: AIG.denote_mkGate
Proof state before:
case h_1
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
b✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.const b✝
⊢ b✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
next heq =>
rw [mkGate, Array.get_push_size] at heq
contradiction
Proof state after:
no goals
Theorem: AIG.denote_mkGate
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
b✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.const b✝
⊢ b✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
rw [mkGate, Array.get_push_size] at heq
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
b✝ : Bool
heq : Decl.gate input.lhs.ref.gate input.rhs.ref.gate input.lhs.inv input.rhs.inv = Decl.const b✝
⊢ b✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Theorem: AIG.denote_mkGate
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
b✝ : Bool
heq : Decl.gate input.lhs.ref.gate input.rhs.ref.gate input.lhs.inv input.rhs.inv = Decl.const b✝
⊢ b✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
contradiction
Proof state after:
no goals
Theorem: AIG.denote_mkGate
Proof state before:
case h_2
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
idx✝ : α
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.atom idx✝
⊢ assign idx✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
next heq =>
rw [mkGate, Array.get_push_size] at heq
contradiction
Proof state after:
no goals
Theorem: AIG.denote_mkGate
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
idx✝ : α
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.atom idx✝
⊢ assign idx✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
rw [mkGate, Array.get_push_size] at heq
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
idx✝ : α
heq : Decl.gate input.lhs.ref.gate input.rhs.ref.gate input.lhs.inv input.rhs.inv = Decl.atom idx✝
⊢ assign idx✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Theorem: AIG.denote_mkGate
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
idx✝ : α
heq : Decl.gate input.lhs.ref.gate input.rhs.ref.gate input.lhs.inv input.rhs.inv = Decl.atom idx✝
⊢ assign idx✝ =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
contradiction
Proof state after:
no goals
Theorem: AIG.denote_mkGate
Proof state before:
case h_3
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
next heq =>
rw [mkGate, Array.get_push_size] at heq
injection heq with heq1 heq2 heq3 heq4
dsimp
congr 2
. unfold denote
  simp only [heq1]
  apply denote.go_eq_of_aig_eq
  apply LawfulOperator.IsPrefix_aig
. simp [heq3]
. unfold denote
  simp only [heq2]
  apply denote.go_eq_of_aig_eq
  apply LawfulOperator.IsPrefix_aig
. simp [heq4]
Proof state after:
no goals
Theorem: AIG.denote_mkGate
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
rw [mkGate, Array.get_push_size] at heq
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq : Decl.gate input.lhs.ref.gate input.rhs.ref.gate input.lhs.inv input.rhs.inv = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Theorem: AIG.denote_mkGate
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq✝ : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq : Decl.gate input.lhs.ref.gate input.rhs.ref.gate input.lhs.inv input.rhs.inv = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
injection heq with heq1 heq2 heq3 heq4
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Theorem: AIG.denote_mkGate
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ (let_fun this := ⋯;
    let lval := denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    let rval := denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯;
    xor lval linv✝ && xor rval rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
dsimp
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ (xor (denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯) linv✝ &&
      xor (denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯) rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Theorem: AIG.denote_mkGate
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ (xor (denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯) linv✝ &&
      xor (denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯) rinv✝) =
    (xor ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧ input.lhs.inv &&
      xor ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧ input.rhs.inv)
Tactic:
congr 2
Proof state after:
case e_x.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯ = ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧

case e_x.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ linv✝ = input.lhs.inv

case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯ = ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧

case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ rinv✝ = input.rhs.inv
Theorem: AIG.denote_mkGate
Proof state before:
case e_x.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ linv✝ = input.lhs.inv

case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯ = ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧

case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ rinv✝ = input.rhs.inv
Tactic:
. simp [heq3]
Proof state after:
case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯ = ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧

case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ rinv✝ = input.rhs.inv
Theorem: AIG.denote_mkGate
Proof state before:
case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ denote.go ridx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯ = ⟦{ aig := aig, ref := input.rhs.ref }, assign⟧

case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ rinv✝ = input.rhs.inv
Tactic:
. unfold denote
  simp only [heq2]
  apply denote.go_eq_of_aig_eq
  apply LawfulOperator.IsPrefix_aig
Proof state after:
case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ rinv✝ = input.rhs.inv
Theorem: AIG.denote_mkGate
Proof state before:
case e_y.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ rinv✝ = input.rhs.inv
Tactic:
. simp [heq4]
Proof state after:
no goals
Theorem: AIG.denote_mkGate
Proof state before:
case e_x.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯ = ⟦{ aig := aig, ref := input.lhs.ref }, assign⟧
Tactic:
unfold denote
Proof state after:
case e_x.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯ =
    denote.go { aig := aig, ref := input.lhs.ref }.ref.gate { aig := aig, ref := input.lhs.ref }.aig.decls assign ⋯ ⋯
Theorem: AIG.denote_mkGate
Proof state before:
case e_x.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯ =
    denote.go { aig := aig, ref := input.lhs.ref }.ref.gate { aig := aig, ref := input.lhs.ref }.aig.decls assign ⋯ ⋯
Tactic:
simp only [heq1]
Proof state after:
case e_x.e_a
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
assign : α → Bool
aig : AIG α
input : aig.GateInput
lidx✝ ridx✝ : Nat
linv✝ rinv✝ : Bool
heq : (aig.mkGate input).aig.decls[(aig.mkGate input).ref.gate] = Decl.gate lidx✝ ridx✝ linv✝ rinv✝
heq1 : input.lhs.ref.gate = lidx✝
heq2 : input.rhs.ref.gate = ridx✝
heq3 : input.lhs.inv = linv✝
heq4 : input.rhs.inv = rinv✝
⊢ denote.go lidx✝ (aig.mkGate input).aig.decls assign ⋯ ⋯ = denote.go lidx✝ aig.decls assign ⋯ ⋯