Bdd #
Pointer, Node and Bdd #
@[instance_reducible]
Equations
- instFintypePointer = Fintype.ofEquiv (Bool ⊕ Fin m✝) (Pointer.proxyTypeEquiv m✝)
@[instance_reducible]
Equations
- instDecidableEqPointer.decEq (Pointer.terminal a) (Pointer.terminal b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
- instDecidableEqPointer.decEq (Pointer.terminal a) (Pointer.node a_1) = isFalse ⋯
- instDecidableEqPointer.decEq (Pointer.node a) (Pointer.terminal a_1) = isFalse ⋯
- instDecidableEqPointer.decEq (Pointer.node a) (Pointer.node b) = if h : a = b then h ▸ isTrue ⋯ else isFalse ⋯
Instances For
@[instance_reducible]
Equations
- instReprPointer = { reprPrec := instReprPointer.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- instHashablePointer.hash (Pointer.terminal a) = mixHash 0 (hash a)
- instHashablePointer.hash (Pointer.node a) = mixHash 1 (hash a)
Instances For
@[instance_reducible]
Equations
- instHashablePointer = { hash := instHashablePointer.hash }
@[instance_reducible]
Equations
- One or more equations did not get rendered due to their size.
@[instance_reducible]
@[instance_reducible]
Equations
- instReprNode = { reprPrec := instReprNode.repr }
Equations
- One or more equations did not get rendered due to their size.
Instances For
@[instance_reducible]
Equations
Bdd.low and Bdd.high #
Edge #
theorem
not_terminal_edge
{n✝ n✝¹ : ℕ}
{w : Vector (Node n✝ n✝¹) n✝¹}
{b : Bool}
{q : Pointer n✝¹}
:
¬Edge w (Pointer.terminal b) q
Terminals have no outgoing edges.
Reachability #
Equations
Instances For
theorem
Pointer.Reachable.recOn
{n m : ℕ}
{v : Vector (Node n m) m}
{p : Pointer m}
{motive : (q : Pointer m) → Reachable v p q → Prop}
{q : Pointer m}
(h1 : Reachable v p q)
(refl : motive p ⋯)
(snoc : ∀ (q r : Pointer m) (h1 : Reachable v p q) (h2 : Edge v q r), motive q h1 → motive r ⋯)
:
motive q h1
theorem
Pointer.Reachable.recOn'
{n m : ℕ}
{v : Vector (Node n m) m}
{q : Pointer m}
{motive : (p : Pointer m) → Reachable v p q → Prop}
{p : Pointer m}
(h1 : Reachable v p q)
(refl : motive q ⋯)
(cons : ∀ (p r : Pointer m) (h1 : Edge v r p) (h2 : Reachable v p q), motive p h2 → motive r ⋯)
:
motive p h1
theorem
Bdd.reachable_node_iff
{n m : ℕ}
{B : Bdd n m}
{j : Fin m}
{q : Pointer m}
:
Pointer.Reachable B.heap (Pointer.node j) q ↔ q = Pointer.node j ∨ Pointer.Reachable B.heap B.heap[j].high q ∨ Pointer.Reachable B.heap B.heap[j].low q
@[simp]
@[simp]
RelevantPointer #
@[reducible, inline]
B.RelevantPointer is the subtype of pointers reachable from B.root.
Equations
- B.RelevantPointer = { q : Pointer m // Pointer.Reachable B.heap B.root q }
Instances For
Pointer.toVar and Bdd.MayPrecede #
Equations
- Pointer.toVar M (Pointer.terminal a) = Fin.last n
- Pointer.toVar M (Pointer.node a) = ⟨↑M[a].var, ⋯⟩
Instances For
Equations
- Pointer.toVarD M (Pointer.terminal a) x✝ = x✝
- Pointer.toVarD M (Pointer.node j) x✝ = ↑M[j].var
Instances For
Equations
- B.MayPrecede p q = (Pointer.toVar B.heap p < Pointer.toVar B.heap q)
Instances For
theorem
Bdd.mayPrecede_eq_of_heap_eq
{n m : ℕ}
{B1 B2 : Bdd n m}
:
B1.heap = B2.heap → B1.MayPrecede = B2.MayPrecede
@[simp]
Ordered #
A BDD is Ordered if all edges relevant from the root respect the variable ordering.
Equations
- B.Ordered = ∀ (p q : Pointer m), Pointer.Reachable B.heap B.root p → Edge B.heap p q → B.MayPrecede p q
Instances For
theorem
Bdd.ordered_iff
{n m : ℕ}
{B : Bdd n m}
:
B.Ordered ↔ ∀ (p q : Pointer m), Pointer.Reachable B.heap B.root p → Edge B.heap p q → B.MayPrecede p q
theorem
Bdd.ordered_iff'
{n m : ℕ}
{B : Bdd n m}
:
B.Ordered ↔ ∀ (p q : Pointer m),
Pointer.Reachable B.heap B.root p → Edge B.heap p q → Pointer.toVar B.heap p < Pointer.toVar B.heap q
theorem
Bdd.ordered_of_terminal
{n m : ℕ}
{b : Bool}
{B : Bdd n m}
:
B.root = Pointer.terminal b → B.Ordered
Terminals induce Ordered BDDs.
OBdd #
OBdd.low and OBdd.high #
sub-Bdds #
@[simp]
var #
Termination #
Instances For
@[instance_reducible]
The OEdge relation between Ordered BDDs is converse well-founded.
@[instance_reducible]
Induction #
theorem
OBdd.init_inductionOn
{n m : ℕ}
(t : OBdd n m)
{motive : OBdd n m → Prop}
(base : ∀ (b : Bool) (B : OBdd n m), B.bdd.heap = t.bdd.heap → B.bdd.root = Pointer.terminal b → motive B)
(step :
∀ (B : OBdd n m) (j : Fin m),
B.bdd.heap = t.bdd.heap → ∀ (h : B.bdd.root = Pointer.node j), motive (B.low h) → motive (B.high h) → motive B)
:
motive t
toTree and evaluate #
@[irreducible]
Equations
- O.toTree = match h : O.bdd.root with | Pointer.terminal b => DecisionTree.leaf b | Pointer.node j => DecisionTree.branch O.bdd.heap[j].var (O.low h).toTree (O.high h).toTree
Instances For
theorem
OBdd.toTree_terminal
{n m : ℕ}
{O : OBdd n m}
{b : Bool}
(h : O.bdd.root = Pointer.terminal b)
:
Equations
Instances For
@[simp]
Spell out OBdd.evaluate for terminals.
theorem
OBdd.independentOf_lt_root
{n m : ℕ}
(O : OBdd n m)
(i : Fin O.var)
:
Nary.IndependentOf O.evaluate (Fin.castLE ⋯ i)
Similarity #
def
OBdd.SimilarRP
{n m m' : ℕ}
{O : OBdd n m}
{U : OBdd n m'}
(p : O.bdd.RelevantPointer)
(q : U.bdd.RelevantPointer)
:
Equations
- OBdd.SimilarRP p q = (O.subBdd p).Similar (U.subBdd q)
Instances For
Isomorphism of Ordered BDDs is an equivalence relation.
theorem
OBdd.Similar_of_terminal
{n m m' : ℕ}
{b : Bool}
{O : OBdd n m}
{U : OBdd n m'}
:
O.bdd.root = Pointer.terminal b → U.bdd.root = Pointer.terminal b → O.Similar U
OBdd.Reduced #
@[instance_reducible]
Equations
- One or more equations did not get rendered due to their size.
Equations
- B.NoRedundancy = ∀ (p : B.RelevantPointer), ¬Pointer.Redundant B.heap ↑p
Instances For
A BDD is Reduced if its graph does not contain redundant nodes or distinct similar subgraphs.
Equations
Instances For
theorem
OBdd.reduced_of_terminal
{n m : ℕ}
{O : OBdd n m}
{b : Bool}
(h : O.bdd.root = Pointer.terminal b)
:
O.Reduced
Terminal BDDs are reduced.
Size #
@[instance_reducible]
instance
OBdd.instDecidableReachable
{n m : ℕ}
(O : OBdd n m)
:
DecidablePred (Pointer.Reachable O.bdd.heap O.bdd.root)
Equations
The number of nodes in the unraveling of O
Equations
Instances For
Lemmas about Ordered #
Lemmas about reachability #
Bdd.usesVar #
@[instance_reducible]
Equations
- OBdd.instDecidableUsesVar i = (usesVar_helper✝ O i O.bdd.root ⋯ ⟨Std.HashSet.emptyWithCapacity, ⋯⟩).1
Raw Bdds #
Pointer.equiv and Node.equiv #
Equations
- p.equiv p' = ((∀ (b : Bool), p = Pointer.terminal b → p' = Pointer.terminal b) ∧ ∀ (j : Fin m), p = Pointer.node j → ∃ (j' : Fin m'), p' = Pointer.node j' ∧ ↑j = ↑j')
Instances For
RawPointer and RawNode #
- terminal (b : Bool) : RawPointer
- node (n : ℕ) : RawPointer
Instances For
Equations
- RawBdd.RawPointer.Bounded m p = ∀ {i : ℕ}, p = RawBdd.RawPointer.node i → i < m
Instances For
theorem
RawBdd.RawPointer.bounded_of_le
{m m' : ℕ}
{p : RawPointer}
(hm : Bounded m p)
(h : m ≤ m')
:
Bounded m' p
Equations
- (RawBdd.RawPointer.terminal b).cook h_2 = Pointer.terminal b
- (RawBdd.RawPointer.node i).cook h_2 = Pointer.node ⟨i, ⋯⟩
Instances For
theorem
RawBdd.RawPointer.cook_equiv
{m1 : ℕ}
{p : RawPointer}
{m2 : ℕ}
{h1 : Bounded m1 p}
{h2 : Bounded m2 p}
:
Equations
Instances For
- lo_bounded : RawPointer.Bounded m N.lo
- hi_bounded : RawPointer.Bounded m N.hi
Instances For
theorem
RawBdd.cook_inj
{m : ℕ}
{p q : RawPointer}
{hp : RawPointer.Bounded m p}
{hq : RawPointer.Bounded m q}
:
def
RawBdd.cook_heap
{n c : ℕ}
(v : Vector (RawNode n) c)
(hh : ∀ (i : Fin c), RawNode.Bounded (↑i) v[i])
:
Equations
- RawBdd.cook_heap v hh = Vector.ofFn fun (i : Fin c) => v[i].cook ⋯
Instances For
theorem
RawBdd.cook_aux
{p : RawPointer}
{n m : ℕ}
{j : Fin n}
{hj : ↑j < m}
{h1 : RawPointer.Bounded n p}
{h2 : RawPointer.Bounded m p}
:
p.cook h1 = Pointer.node j → p.cook h2 = Pointer.node ⟨↑j, hj⟩
theorem
RawBdd.push_ordered
{n✝ n✝¹ : ℕ}
{v : Vector (RawNode n✝) n✝¹}
{h0 : ∀ (i : Fin n✝¹), RawNode.Bounded (↑i) v[i]}
{p : RawPointer}
{h1 : RawPointer.Bounded n✝¹ p}
{N : RawNode n✝}
{h2 : ∀ (i : Fin (n✝¹ + 1)), RawNode.Bounded (↑i) (v.push N)[i]}
{h3 : RawPointer.Bounded (n✝¹ + 1) p}
:
theorem
RawBdd.push_evaluate
{n m : ℕ}
{O : OBdd n (m + 1)}
{v : Vector (RawNode n) m}
{N : RawNode n}
{h0 : ∀ (i : Fin (m + 1)), RawNode.Bounded (↑i) (v.push N)[i]}
{p : RawPointer}
{hp : RawPointer.Bounded (m + 1) p}
{h1 : ∀ (i : Fin m), RawNode.Bounded (↑i) v[i]}
{hp' : RawPointer.Bounded m p}
{ho : { heap := cook_heap v h1, root := p.cook hp' }.Ordered}
(h_heap : O.bdd.heap = cook_heap (v.push N) h0)
(h_root : O.bdd.root = p.cook hp)
: