internlm/Lean-Github huggingface dataset:
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
case isTrue.mpr.right
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
hrest : ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
⊢ ⟦{ aig := (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig, ref := (input.getRef idx hidx1).cast ⋯ },
      assign⟧ =
    ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧
Tactic:
rw [AIG.LawfulOperator.denote_mem_prefix (f := AIG.mkAndCached)]
Proof state after:
case isTrue.mpr.right
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
hrest : ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
⊢ ⟦{ aig := aig, ref := { gate := ((input.getRef idx hidx1).cast ⋯).gate, hgate := ?isTrue.mpr.right } }, assign⟧ =
    ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧

case isTrue.mpr.right
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
hrest : ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
⊢ ((input.getRef idx hidx1).cast ⋯).gate < aig.decls.size
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
case isTrue.mpr.right
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
hrest : ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
⊢ ⟦{ aig := aig, ref := { gate := ((input.getRef idx hidx1).cast ⋯).gate, hgate := ?isTrue.mpr.right } }, assign⟧ =
    ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧

case isTrue.mpr.right
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
hrest : ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
⊢ ((input.getRef idx hidx1).cast ⋯).gate < aig.decls.size
Tactic:
. simp
Proof state after:
case isTrue.mpr.right
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
hrest : ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
⊢ ((input.getRef idx hidx1).cast ⋯).gate < aig.decls.size
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
case isTrue.mpr.right
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
hrest : ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
⊢ ((input.getRef idx hidx1).cast ⋯).gate < aig.decls.size
Tactic:
. simp [Ref.hgate]
Proof state after:
no goals
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
hrest : ∀ (idx : Nat) (hidx1 : idx < len), curr ≤ idx → ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
⊢ curr ≤ idx
Tactic:
omega
Proof state after:
no goals
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
case isTrue.mpr.right
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
hrest : ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
⊢ ⟦{ aig := aig, ref := { gate := ((input.getRef idx hidx1).cast ⋯).gate, hgate := ?isTrue.mpr.right } }, assign⟧ =
    ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧
Tactic:
simp
Proof state after:
no goals
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
case isTrue.mpr.right
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
hacc : ⟦{ aig := aig, ref := acc }, assign⟧ = true
idx : Nat
hidx1 : idx < len
hidx2 : curr + 1 ≤ idx
hrest : ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
⊢ ((input.getRef idx hidx1).cast ⋯).gate < aig.decls.size
Tactic:
simp [Ref.hgate]
Proof state after:
no goals
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
case isTrue.hcurr
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : curr < len
hgo :
  go (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).aig
      (aig.mkAndCached { lhs := acc, rhs := input.getRef curr h✝ }).ref (curr + 1) len (input.cast ⋯) mkAndCached =
    res
⊢ curr + 1 ≤ len
Tactic:
omega
Proof state after:
no goals
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
case isFalse
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : ¬curr < len
hgo : { aig := aig, ref := acc } = res
⊢ (⟦{ aig := res.aig, ref := res.ref }, assign⟧ = true) =
    (⟦{ aig := aig, ref := acc }, assign⟧ = true ∧
      ∀ (idx : Nat) (hidx1 : idx < len), curr ≤ idx → ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true)
Tactic:
rw [← hgo]
Proof state after:
case isFalse
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : ¬curr < len
hgo : { aig := aig, ref := acc } = res
⊢ (⟦{ aig := { aig := aig, ref := acc }.aig, ref := { aig := aig, ref := acc }.ref }, assign⟧ = true) =
    (⟦{ aig := aig, ref := acc }, assign⟧ = true ∧
      ∀ (idx : Nat) (hidx1 : idx < len), curr ≤ idx → ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true)
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
case isFalse
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : ¬curr < len
hgo : { aig := aig, ref := acc } = res
⊢ (⟦{ aig := { aig := aig, ref := acc }.aig, ref := { aig := aig, ref := acc }.ref }, assign⟧ = true) =
    (⟦{ aig := aig, ref := acc }, assign⟧ = true ∧
      ∀ (idx : Nat) (hidx1 : idx < len), curr ≤ idx → ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true)
Tactic:
simp only [eq_iff_iff, iff_self_and]
Proof state after:
case isFalse
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : ¬curr < len
hgo : { aig := aig, ref := acc } = res
⊢ ⟦{ aig := aig, ref := acc }, assign⟧ = true →
    ∀ (idx : Nat) (hidx1 : idx < len), curr ≤ idx → ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
Theorem: AIG.RefStream.fold.denote_go_and
Proof state before:
case isFalse
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
acc : aig.Ref
curr : Nat
hcurr : curr ≤ len
input : aig.RefStream len
res : Entrypoint α
h✝ : ¬curr < len
hgo : { aig := aig, ref := acc } = res
⊢ ⟦{ aig := aig, ref := acc }, assign⟧ = true →
    ∀ (idx : Nat) (hidx1 : idx < len), curr ≤ idx → ⟦{ aig := aig, ref := input.getRef idx hidx1 }, assign⟧ = true
Tactic:
omega
Proof state after:
no goals
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ ⟦fold aig (FoldTarget.mkAnd s), assign⟧ = true ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Tactic:
unfold fold
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ ⟦let res := aig.mkConstCached true;
        let aig_1 := res.aig;
        let acc := res.ref;
        let input := (FoldTarget.mkAnd s).stream.cast ⋯;
        fold.go aig_1 acc 0 (FoldTarget.mkAnd s).len input (FoldTarget.mkAnd s).func,
        assign⟧ =
      true ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ ⟦let res := aig.mkConstCached true;
        let aig_1 := res.aig;
        let acc := res.ref;
        let input := (FoldTarget.mkAnd s).stream.cast ⋯;
        fold.go aig_1 acc 0 (FoldTarget.mkAnd s).len input (FoldTarget.mkAnd s).func,
        assign⟧ =
      true ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Tactic:
simp only [FoldTarget.mkAnd]
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ ⟦fold.go (aig.mkConstCached true).aig (aig.mkConstCached true).ref 0 len (s.cast ⋯) mkAndCached, assign⟧ = true ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ ⟦fold.go (aig.mkConstCached true).aig (aig.mkConstCached true).ref 0 len (s.cast ⋯) mkAndCached, assign⟧ = true ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Tactic:
rw [fold.denote_go_and]
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (⟦{ aig := (aig.mkConstCached true).aig, ref := (aig.mkConstCached true).ref }, assign⟧ = true ∧
      ∀ (idx : Nat) (hidx1 : idx < len),
        0 ≤ idx → ⟦{ aig := (aig.mkConstCached true).aig, ref := (s.cast ⋯).getRef idx hidx1 }, assign⟧ = true) ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true

case hcurr
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ 0 ≤ len
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (⟦{ aig := (aig.mkConstCached true).aig, ref := (aig.mkConstCached true).ref }, assign⟧ = true ∧
      ∀ (idx : Nat) (hidx1 : idx < len),
        0 ≤ idx → ⟦{ aig := (aig.mkConstCached true).aig, ref := (s.cast ⋯).getRef idx hidx1 }, assign⟧ = true) ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true

case hcurr
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ 0 ≤ len
Tactic:
. simp only [denote_projected_entry, mkConstCached_eval_eq_mkConst_eval, denote_mkConst,
  Nat.zero_le, getRef_cast, Ref_cast', true_implies, true_and]
  constructor
  . intro h idx hidx
    specialize h idx hidx
    rw [AIG.LawfulOperator.denote_mem_prefix (f := mkConstCached)] at h
    rw [← h]
  . intro h idx hidx
    specialize h idx hidx
    rw [AIG.LawfulOperator.denote_mem_prefix (f := mkConstCached)]
    . simp only [← h]
    . apply RefStream.hrefs
      simp [FoldTarget.mkAnd, hidx]
Proof state after:
case hcurr
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ 0 ≤ len
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
case hcurr
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ 0 ≤ len
Tactic:
. omega
Proof state after:
no goals
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (⟦{ aig := (aig.mkConstCached true).aig, ref := (aig.mkConstCached true).ref }, assign⟧ = true ∧
      ∀ (idx : Nat) (hidx1 : idx < len),
        0 ≤ idx → ⟦{ aig := (aig.mkConstCached true).aig, ref := (s.cast ⋯).getRef idx hidx1 }, assign⟧ = true) ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Tactic:
simp only [denote_projected_entry, mkConstCached_eval_eq_mkConst_eval, denote_mkConst,
Nat.zero_le, getRef_cast, Ref_cast', true_implies, true_and]
Proof state after:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (∀ (idx : Nat) (hidx1 : idx < len),
      ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ =
        true) ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (∀ (idx : Nat) (hidx1 : idx < len),
      ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ =
        true) ↔
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Tactic:
constructor
Proof state after:
case mp
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (∀ (idx : Nat) (hidx1 : idx < len),
      ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ =
        true) →
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true

case mpr
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true) →
    ∀ (idx : Nat) (hidx1 : idx < len),
      ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ = true
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
case mp
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (∀ (idx : Nat) (hidx1 : idx < len),
      ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ =
        true) →
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true

case mpr
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true) →
    ∀ (idx : Nat) (hidx1 : idx < len),
      ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ = true
Tactic:
. intro h idx hidx
  specialize h idx hidx
  rw [AIG.LawfulOperator.denote_mem_prefix (f := mkConstCached)] at h
  rw [← h]
Proof state after:
case mpr
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true) →
    ∀ (idx : Nat) (hidx1 : idx < len),
      ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ = true
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
case mpr
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true) →
    ∀ (idx : Nat) (hidx1 : idx < len),
      ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ = true
Tactic:
. intro h idx hidx
  specialize h idx hidx
  rw [AIG.LawfulOperator.denote_mem_prefix (f := mkConstCached)]
  . simp only [← h]
  . apply RefStream.hrefs
    simp [FoldTarget.mkAnd, hidx]
Proof state after:
no goals
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
case mp
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
⊢ (∀ (idx : Nat) (hidx1 : idx < len),
      ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ =
        true) →
    ∀ (idx : Nat) (hidx : idx < len), ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Tactic:
intro h idx hidx
Proof state after:
case mp
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
h :
  ∀ (idx : Nat) (hidx1 : idx < len),
    ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ = true
idx : Nat
hidx : idx < len
⊢ ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
case mp
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
h :
  ∀ (idx : Nat) (hidx1 : idx < len),
    ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx1).gate, hgate := ⋯ } }, assign⟧ = true
idx : Nat
hidx : idx < len
⊢ ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Tactic:
specialize h idx hidx
Proof state after:
case mp
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
idx : Nat
hidx : idx < len
h : ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx).gate, hgate := ⋯ } }, assign⟧ = true
⊢ ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Theorem: AIG.RefStream.denote_fold_and
Proof state before:
case mp
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
idx : Nat
hidx : idx < len
h : ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx).gate, hgate := ⋯ } }, assign⟧ = true
⊢ ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true
Tactic:
rw [AIG.LawfulOperator.denote_mem_prefix (f := mkConstCached)] at h
Proof state after:
case mp
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
idx : Nat
hidx : idx < len
h✝ : ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx).gate, hgate := ⋯ } }, assign⟧ = true
h : ⟦{ aig := aig, ref := { gate := (s.getRef idx hidx).gate, hgate := ?mp } }, assign⟧ = true
⊢ ⟦{ aig := aig, ref := s.getRef idx hidx }, assign⟧ = true

case mp
α : Type
inst✝² : BEq α
inst✝¹ : Hashable α
inst✝ : DecidableEq α
aig✝ : AIG α
len : Nat
assign : α → Bool
aig : AIG α
s : aig.RefStream len
idx : Nat
hidx : idx < len
h : ⟦{ aig := (aig.mkConstCached true).aig, ref := { gate := (s.getRef idx hidx).gate, hgate := ⋯ } }, assign⟧ = true
⊢ (s.getRef idx hidx).gate < aig.decls.size