710 likes | 878 Views
Subtype marks. Tamás Kozsik kto@elte.hu http://kto.web.elte.hu/ E ötvös Loránd University, Budapest Central-European Functional Programming School Eötvös Loránd University, Budapest, Hungary 4-16 July, 2005. Contents. Context Motivation Intuitive description of subtype marks Examples
E N D
Subtype marks Tamás Kozsik kto@elte.hu http://kto.web.elte.hu/ Eötvös Loránd University, Budapest Central-European Functional Programming School Eötvös Loránd University, Budapest, Hungary 4-16 July, 2005
Contents • Context • Motivation • Intuitive description of subtype marks • Examples • Discussion Tamás Kozsik: Subtype Marks
Related topics at CEFP • Time and safety critical applications (Kevin) • Reason about programs (Máté) • Refactor programs (Simon) • Test programs (Pieter) Tamás Kozsik: Subtype Marks
Fortune “Beware of bugs in the above code; I have only proved it correct, not tried it.” (Donald Knuth) Tamás Kozsik: Subtype Marks
Aims • Safety critical applications • Formal proof of correctness • Reasoning about the code • Theorem prover + Type system • Enyv = Egyszerű NYelV • Simple functional language • “Subtype marks” Tamás Kozsik: Subtype Marks
Proving correct • Methodologies: formal methods • Program logics • Formal semantics • Software development tools • Model checkers • Proof systems • Programming languages • Alphard, Eiffel etc. Tamás Kozsik: Subtype Marks
Invariant • Widely used safety property • Temporal logics • Type invariant • Property of legal values • Restrict the type value set Tamás Kozsik: Subtype Marks
Type systems? • Uniqueness, strictness, concurrency • Types with size information(Kevin Hammond / Hume) • Types with shape information(Sven Bodo Scholz / SAC) • Annotated types - invariants (Pieter Koopman, Diederik van Arkel) • Dependent types Tamás Kozsik: Subtype Marks
Motivation - 1 fac :: Int -> Int fac 0 = 1 fac n = n * (fac (n-1)) Tamás Kozsik: Subtype Marks
Motivation - 2 fac :: Int -> Int fac n = if (n<0) (abort "Bad argument!") (f n) where f 0 = 1 f n = n * (f (n-1)) Tamás Kozsik: Subtype Marks
Motivation - 3 fac :: Int -> Int // PRE: only for non-negative arg. fac 0 = 1 fac n = n * (fac (n-1)) Tamás Kozsik: Subtype Marks
Motivation - 4 fac :: Nat -> Nat fac 0 = 1 fac n = n * (fac (n-1)) Tamás Kozsik: Subtype Marks
Motivation - 5 fac :: Int{N}-> Int{N} fac 0 = 1 fac n = n * (fac (n-1)) Tamás Kozsik: Subtype Marks
Motivation - 6 fac :: Int{N} -> Int{N} fac 0 = 1 fac n = let nm1 :: Int{N!}, nm1 = n-1 in n * (fac nm1) Tamás Kozsik: Subtype Marks
Enyv • Simple functional language • Syntax: similar to that of Clean • Semantics: graph rewrite systems • Subtype marks • Let’s see some examples… Tamás Kozsik: Subtype Marks
:: List a = Nil | Cons a (List a) Head :: List a -> a Head (Cons x xs) = x Tail :: List a ->List a Tail (Cons x xs) = xs Append :: List a -> a -> List a Append Nil x = Cons x Nil Append (Cons y ys) x = Cons y (Append ys x) Reverse :: List a -> List a Reverse Nil = Nil Reverse (Cons x xs) = Append (Reverse xs) x Tamás Kozsik: Subtype Marks
Insert :: List Int -> Int -> List Int Insert Nil e = Cons e Nil Insert ys=:(Cons x xs) e = If (x < e) (Cons x (Insert xs e)) (Cons e ys) Sort :: List Int -> List Int Sort Nil = Nil Sort (Cons x xs) = Insert (Sort xs) x Tamás Kozsik: Subtype Marks
Insert :: List Int -> Int -> List Int Insert Nil e = Cons e Nil Insert (Cons x xs) e = If (x < e) (Cons x (Insert xs e)) (Cons e (Cons x xs)) Sort :: List Int -> List Int Sort Nil = Nil Sort (Cons x xs) = Insert (Sort xs) x Tamás Kozsik: Subtype Marks
Expressions and functions • Expressions • Variables • Function and data constructor symbols • Applications • Let-expressions (recursive, let-rec) • Functions • Alternatives • Pattern matching • No block-structure, no modules, no macros… Tamás Kozsik: Subtype Marks
Types • Algebraic type definitions • Restricted parametric polymorphism:top-level universal quantification • No existential quantification, no bounded polymorphism (type classes),no dynamics,no modules (no private types, no ADTs),no uniqueness,no generics Tamás Kozsik: Subtype Marks
Subtype marks • Type invariants • Annotations attached to type constructors • Richer type system • Subtype polymorphism • Connects the type system and a theorem prover Tamás Kozsik: Subtype Marks
Non-empty lists: C C : List a ↦ {true,false} C(xs) = (∃y,ys: xs = Consy ys) • Definition used by a theorem prover • Not used by the type system • “Denotational semantics for subtype marks” Tamás Kozsik: Subtype Marks
Non-empty lists: C Nil :>: List a Cons :>: a -> List a -> List{C} a • Definition used by the type system • Correctness proven by theorem prover • “Axiomatic semantics for subtype marks” Tamás Kozsik: Subtype Marks
Sorted lists: S Nil :>: List{S} a Cons :>: a -> List a -> List a • Presence of subtype mark:the value is known to have the property • Absence of subtype mark:the value is not known to have the property Tamás Kozsik: Subtype Marks
Typing functions • Preconditions • Postconditions • Propagation of properties Tamás Kozsik: Subtype Marks
Precondition Head :: List{C} a -> a Head (Cons x xs) = x Tail :: List{C} a -> List a Tail (Cons x xs) = xs • Useful for partial functions • Not only for partial functions Tamás Kozsik: Subtype Marks
Postconditions Append :: List a -> a -> List{C} a Append Nil x = Cons x Nil Append (Cons y ys) x = Cons y (Append ys x) Head (Append x xs) Tamás Kozsik: Subtype Marks
Pre- and postconditions fac :: Int{N} -> Int{N} fac 0 = 1 fac n = let nm1 :: Int{N!}, nm1 = n-1 in n * (fac nm1) Tamás Kozsik: Subtype Marks
Propagation Reverse :: List a -> List a Reverse :: List{C} a -> List{C} a Reverse Nil = Nil Reverse (Cons x xs) = Append (Reverse xs) x • More than one type • Polymorphic notation? Tamás Kozsik: Subtype Marks
Sorted lists Tail :: List{C} a -> List a Tail :: List{C,S} a -> List{S} a Tail (Cons x xs) = xs • How to type this? Tamás Kozsik: Subtype Marks
Data constructors • Composition types: expressions • Decomposition types: patterns Cons :>: a -> List a -> List{C} a Cons :<: a -> List a -> List{C} a Cons :<: a -> List{S} a -> List{C,S} a Tamás Kozsik: Subtype Marks
Typing Tail Cons :<: a -> List a -> List{C} a Cons :<: a -> List{S} a -> List{C,S} a Tail :: List{C} a -> List a Tail :: List{C,S} a -> List{S} a Tail (Cons x xs) = xs Tamás Kozsik: Subtype Marks
Subtype polymorphism Tail :: List{C} a -> List a Tail :: List{C,S} a -> List{S} a Tail (Cons x xs) = xs Tail :: List{C,S} a -> List a Tail :: List{C,S,X} a -> List{S} a ... • Weakening / subsumption Tamás Kozsik: Subtype Marks
Why subtyping is needed? Reverse (Tail (Sort (Append xs x))) Append :: List a -> a -> List{C} a Reverse :: List a -> List a Reverse :: List{C} a -> List{C} a Sort :: List Int-> List{S} Int Sort :: List{C}Int -> List{C,S} Int Tail :: List{C} a -> List a Tail :: List{C,S} a -> List{S} a Tail :: List{C,S} a -> List a Tamás Kozsik: Subtype Marks
Variance • Subtyping - substitution principle • Co-variant return, contra-variant arguments Int -> Int{N} ≤ Int -> Int Int -> Int ≤ Int{N} -> Int Int{N} -> Int{N} ? Int -> Int Tamás Kozsik: Subtype Marks
Subtyping is a partial order • Reflexive, antisymmetric, transitive Int -> Int{N} Int -> IntInt{N} -> Int{N} Int{N} -> Int Tamás Kozsik: Subtype Marks
Believe-me marks fac :: Int{N} -> Int{N} fac 0 = 1 fac n = let nm1 :: Int{N!}, nm1 = n-1 in n * (fac nm1) Tamás Kozsik: Subtype Marks
Insertion sort Insert :: List{S} Int -> Int ->List{S!} Int Insert Nil e = Cons e Nil Insert (Cons x xs) e = If (x < e ) (Cons x (Insert xs e)) (Cons e (Cons x xs)) Sort :: List Int -> List{S} Int Sort Nil = Nil Sort (Cons x xs) = Insert (Sort xs) x Tamás Kozsik: Subtype Marks
Typing Sort Nil :>: List{S} a Insert :: List{S} Int -> Int ->List{S!} Int Sort :: List Int -> List{S} Int Sort Nil = Nil Sort (Cons x xs) = Insert (Sort xs) x Recursion! Tamás Kozsik: Subtype Marks
Typing Insert? Insert :: List{S} Int -> Int ->List{S!} Int Insert Nil e = Cons e Nil Insert (Cons x xs) e = If (x < e ) (Cons x (Insert xs e)) (Cons e (Cons x xs)) • Need the formula associated to S • Need a theorem prover Tamás Kozsik: Subtype Marks
Formula associated to S • The list is sorted Sorted Nil = True Sorted (Cons x Nil) = True Sorted (Cons x xs=:(Cons y ys)) = x <= y && Sorted xs Tamás Kozsik: Subtype Marks
Proving Insert correct Insert :: List{S} Int -> Int ->List{S!} Int Sorted(xs) → Sorted(Insert xs e) • Sparkle ~(Sorted xs = False) -> ~(Sorted (Insert xs e) = False) Tamás Kozsik: Subtype Marks
Undefined • Cons 1 (Cons 2 (Cons 3 … • Cons 1/0 Nil • Partially undefined values - laziness • What if Sorted would be a partial function? • Partial correctness Tamás Kozsik: Subtype Marks
Polymorphic subtype marks • Propagation of properties Reverse :: List a -> List a Reverse :: List{C} a -> List{C} a Reverse Nil = Nil Reverse (Cons x xs) = Append (Reverse xs) x • Subtype mark variable Reverse :: List{p:C} a -> List{p:C} a Tamás Kozsik: Subtype Marks
Subtype mark variables Tail :: List{C,p:S} a -> List{p:S} a Sort :: List{p:C} Int -> List{p:C,S} Int Cons :<: a -> List{p:S} a -> List{C,p:S} a Tamás Kozsik: Subtype Marks
Complex numbers :: Complex = Cart Real Real // Cartesian | Polar Real Real // Polar Cart :>: Real -> Real -> Complex{Cart} Cart :<: Real -> Real -> Complex{Cart} Polar :>: Real -> Real -> Complex{Polar} Polar :<: Real -> Real -> Complex{Polar} Tamás Kozsik: Subtype Marks
Complex numbers: conversions polar :: Complex -> Complex{Polar!} polar (Cart re im) = let delta = if (im<0.0) 1.0 0.0 in Polar (sqrt (re*re + im*im)) ( (atan (im/re)) + delta*Pi ) polar c = c cart :: Complex -> Complex{Cart!} cart (Polar r phi) = Cart (r * (cos phi)) (r * (sin phi)) cart c = c Tamás Kozsik: Subtype Marks
Complex numbers: Cartesian addCC :: Complex{Cart} -> Complex{Cart} -> Complex{Cart} addCC (Cart re1 im1) (Cart re2 im2) = Cart (re1+re2) (im1+im2) • Similarly: subCC, mulCC, divCC conjugate :: Complex{Cart} -> Complex{Cart} conjugate (Cart re im) = Cart re (0.0-im) Tamás Kozsik: Subtype Marks
Complex numbers: polar mulCP :: Complex{Polar} -> Complex{Polar} -> Complex{Polar} mulCP (Polar r1 phi1) (Polar r2 phi2) = Polar (r1*r2) (phi1+phi2) • Similarly: divCP absCP :: Complex{Polar} -> Real absCP (Polar r phi) = r powCP :: Complex{Polar} -> Real ->Complex(Polar) powCP (Polar r phi) x = Polar (r^x) (x*phi) Tamás Kozsik: Subtype Marks
Complex numbers: full domain addC :: Complex -> Complex -> Complex{Cart} addC c1 c2 = addCC (cart c1) (cart c2) mulC :: Complex{p:Polar,c:Cart} -> Complex{p:Polar,c:Cart} -> Complex{p:Polar,c:Cart!} mulC (Cart re1 im1) (Cart re2 im2) = mulCC (Cart re1 im1) (Cart re2 im2) mulC c1 c2 = mulCP (polar c1) (polar c2) Tamás Kozsik: Subtype Marks