0 | module Data.Container.Base.TreeUtils
2 | import Decidable.Equality
3 | import Language.Reflection
4 | import Derive.Prelude
7 | import Data.Container.Base.Object.Definition
8 | import Data.Container.Base.Extension.Definition
10 | import Data.Container.SubTerm
12 | %language ElabReflection
33 | namespace BinaryTrees
36 | data BinTreeShape : Type where
37 | LeafS : BinTreeShape
38 | NodeS : BinTreeShape -> BinTreeShape -> BinTreeShape
40 | %runElab derive "BinTreeShape" [Eq, Show]
41 | %name BinTreeShape
b, b1, b2, b3, b4, b5
44 | numLeaves : BinTreeShape -> Nat
46 | numLeaves (NodeS lt rt) = numLeaves lt + numLeaves rt
49 | numNodes : BinTreeShape -> Nat
51 | numNodes (NodeS lt rt) = numNodes lt + (1 + numNodes rt)
54 | numNodesAndLeaves : BinTreeShape -> Nat
55 | numNodesAndLeaves LeafS = 1
56 | numNodesAndLeaves (NodeS lt rt)
57 | = numNodesAndLeaves lt + (1 + numNodesAndLeaves rt)
59 | namespace NodesAndLeaves
62 | data BinTreePos : (b : BinTreeShape) -> Type where
63 | AtLeaf : BinTreePos LeafS
64 | AtNode : {l, r : BinTreeShape} -> BinTreePos (NodeS l r)
65 | GoLeft : {l, r : BinTreeShape} -> BinTreePos l -> BinTreePos (NodeS l r)
66 | GoRight : {l, r : BinTreeShape} -> BinTreePos r -> BinTreePos (NodeS l r)
68 | %runElab deriveIndexed "BinTreePos" [Eq, Show]
73 | MOrd (BinTreePos b) where
74 | mcompare AtLeaf AtLeaf = Just EQ
75 | mcompare AtNode AtNode = Just EQ
76 | mcompare (GoLeft b1) (GoLeft b2) = mcompare b1 b2
77 | mcompare (GoRight b1) (GoRight b2) = mcompare b1 b2
78 | mcompare AtNode (GoLeft _) = Just LT
79 | mcompare AtNode (GoRight _) = Just LT
80 | mcompare (GoLeft _) AtNode = Just GT
81 | mcompare (GoRight _) AtNode = Just GT
82 | mcompare (GoLeft _) (GoRight _) = Nothing
83 | mcompare (GoRight _) (GoLeft _) = Nothing
90 | data BinTreePosNode : (b : BinTreeShape) -> Type where
91 | AtNode : {l, r : BinTreeShape} -> BinTreePosNode (NodeS l r)
92 | GoLeft : {l, r : BinTreeShape} -> BinTreePosNode l -> BinTreePosNode (NodeS l r)
93 | GoRight : {l, r : BinTreeShape} -> BinTreePosNode r -> BinTreePosNode (NodeS l r)
95 | %runElab deriveIndexed "BinTreePosNode" [Eq, Show]
98 | {b : BinTreeShape} -> Finite (BinTreePosNode b) where
99 | values {b = LeafS} = []
100 | values {b = (NodeS l r)} =
101 | let tl = GoLeft <$> values {a=BinTreePosNode l}
102 | tr = GoRight <$> values {a=BinTreePosNode r}
103 | in tl ++ [AtNode] ++ tr
106 | MOrd (BinTreePosNode b) where
107 | mcompare AtNode AtNode = Just EQ
108 | mcompare (GoLeft b1) (GoLeft b2) = mcompare b1 b2
109 | mcompare (GoRight b1) (GoRight b2) = mcompare b1 b2
110 | mcompare AtNode (GoLeft _) = Just LT
111 | mcompare AtNode (GoRight _) = Just LT
112 | mcompare (GoLeft _) AtNode = Just GT
113 | mcompare (GoRight _) AtNode = Just GT
114 | mcompare (GoLeft _) (GoRight _) = Nothing
115 | mcompare (GoRight _) (GoLeft _) = Nothing
120 | data BinTreePosLeaf : (b : BinTreeShape) -> Type where
121 | AtLeaf : BinTreePosLeaf LeafS
122 | GoLeft : {l, r : BinTreeShape} -> BinTreePosLeaf l -> BinTreePosLeaf (NodeS l r)
123 | GoRight : {l, r : BinTreeShape} -> BinTreePosLeaf r -> BinTreePosLeaf (NodeS l r)
125 | %runElab deriveIndexed "BinTreePosLeaf" [Eq, Show]
129 | {b : BinTreeShape} -> Finite (BinTreePosLeaf b) where
130 | values {b = LeafS} = [AtLeaf]
131 | values {b = (NodeS l r)} =
132 | let tl = GoLeft <$> values {a=BinTreePosLeaf l}
133 | tr = GoRight <$> values {a=BinTreePosLeaf r}
137 | MOrd (BinTreePosLeaf b) where
138 | mcompare AtLeaf AtLeaf = Just EQ
139 | mcompare (GoLeft b1) (GoLeft b2) = mcompare b1 b2
140 | mcompare (GoRight b1) (GoRight b2) = mcompare b1 b2
141 | mcompare (GoLeft _) (GoRight _) = Nothing
142 | mcompare (GoRight _) (GoLeft _) = Nothing