Documentation

Bdd.Basic

instance instToStringVector_bdd {k : } {α : Type u} [ToString α] :
Equations
inductive Pointer (m : ) :

Pointer to a BDD node or terminal

Instances For
    instance instReprPointer {m✝ : } :
    Repr (Pointer m✝)
    Equations
    Equations
    • One or more equations did not get rendered due to their size.
    inductive Pointer.le {m : } :
    Pointer mPointer mProp
    Instances For
      instance Pointer.instLE {m : } :
      Equations
      structure Node (n m : ) :

      BDD node

      Instances For
        instance instDecidableEqNode {n✝ m✝ : } :
        DecidableEq (Node n✝ m✝)
        Equations
        instance instReprNode {n✝ m✝ : } :
        Repr (Node n✝ m✝)
        Equations
        instance Node.instToString {n m : } :
        Equations
        structure Bdd (n m : ) :

        Raw BDD

        Instances For
          instance instDecidableEqBdd {n✝ m✝ : } :
          DecidableEq (Bdd n✝ m✝)
          Equations
          instance Bdd.instToString {n m : } :
          Equations
          inductive Edge {n m : } (M : Vector (Node n m) m) :
          Pointer mPointer mProp
          Instances For
            theorem not_terminal_edge {n✝ n✝¹ : } {w : Vector (Node n✝ n✝¹) n✝¹} {b : Bool} {q : Pointer n✝¹} :

            Terminals have no outgoing edges.

            def Pointer.toVar {n m : } (M : Vector (Node n m) m) :
            Pointer mFin n.succ
            Equations
            Instances For
              @[simp]
              theorem Pointer.toVar_terminal_eq {b : Bool} {n m : } (w : Vector (Node n m) m) :
              toVar w (terminal b) = n
              @[simp]
              theorem Pointer.toVar_node_eq {n m : } (w : Vector (Node n m) m) {j : Fin m} :
              toVar w (node j) = w[j].var
              theorem Pointer.toVar_heap_set {n✝ : } {i j : Fin n✝} {n✝¹ : } {M : Vector (Node n✝¹ n✝) n✝} {N : Node n✝¹ n✝} :
              i jtoVar (M.set (↑i) N ) (node j) = toVar M (node j)
              def Pointer.MayPrecede {n m : } (M : Vector (Node n m) m) (p q : Pointer m) :
              Equations
              Instances For
                theorem Pointer.not_terminal_MayPrecede {n✝ n✝¹ : } {M : Vector (Node n✝ n✝¹) n✝¹} {b : Bool} {p : Pointer n✝¹} :

                Terminals must not precede other pointers.

                theorem Pointer.MayPrecede_node_terminal {b : Bool} {n m : } (w : Vector (Node n m) m) {j : Fin m} :

                Non-terminals may precede terminals.

                def Pointer.Reachable {n m : } (w : Vector (Node n m) m) (a : Pointer m) :
                Equations
                Instances For
                  theorem Pointer.Reachable.trans {n✝ n✝¹ : } {v : Vector (Node n✝ n✝¹) n✝¹} {a b c : Pointer n✝¹} (hab : Reachable v a b) (hbc : Reachable v b c) :
                  Reachable v a c
                  @[reducible, inline]
                  abbrev Bdd.RelevantPointer {n m : } (B : Bdd n m) :

                  B.RelevantPointer is the subtype of pointers reachable from B.root.

                  Equations
                  Instances For
                    instance Bdd.instDecidableEqRelevantPointer {n✝ m✝ : } {B : Bdd n✝ m✝} :
                    Equations
                    def Bdd.toRelevantPointer {n m : } (B : Bdd n m) :
                    Equations
                    Instances For
                      @[reducible, inline]
                      abbrev Bdd.RelevantEdge {n m : } (B : Bdd n m) (p q : B.RelevantPointer) :

                      The Edge relation lifted to RelevantPointers.

                      Equations
                      Instances For
                        theorem Bdd.relevantEdge_of_edge_of_reachable {n m : } {p q : Pointer m} {B : Bdd n m} (e : Edge B.heap p q) (hp : Pointer.Reachable B.heap B.root p) :
                        def Bdd.RelevantMayPrecede {n m : } (B : Bdd n m) (p q : B.RelevantPointer) :

                        The MayPrecede relation lifted to RelevantPointers.

                        Equations
                        Instances For
                          def Bdd.Ordered {n m : } (B : Bdd n m) :

                          A BDD is Ordered if all edges relevant from the root respect the variable ordering.

                          Equations
                          Instances For
                            theorem Bdd.Ordered_of_terminal {n✝ n✝¹ : } {M : Vector (Node n✝ n✝¹) n✝¹} {b : Bool} :
                            { heap := M, root := Pointer.terminal b }.Ordered

                            Terminals induce Ordered BDDs.

                            theorem Bdd.Ordered_of_terminal' {n m : } {b : Bool} {B : Bdd n m} :
                            def OBdd (n m : ) :
                            Equations
                            Instances For
                              def OEdge {n m : } (O U : OBdd n m) :
                              Equations
                              Instances For
                                def Bdd.var {n m : } (B : Bdd n m) :
                                Equations
                                Instances For
                                  def OBdd.var {n m : } (O : OBdd n m) :
                                  Equations
                                  Instances For
                                    def OBdd.rav {n m : } (B : OBdd n m) :
                                    Equations
                                    Instances For

                                      The OEdge relation between Ordered BDDs is well-founded.

                                      The OEdge relation between Ordered BDDs is converse well-founded.

                                      theorem Bdd.ordered_of_reachable' {n m : } {p : Pointer m} {B : Bdd n m} :
                                      B.OrderedPointer.Reachable B.heap B.root p{ heap := B.heap, root := p }.Ordered
                                      theorem Bdd.ordered_of_reachable {n m : } {p : Pointer m} {O : OBdd n m} :
                                      Pointer.Reachable (↑O).heap (↑O).root p{ heap := (↑O).heap, root := p }.Ordered
                                      theorem Bdd.ordered_of_relevant {n m : } (O : OBdd n m) (S : (↑O).RelevantPointer) :
                                      { heap := (↑O).heap, root := S }.Ordered

                                      All BDDs in the graph of an Ordered BDD are Ordered.

                                      def Bdd.low {n m : } {j : Fin m} (B : Bdd n m) :
                                      B.root = Pointer.node jBdd n m
                                      Equations
                                      Instances For
                                        theorem Bdd.edge_of_low {n m : } {j : Fin m} (B : Bdd n m) {h : B.root = Pointer.node j} :
                                        Edge B.heap B.root (B.low h).root
                                        def Bdd.high {n m : } {j : Fin m} (B : Bdd n m) :
                                        B.root = Pointer.node jBdd n m
                                        Equations
                                        Instances For
                                          theorem Bdd.edge_of_high {n m : } {j : Fin m} (B : Bdd n m) {h : B.root = Pointer.node j} :
                                          Edge B.heap B.root (B.high h).root
                                          theorem Bdd.reachable_of_edge {n✝ n✝¹ : } {M : Vector (Node n✝ n✝¹) n✝¹} {p q : Pointer n✝¹} :
                                          Edge M p qPointer.Reachable M p q
                                          theorem Bdd.ordered_of_relevant' {n m : } {v : Vector (Node n m) m} {q p : Pointer m} {B : Bdd n m} {h : B.heap = v} {r : B.root = q} :
                                          B.OrderedPointer.Reachable v q p{ heap := v, root := p }.Ordered
                                          theorem Bdd.ordered_of_edge {n m : } {p : Pointer m} {B : Bdd n m} :
                                          B.OrderedEdge B.heap B.root p{ heap := B.heap, root := p }.Ordered
                                          theorem Bdd.high_ordered {n m : } {j : Fin m} {B : Bdd n m} (h : B.root = Pointer.node j) :
                                          B.Ordered(B.high h).Ordered
                                          theorem Bdd.low_ordered {n m : } {j : Fin m} {B : Bdd n m} (h : B.root = Pointer.node j) :
                                          B.Ordered(B.low h).Ordered
                                          theorem Bdd.low_heap_eq_heap {n m : } {j : Fin m} {B : Bdd n m} {h : B.root = Pointer.node j} :
                                          (B.low h).heap = B.heap
                                          theorem Bdd.low_root_eq_low {n m : } {j : Fin m} {B : Bdd n m} {h : B.root = Pointer.node j} :
                                          (B.low h).root = B.heap[j].low
                                          theorem Bdd.high_heap_eq_heap {n m : } {j : Fin m} {B : Bdd n m} {h : B.root = Pointer.node j} :
                                          (B.high h).heap = B.heap
                                          theorem Bdd.high_root_eq_high {n m : } {j : Fin m} {B : Bdd n m} {h : B.root = Pointer.node j} :
                                          (B.high h).root = B.heap[j].high
                                          def OBdd.high {n m : } {j : Fin m} (O : OBdd n m) :
                                          (↑O).root = Pointer.node jOBdd n m
                                          Equations
                                          Instances For
                                            def OBdd.low {n m : } {j : Fin m} (O : OBdd n m) :
                                            (↑O).root = Pointer.node jOBdd n m
                                            Equations
                                            Instances For
                                              @[simp]
                                              theorem OBdd.low_heap_eq_heap {n m : } {j : Fin m} {O : OBdd n m} {h : (↑O).root = Pointer.node j} :
                                              (↑(O.low h)).heap = (↑O).heap
                                              theorem OBdd.low_root_eq_low {n m : } {j : Fin m} {O : OBdd n m} {h : (↑O).root = Pointer.node j} :
                                              (↑(O.low h)).root = (↑O).heap[j].low
                                              @[simp]
                                              theorem OBdd.high_heap_eq_heap {n m : } {j : Fin m} {O : OBdd n m} {h : (↑O).root = Pointer.node j} :
                                              (↑(O.high h)).heap = (↑O).heap
                                              theorem OBdd.high_root_eq_high {n m : } {j : Fin m} {O : OBdd n m} {h : (↑O).root = Pointer.node j} :
                                              (↑(O.high h)).root = (↑O).heap[j].high
                                              theorem oedge_of_low {n✝ m✝ : } {O : OBdd n✝ m✝} {j : Fin m✝} {h : (↑O).root = Pointer.node j} :
                                              OEdge O (O.low h)
                                              theorem oedge_of_high {n✝ m✝ : } {O : OBdd n✝ m✝} {j : Fin m✝} {h : (↑O).root = Pointer.node j} :
                                              OEdge O (O.high h)
                                              @[irreducible]
                                              def OBdd.toTree {n m : } (O : OBdd n m) :
                                              Equations
                                              Instances For
                                                theorem OBdd.evaluate_cast {n m n' : } {I : Vector Bool n'} {O : OBdd n m} (h : n = n') :
                                                (h O).evaluate I = O.evaluate ( I)
                                                def OBdd.HSimilar {n m m' : } (O : OBdd n m) (U : OBdd n m') :
                                                Equations
                                                Instances For
                                                  def OBdd.Similar {n m : } :
                                                  OBdd n mOBdd n mProp
                                                  Equations
                                                  Instances For
                                                    def OBdd.SimilarRP {n m : } (O : OBdd n m) (p q : (↑O).RelevantPointer) :
                                                    Equations
                                                    Instances For
                                                      instance OBdd.instDecidableSimilarRP {n✝ m✝ : } {O : OBdd n✝ m✝} {l r : (↑O).RelevantPointer} :
                                                      Equations

                                                      Isomorphism of Ordered BDDs is an equivalence relation.

                                                      Equations
                                                      • =
                                                      Instances For
                                                        inductive Pointer.Redundant {n m : } (M : Vector (Node n m) m) :

                                                        A pointer is redundant if it point to node N with N.low = N.high.

                                                        Instances For
                                                          Equations
                                                          • One or more equations did not get rendered due to their size.
                                                          def Bdd.NoRedundancy {n m : } (B : Bdd n m) :
                                                          Equations
                                                          Instances For
                                                            def OBdd.Reduced {n m : } (O : OBdd n m) :

                                                            A BDD is Reduced if its graph does not contain redundant nodes or distinct similar subgraphs.

                                                            Equations
                                                            Instances For
                                                              theorem transGen_iff_single_and_reflTransGen {α✝ : Type u_1} {r : α✝α✝Prop} {a b : α✝} :
                                                              Relation.TransGen r a b ∃ (c : α✝), r a c Relation.ReflTransGen r c b
                                                              def RelevantPointer.var {n m : } {B : Bdd n m} (p : B.RelevantPointer) :
                                                              Equations
                                                              Instances For
                                                                def RelevantPointer.gap {n m : } {B : Bdd n m} (p : B.RelevantPointer) :
                                                                Equations
                                                                Instances For
                                                                  theorem RelevantEdge.flip_wellFounded {n✝ m✝ : } {B : Bdd n✝ m✝} (o : B.Ordered) :
                                                                  @[irreducible]
                                                                  instance OBdd.instDecidableReflTransGen {n m : } (O : OBdd n m) (p : (↑O).RelevantPointer) (q : Pointer m) :
                                                                  Equations
                                                                  def OBdd.size {n m : } (O : OBdd n m) :
                                                                  Equations
                                                                  Instances For
                                                                    instance Pointer.instDecidableEitherReachable {n m : } (O U : OBdd n m) (h : (↑O).heap = (↑U).heap) :
                                                                    DecidablePred fun (q : Pointer m) => Reachable (↑O).heap (↑O).root q Reachable (↑O).heap (↑U).root q
                                                                    Equations
                                                                    • One or more equations did not get rendered due to their size.
                                                                    instance OBdd.instFintypeEitherRelevantPointer {n m : } (O U : OBdd n m) (h : (↑O).heap = (↑U).heap) :
                                                                    Fintype { q : Pointer m // Pointer.Reachable (↑O).heap (↑O).root q Pointer.Reachable (↑O).heap (↑U).root q }
                                                                    Equations
                                                                    theorem eq_of_constant_eq {α : Sort u_1} {β : Sort u_2} {c c' : β} [Inhabited α] :
                                                                    Function.const α c = Function.const α c'c = c'

                                                                    The output of equal constant functions with inhabited domain is equal.

                                                                    theorem Bdd.terminal_or_node {n m : } (B : Bdd n m) :
                                                                    (∃ (b : Bool), B.root = Pointer.terminal b B = { heap := B.heap, root := Pointer.terminal b }) ∃ (j : Fin m), B.root = Pointer.node j B = { heap := B.heap, root := Pointer.node j }
                                                                    @[irreducible]
                                                                    theorem OBdd.init_inductionOn {n m : } (t : OBdd n m) {motive : OBdd n mProp} (base : ∀ (b : Bool), motive { heap := (↑t).heap, root := Pointer.terminal b }, ) (step : ∀ (j : Fin m) (hl : { heap := (↑t).heap, root := (↑t).heap[j].low }.Ordered), motive { heap := (↑t).heap, root := (↑t).heap[j].low }, ∀ (hh : { heap := (↑t).heap, root := (↑t).heap[j].high }.Ordered), motive { heap := (↑t).heap, root := (↑t).heap[j].high }, ∀ (h : { heap := (↑t).heap, root := Pointer.node j }.Ordered), motive { heap := (↑t).heap, root := Pointer.node j }, ) :
                                                                    motive t
                                                                    def OBdd.isTerminal {n m : } (O : OBdd n m) :
                                                                    Equations
                                                                    Instances For
                                                                      theorem not_OEdge_of_isTerminal {n m : } {U O : OBdd n m} :
                                                                      theorem Bdd.terminal_relevant_iff {b : Bool} {n m : } {B : Bdd n m} (h : B.root = Pointer.terminal b) (S : B.RelevantPointer) {motive : Pointer mProp} :
                                                                      motive S motive (Pointer.terminal b)

                                                                      The graph induced by a terminal BDD consists of a sole terminal pointer.

                                                                      theorem Bdd.eq_terminal_of_relevant {b : Bool} {n m : } {v : Vector (Node n m) m} {B : Bdd n m} (h : B = { heap := v, root := Pointer.terminal b }) (S : B.RelevantPointer) :
                                                                      theorem OBdd.reduced_of_terminal {n m : } {O : OBdd n m} :

                                                                      Terminal BDDs are reduced.

                                                                      theorem OBdd.reduced_of_relevant {n m : } {O : OBdd n m} (S : (↑O).RelevantPointer) :
                                                                      O.ReducedReduced { heap := (↑O).heap, root := S },

                                                                      Sub-BDDs of a reduced BDD are reduced.

                                                                      theorem OBdd.reachable_of_edge {n✝ n✝¹ : } {w : Vector (Node n✝ n✝¹) n✝¹} {p q : Pointer n✝¹} :
                                                                      Edge w p qPointer.Reachable w p q
                                                                      theorem OBdd.ordered_of_edge {n m : } {v : Vector (Node n m) m} {q : Pointer m} {O : OBdd n m} {h : (↑O).heap = v} {r : (↑O).root = q} (p : Pointer m) :
                                                                      Edge v q p{ heap := v, root := p }.Ordered
                                                                      theorem OBdd.ordered_of_low_edge {n✝ n✝¹ : } {v : Vector (Node n✝ n✝¹) n✝¹} {j : Fin n✝¹} :
                                                                      { heap := v, root := Pointer.node j }.Ordered{ heap := v, root := v[j].low }.Ordered
                                                                      theorem OBdd.ordered_of_high_edge {n✝ n✝¹ : } {v : Vector (Node n✝ n✝¹) n✝¹} {j : Fin n✝¹} :
                                                                      { heap := v, root := Pointer.node j }.Ordered{ heap := v, root := v[j].high }.Ordered
                                                                      @[simp]
                                                                      theorem OBdd.evaluate_node {n m : } {v : Vector (Node n m) m} {I : Vector Bool n} {j : Fin m} {h : { heap := v, root := Pointer.node j }.Ordered} :
                                                                      evaluate { heap := v, root := Pointer.node j }, h I = if I[v[j].var] = true then evaluate { heap := v, root := v[j].high }, I else evaluate { heap := v, root := v[j].low }, I

                                                                      Spell out OBdd.evaluate for non-terminals.

                                                                      theorem OBdd.evaluate_node' {n m : } {v : Vector (Node n m) m} {j : Fin m} {h : { heap := v, root := Pointer.node j }.Ordered} :
                                                                      evaluate { heap := v, root := Pointer.node j }, h = fun (I : Vector Bool n) => if I[v[j].var] = true then evaluate { heap := v, root := v[j].high }, I else evaluate { heap := v, root := v[j].low }, I
                                                                      @[simp]
                                                                      theorem OBdd.evaluate_terminal {b : Bool} {n m : } {v : Vector (Node n m) m} {h : { heap := v, root := Pointer.terminal b }.Ordered} :

                                                                      Spell out OBdd.evaluate for terminals.

                                                                      theorem OBdd.evaluate_terminal' {b : Bool} {n m : } {O : OBdd n m} :
                                                                      @[simp]
                                                                      theorem OBdd.toTree_terminal {b : Bool} {n m : } {v : Vector (Node n m) m} {h : { heap := v, root := Pointer.terminal b }.Ordered} :
                                                                      theorem OBdd.toTree_terminal' {b : Bool} {n m : } {O : OBdd n m} :
                                                                      theorem OBdd.HSimilar_of_terminal {n m m' : } {b : Bool} {O : OBdd n m} {U : OBdd n m'} :
                                                                      (↑O).root = Pointer.terminal b(↑U).root = Pointer.terminal bO.HSimilar U
                                                                      theorem OBdd.toTree_node {n m : } {O : OBdd n m} {j : Fin m} (h : (↑O).root = Pointer.node j) :
                                                                      theorem OBdd.evaluate_node'' {n m : } {O : OBdd n m} {j : Fin m} (h : (↑O).root = Pointer.node j) :
                                                                      O.evaluate = fun (I : Vector Bool n) => if I[(↑O).heap[j].var] = true then (O.high h).evaluate I else (O.low h).evaluate I
                                                                      theorem OBdd.var_lt_high_var {n m : } {j : Fin m} {O : OBdd n m} {h : (↑O).root = Pointer.node j} :
                                                                      O.var < (O.high h).var
                                                                      theorem OBdd.var_lt_low_var {n m : } {j : Fin m} {O : OBdd n m} {h : (↑O).root = Pointer.node j} :
                                                                      O.var < (O.low h).var
                                                                      @[irreducible]
                                                                      theorem OBdd.independentOf_lt_root {n m : } (O : OBdd n m) (i : Fin O.var) :
                                                                      def OBdd.size' {n m : } :
                                                                      OBdd n m
                                                                      Equations
                                                                      Instances For
                                                                        theorem OBdd.size_zero_of_terminal {n✝ m✝ : } {O : OBdd n✝ m✝} :
                                                                        O.isTerminalO.size' = 0
                                                                        theorem OBdd.high_reduced {n m : } {O : OBdd n m} {j : Fin m} {h : (↑O).root = Pointer.node j} :
                                                                        O.Reduced(O.high h).Reduced
                                                                        theorem OBdd.low_reduced {n m : } {O : OBdd n m} {j : Fin m} {h : (↑O).root = Pointer.node j} :
                                                                        O.Reduced(O.low h).Reduced
                                                                        theorem OBdd.size_node {n m : } {O : OBdd n m} {j : Fin m} (h : (↑O).root = Pointer.node j) :
                                                                        O.size' = 1 + (O.low h).size' + (O.high h).size'
                                                                        theorem OBdd.evaluate_high_eq_evaluate_set_true {n m : } {O : OBdd n m} {j : Fin m} {h : (↑O).root = Pointer.node j} :
                                                                        (O.high h).evaluate = O.evaluate fun (I : Vector Bool n) => I.set (↑(↑O).heap[j].var) true
                                                                        theorem OBdd.evaluate_low_eq_evaluate_set_false {n m : } {O : OBdd n m} {j : Fin m} {h : (↑O).root = Pointer.node j} :
                                                                        (O.low h).evaluate = O.evaluate fun (I : Vector Bool n) => I.set (↑(↑O).heap[j].var) false
                                                                        theorem OBdd.evaluate_high_eq_of_evaluate_eq_and_var_eq' {n m m' : } {O : OBdd n m} {U : OBdd n m'} {j : Fin m} {i : Fin m'} {ho : (↑O).root = Pointer.node j} {hu : (↑U).root = Pointer.node i} :
                                                                        O.evaluate = U.evaluate(↑O).heap[j].var = (↑U).heap[i].var(O.high ho).evaluate = (U.high hu).evaluate
                                                                        theorem OBdd.evaluate_high_eq_of_evaluate_eq_and_var_eq {n m : } {O U : OBdd n m} {j i : Fin m} {ho : (↑O).root = Pointer.node j} {hu : (↑U).root = Pointer.node i} :
                                                                        O.evaluate = U.evaluate(↑O).heap[j].var = (↑U).heap[i].var(O.high ho).evaluate = (U.high hu).evaluate
                                                                        theorem OBdd.evaluate_low_eq_of_evaluate_eq_and_var_eq' {n m m' : } {O : OBdd n m} {U : OBdd n m'} {j : Fin m} {i : Fin m'} {ho : (↑O).root = Pointer.node j} {hu : (↑U).root = Pointer.node i} :
                                                                        O.evaluate = U.evaluate(↑O).heap[j].var = (↑U).heap[i].var(O.low ho).evaluate = (U.low hu).evaluate
                                                                        theorem OBdd.evaluate_low_eq_of_evaluate_eq_and_var_eq {n m : } {O U : OBdd n m} {j i : Fin m} {ho : (↑O).root = Pointer.node j} {hu : (↑U).root = Pointer.node i} :
                                                                        O.evaluate = U.evaluate(↑O).heap[j].var = (↑U).heap[i].var(O.low ho).evaluate = (U.low hu).evaluate
                                                                        theorem OBdd.not_reduced_of_sim_high_low {n m : } {O : OBdd n m} {j : Fin m} (h : (↑O).root = Pointer.node j) :
                                                                        (O.high h).Similar (O.low h)¬O.Reduced
                                                                        def OBdd.HIsomorphism {n m n' m' : } (O : OBdd n m) (U : OBdd n' m') :
                                                                        Equations
                                                                        • One or more equations did not get rendered due to their size.
                                                                        Instances For
                                                                          def OBdd.Isomorphism {n m : } :
                                                                          OBdd n mOBdd n mProp
                                                                          Equations
                                                                          Instances For
                                                                            def OBdd.RelevantIsomorphism {n m : } (O : OBdd n m) (p q : (↑O).RelevantPointer) :
                                                                            Equations
                                                                            Instances For
                                                                              def OBdd.Reduced' {n m : } (O : OBdd n m) :
                                                                              Equations
                                                                              Instances For
                                                                                @[irreducible]
                                                                                theorem OBdd.Canonicity {n m m' : } {O : OBdd n m} {U : OBdd n m'} (ho : O.Reduced) (hu : U.Reduced) :

                                                                                Reduced OBDDs are canonical.

                                                                                theorem OBdd.terminal_of_constant {b : Bool} {n m : } (O : OBdd n m) :
                                                                                O.Reduced(O.evaluate = fun (x : Vector Bool n) => b) → (↑O).root = Pointer.terminal b

                                                                                The only reduced BDD that denotes a constant function is the terminal BDD.

                                                                                theorem OBdd.Canonicity_reverse {n m m' : } {O : OBdd n m} {U : OBdd n m'} :
                                                                                @[irreducible]
                                                                                theorem OBdd.not_oedge_reachable {n m : } {O U : OBdd n m} :
                                                                                OEdge O U¬Pointer.Reachable (↑O).heap (↑U).root (↑O).root

                                                                                An acyclicity lemma: an edge from O to U implies that O is not reachable from U.

                                                                                theorem Pointer.Reachable_iff {n m : } {r p : Pointer m} {M : Vector (Node n m) m} :
                                                                                Reachable M r p r = p ∃ (j : Fin m), r = node j (Reachable M M[j].low p Reachable M M[j].high p)
                                                                                theorem OBdd.reachable_or_eq_low_high {n m : } {p : Pointer m} {O : OBdd n m} :
                                                                                Pointer.Reachable (↑O).heap (↑O).root p(↑O).root = p ∃ (j : Fin m) (h : (↑O).root = Pointer.node j), Pointer.Reachable (↑O).heap (↑(O.low h)).root p Pointer.Reachable (↑O).heap (↑(O.high h)).root p
                                                                                theorem not_isTerminal_of_root_eq_node {n m : } {j : Fin m} {O : OBdd n m} (h : (↑O).root = Pointer.node j) :
                                                                                def OBdd.OReachable {n m : } (a : OBdd n m) :
                                                                                OBdd n mProp
                                                                                Equations
                                                                                Instances For
                                                                                  theorem OBdd.low_oreachable {n m : } {j : Fin m} {O U : OBdd n m} {U_root_def : (↑U).root = Pointer.node j} :
                                                                                  O.OReachable UO.OReachable (U.low U_root_def)
                                                                                  theorem OBdd.high_oreachable {n m : } {j : Fin m} {O U : OBdd n m} {U_root_def : (↑U).root = Pointer.node j} :
                                                                                  O.OReachable UO.OReachable (U.high U_root_def)
                                                                                  theorem OBdd.reachable_node_iff {n m : } {j : Fin m} {O : OBdd n m} (h : (↑O).root = Pointer.node j) :
                                                                                  Pointer.Reachable (↑O).heap (↑O).root = fun (q : Pointer m) => Pointer.Reachable (↑O).heap (↑O).root q ¬Pointer.Reachable (↑O).heap (↑(O.low h)).root q ¬Pointer.Reachable (↑O).heap (↑(O.high h)).root q Pointer.Reachable (↑O).heap (↑(O.low h)).root q ¬Pointer.Reachable (↑O).heap (↑(O.high h)).root q Pointer.Reachable (↑O).heap (↑(O.high h)).root q ¬Pointer.Reachable (↑O).heap (↑(O.low h)).root q Pointer.Reachable (↑O).heap (↑(O.low h)).root q Pointer.Reachable (↑O).heap (↑(O.high h)).root q
                                                                                  instance OBdd.instFintypeReachableFromNode {n m : } {j : Fin m} (O : OBdd n m) (h : (↑O).root = Pointer.node j) :
                                                                                  Fintype { q : Pointer m // q = (↑O).root Pointer.Reachable (↑O).heap (↑(O.low h)).root q Pointer.Reachable (↑O).heap (↑(O.high h)).root q }
                                                                                  Equations
                                                                                  • One or more equations did not get rendered due to their size.
                                                                                  theorem OBdd.reachable_from_node_iff' {n m : } {j : Fin m} {p : Pointer m} {O : OBdd n m} (h : (↑O).root = Pointer.node j) :
                                                                                  Pointer.Reachable (↑O).heap (↑O).root p p = (↑O).root Pointer.Reachable (↑O).heap (↑(O.low h)).root p Pointer.Reachable (↑O).heap (↑(O.high h)).root p
                                                                                  theorem OBdd.card_reachable_node' {n m : } {j : Fin m} {O : OBdd n m} (h : (↑O).root = Pointer.node j) :
                                                                                  Fintype.card { p : Pointer m // Pointer.Reachable (↑O).heap (↑O).root p } = Fintype.card { p : Pointer m // p = (↑O).root Pointer.Reachable (↑O).heap (↑(O.low h)).root p Pointer.Reachable (↑O).heap (↑(O.high h)).root p }
                                                                                  theorem OBdd.eq_root_disjoint_reachable_low_or_high {n m : } {j : Fin m} {O : OBdd n m} (h : (↑O).root = Pointer.node j) :
                                                                                  Disjoint (fun (x : Pointer m) => x = (↑O).root) fun (p : Pointer m) => Pointer.Reachable (↑O).heap (↑(O.low h)).root p Pointer.Reachable (↑O).heap (↑(O.high h)).root p
                                                                                  theorem OBdd.card_reachable_node {n m : } {j : Fin m} {O : OBdd n m} (h : (↑O).root = Pointer.node j) :
                                                                                  Fintype.card { q : Pointer m // Pointer.Reachable (↑O).heap (↑O).root q } = 1 + Fintype.card { q : Pointer m // Pointer.Reachable (↑(O.low h)).heap (↑(O.low h)).root q Pointer.Reachable (↑(O.high h)).heap (↑(O.high h)).root q }
                                                                                  theorem Bdd.ordered_of_low_high_ordered {n m : } {j : Fin m} {B : Bdd n m} (h : B.root = Pointer.node j) :
                                                                                  (B.low h).OrderedB.var < (B.low h).var(B.high h).OrderedB.var < (B.high h).varB.Ordered
                                                                                  @[irreducible]
                                                                                  theorem Bdd.ordered_of_ordered_heap_not_reachable_set {n m : } (O : OBdd n m) (i : Fin m) (N : Node n m) :
                                                                                  ¬Pointer.Reachable (↑O).heap (↑O).root (Pointer.node i){ heap := (↑O).heap.set (↑i) N , root := (↑O).root }.Ordered
                                                                                  theorem Pointer.mayPrecede_of_reachable {n m : } {p : Pointer m} {B : Bdd n m} :
                                                                                  B.OrderedReachable B.heap B.root ptoVar B.heap B.root toVar B.heap p
                                                                                  theorem OBdd.reduced_var_dependent {n m : } {O : OBdd n m} {p : Fin n} :
                                                                                  O.Reduced(∀ (i : Fin p), Nary.IndependentOf O.evaluate i, )p (↑O).var
                                                                                  def Bdd.usesVar {n m : } (B : Bdd n m) (i : Fin n) :
                                                                                  Equations
                                                                                  Instances For
                                                                                    theorem Bdd.usesVar_of_high_usesVar {n m : } {j : Fin m} {i : Fin n} {B : Bdd n m} {h : B.root = Pointer.node j} :
                                                                                    (B.high h).usesVar iB.usesVar i
                                                                                    theorem Bdd.usesVar_of_low_usesVar {n m : } {j : Fin m} {i : Fin n} {B : Bdd n m} {h : B.root = Pointer.node j} :
                                                                                    (B.low h).usesVar iB.usesVar i
                                                                                    theorem OBdd.usesVar_of_high_usesVar {n m : } {j : Fin m} {i : Fin n} {O : OBdd n m} {h : (↑O).root = Pointer.node j} :
                                                                                    (↑(O.high h)).usesVar i(↑O).usesVar i
                                                                                    theorem OBdd.usesVar_of_low_usesVar {n m : } {j : Fin m} {i : Fin n} {O : OBdd n m} {h : (↑O).root = Pointer.node j} :
                                                                                    (↑(O.low h)).usesVar i(↑O).usesVar i
                                                                                    @[irreducible]
                                                                                    theorem OBdd.dependsOn_of_usesVar_of_reduced {n m : } {j : Fin m} {i : Fin n} {O : OBdd n m} :
                                                                                    O.ReducedPointer.Reachable (↑O).heap (↑O).root (Pointer.node j)(↑O).heap[j].var = i∃ (v : Vector Bool n), O.evaluate v O.evaluate (v.set (↑i) true )
                                                                                    @[irreducible]
                                                                                    theorem OBdd.usesVar_of_dependsOn {n m : } {v : Vector Bool n} {b : Bool} {O : OBdd n m} {i : Fin n} :
                                                                                    O.evaluate v O.evaluate (v.set (↑i) b )(↑O).usesVar i
                                                                                    theorem OBdd.usesVar_iff_dependsOn_of_reduced {n m : } {i : Fin n} {O : OBdd n m} :
                                                                                    theorem OBdd.usesVar_iff {n m : } (i : Fin n) (O : OBdd n m) :
                                                                                    (↑O).usesVar i ∃ (j : Fin m) (hj : (↑O).root = Pointer.node j), (↑O).heap[j].var = i (↑(O.low hj)).usesVar i (↑(O.high hj)).usesVar i
                                                                                    @[irreducible]
                                                                                    theorem OBdd.toTree_usesVar {n m : } {i : Fin n} {O : OBdd n m} :
                                                                                    theorem OBdd.evaluate_eq_of_forall_usesVar {n m : } {O : OBdd n m} {I J : Vector Bool n} :
                                                                                    (∀ (i : Fin n), (↑O).usesVar iI[i] = J[i])O.evaluate I = O.evaluate J
                                                                                    theorem Pointer.eq_terminal_of_reachable {n✝ n✝¹ : } {w : Vector (Node n✝ n✝¹) n✝¹} {b : Bool} {p : Pointer n✝¹} :
                                                                                    Reachable w (terminal b) pp = terminal b
                                                                                    theorem Bdd.terminal_of_zero_vars {n m : } {B : Bdd n m} :
                                                                                    n = 0∃ (b : Bool), B.root = Pointer.terminal b
                                                                                    theorem Bdd.terminal_of_zero_heap {n m : } {B : Bdd n m} :
                                                                                    m = 0∃ (b : Bool), B.root = Pointer.terminal b
                                                                                    theorem Pointer.toVar_lt_of_trans_edge_of_ordered {n✝ n✝¹ : } {M : Vector (Node n✝ n✝¹) n✝¹} {x y : Pointer n✝¹} :
                                                                                    { heap := M, root := x }.OrderedRelation.TransGen (Edge M) x ytoVar M x < toVar M y