Download - Nested Refinements: A Logic for Duck Typing
![Page 1: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/1.jpg)
Nested Refinements:A Logic for Duck
Typing
Ravi Chugh, Pat Rondon, Ranjit Jhala (UCSD)
::
![Page 2: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/2.jpg)
2
What 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 objects
![Page 3: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/3.jpg)
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 features
tag tests affect control flow
dictionary objects indexed by arbitrary string keys
first-class functions can appear inside objects
![Page 4: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/4.jpg)
…
occurrence types
∨, ∧
Our Approach: Quantifier-free formulas
tag tests affect control flow
dictionary objects indexed by arbitrary string keys
first-class functions can appear inside objects
Expressiveness
Usability
F≤
Coq
refinement types
nested refinements
syntactic approaches dependent approaches
1. increase expressiveness
2. retain level of automation
![Page 5: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/5.jpg)
5
Functions inside dictionariesChallenge:
{|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 objects
![Page 6: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/6.jpg)
6
Key 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)
![Page 7: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/7.jpg)
7
Key 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 logic
![Page 8: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/8.jpg)
8
• All values described by refinement formulasT ::= {|p}
• “Has-type” predicate for arrows in formulasp ::= … | x :: y:T1T2
• Can express idioms of dynamic languages
• Automatic type checking– Decidable refinement logic
– Subtyping = SMT Validity + Syntactic Subtyping
Key Idea: Nested Refinements
![Page 9: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/9.jpg)
Outline
Intro
Examples
Subtyping
Type Soundness
Conclusion9
![Page 10: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/10.jpg)
10
let negate x = if tagof x = “Int” then 0 – x else not x
y:Top{|=tag(y)}tagof ::
x:{|tag()=“Int”tag()=“Bool”} {|tag()=tag(x)}
x:IntOrBool{|tag()=tag(x)}
y:{|true}
![Page 11: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/11.jpg)
11
IntOrBoolx ::Γ
{|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
✓
![Page 12: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/12.jpg)
12
IntOrBoolx ::Γ
{|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
✓✓
✓
![Page 13: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/13.jpg)
13
{|:: }x: IntOrBool {|tag()=tag(x)}
x:IntOrBool{|tag()=tag(x)}
Nesting structure hidden with syntactic sugar
![Page 14: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/14.jpg)
14
Dictionary Operations
d:Dictk:Str{|=true has(d,k)}mem ::
d:Dictk:{|has(d,)}{|=sel(d,k)}get ::
d:Dictk:Strx:Top{|=upd(d,k,x)}set ::
Types in terms of McCarthy operators
![Page 15: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/15.jpg)
15
let getCount d c = if mem d c then toInt (d[c]) else 0
d:Dictc:StrInt
{|=true has(d,c)}
safe dictionary key lookup
get d c
![Page 16: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/16.jpg)
16
let incCount d c = let i = getCount d c in {d with c = i + 1}
d:Dictc:StrInt
d:Dictc: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)
![Page 17: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/17.jpg)
17
T ::= {|p}
p ::= … | x::U
U ::= y:T1T2
| A
| List T
| Null
Adding Type Constructors
“type terms”
![Page 18: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/18.jpg)
18
let apply f x = f x
∀A,B.{|::{|::A}{|::B}} {|::A} {|::B}
∀A,B.(AB)AB
![Page 19: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/19.jpg)
19
let dispatch d f = d[f](d)
∀A,B.d:{|::A}f:{|d[]::AB}{|::B}
d::A but additional constraints on A≈ ∀A<:{f:AB}.d::A
a form of“bounded quantification”
![Page 20: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/20.jpg)
20
let map f xs = if xs = null then null else new List(f xs[“hd”], map f xs[“tl”])
∀A,B. {|::AB}{|::List[A]}{|::List[B]}
encode recursive data as dictionaries
∀A,B.(AB)List[A]List[B]
![Page 21: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/21.jpg)
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{|=truex::B}List[A]List[B]
usual definition,but an interesting type
![Page 22: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/22.jpg)
Outline
Intro
Examples
Subtyping
Type Soundness
Conclusion22
![Page 23: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/23.jpg)
23
SMT Γ=42 tag()=“Int”
Γ {|=42} < Int_|
(Int,IntInt)IntapplyInt ::
applyInt (42,negate)
x:IntOrBool{|tag()=tag(x)}negate ::
Γ
✓
type environment
![Page 24: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/24.jpg)
24
SMT
…negate::x:IorB{|tag()=tag(x)}…=negate
::IntInt
Γ {|=negate} < {|::IntInt}_|
(Int,IntInt)IntapplyInt ::
applyInt (42,negate)
x:IntOrBool{|tag()=tag(x)}negate ::
Γtype environment
![Page 25: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/25.jpg)
25
Γ {|=negate} < {|::IntInt}_|
(Int,IntInt)IntapplyInt ::
applyInt (42,negate)
x:IntOrBool{|tag()=tag(x)}negate ::
Γ
✗ distinct uninterpreted
constants!
type environment
SMT
…negate::x:IorB{|tag()=tag(x)}…=negate
::IntInt
![Page 26: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/26.jpg)
26
IorB {|tag()=tag(x)} <: Int Int
Int <: IorB {|tag()=tag(x)} <: Int
tag()=“Int” tag()=“Int” tag()=“Bool”
tag()=“Int”tag()=tag(x) tag()=“Int”
Invalid, since these are uninterpreted constants
Want conventional syntactic subtyping
✓ ✓
::x:IorB{|tag()=tag(x)}
::IntInt✗
![Page 27: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/27.jpg)
27
Subtyping with Nesting
base predicate: p qij
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::Ue.g. tag()=tag(x)e.g. tag(sel(d,k))=“Int”
![Page 28: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/28.jpg)
28
Subtyping with Nesting
Implication
SMT Solver
Subtyping Arrow Rule
base predicate: p qij “has-type” predicate: p x::U
Implication
SMT Solver
Subtyping
p x::U’
U’ <: U
p qij
1) Convert q to CNF clauses (q11…)…(qn1…)2) For each clause, discharge some literal qij as follows:
To prove p q :
![Page 29: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/29.jpg)
29
UninterpretedReasoning
…negate::x:IorB{|tag()=tag(x)}…=negate
::x:IorB{|tag()=tag(x)}
applyInt (42,negate)
Γ {|=negate} < {|::IntInt}_|
+
SyntacticReasoning
Γ x:IorB{|tag()=tag(x)} <: IntInt_|
![Page 30: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/30.jpg)
Outline
Intro
Examples
Subtyping
Type Soundness
Conclusion30
![Page 31: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/31.jpg)
31
0 :: {|x.x+1::IntInt}_|
x.x+1 :: {|::IntInt}_|
f:{|::IntInt} 0 :: {|f::IntInt}_|
SubstitutionLemma
_| v :: TxandIf x:Tx,Γ e[:: T_|
Γ[v/x] e[v/x] :: T[v/x]_|then
independent of 0, and just echoes the binding from the environment
![Page 32: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/32.jpg)
32
0 :: {|x.x+1::IntInt}_|
SMT =0 x.x+1::IntInt✗{|=0} < {|x.x+1::IntInt}0 :: {|
=0}
SubstitutionLemma
_| v :: TxandIf x:Tx,Γ e[:: T_|
Γ[v/x] e[v/x] :: T[v/x]_|then
1st attempt
![Page 33: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/33.jpg)
33
0 :: {|x.x+1::IntInt}_|
{|=0} < {|x.x+1::IntInt}0 :: {|=0}
SubstitutionLemma
_| v :: TxandIf x:Tx,Γ e[:: T_|
Γ[v/x] e[v/x] :: T[v/x]_|then✗SMT =0 ::U’
Arrow U’ <: IntInt
+2nd attempt✗
![Page 34: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/34.jpg)
34
x.x+1::IntInt|=I
x.x+1::{|::IntInt}|_
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
n
![Page 35: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/35.jpg)
35
Type Soundness
StratifiedSubstitutionLemma
_| v :: TxandIf x:Tx,Γ e[:: T_|
Γ[v/x] e[v/x] :: T[v/x]_|then n+1
nn
StratifiedPreservation
e vandIf e[:: T_| 0_|then v[:: Tm for some m
“Level 0” for type checking source programs,using only [S-Valid-Uninterpreted]
artifact of the metatheory
![Page 36: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/36.jpg)
36
Recap• Dynamic languages make heavy use of:
– run-time tag tests, dictionary objects, lambdas
• Nested refinements– generalizes refinement type architecture– enables combination of dictionaries and lambdas
• Decidable refinement logic– all proof obligations discharged algorithmically– novel subtyping decomposition to retain precision
• Syntactic type soundness
![Page 37: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/37.jpg)
37
Future Work• Imperative Updates
• Inheritance (prototypes in JS, classes in Python)
• Applications
• More local type inference / syntactic sugar
• Dictionaries in statically-typed languages
![Page 38: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/38.jpg)
38
Thanks!
Dravichugh.com/nested
::
![Page 39: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/39.jpg)
39
Extra Slides
![Page 40: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/40.jpg)
40
Constants
tagof :: x:Top{|=tag(x)}
mem :: d:Dictk:Str{|Bool()=True has(d,k)}get :: d:Dictk:{|Str()has(d,)}{|=sel(d,k)}
set :: d:Dictk:Strx:Top{|=upd(d,k,x)}
rem :: d:Dictk:Str{|=upd(d,k,bot)}
![Page 41: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/41.jpg)
41
• Types
• Formulas
• Logical Values
Macros{|tag()=“Int”}Int
x:T1T2 {|:: }x:T1T2
tag(x) = “Str”Str(x)
sel(,“k”)x.k sel(,k)x[k]
sel(d,k)!=bothas(d,k) ∀k’. k’!=k sel(d,k)!=sel(d’,k)
EqMod(d,d’,k)
![Page 42: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/42.jpg)
42
Ontolet 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[TopTop]f:{|=nullStr()::ATop}obj:{|::A (f=null::AInt) (Str(f)[f]::AInt)}List[TopTop]
onto ::
functional version of Dojo function
![Page 43: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/43.jpg)
43
Onto (2)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[TopTop]*f:{g|g=nullStr(g)g::{x|x=obj}Top}*obj:{o|(f=nullo::{x|x=o}Int) (Str(f)o[f]::{x|x=o}Int)}List[TopTop]
onto ::
functional version of Dojo function
![Page 44: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/44.jpg)
44
Traditional vs. Nested Refinements
![Page 45: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/45.jpg)
45
• Reuse refinement type architecture
• Find a decidable refinement logic for– Tag-tests– Dictionaries– Lambdas
• Define nested refinement type architecture
Approach: Refinement Types
✓✗✓✓*
![Page 46: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/46.jpg)
46
Nested Refinements
T ::= {|p}U ::= x:T1T2
p ::= pq | … | x = y | x < y | … | tag(x) = “Int” | … | sel(x,y) = z | … | x :: U
• Refinement formulas over a decidable logic– uninterpreted functions, McCarthy arrays, linear arithmetic
• Only base values refined by formulasAll values
T ::= {|p} | x:T1T2
p ::= pq | … | x = y | x < y | … | tag(x) = “Int” | … | sel(x,y) = z | …
traditional refinements
![Page 47: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/47.jpg)
47
Nested Refinements
T ::= {|p}U ::= x:T1T2
p ::= pq | … | x = y | x < y | … | tag(x) = “Int” | … | sel(x,y) = z | … | x::U
• Refinement 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:T1T2
p ::= pq | … | x = y | x < y | … | tag(x) = “Int” | … | sel(x,y) = z | …
traditional refinements
![Page 48: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/48.jpg)
48
Nested Refinements
T ::= {|p}U ::= x:T1T2
p ::= pq | … | x = y | x < y | … | tag(x) = “Int” | … | sel(x,y) = z | … | x::U
• Refinement 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
![Page 49: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/49.jpg)
49
Subtyping (Traditional Refinements)
T ::= {|p} | x:T1T2
traditional refinements
Implication
SMT Solver
Subtyping
tag()=“Int” trueInt <: Top
![Page 50: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/50.jpg)
50
Subtyping (Traditional Refinements)
T ::= {|p} | x:T1T2
traditional refinements
Implication
SMT Solver
Subtyping
Top Int <: Int Int
Int <: Top Int <: Int
tag()=“Int” true
tag()=“Int” tag()=“Int”
![Page 51: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/51.jpg)
51
Subtyping (Traditional Refinements)
T ::= {|p} | x:T1T2
traditional refinements
Implication
SMT Solver
Subtyping
Top Int <: Int Int
Int <: Top Int <: Int
tag()=“Int” true
tag()=“Int” tag()=“Int”
Arrow Rule
![Page 52: Nested Refinements: A Logic for Duck Typing](https://reader035.vdocuments.us/reader035/viewer/2022062222/568162bf550346895dd34e24/html5/thumbnails/52.jpg)
52
Subtyping (Traditional Refinements)
T ::= {|p} | x:T1T2
traditional refinements
Implication
SMT Solver
Subtyping Arrow Rule
Decidable if:• Only values in formulas• Underlying theories decidable