-- spec.hs: conjuring a function from a specification -- -- Adapted from Colin Runciman's example "ListFuns" import Conjure import Test.LeanCheck (holds, exists) import Prelude hiding (sum) squareSpec :: (Int -> Int) -> Bool squareSpec square = square 0 == 0 && square 1 == 1 && square 2 == 4 squarePrimitives :: [Prim] squarePrimitives = [ pr (0::Int) , pr (1::Int) , prim "+" ((+) :: Int -> Int -> Int) , prim "*" ((*) :: Int -> Int -> Int) ] squarePropertySpec :: (Int -> Int) -> Bool squarePropertySpec square = and [ holds n $ \x -> square x >= x , holds n $ \x -> square x >= 0 , exists n $ \x -> square x > x ] where n = 60 sumSpec :: ([Int] -> Int) -> Bool sumSpec sum = sum [] == 0 && sum [1,2] == 3 && sum [3,4,5] == 12 -- hoping for something like -- sum xs = if null xs then 0 else head xs + sum (tail xs) sumPrimitives :: [Prim] sumPrimitives = [ prim "null" (null :: [Int] -> Bool) , pr (0::Int) , prim "+" ((+) :: Int -> Int -> Int) , prim "head" (head :: [Int] -> Int) , prim "tail" (tail :: [Int] -> [Int]) ] appSpec :: ([Int] -> [Int] -> [Int]) -> Bool appSpec (++) = [] ++ [0,1] == [0,1] && [2,3] ++ [] == [2,3] && [4,5,6] ++ [7,8,9] == [4,5,6,7,8,9] -- hoping for something like -- app xs ys = if null xs then ys else head xs : app (tail xs) ys appPrimitives :: [Prim] appPrimitives = [ prim "null" (null :: [Int] -> Bool) , prim ":" ((:) :: Int -> [Int] -> [Int]) , prim "head" (head :: [Int] -> Int) , prim "tail" (tail :: [Int] -> [Int]) ] main :: IO () main = do conjureFromSpec "square" squareSpec squarePrimitives conjureFromSpec "square" squarePropertySpec squarePrimitives conjureFromSpec "sum" sumSpec sumPrimitives conjureFromSpec "++" appSpec appPrimitives