/
Nested Refinements: Nested Refinements:

Nested Refinements: - PowerPoint Presentation

sherrill-nordquist
sherrill-nordquist . @sherrill-nordquist
Follow
405 views
Uploaded On 2016-06-05

Nested Refinements: - PPT Presentation

A Logic for Duck Typing Ravi Chugh Pat Rondon Ranjit Jhala UCSD 2 What are Dynamic Languages let onto callbacks f obj if f null then new List obj callbacks ID: 350206

Share:

Link:

Embed:

Download Presentation from below link

Download Presentation The PPT/PDF document "Nested Refinements:" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

Slide1

Nested Refinements:A Logic for Duck Typing

Ravi Chugh, Pat Rondon, Ranjit Jhala (UCSD)

::Slide2

2What are “Dynamic Languages”?

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)

tag tests

affect control flow

dictionary objects

indexed by arbitrary string keys

first-class functions

can appear inside objectsSlide3

3

Problem: Lack of static types

… makes rapid prototyping / multi-language applications easy

… makes reliability / performance / maintenance hard

This Talk:

System D

… a type system for these featurestag testsaffect control flowdictionary objectsindexed by arbitrary string keysfirst-class functionscan appear inside objectsSlide4

occurrence types

∨, ∧

Our Approach:

Quantifier-free formulas

tag tests

affect control flowdictionary objectsindexed by arbitrary string keysfirst-class functionscan appear inside objectsExpressivenessUsabilityF≤

Coq

refinement types

nested refinements

syntactic approaches

dependent approaches

1. increase expressiveness

2. retain level of automationSlide5

5

Functions inside dictionaries

Challenge:

{

|tag() = “Int”tag() = “Bool”}x ::{



|tag

(

)

=

“Dict”

 

tag(

sel

(,“n”

))

=

“Int”

tag

(

sel

(

,

m

))

=

Int”



}

d

::

tag tests

affect control flow

dictionary objects

indexed by arbitrary string keys

first-class functions

can appear inside objectsSlide6

6Key Idea: Nested Refinements

{



|

tag

() = “Dict” sel(,f) :: }d ::

{



|

tag

(

)=“Int

}

{

|tag(

)=

“Int” }

uninterpreted

predicate

x

::

U

” says

x

has-type

U

syntactic arrow type…

1 + d[f](0)Slide7

7Key Idea: Nested Refinements

{



|

tag

() = “Dict” sel(,f) :: }d ::

{



|

tag

(

)=“Int

}

{

|tag(

)=

“Int” }

uninterpreted

predicate

x

::

U

” says

x

has-type

U

1 + d[f](0)

syntactic arrow type…

… but uninterpreted constant in the logicSlide8

All values described by refinement formulas

T ::=

{



|

p}“Has-type” predicate for arrows in formulasp ::= … | x :: y:T1T2Can express idioms of dynamic languagesAutomatic type checkingDecidable refinement logicSubtyping = SMT Validity + Syntactic Subtyping8Key Idea: Nested RefinementsSlide9

OutlineIntroExamples

SubtypingType SoundnessConclusion

9Slide10

10

let negate x = if

tagof x =

Int

” then 0 – x else not xy:Top{| = tag(y)}tagof ::

x:

{



|

tag

(

)

= “Int”

tag()

=

Bool”}

{

|

tag

(

)

=

tag

(

x

)

}

x:IntOrBool

{

|

tag

(

)

=

tag

(

x

)

}

y:

{

|

true

}Slide11

IntOrBool

x

::

Γ

11

{

|Int()}x ::{



|

Int(

)

}

0 - x

::

x:IntOrBool

{

|tag(

)

=

tag

(

x

)

}

let

negate x

=

if

tagof x

=

Int

then

0 – x

else

not x

tag

(

x

)

=

Int

type environment

SMT Solver

✓Slide12

IntOrBool

x

::

Γ

12

{

|Bool()}x ::{



|

Bool(

)

}

not x

::

x:IntOrBool



{

|tag

(

)

=

tag

(

x

)

}

let

negate x

=

if

tagof x

=

Int

then

0 – x

else

not x

not

(

tag

(

x

)

=

Int

)

type environment

SMT Solver

✓Slide13

13

{

|



::

}x:IntOrBool{|tag() = tag(x) }x:IntOrBool



{



|

tag

(

)

= tag(x

)

}Nesting structure hidden with syntactic sugarSlide14

Dictionary Operations14

d:Dict



k

:Str

 {| = true  has(d,k)}mem ::d:Dictk:{

|

has

(d,

)

}

{

|

 = sel(

d,

k

)}

get

::

d:Dict

k

:Str

x

:Top

{

|

=

upd

(

d

,

k

,

x

)

}

set

::

Types in terms of McCarthy operatorsSlide15

15

let getCount d c = if

mem d c then

toInt

(

d

[c]) else 0d:Dictc:StrInt{| = true  has(d,c)

}

safe dictionary key lookup

get d cSlide16

16

let incCount d c = let

i =

getCount

d c

in {d with c = i + 1}d:Dictc:StrIntd:Dictc:Str{|EqMod(

,

d,c

) 

Int(

[c

])

}

tag

(

sel

(

,c

))

=

Int”

let

getCount d c

=

if

mem d c

then

toInt

(

d

[

c

])

else

0

set d c (i+1)Slide17

T ::=

{



|

p

}p ::= … | x :: UU ::= y:T1T2

| A |

List

T

| Null

17Adding Type Constructors

“type terms”Slide18

18

let apply f x = f

x

∀A,B.

{

|:: {|:: A }{|:: B } }



{

|



::

A }

{

|

:: B

}

∀A,B.

(

A

B

)

A

BSlide19

19

let dispatch d f = d[

f](

d

)

∀A,B.

d:{| :: A } f:{|d[] :: AB }



{

|



::

B

}

d

::

A but additional constraints on A≈ ∀A

<:

{f:

A  B}. d ::

A

a form of

“bounded quantification”Slide20

20

let map f

xs

=

if

xs

= null then null else new List(f xs[“hd”], map f xs[“tl”])∀A,B. {|:: AB

}



{

|



::

List[A]

}

{

|

:: List

[

B

]

}

encode recursive data as dictionaries

∀A,B.

(

A

B

)

List

[

A

]

List

[

B

]Slide21

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”])

∀A,B. (

x:A



{



|

n = true

x:: B

}

List[A]

List

[

B

]

usual definition,

but an interesting typeSlide22

OutlineIntroExamples

SubtypingType SoundnessConclusion

22Slide23

23

SMT

Γ

=42  tag() = “Int” Γ {|= 42} < Int

_

|

(

Int,

Int

Int)

Int

applyInt ::

applyInt

(

42,

negate

)

x:IntOrBool

{

|

tag

(

)

=

tag

(

x

)

}

negate ::

Γ

type environmentSlide24

SMT

negate

:: x:IorB{|tag() = tag(x)}…  =negate  ::

Int



Int

24

Γ

{

|

=

negate

} < {

|

::

Int

Int

}

_

|

(

Int,

Int

Int

)

Int

applyInt

::

applyInt

(

42,

negate

)

x:IntOrBool

{

|

tag

(

)

=

tag

(

x

)

}

negate ::

Γ

type environmentSlide25

25

Γ

{

|= negate } < {|:: IntInt }

_

|

(

Int,

Int

Int)

Int

applyInt

::

applyInt (

42,

negate

)

x:IntOrBool

{

|

tag

(

)

=

tag

(

x

)

}

negate ::

Γ

distinct uninterpreted constants!

type environment

SMT

negate

::

x:IorB

{

|

tag

(

)

=

tag

(

x

)

}

=

negate

::

Int

IntSlide26

26

IorB  {

|

tag() = tag(x)} <: Int  IntInt <: IorB{|tag() = tag(x)

} <: Int

tag

(

)

= “Int”

tag

() =

Int

” 

tag

(

)

=

Bool”

tag

(

)

=

Int

tag

(

)

=

tag

(

x

)

tag

(

)

=

Int

Invalid, since these are uninterpreted constants

W

ant conventional syntactic subtyping

::

x:IorB

{

|

tag

(

)

=

tag

(

x

)

}

::

Int

Int

✗Slide27

Subtyping with Nesting27

base predicate: p

 q

ij

1) Convert

q

to CNF clauses (q11  … )  …  (qn1  … )2) For each clause, discharge some literal qij as follows:To prove p  q :

anything except

x

::

U

e.g.

tag

(

) = tag(

x)

e.g.

tag(sel

(

d

,

k

))

=

Int

”Slide28

Subtyping with Nesting28

Implication

SMT Solver

Subtyping

Arrow Rule

base predicate:

p  qij“has-type” predicate: p  x :: UImplicationSMT SolverSubtyping

p

x ::

U’

U’

<: U

p

 qij

1) Convert

q

to CNF clauses (q11

)

(q

n1

)

2) For each clause, discharge some literal

q

ij

as follows:

To prove

p

q

:Slide29

Uninterpreted

Reasoning

negate:: x:IorB{|tag() = tag(x)}… 



=negate

::

x:IorB

{



|

tag()

=

tag(x)

}

29

applyInt

(

42,

negate

)

Γ

{

|

=

negate

}

<

{

|

::

Int

Int

}

_

|

+

Syntactic

Reasoning

Γ

x:IorB

{

|

tag

(

)

=

tag

(

x

)

}

<:

Int

Int

_

|Slide30

OutlineIntroExamples

SubtypingType SoundnessConclusion

30Slide31

31

0 :: {

|

x.x+1:: IntInt }_|x.x+1 :: {|:: IntInt }

_

|

f:

{



|

::

Int

Int }

0

:: {

|

f

::

Int

Int

}

_

|

Substitution

Lemma

_

|

v ::

T

x

and

If

x:T

x

,

Γ e

[

::

T

_

|

Γ

[

v

/

x

]

e

[

v

/

x

]

::

T

[

v

/

x

]

_

|

then

independent of

0

, and just echoes the binding from the environmentSlide32

32

0

::

{

|x.x+1:: IntInt }_|SMT=0  

x.x+1

:: Int



Int

{

|

=

0 } < {

|

x.x+1

::

Int

Int

}

0

::

{

|

=

0

}

Substitution

Lemma

_

|

v ::

T

x

and

If

x:T

x

,

Γ e

[

::

T

_

|

Γ

[

v

/

x

]

e

[

v

/

x

]

::

T

[

v

/

x

]

_

|

then

1

st

attemptSlide33

33

0

::

{

|x.x+1:: IntInt }_|{|=

0 }

< {



|

x.x+1

::

Int

Int

}0

::

{

|

=

0

}

Substitution

Lemma

_

|

v ::

T

x

and

If

x:T

x

,

Γ e

[

::

T

_

|

Γ

[

v

/

x

]

e

[

v

/

x

]

::

T

[

v

/

x

]

_

|

then

SMT

=

0

::

U’

Arrow

U’ <:

Int

Int

+

2

nd

attempt

✗Slide34

34

x.x+1

::

IntInt|=Ix.x+1:: {|:: Int

Int

}

|

_

SMT

Γ

p

 q

Γ

{

|

=

p

}

<

{

|

=

q

}

_

|

[S-Valid-Uninterpreted]

|

=

I

Γ

p

q

Γ

{

|

=

p

}

<

{

|

=

q

}

_

|

[S-Valid-Interpreted]

iff

Rule not closed under substitution

Interpret formulas by “hooking back” into type system

Stratification to create ordering for induction

n

n-1

n

nSlide35

Type Soundness35

StratifiedSubstitution

Lemma

_

|

v ::

TxandIfx:Tx, Γ e[:: T_|Γ[v/x] e

[v/

x]

:: T

[

v/

x]

_

|

then

n+1

n

n

Stratified

Preservation

e

v

and

If

e

[

::

T

_

|

0

_

|

then

v

[

::

T

m

for some m

“Level 0”

for type checking source programs,

using

only [S-Valid-Uninterpreted]

artifact

of the metatheorySlide36

RecapDynamic languages make heavy use of:run-time tag tests, dictionary objects, lambdasNested refinementsgeneralizes refinement type architectureenables combination of dictionaries and lambdas

Decidable refinement logicall proof obligations discharged algorithmicallynovel subtyping decomposition to retain precisionSyntactic type soundness36Slide37

Future WorkImperative UpdatesInheritance (prototypes in JS, classes in Python)ApplicationsMore local type inference / syntactic sugarDictionaries in statically-typed languages

37Slide38

38Thanks!

D

ravichugh.com/nested

::Slide39

39Extra SlidesSlide40

Constants40

tagof::x:Top

{

| = tag(x)}mem::d:Dictk:Str {|Bool()

 =

True 

has

(d

,k)

}get::d:Dict

k:{

|Str(

)

has

(

d

,

)

}

{

|

=

sel

(

d

,

k

)

}

set

::

d:Dict

k

:Str

x

:Top

{

|

=

upd

(

d

,

k

,

x

)

}

rem

::

d:Dict

k

:Str

{

|

=

upd

(

d

,

k

,

bot

)

}Slide41

TypesFormulasLogical ValuesMacros

41

{

|

tag()=“Int” }Int  x:T1T2  {

|

::

}

x:T

1



T

2

tag

(

x) = “Str”

Str(x)

sel

(

n

,

“k”

)

x.k

sel

(

n

,

k

)

x[k]

sel

(

d

,

k

)

!=

bot

has(d,k)

∀k’. k’

!=

k

sel

(

d

,

k

)

!=

sel

(

d’

,

k

)

EqMod(d,d’,k)

Slide42

Onto42

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)

∀A.

callbacks:List

[Top



Top]

f:{



|=

null

 Str(

)



::

A

Top

}

obj

:

{

|

::

A



(

f

=

null

::

A

Int

)



(

Str

(

f

)

[

f

]

::

A

Int

)

}

List

[

Top

Top

]

onto ::

functional version of Dojo functionSlide43

Onto (2)43

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)

callbacks:

List

[

Top

Top

]

*

f:{

g|g

=

null Str

(

g

)



g

::

{

x

|

x

=

obj

}

Top

}

*

obj

:

{

o

|

(

f

=

null

o

::

{

x

|

x

=

o

}

Int

)



(

Str

(

f

)

o

[

f

]

::

{

x

|

x

=

o

}

Int

)

}

List

[

Top

Top

]

onto ::

functional version of Dojo functionSlide44

44

Traditional vs. Nested RefinementsSlide45

45Reuse refinement type architectureFind a decidable refinement logic forTag-tests

DictionariesLambdasDefine nested refinement type architectureApproach: Refinement Types

*Slide46

46Nested Refinements

T ::= {|

p

}

U ::= x:T

1

T2p ::= pq | … | x = y | x < y | … | tag(x) = “Int” | … | sel(x,y) = z | … | x :: URefinement formulas over a decidable logicuninterpreted functions, McCarthy arrays, linear arithmeticOnly base values refined by formulas

All values

T ::= {



|

p

}

| x:T1

T2p

::= p

q | … |

x

=

y

|

x

<

y

| …

|

tag(x

) = “

Int

” | …

|

sel(x,y

) =

z

| …

traditional refinementsSlide47

47Nested Refinements

T ::= {|

p

}

U ::= x:T

1

T2p ::= pq | … | x = y | x < y | … | tag(x) = “Int” | … | sel(x,y) = z | … | x::URefinement formulas over a decidable logic

uninterpreted

functions, McCarthy arrays, linear arithmetic

Only base values refined by formulas

“has-type” allows “type terms” in formulas

All values

T ::= {



|

p

} | x:T1

T

2

p ::= p

q

| …

|

x

=

y

|

x

<

y

| …

|

tag(x

) = “

Int

” | …

|

sel(x,y

) =

z

| …

traditional refinementsSlide48

48Nested Refinements

T ::= {|

p

}

U ::= x:T

1

T2p ::= pq | … | x = y | x < y | … | tag(x) = “Int” | … | sel(x,y) = z | … | x::URefinement formulas over a decidable logicuninterpreted functions, McCarthy arrays, linear arithmeticOnly base values refined by formulas“has-type” allows “type terms” in formulasAll valuesSlide49

Subtyping (Traditional Refinements)49

T ::= {|

p

}

| x:T

1T2traditional refinementsImplicationSMT SolverSubtypingtag()=“Int”  trueInt <: TopSlide50

Subtyping (Traditional Refinements)50

T ::= {|

p

}

| x:T

1T2traditional refinementsImplicationSMT SolverSubtypingTop  Int <: Int  IntInt <: TopInt <: Int

tag

(

)=“Int

true

tag

(

)=

“Int”

tag

(

)=“Int”Slide51

Subtyping (Traditional Refinements)51

T ::= {|

p

}

| x:T

1T2traditional refinementsImplicationSMT SolverSubtypingTop  Int <: Int  IntInt <: TopInt <: Int

tag

(

)=“Int

true

tag

(

)=

“Int”

tag

(

)=“Int”

Arrow RuleSlide52

Subtyping (Traditional Refinements)52

T ::= {|

p

}

| x:T

1T2traditional refinementsImplicationSMT SolverSubtypingArrow RuleDecidable if:Only values in formulas

Underlying theories decidable