import Base import ./lib.bend as T # empty is Leaf. law empty_is_leaf: for -a: Quant for -A: Kind(a) { T.Tree.empty(a, A) == T.Leaf{} : T.Tree } # leaf is Leaf. law leaf_is_leaf: for -a: Quant for -A: Kind(a) { T.Tree.leaf(a, A) == T.Leaf{} : T.Tree } # leaf equals empty. law leaf_eq_empty: for -a: Quant for -A: Kind(a) { T.Tree.leaf(a, A) == T.Tree.empty(a, A) : T.Tree } # singleton is Node{Leaf, x, Leaf}. law singleton_is_node: for -a: Quant for -A: Kind(a) for x: A { T.Tree.singleton(a, A, x) == T.Node{T.Leaf{}, x, T.Leaf{}} : T.Tree } # size(empty) is 0. law size_empty: for -a: Quant for -A: Kind(a) { T.Tree.size(a, A, T.Tree.empty(a, A)) == 0n : Nat } # size(Leaf) is 0. law size_leaf: for -a: Quant for -A: Kind(a) { T.Tree.size(a, A, T.Leaf{}) == 0n : Nat } # size(singleton(x)) is 1. law size_singleton: for -a: Quant for -A: Kind(a) for x: A { T.Tree.size(a, A, T.Tree.singleton(a, A, x)) == 1n : Nat } # size(Node{Leaf,x,Leaf}) is 1. law size_node_leaves: for -a: Quant for -A: Kind(a) for x: A { T.Tree.size(a, A, T.Node{T.Leaf{}, x, T.Leaf{}}) == 1n : Nat } # Definitional size of Node. law size_node_def: for -a: Quant for -A: Kind(a) for l: T.Tree for v: A for r: T.Tree { T.Tree.size(a, A, T.Node{l, v, r}) == 1n+Nat.add(T.Tree.size(a, A, l), T.Tree.size(a, A, r)) : Nat } # size(Node{Leaf, x, singleton(y)}) is 2. law size_left_leaf_right_one: for -a: Quant for -A: Kind(a) for x: A for y: A { T.Tree.size(a, A, T.Node{T.Leaf{}, x, T.Tree.singleton(a, A, y)}) == 2n : Nat } # size of balanced three-node tree is 3. law size_both_singletons: for -a: Quant for -A: Kind(a) for x: A for y: A for z: A { T.Tree.size(a, A, T.Node{T.Tree.singleton(a, A, x), y, T.Tree.singleton(a, A, z)}) == 3n : Nat } # to_list(empty) is Nil. law to_list_empty: for -a: Quant for -A: Kind(a) { T.Tree.to_list(a, A, T.Tree.empty(a, A)) == Nil{} : List } # to_list(Leaf) is Nil. law to_list_leaf: for -a: Quant for -A: Kind(a) { T.Tree.to_list(a, A, T.Leaf{}) == Nil{} : List } # to_list(singleton(x)) is x <> Nil. law to_list_singleton: for -a: Quant for -A: Kind(a) for x: A { T.Tree.to_list(a, A, T.Tree.singleton(a, A, x)) == x <> Nil{} : List } # to_list(Node{Leaf,x,Leaf}) is x <> Nil. law to_list_node_leaves: for -a: Quant for -A: Kind(a) for x: A { T.Tree.to_list(a, A, T.Node{T.Leaf{}, x, T.Leaf{}}) == x <> Nil{} : List } # to_list with right singleton. law to_list_right_one: for -a: Quant for -A: Kind(a) for x: A for y: A { T.Tree.to_list(a, A, T.Node{T.Leaf{}, x, T.Tree.singleton(a, A, y)}) == x <> (y <> Nil{}) : List } # to_list with left singleton. law to_list_left_one: for -a: Quant for -A: Kind(a) for x: A for y: A { T.Tree.to_list(a, A, T.Node{T.Tree.singleton(a, A, x), y, T.Leaf{}}) == x <> (y <> Nil{}) : List } # is_empty(empty) is True. law is_empty_empty: for -a: Quant for -A: Kind(a) { T.Tree.is_empty(a, A, T.Tree.empty(a, A)) == True{} : Bool } # is_empty(Leaf) is True. law is_empty_leaf: for -a: Quant for -A: Kind(a) { T.Tree.is_empty(a, A, T.Leaf{}) == True{} : Bool } # is_empty(singleton(x)) is False. law is_empty_singleton: for -a: Quant for -A: Kind(a) for x: A { T.Tree.is_empty(a, A, T.Tree.singleton(a, A, x)) == False{} : Bool } # is_empty(Node{...}) is False. law is_empty_node: for -a: Quant for -A: Kind(a) for l: T.Tree for v: A for r: T.Tree { T.Tree.is_empty(a, A, T.Node{l, v, r}) == False{} : Bool }