nested refinements
play

Nested Refinements: A Logic for Duck Typing :: Ravi Chugh, Pat - PowerPoint PPT Presentation

Nested Refinements: A Logic for Duck Typing :: Ravi Chugh, Pat Rondon, Ranjit Jhala (UCSD) WhatareDynamicLanguages? affectcontrolflow tagtests indexedbyarbitrarystringkeys dic<onaryobjects


  1. Nested Refinements: A Logic for Duck Typing :: Ravi Chugh, Pat Rondon, Ranjit Jhala (UCSD)

  2. What
are
“Dynamic
Languages”?
 affect
control
flow
 tag
tests 
 indexed
by
arbitrary
string
keys
 dic<onary
objects 
 can
appear
inside
objects
 first‐class
func<ons 
 let onto callbacks f obj = if f = null then new List(obj, callbacks) else let cb = if tagof f = “Str” then obj[f] else f in new List(fun () -> cb obj, callbacks) 2 


  3. affect
control
flow
 tag
tests 
 indexed
by
arbitrary
string
keys
 dic<onary
objects 
 can
appear
inside
objects
 first‐class
func<ons 
 Problem: 
Lack
of
sta<c
types
 
 …
makes
rapid
prototyping
/
mul<‐language
applica<ons
easy
 
 …
makes
reliability
/
performance
/
maintenance
hard
 This
Talk: 
System
D
 
 …
a
type
system
for
these
features
 3 


  4. affect
control
flow
 tag
tests 
 indexed
by
arbitrary
string
keys
 dic<onary
objects 
 can
appear
inside
objects
 first‐class
func<ons 
 Usability 
 Our
Approach: 
Quan<fier‐free
formulas
 F ≤ 
 
1.
increase
expressiveness
 ∨ ,
 ∧ 
 refinement
 nested
 occurrence
 types 
 refinements 
 
2.
retain
level
of
automa<on
 types 
 … 
 Coq 
 syntac<c
approaches 
 dependent
approaches 
 Expressiveness 


  5. affect
control
flow
 tag
tests 
 indexed
by
arbitrary
string
keys
 dic<onary
objects 
 can
appear
inside
objects
 first‐class
func<ons 
 { ν | tag( ν ) = “Int” ∨ tag( ν ) = “Bool” } x :: d :: { ν | tag( ν ) = “Dict” ∧ tag(sel( ν ,“n”)) = “Int” ∧ tag(sel( ν ,m)) = “Int” } Challenge: 
 Func<ons
inside
dic<onaries
 5 


  6. Key
Idea:
Nested
Refinements
 1 + d[f](0) d :: { ν | tag( ν ) = “Dict” ∧ sel( ν ,f) :: { ν | tag( ν )=“Int” } } → { ν | tag( ν )=“Int” } syntac<c
arrow
type…
 uninterpreted
predicate
 “ x :: U ”
says
 “ x 
has‐type
 U ”
 6 


  7. Key
Idea:
Nested
Refinements
 1 + d[f](0) d :: { ν | tag( ν ) = “Dict” ∧ sel( ν ,f) :: { ν | tag( ν )=“Int” } } → { ν | tag( ν )=“Int” } syntac<c
arrow
type…
 uninterpreted
predicate
 “ x :: U ”
says
 …
but
uninterpreted
 “ x 
has‐type
 U ”
 constant
in
the
logic
 7 


  8. Key
Idea:
Nested
Refinements
 • All
values
described
by
refinement
formulas
 T ::= { ν | p } 
 • “Has‐type”
predicate
for
arrows
in
formulas
 p ::= … | x :: y:T 1 → T 2 
 • Can
express
idioms
of
dynamic
languages
 • Automa<c
type
checking
 – Decidable
refinement
logic
 – Subtyping
=
SMT
Validity
+
Syntac<c
Subtyping
 8 


  9. Outline
 Intro
 Examples
 Subtyping
 Type
Soundness
 Conclusion
 9 


  10. x:{ ν | tag( ν ) = “Int” ∨ tag( ν ) = “Bool” } → { ν | tag( ν ) = tag(x) } x:IntOrBool → { ν | tag( ν ) = tag(x) } let negate x = if tagof x = “Int” then 0 – x else not x y:Top → { ν | ν = tag(y) } tagof :: y:{ ν | true } 10 


  11. ✓ 
 x:IntOrBool → { ν | tag( ν ) = tag(x) } let negate x = if tagof x = “Int” then 0 – x else not x type
environment
 Γ ∧ tag(x) = “Int” x :: IntOrBool ✓ 
 SMT
Solver 
 x :: { ν | Int( ν ) } ✓ 
 0 - x :: { ν | Int( ν ) } 11 


  12. ✓ 
 x:IntOrBool → { ν | tag( ν ) = tag(x) } let negate x = if tagof x = “Int” then 0 – x else not x type
environment
 Γ ∧ not (tag(x) = “Int”) x :: IntOrBool ✓ 
 SMT
Solver 
 x :: { ν | Bool( ν ) } ✓ 
 not x :: { ν | Bool( ν ) } 12 


  13. x:IntOrBool → { ν | tag( ν ) = tag(x) } Nes<ng
structure
hidden
with
syntac<c
sugar
 → { ν | ν :: } x: IntOrBool { ν | tag( ν ) = tag(x) } 13 


  14. Dic<onary
Opera<ons
 Types
in
terms
of
McCarthy
operators
 d:Dict → k:Str → { ν | ν = true ⇔ has(d,k) } mem :: get :: d:Dict → k:{ ν | has(d, ν ) } → { ν | ν = sel(d,k) } d:Dict → k:Str → x:Top → { ν | ν = upd(d,k,x) } set :: 14 


  15. d:Dict → c:Str → Int let getCount d c = get d c if mem d c then toInt (d[c]) else 0 safe
dic<onary
 key
lookup
 { ν | ν = true ⇔ has(d,c) } 15 


  16. d:Dict → c:Str → Int let getCount d c = if mem d c then toInt (d[c]) else 0 tag(sel( ν ,c)) = “Int” d:Dict → c:Str → { ν | EqMod( ν ,d,c) ∧ Int( ν [c]) } let incCount d c = let i = getCount d c in {d with c = i + 1} set d c (i+1) 16 


  17. Adding
Type
Constructors
 T ::= { ν | p } 
 p ::= … | x :: U U ::= y:T 1 → T 2 “type
terms”
 | A | List T | Null 17 


  18. let apply f x = f x ∀ A,B. { ν | ν :: { ν | ν :: A } → { ν | ν :: B } } → { ν | ν :: A } → { ν | ν :: B } ∀ A,B. (A → B) → A → B 18 


  19. let dispatch d f = d[f](d) ∀ A,B. d:{ ν | ν :: A } → f:{ ν | d[ ν ] :: A → B } → { ν | ν :: B } a
form
of
 “bounded
quan<fica<on” d :: A 
but
addi<onal
constraints
on
 A ≈ ∀ A <: {f: A → B}. d :: A 19 


  20. ∀ A,B. { ν | ν :: A → B } → { ν | ν :: List[A] } → { ν | ν :: List[B] } ∀ A,B. (A → B) → List[A] → List[B] let map f xs = if xs = null then null else new List(f xs[“hd”], map f xs[“tl”]) encode
recursive
data
as
dic<onaries
 20 


  21. let filter f xs = if xs = null then null else if not (f xs[“hd”]) then filter f xs[“tl”] else new List(xs[“hd”], filter f xs[“tl”]) usual
defini<on,
 but
an
interes<ng
type
 ∀ A,B. (x:A → { ν | ν = true ⇒ x :: B } → List[A] → List[B] 21 


  22. Outline
 Intro
 Examples
 Subtyping
 Type
Soundness
 Conclusion
 22 


  23. type
environment
 Γ applyInt :: (Int, Int → Int) → Int negate :: x:IntOrBool → { ν | tag( ν ) = tag(x) } applyInt (42, negate) ✓ 
 SMT
 Γ ∧ ν = 42 ⇒ tag( ν ) = “Int” _ Γ { ν | ν = 42 } < Int | 23 


  24. type
environment
 Γ applyInt :: (Int, Int → Int) → Int negate :: x:IntOrBool → { ν | tag( ν ) = tag(x) } applyInt (42, negate) … ∧ negate :: x:IorB → { ν | tag( ν ) = tag(x) } SMT
 … ∧ ν = negate 
 ⇒ ν :: Int → Int _ Γ { ν | ν = negate } < { ν | ν :: Int → Int } | 24 


  25. type
environment
 Γ applyInt :: (Int, Int → Int) → Int negate :: x:IntOrBool → { ν | tag( ν ) = tag(x) } applyInt (42, negate) … ∧ negate :: x:IorB → { ν | tag( ν ) = tag(x) } SMT
 … ∧ ν = negate 
 ✗ 
 dis<nct
 ⇒ ν :: Int → Int uninterpreted
 constants!
 _ Γ { ν | ν = negate } < { ν | ν :: Int → Int } | 25 


  26. Invalid,
since
these
are
uninterpreted
constants
 ν :: x:IorB → { ν | tag( ν ) = tag(x) } ✗ 
 ⇒ ν :: Int → Int Want
conven<onal
syntac<c
subtyping
 ✓ 
 ✓ 
 ⇒ tag( ν ) = “Int” ⇒ tag( ν ) = “Int” tag( ν ) = “Int” ∧ tag( ν ) = tag(x) ⇒ ∨ tag( ν ) = “Bool” ⇒ tag( ν ) = “Int” Int <: IorB { ν | tag( ν ) = tag(x) } <: Int IorB → { ν | tag( ν ) = tag(x) } <: Int → Int 26 


  27. Subtyping
with
Nes<ng
 To
prove
 p 
 ⇒ 
 q 
: 1)
Convert
 q 
to
CNF
clauses
 (q 11 ∨ … ) ∧ … ∧ (q n1 ∨ … ) 2)
For
each
clause,
discharge
some
literal
 q ij as
follows: base
predicate: p 
 ⇒ 
 q ij anything
except
 x :: U e.g.
 tag( ν ) = tag(x) e.g.
 tag(sel(d,k)) = “Int” 27 


  28. Subtyping
with
Nes<ng
 To
prove
 p 
 ⇒ 
 q 
: 1)
Convert
 q 
to
CNF
clauses
 (q 11 ∨ … ) ∧ … ∧ (q n1 ∨ … ) 2)
For
each
clause,
discharge
some
literal
 q ij as
follows: base
predicate: p 
 ⇒ 
 q ij “has‐type”
predicate: p 
 ⇒ 
 x :: U Subtyping
 Subtyping
 Arrow
Rule
 Implica<on
 Implica<on
 U’ 
 <: 
 U p 
 ⇒ 
 x :: U’ p 
 ⇒ 
 q ij 
 SMT
Solver
 SMT
Solver
 28 


  29. applyInt (42, negate) … ∧ negate :: x:IorB → { ν | tag( ν ) = tag(x) } Uninterpreted
 … ∧ ν = negate 
 Reasoning
 ⇒ ν :: x:IorB → { ν | tag( ν ) = tag(x) } + Syntac<c
 _ Γ x:IorB → { ν | tag( ν ) = tag(x) } <: Int → Int | Reasoning
 _ Γ { ν | ν = negate } < { ν | ν :: Int → Int } | 29 


  30. Outline
 Intro
 Examples
 Subtyping
 Type
Soundness
 Conclusion
 30 


  31. _ If
 x:T x , Γ e[:: T | Subs<tu<on
 _ and
 | v :: T x Lemma
 _ then
 Γ [v/x] e[v/x] :: T[v/x] | independent
of
 0 ,
and
just
echoes
the
 binding
from
the
environment
 _ f:{ ν | ν :: Int → Int } | 0 :: { ν | f :: Int → Int } _ λ x.x+1 :: { ν | ν :: Int → Int } | _ | 0 :: { ν | λ x.x+1 :: Int → Int } 31 


Recommend


More recommend