0size returns positive valuesavghead and tail are Safeaveragemapinitinit'insertLists ElementsListkeysMapevalcreate : Allocate and Fill a ByteStringunsafeTake : Extract prefix of size nunpack : Convert ByteString into List of Char
sort :: (Ord a) => List a -> List a
sort [] = Emp
sort (x:xs) = insert x (sort xs)
insert :: (Ord a) => a -> List a -> List a
insert x Emp = x ::: Emp
insert x (y:::ys)
| x <= y = x ::: y ::: ys
| otherwise = y ::: insert x ys
Goal: specify & verify that output:
insertQ: Can you fix the type of insert so sort checks?
Same size is all fine, how about same elements in output?
Hence, we can write Set-valued measures
Using the Data.Set API for convenience
import qualified Data.Set as S
Lists Elementsinline lets us reuse Haskell terms in refinements.
Lets verify that sortE returns the same set of elements:
Q: Can you fix the type for insertE so sortE verifies?
Yes, yes, but does sort actually sort ?
How to specify ordered lists ?
Lets write a type for ordered pairs
Legal Values value of opX < opY
okPair = OP 2 4 -- legal
badPair = OP 4 2 -- illegal
Q: Can you refine the data type to legal values only?
Q: Can you refine Csv so scores' is rejected?
Refine the List data type to enforce ordering!
Lets define a type for ordered lists
Lets refine the type to enforce order
Head oHd is smaller than every value v in tail oTl
Illegal values unrepresentable
Q: Oops. There's a problem! Can you fix it?
ListWe just wrote two measures for List
length :: List a -> Natelems :: List a -> Set a
Data constructor refinements are conjoined
data List a where
Emp :: {v:List a | length v = 0
&& elems v = empty}
(:::) :: x:a
-> xs:List a
-> {v:List a | length v = 1 + length xs
&& elems v = addElem x xs }
Unlike indexed types, measures ...
Decouple properties from data type
Reuse same data type with different invariants
Limited to decidable logics but ...
Offer massive amounts of automation
Compare with insertionSort in:
Next: Case Studies