packages feed

liquidhaskell-0.8.0.2: docs/slides/NEU14/02_Termination-blank.hs

module Termination (fac, tailFac, map, merge) where

import Prelude hiding (gcd, mod, map, repeat, take)
import Language.Haskell.Liquid.Prelude



-------------------------------------------------------------------------
-- | Simple Termination
-------------------------------------------------------------------------

fac   :: Int -> Int
fac   = undefined










-------------------------------------------------------------------------
-- | Semantic Termination
-------------------------------------------------------------------------

gcd :: Int -> Int -> Int
gcd a 0 = a
gcd a b = gcd b (a `mod` b)


mod :: Int -> Int -> Int
mod a b
  | a - b >  b = mod (a - b) b
  | a - b <  b = a - b
  | a - b == b = 0

-------------------------------------------------------------------------
-- Explicit Metrics #1 
-------------------------------------------------------------------------

tailFac   :: Int -> Int
tailFac n = loop 1 n

loop      :: Int -> Int -> Int
loop      = undefined

         


-------------------------------------------------------------------------
-- Explicit Metrics #2 
-------------------------------------------------------------------------

range :: Int -> Int -> [Int]
range lo hi = undefined



-------------------------------------------------------------------------
-- | Structural Recursion 
-------------------------------------------------------------------------

data List a = N | C a (List a)

map :: (a -> b) -> List a -> List b
map = undefined
















{-@ measure size :: List a -> Int
    size (N)      = 0  
    size (C x xs) = (1 + size xs)
  @-}




-------------------------------------------------------------------------
-- | Default Metrics
-------------------------------------------------------------------------


{-@ data List [size] a = N | C {x :: a, xs :: List a } @-}



-------------------------------------------------------------------------
-- | Termination Expressions Metrics
-------------------------------------------------------------------------

merge :: (Ord a) => List a -> List a -> List a
merge (C x xs) (C y ys)
  | x < y      = x `C` merge xs (y `C` ys)
  | otherwise  = y `C` merge (x `C` xs) ys
merge _   ys   = ys









-------------------------------------------------------------------------
-- | Infinite Streams
-------------------------------------------------------------------------

{- data List [sz] a <p :: List a -> Prop>
      = N | C { x  :: a
              , xs :: List <p> a <<p>>
              }
  -}


{-@ measure emp  :: (List a) -> Prop
    emp (N)      = true
    emp (C x xs) = false
  @-}

{- type Stream a = {xs: List <{\v -> not (emp v)}> a | not (emp xs)} @-}

{- Lazy repeat @-}
                 
{- repeat :: a -> Stream a @-}
-- repeat   :: a -> List a
-- repeat x = x `C` repeat x


{- take :: Nat -> Stream a -> List a @-}
-- take  :: Int -> List a -> List a
-- take 0 _        = N
-- take n (C x xs) = x `C` take (n-1) xs
-- take _ N        = liquidError "never happens"



























-----------------------------------------------------


{-@ invariant {v : List a | 0 <= size v} @-}