Guest User

Untitled

a guest
Jan 18th, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.46 KB | None | 0 0
  1. {-@ LIQUID "--no-termination" @-}
  2. {-@ LIQUID "--reflection" @-}
  3. {-@ LIQUID "--no-adt" @-}
  4. {- LIQUID "--diff" @-}
  5. {-@ LIQUID "--ple" @-}
  6.  
  7. module FingerTree where
  8.  
  9. import Language.Haskell.Liquid.ProofCombinators
  10.  
  11. {-@ measure digitSize @-}
  12. digitSize :: Digit a -> Int
  13. digitSize (One {}) = 1
  14. digitSize (Two {}) = 2
  15. digitSize (Three {}) = 3
  16. digitSize (Four {}) = 4
  17.  
  18. data Digit a
  19. = One a
  20. | Two a a
  21. | Three a a a
  22. | Four a a a a
  23. deriving (Show)
  24.  
  25. data Node a = Node2 {a2::a, b2::a} | Node3 {a3::a, b3::a, c3:: a}
  26. deriving (Show)
  27.  
  28. data FingerTree a
  29. = Empty
  30. | Single a
  31. | Deep (Digit a) (FingerTree (Node a)) (Digit a)
  32. deriving Show
  33.  
  34. {-@ reflect fingerTreeSize @-}
  35. fingerTreeSize :: FingerTree a -> Int
  36. fingerTreeSize t = size to1 t
  37.  
  38. {-@ reflect size @-}
  39. size :: (a -> Int) -> FingerTree a -> Int
  40. size _ Empty = 0
  41. size f (Single a) = f a
  42. size f (Deep l m r) = digitS f l + size (nodeS f) m + digitS f r
  43.  
  44. {-@ reflect digitS @-}
  45. digitS :: (a -> Int) -> Digit a -> Int
  46. digitS f (One a) = f a
  47. digitS f (Two a b) = f a + f b
  48. digitS f (Three a b c) = f a + f b + f c
  49. digitS f (Four a b c d) = f a + f b + f c + f d
  50.  
  51. {-@ reflect nodeS @-}
  52. nodeS :: (a -> Int) -> Node a -> Int
  53. nodeS f (Node2 a b) = f a + f b
  54. nodeS f (Node3 a b c) = f a + f b + f c
  55.  
  56. {-@ reflect consts @-}
  57. consts a b = a
  58.  
  59. {-@ reflect to1 @-}
  60. to1 :: a -> Int
  61. to1 _ = 1
  62.  
  63. {-@ n2Int1 :: a:Int -> b:Int -> {n:Node Int | nodeS to1 n == 2} @-}
  64. n2Int1 :: Int -> Int -> Node Int
  65. n2Int1 a b = Node2 a b
  66.  
  67. -- {-@ n2Int :: a:Int -> b:Int -> {f:(Int -> Int) | f a == 1 && f b == 1} -> {n:Node Int | nodeS f n == 2} @-}
  68. -- n2Int :: Int -> Int -> (Int -> Int) -> Node Int
  69. -- n2Int a b f = Node2 a b
  70.  
  71. {-@ measure isEmpty @-}
  72. isEmpty Empty = True
  73. isEmpty (Single _) = False
  74. isEmpty Deep{} = False
  75.  
  76. {-@ singleton :: v:Int -> {ft:FingerTree Int | isEmpty ft} @-}
  77. singleton :: Int -> FingerTree Int
  78. singleton a = Empty
  79.  
  80. {-@ fromList :: xs:_ -> {t:_ | fingerTreeSize t == len xs} @-}
  81. fromList :: [a] -> FingerTree a
  82. fromList [] = Empty
  83. fromList (x:xs) = add x (fromList xs)
  84.  
  85. {-@ infix <| @-}
  86. -- | /O(1)/. Add an element to the left end of a sequence.
  87. -- Mnemonic: a triangle with the single element at the pointy end.
  88. {- (<|) :: a -> ft:FingerTree a -> {v : FingerTree a | fingerTreeSize v == fingerTreeSize ft + 1} @-}
  89. {-@ reflect <| @-}
  90. (<|) :: a -> FingerTree a -> FingerTree a
  91. a <| Empty = Single a
  92. a <| Single b = Deep (One a) Empty (One b)
  93. a <| Deep (Four b c d e) m sf = {- m `seq` -} Deep (Two a b) (Node3 c d e <| m) sf
  94. a <| Deep l m r = Deep (consDigit a l) m r
  95.  
  96. {-@ lem_add :: f:_ -> a:_ -> t:_ -> { size f (a <| t) == size f t + f a } @-}
  97. lem_add :: (a -> Int) -> a -> FingerTree a -> ()
  98.  
  99. lem_add f _ Empty
  100. = ()
  101.  
  102. lem_add f _ (Single {})
  103. = ()
  104.  
  105. lem_add f a t@(Deep (Four b c d e) m sf)
  106. = size f t + f a
  107. === digitS f (Four b c d e) + size (nodeS f) m + digitS f sf + f a
  108. === f a + f b + digitS f sf + f c + f d + f e + size (nodeS f) m
  109. === f a + f b + digitS f sf + nodeS f (Node3 c d e) + size (nodeS f) m
  110. ? lem_add (nodeS f) (Node3 c d e) m
  111. === f a + f b + digitS f sf + size (nodeS f) ((Node3 c d e) <| m)
  112. === size f (Deep (Two a b) ((Node3 c d e) <| m) sf)
  113. === size f (a <| (Deep (Four b c d e) m sf))
  114. === size f (a <| t)
  115. *** QED
  116.  
  117. lem_add f a t@(Deep l m r)
  118. = ()
  119.  
  120. {-@ thm_add :: a:_ -> t:_ -> { fingerTreeSize (a <| t) == 1 + fingerTreeSize t} @-}
  121. thm_add :: a -> FingerTree a -> Proof -- FingerTree a
  122. thm_add a t
  123. = fingerTreeSize (a <| t)
  124. === size to1 (a <| t)
  125. ? lem_add to1 a t
  126. === size to1 t + to1 a
  127. === fingerTreeSize t + 1
  128. *** QED
  129.  
  130. {-@ add :: a:_ -> t:_ -> { v: _ | fingerTreeSize v == 1 + fingerTreeSize t} @-}
  131. add :: a -> FingerTree a -> FingerTree a
  132. add a t = (a <| t) ? thm_add a t
  133.  
  134. {-@ measure isFour @-}
  135. isFour :: Digit a -> Bool
  136. isFour (Four {}) = True
  137. isFour _ = False
  138.  
  139. {-@ reflect consDigit @-}
  140. {-@ consDigit :: _ -> {d:_ | not (isFour d)} -> _ @-}
  141. consDigit :: a -> Digit a -> Digit a
  142. consDigit a (One b) = Two a b
  143. consDigit a (Two b c) = Three a b c
  144. consDigit a (Three b c d) = Four a b c d
  145.  
  146. {-@ ft1 :: {v:_ | fingerTreeSize v == 10} @-}
  147. ft1 :: FingerTree Int
  148. ft1 = fromList [1,2,3,4,5,6,7,8,9,10]
  149.  
  150. {-@ ten :: {v:_ | len v = 10} @-}
  151. ten :: [Int]
  152. ten = [1,2,3,4,5,6,7,8,9,10]
  153.  
  154. ft2 :: FingerTree Int
  155. ft2 = fromList [1..20000]
  156.  
  157. main :: IO ()
  158. main = do
  159. print "test"
  160. print $ fingerTreeSize ft1 -- 10
  161. print $ fingerTreeSize ft2 -- 20000
Add Comment
Please, Sign In to add comment