Static Contract Checking for Haskell - PowerPoint PPT Presentation

1 / 41
About This Presentation
Title:

Static Contract Checking for Haskell

Description:

else head xs `max` 0. No more warnings from compiler! 5. Satisfying a ... e 2 t , e B t is crash-free (related to Blume&McAllester:ICFP'04) Normal form e' ... – PowerPoint PPT presentation

Number of Views:20
Avg rating:3.0/5.0
Slides: 42
Provided by: nx5000
Category:

less

Transcript and Presenter's Notes

Title: Static Contract Checking for Haskell


1
Static Contract Checking for Haskell
  • Dana N. Xu
  • University of Cambridge
  • Joint work with

Simon Peyton Jones Microsoft Research Cambridge
Koen Claessen Chalmers University of Technology
2
Program Errors Give Headache!
  • Module UserPgm where
  • f Int-gtInt
  • f xs head xs max 0
  • f

Module Prelude where head a -gt a head
(xxs) x head error empty list
Glasgow Haskell Compiler (GHC) gives at
run-time Exception Prelude.head empty list
3
Typesgtgt gt gt gt gt Contracts gtgt gt gt gt gt
  • head (xxs) x
  • head Int -gt Int
  • (head 1)
  • head 2 xs not (null xs) -gt r True
  • (head )

Type
not Bool -gt Bool not True False not False
True null a -gt Bool null True null
(xxs) False
Bug!
Contract (original Haskell boolean expression)
Bug!
4
Contract Checking
  • head 2 xs not (null xs) -gt r True
  • head (xxs) x
  • f xs head xs max 0
  • Warning f calls head
  • which may fail heads precondition!
  • f_ok xs if null xs then 0
  • else head xs max 0

No more warnings from compiler!
5
Satisfying a predicate contract
Arbitrary boolean-valued Haskell expression
  • e 2 x p if (1) pe/x gives True and
  • (2) e is crash-free.

Recursive function, higher-order function,
partial function can be called!
6
Expressiveness of the Specification Language
data T T1 Bool T2 Int T3 T T sumT T -gt
Int sumT 2 x noT1 x -gt r True sumT (T2
a) a sumT (T3 t1 t2) sumT t1 sumT t2 noT1
T -gt Bool noT1 (T1 _) False noT1 (T2 _)
True noT1 (T3 t1 t2) noT1 t1 noT1 t2
7
Expressiveness of the Specification Language
  • sumT T -gt Int
  • sumT 2 x noT1 x -gt r True
  • sumT (T2 a) a
  • sumT (T3 t1 t2) sumT t1 sumT t2
  • rmT1 T -gt T
  • rmT1 2 x True -gt r noT1 r
  • rmT1 (T1 a) if a then T2 1 else T2 0
  • rmT1 (T2 a) T2 a
  • rmT1 (T3 t1 t2) T3 (rmT1 t1) (rmT1 t2)
  • For all crash-free tT, sumT (rmT1 t) will not
    crash.

8
Higher Order Functions
  • all (a -gt Bool) -gt a -gt Bool
  • all f True
  • all f (xxs) f x all f xs
  • filter (a -gt Bool) -gt a -gt a
  • filter 2 f True -gt xs True -gt r all f
    r
  • filter f
  • filter f (xxs) case (f x) of
  • True -gt x filter f xs
  • False -gt filter f xs

9
Contracts for higher-order functions parameter
f1 (Int -gt Int) -gt Int f1 2 (x True -gt y
y gt 0) -gt r r gt 0 f1 g (g 1) - 1 f2
r True f2 f1 (\x -gt x 1)
Error f1s postcondition fails because (g
1) gt 0 does not imply (g 1) 1
gt 0 Error f2 calls f1 which fails f1s
precondition
FindlerFelleisenICFP02, BlumeMcAllesterICFP
04
10
Functions without Contracts
  • data T T1 Bool T2 Int T3 T T
  • noT1 T -gt Bool
  • noT1 (T1 _) False
  • noT1 (T2 _) True
  • noT1 (T3 t1 t2) noT1 t1 noT1 t2
  • () True x x
  • () False x False

No abstraction is more compact than the function
definition itself!
11
Contract Synonym
  • contract Ok x True
  • contract NonNull x not (null x)
  • head Int -gt Int
  • head 2 NonNull -gt Ok
  • head (xxs) x
  • - contract Ok x True -
  • - contract NonNull x not (null x) -
  • - contract head NonNull -gt Ok -

Actual Syntax
12
Questions on e 2 t
  • bot bot
  • ? x. x 2 x bot ! r
    True ?
  • ? x. error f 2 x bot ! r True ?
  • ? x. x 2 x True ! r bot
    ?
  • ? x. head 2 x True ! r bot ?
  • (True, 2) 2 x (snd x) gt 0 ?
  • (head , 3) 2 x (snd x) gt 0 ?
  • error f 2 ?
  • ? 2 x False
  • ? 2 x head

13
LanguageSyntax
following Haskells lazy semantics
14
Two special constructors
  • BAD is an expression that crashes.
  • error String -gt a
  • error s BAD
  • head (xxs) x
  • head BAD
  • UNR (short for unreachable) is an expression
    that gets stuck. This is not a crash, although
    execution comes to a halt without delivering a
    result. (identifiable infinite loop)

15
Syntax of Contracts(related to
FindlerICFP02,BlumeICFP04,HinzeFLOPS06,Flanaga
nPOPL06)
t 2 Contract t x p Predicate Contract
xt1 ! t2 Dependent Function Contract
(t1, t2) Tuple Contract Any
Polymorphic Any Contract
Full version xx x gt0 -gt r r gt
x Short hand x x gt 0 -gt r r gt
x k(x x gt 0 -gt y y gt 0) -gt r r gt k
5
16
Contract Satisfaction(related to
FindlerICFP02,BlumeICFP04,HinzeFLOPS06)
Given e ? and c t ?, we define e 2 t as
follows
e 2 x p , e" or (e is crash-free and
pe/x!BAD,
False A1 e2 xt1! t2 , e" or
8 e1 2 t1. (e e1) 2 t2e1/x A2 e 2
(t1, t2) , e" or (e1 2 t1 and e2 2 t2)
A3 e 2 Any , True
A4
e" means e diverges or e ! UNR
17
Answers on e 2 t
  • ? x. x 2 x bot ! r True
  • ? x. BAD 2 x bot ! r True
  • ? x. x 2 x True ! r bot
  • ? x. BAD 2 x True ! r bot
  • ? x. BAD 2 x True ! Any
  • (True, 2) 2 x (snd x) gt 0
  • (BAD, 3) 2 x (snd x) gt 0
  • BAD 2 Any
  • UNR, bot 2 x False
  • UNR, bot 2 x BAD
  • BAD 2 (Any, Any) BAD 2 Any ! Any

18
Lattice for Contracts
Any
(x xgt0, Any)
Any -gt r rgt0
x True
(x xgt0, r rgt0)
x xgt0-gtr rgtx
x False
19
Laziness
  • fst 2 (x True, Any) -gt r True
  • fst (a,b) a
  • fst (5, error f)
  • fstN (Int, Int) -gt Int
  • fstN 2 (x True, Any) -gt r True
  • fstN (a, b) n if n gt 0
  • then fstN (a1, b) (n-1)
  • else a
  • g2 fstN (5, error fstN) 100

Every expression satisfies Any
20
What to Check?
  • Does function f satisfies its contract t (written
    f2 t)?
  • At the definition of each function f,
  • Check f 2 t assuming all functions called in f
    satisfy their contracts.
  • Goal main 2 x True

21
How to Check?
This Talk
Define e 2 t
Grand Theorem e 2 t , e B t is crash-free
(related to BlumeMcAllesterICFP04)
Construct e B t (e ensures t)
ESC/Haskell (XuHW06)
Simplify (e B t)
Normal form e
If e is syntactically safe, then Done!
22
What we cant do?
  • g1, g2 2 Ok -gt Ok
  • g1 x case (prime x gt square x) of
  • True -gt x
  • False -gt error urk
  • g2 xs ys
  • case (rev (xs ys) rev ys rev xs) of
  • True -gt xs
  • False -gt error urk

Crash!
Crash!
Hence, three possible outcomes (1) Definitely
Safe (no crash, but may loop) (2) Definite Bug
(definitely crashes) (3) Possible Bug
23
Crashing
  • Definition (Crash).
  • A closed term e crashes iff e ! BAD
  • Definition (Crash-free Expression)
  • An expression e is crash-free iff
  • 8 C. BAD 2 C, Ce (), Ce ! BAD

24
Definition of B and C (B pronounced ensures C
pronounced requires)
  • e B x p
  • case pe/x of
  • True -gt e
  • False -gt BAD
  • e C x p
  • case pe/x of True -gt e
  • False -gt UNR
  • Example
  • 5 2 x x gt 0
  • 5 B x x gt 0
  • case (5 gt 0) of
  • True -gt 5
  • False -gt BAD

related to FindlerICFP02,BlumeICFP04,HinzeFLOP
S06
25
Definition of B and C (cont.)
  • e B xt1 ! t2
  • ? v. (e (vC t1)) B t2vCt1/x
  • e C xt1 ! t2
  • ? v. (e (vB t1)) C t2vBt1/x
  • e B (t1, t2)
  • case e of
  • (e1, e2) -gt (e1 B t1, e2 B t2)
  • e C (t1, t2)
  • case e of
  • (e1, e2) -gt (e1 C t1, e2 C t2)

26
Higher-Order Function
f1 (Int -gt Int) -gt Int f1 2 (x True -gt y
y gt 0) -gt r r gt 0 f1 g (g 1) - 1 f2
r True f2 f1 (\x -gt x 1)
  • f1 B (x True -gt y y gt 0) -gt r r gt
    0
  • B C
    B
  • ? v1. case (v1 1) gt 0 of
  • True -gt case (v1 1) - 1 gt 0 of
  • True -gt (v1 1) -1
  • False -gt BAD
  • False -gt UNR

27
Modified Definition of B and C
  • e B x p
  • case pe/x of
  • True -gt e
  • False -gt BAD

old
if e ! BAD, then (fin e) ! False else (fin e) !
e
  • e B x p
  • e seq case fin (pe/x) of
  • True -gt e
  • False -gt BAD

new
e_1 seq e_2 case e_1 of DEFAULT -gt e_2
28
Why need seq and fin?
e B x p e seq case fin (pe/x) of
True -gt e False -gt BAD
Without seq
(UNR B x False) ! BAD But UNR 2 x
False ? x. x 2 x BAD ! x True
But ? x. x B x BAD ! x True ! ? v. (v
seq BAD) which is NOT crash-free.
Without fin
29
Definition of B and C for Any
e B Any UNR e C Any BAD
f5 2 Any -gt r True f5 x 5 error String
-gt a -- HM Type error 2 x True -gt Any
-- Contract
30
Properties of B and C
  • Key Lemma
  • For all closed, crash-free e, and closed t,
  • (e C t) 2 t
  • Projections (related to FindlerBlumeFLOPS06)
  • For all e and t, if e 2 t, then
  • e ¹ e B t
  • e C t ¹ e
  • Definition (Crashes-More-Often)
  • e1 ¹ e2 iff for all C, Cei () for
    i1,2 and
  • Ce2 ! BAD ) Ce1 !
    BAD

31
About 30 Lemmas ?
  • Lemma Monotonicity of Satisfaction
  • If e1 2 t and e1 ¹ e2, then e22 t
  • Lemma Congruence of ¹
  • e1 ¹ e2 ) 8 C. Ce1 ¹ Ce2
  • Lemma Idempotence of Projection
  • 8 e, t. e B t B t e B t
  • 8 e, t. e C t C t eC t
  • Lemma A Projection Pair
  • 8 e, t. e B t C t ¹ e
  • Lemma A Closure Pair
  • 8 e, t. e ¹ eC t B t

32
Lattice for Expressions (¹ )
BAD
(3,BAD)
? x. 6
5
(3, 4)
? x . x
UNR
33
Lattice for Contracts
Any
(x xgt0, Any)
Any -gt r rgt0
x True
(x xgt0, r rgt0)
x xgt0-gtr rgtx
x False
34
Conclusion
Where the bug is
Contract
Glasgow Haskell Compiler (GHC)
Why it is a bug
Haskell Program
35
Contributions
  • Automatic static contract checking instead of
    dynamic contract checking.
  • Compared with ESC/Haskell
  • Allow pre/post specification for higher-order
    functions parameter through contracts.
  • Reduce more false alarms caused by Laziness and
    in an efficient way.
  • Allow user-defined data constructors to be used
    to define contracts
  • Specifications are more type-like, so we can
    define contract synonym.
  • We develop a concise notation (B and C) for
    contract checking, which enjoys many properties.
    We give a new and relatively simpler proof of the
    soundness and completeness of dynamic contract
    checking, this proof is much trickier than it
    looks.
  • We implement the idea in GHC
  • Accept full Haskell
  • Support separate compilation as the verification
    is modular.
  • Can check functions without contract through CEG
    unrolling.

36
Sorting
(gt) True x x (gt) False x True
  • sorted True
  • sorted (x) True
  • sorted (xyxs) x lt y sorted (y xs)
  • insert i True -gt xs sorted xs
  • -gt r sorted r
  • merge Int -gt Int -gt Int
  • merge xs sorted xs -gt ys sorted ys
  • -gt r sorted r
  • bubbleHelper Int -gt (Int, Bool)
  • bubbleHelper xs True
  • -gt r not (snd r) gt sorted (fst
    r)
  • Insertsort, mergesort, bubblesort xs True
  • -gt r sorted
    r

37
Various Examples
  • zip a -gt b -gt (a,b)
  • zip xs True -gt ys sameLen xs ys
  • -gt rs sameLen rs xs
  • sameLen True
  • sameLen (xxs) (yys) sameLen xs ys
  • sameLen _ _ False
  • f91 Int -gt Int
  • f91 n lt 101 -gt r r 91
  • f91 n case (n lt 100) of
  • True -gt f91 (f91 (n 11))
  • False -gt n 10

38
  • f x x gt 0 -gt r True
  • f x x
  • f B x x gt 0 -gt r True
  • (?x.x) B x x gt 0 -gt r True
  • ?v. (?x.x (v C x x gt 0)) B r True
  • ?v. (case v gt 0 of
  • True -gt v
  • False -gt UNR)
  • g f

f C x x gt 0 -gt r True ?v. (case v gt 0
of True -gt v False -gt BAD)
39
Constructor Contracts
  • x x gt 0 xs all (lt 0) xs
  • x x gt 0 Any
  • Any Any
  • Support any user-defined data constructors!
  • (related to HinzeJeuringLöhFLOPS06)

40
How to Check e 2 t?
This Talk
  • Given e and t
  • We construct a term (eBt) (pronounced e ensures
    t)
  • related to FindlerFelleisenICFP02 (dynamic
    contract checking algorithm)
  • Prove (eBt) is crash-free.
  • simplify the term (eBt) to e and e is
    syntactically safe, then we are done.
  • Theorem 1 (related to BlumeMcAllesterICFP
    04)
  • eBt is crash-free , e 2 t
  • Theorem 2
  • simpl (eBt) is syntactically safe ) eBt is
    crash-free

ESC/Haskell (HW06)
41
(No Transcript)
Write a Comment
User Comments (0)
About PowerShow.com