Unfailing Haskell: Stopping Pattern Match Errors Neil Mitchell and - - PowerPoint PPT Presentation
Unfailing Haskell: Stopping Pattern Match Errors Neil Mitchell and - - PowerPoint PPT Presentation
Unfailing Haskell: Stopping Pattern Match Errors Neil Mitchell and Colin Runciman University of York, UK http://www.cs.york.ac.uk/~ ndm/ Is this safe? r i ser s : : O r d a => [ a] - > [ [ a] ] r i ser s [ ] = [ ] r i ser s [ x] =
Is this safe?
r i ser s : : O r d a => [ a] - > [ [ a] ] r i ser s [ ] = [ ] r i ser s [ x] = [ [ x] ] r i ser s ( x: y: et c) = i f x <= y t hen ( x: s) : ss el se [ x] : ( s: ss) wher e ( s: ss) = r i ser s ( y: et c) > r i ser s [ 1, 2, 3, 1, 2] [ [ 1, 2, 3] , [ 1, 2] ]
Answer: Yes
Reasoning:
( s: ss) = r i ser s ( y: et c) ∴ r i ser s ( _: _) = ( _: _)
By case analysis:
r i ser s [ x] = [ [ x] ] r i ser s ( x: y: et c) = ( x: s) : ss or [ x] ( s: ss)
Is this safe?
t r anspose : : [ [ a] ] - > [ [ a] ] t r anspose x@ ( ( _: _) : _) = m ap head x : t r anspose ( m ap t ai l x) t r anspose x = [ ] > t r anspose [ “ 123” , ” 456” , ” 789” ] [ “ 147” , ” 258” , ” 369” ]
Answer: No
Try:
t r anspose [ “ 123” , ” 45” ] Pr ogr am er r or : pat t er n m at ch f ai l ur e: head [ ]
The checker
Takes reduced Haskell Generates a proof that a program will
not crash with a case error
Uses static analysis It is conservative
Reduced Haskell
dat a Li st = Cons Cons 1 Cons 2 | Ni l head @ 1 = case @ 1 of Cons - > @
- 1. Cons1
m ap @ 1 @ 2 = case @ 2 of Ni l - > Ni l Cons - > Cons ( @ 1 @
- 2. Cons1) ( m
ap @ 1 @
- 2. Cons2)
r ever se @ 1 = r ev @ 1 Ni l r ev @ 1 @ 2 = case @ 1 of Ni l - > @ 2 Cons - > r ev @
- 1. Cons2 ( Cons @
- 1. Cons1 @
2)
An overview
Find non-exhaustive patterns Find callers Perform backward analysis Perform fixed pointing Report result Reduced Haskell Haskell Program
Constraints, intro by example
head ( x: xs) = x head@ 1{ : } f r om Just ( Just x) = x f r om Just @ 1{ Just } f ol dr 1 f [ x] = x f ol dr 1 f ( x: xs) = f x ( f ol dr 1 f xs) f ol dr 1@ 2{ : }
Constraints with paths
m apHead [ ] = [ ] m apHead ( x: xs) = head x : m apHead xs m apHead@
- 1. * t ai l . head{ : }
m apHead@
- 1. head{ : } ^
m apHead@
- 1. t ai l . head{ : } ^
m apHead@
- 1. t ai l . t ai l . head{ : } ^ …
Finding a fixed point
In m
apHead
@
1 ≠ @
- 1. t ai l
Condition, ignoring recursive call
m
apHead@
- 1. head{ : }
Rule
@
n ≠ @
- n. pat h fl
@ n¶ = @
- n. * pat h
m
apHead@
- 1. * t ai l . head{ : }
Infinite constraints
r evHead x = m apHead ( r ever se x) r evHead@
- 1. * t ai l { : }
r evHead@
- 1. * t ai l { : } ∨
r evHead@
- 1. * t ai l . head{ : }
r evHead@ 1{ : } ^ r evHead@
- 1. t ai l { : } ^
r evHead@
- 1. t ai l . t ai l { : } ^ …
r evHead@ 1 is infinite
Backward Analysis
head@
1{ : } , applies to head
f @
1 = head ( i ni t @ 1)
( i ni t f @
1) { : } , applies to…?
Backward analysis
Const r ai nt Expr - > Const r ai nt Ar g
f @
- 1. t ai l { : }
Higher Order Functions
They complicate analysis Can be removed in some cases
m
ap, f ol dr , f ol dl , f i l t er . . .
t est n x = m ap ( f n) x m apf n [ ] = [ ] m apf n ( x: xs) = f n x : m apf n xs
Laziness
A function may be safe lazily, but not
strictly
saf eTai l X = cond ( nul l x) [ ] ( t ai l x) cond c t f = i f c t hen t el se f
Can inline
saf eTai l x = i f nul l x t hen [ ] el se t ai l x
Real Programs
Has been tested on real programs
Clausify – propositional simplifier Adjoxo – adjudicate XOX games Soda – word search solver
Minor modifications were needed for
success
Apart from Clausify
Conclusions
Manages to prove a function safe wrt
pattern match errors, even if incomplete patterns
Algorithm identified and implemented Good initial results Future Work
Improve results Better support for full Haskell