0 | module Data.Tree.Perfect
2 | import Control.WellFounded
3 | import Data.Monoid.Exponentiation
4 | import Data.Nat.Views
6 | import Data.Nat.Order.Properties
7 | import Data.Nat.Exponentiation
8 | import Syntax.WithProof
9 | import Syntax.PreorderReasoning.Generic
14 | data Tree : Nat -> Type -> Type where
15 | Leaf : a -> Tree Z a
16 | Node : Tree n a -> Tree n a -> Tree (S n) a
19 | Functor (Tree n) where
20 | map f (Leaf a) = Leaf (f a)
21 | map f (Node l r) = Node (map f l) (map f r)
24 | replicate : (n : Nat) -> a -> Tree n a
25 | replicate Z a = Leaf a
26 | replicate (S n) a = let t = replicate n a in Node t t
29 | {n : _} -> Applicative (Tree n) where
32 | Leaf f <*> Leaf a = Leaf (f a)
33 | Node fl fr <*> Node xl xr = Node (fl <*> xl) (fr <*> xr)
36 | data Path : Nat -> Type where
38 | Left : Path n -> Path (S n)
39 | Right : Path n -> Path (S n)
42 | toNat : {n : _} -> Path n -> Nat
44 | toNat (Left p) = toNat p
45 | toNat {n = S n} (Right p) = toNat p + pow2 n
48 | toNatBounded : (n : Nat) -> (p : Path n) -> toNat p `LT` pow2 n
49 | toNatBounded Z Here = reflexive
50 | toNatBounded (S n) (Left p) = CalcWith $
52 | <~ pow2 n ...( toNatBounded n p )
53 | <~ pow2 n + pow2 n ...( lteAddRight (pow2 n) )
54 | ~~ pow2 (S n) ...( sym unfoldPow2 )
55 | toNatBounded (S n) (Right p) = CalcWith $
56 | let ih = toNatBounded n p in
57 | |~ S (toNat p) + pow2 n
58 | <~ pow2 n + pow2 n ...( plusLteMonotoneRight _ _ _ ih )
59 | ~~ pow2 (S n) ...( sym unfoldPow2 )
69 | data View : (k, n : Nat) -> Type where
71 | SLT : (0 p : k `LT` pow2 n) -> View k (S n)
72 | SNLT : (0 p : k `GTE` pow2 n) ->
73 | (0 rec : minus k (pow2 n) `LT` pow2 n) -> View k (S n)
76 | view : (k, n : Nat) -> (0 _ : k `LT` (pow2 n)) -> View k n
78 | view (S _) Z p = void $
absurd (fromLteSucc p)
79 | view k (S n) p with (@@ lt k (pow2 n))
80 | view k (S n) p | (
True ** eq)
= SLT (ltIsLT k (pow2 n) eq)
81 | view k (S n) p | (
False ** eq)
= SNLT gte prf where
83 | 0 gte : k `GTE` pow2 n
84 | gte = notLTImpliesGTE (notltIsNotLT k (pow2 n) eq)
86 | 0 prf : minus k (pow2 n) `LT` pow2 n
88 | |~ S (minus k (pow2 n))
89 | <~ minus (pow2 (S n)) (pow2 n)
90 | ...( minusLtMonotone p pow2Increasing )
91 | ~~ minus (pow2 n + pow2 n) (pow2 n)
92 | ...( cong (\ m => minus m (pow2 n)) unfoldPow2 )
94 | ...( minusPlus (pow2 n) )
98 | fromNat : (k, n : Nat) -> (0 _ : k `LT` pow2 n) -> Path n
99 | fromNat k n p with (view k n p)
100 | fromNat Z Z p | ZZ = Here
101 | fromNat k (S n) p | SLT lt = Left (fromNat k n lt)
102 | fromNat k (S n) p | SNLT _ lt = Right (fromNat (minus k (pow2 n)) n lt)
106 | fromNatCorrect : (k, n : Nat) -> (0 p : k `LT` pow2 n) ->
107 | toNat (fromNat k n p) === k
108 | fromNatCorrect k n p with (view k n p)
109 | fromNatCorrect Z Z p | ZZ = Refl
110 | fromNatCorrect k (S n) p | SLT lt = fromNatCorrect k n lt
111 | fromNatCorrect k (S n) p | SNLT gte lt
112 | = rewrite fromNatCorrect (minus k (pow2 n)) n lt in
113 | irrelevantEq $
plusMinusLte (pow2 n) k gte
116 | lookup : Tree n a -> Path n -> a
117 | lookup (Leaf a) Here = a
118 | lookup (Node l _) (Left p) = lookup l p
119 | lookup (Node _ r) (Right p) = lookup r p