190 likes | 313 Vues
This document discusses the refinement types system introduced by Robert Harper, which improves type inference in ML using a lattice-based approach. It is inspired by the Yardeni & Shapiro type system for Prolog and applies regular trees to isolate subsets of datatypes. Key topics include the construction of datatype refinements, the behavior of constructors with functions, and methods for deciding subtyping. Various examples, including bit strings and recursive types, illustrate the application and propagation of refinements within the type system.
E N D
Freeman-Pfenning: Refinement Types Robert Harper Fall Semester, 2003
Refinement Types • First system of type refinements for ML. • Inspired by Yardeni & Shapiro type system for Prolog. • Main idea: use regular trees to isolate subsets of a datatype. • Use lattice-based abstract interpretation methods for type inference. 15-814 Type Refinements
Lists Example • Start with an ML datatype:datatype list = nil j cons of * list • Introduce rectype’s that define refinements (subsets / properties) of interest.rectype singleton = cons of * nil • Infer refined types for functions based on these.cons 2 * nil ! singleton Æ * list ! list 15-814 Type Refinements
list singÇnil sing nil ? Refinement Types • The declared refinements of a datatype determine a finite lattice of subsets. 15-814 Type Refinements
Refinement Types • Peculiarity: the lattice is supposed to consist of declared types only (rather than, say, all possible subsets). • But some points are declared ( sing) and some not ( nil). • I’m not sure I understand how this is supposed to work. 15-814 Type Refinements
Declared Refinements • If a constructor contains a function, the domain cannot be refined! • Example (I think):datatype D = I of int | F of D! Drectype R = I of Int | F of D ! R • This seems essential to preserve regularity of the subset. 15-814 Type Refinements
Refinement Types in General • Empty (?) and total (>). • Intersection (1Æ2) and union (1Ç2). • Function space (1!2). • Declared refinements ( r). • Bounded refinement variables (::). • Pre-order induced by lattice structure. 15-814 Type Refinements
Bit Strings • Type of bit strings (lsb outermost).datatype bs = e | z of bs | o of bs • No leading zero bits:rectype std = e | stdposand stdpos = o(e) | z(stdpos) | o(stdpos) • For example, o(e) is not std, but e is. 15-814 Type Refinements
Bit Strings • Bit-wise addition function:fun add e m = m | add n e = n | add (z m) (z n) = z (add m n) | add (o m) (z n) = o (add m n) | add (z m) (o n) = o (add m n) | add (o m) (o n) = z (add (add (o e) m) n) 15-814 Type Refinements
Bit Strings • Refinement checker infers many types for add. • Propagate consequences of all refinements for arguments. • Three declared (?) refinements: std, stdpos, e. • Nine total clauses, includingstd ! std ! std. 15-814 Type Refinements
Refinement Propagation • Each constructor has a conjunct for each recursive type in which it appears.o 2 e! stdpos Æ stdpos! stdpos • Case analysis checks each arm against all possible matches. • eg, for z(x) ) p, x could be e or stdpos. • multiple matches lead to disjunctive result • eg, if arg is stdpos, result could be result of either z or o case. 15-814 Type Refinements
Extending the Lattice • The lattice structure on refinements of a datatype extends to function types:1!1·2!2 if 2·2 and 1·2 . • Requires variance annotations on type constructors. • eg, + list states that list preserves order • How to decide subtyping? 15-814 Type Refinements
Deciding Subtyping • For two refinements of a datatype, determined by the finite lattice. • For refinements of a function type, seems to employ an ad hoc rule. • Put types into DNF using 1Æ(2Ç3) ´ (1Æ2)Ç(2Æ3)(1Ç2)!´ (1!)Æ(2!) • Conjuncts are all CNF! DNF, or all named refinements of a datatype, or all variables with a common bound. 15-814 Type Refinements
Deciding Subtyping • DNF subtyping:Çii·Çjj iff 8i9j st i·j. • CNF subtyping: • For named refinements, consult lattice ordering. • For functions, see following. • For variables??? 15-814 Type Refinements
Deciding Subtyping • To decide =Æi (i!i) ·Æj (’j!’j)=’, decide whether app(,) · app(’,) for every = i or ’j. • Define app(,) = Æ·ii, the most precise answer for argument of type . • I’m not clear on the motivation for this definition. 15-814 Type Refinements
Refinement Inference • Invariant: assumed and derived refinements are in DNF. • Ignore polymorphism here, but see paper. • Applications:` e1(e2) 2Çi,j app(i,j), where ` e12Çii, and ` e22Çjj . 15-814 Type Refinements
Refinement Inference • Abstractions: ` x.e 2Æi (i!i), where, x2i` e 2i for each refinement of the domain type. • Question: how do we determine all such i’s in general? 15-814 Type Refinements
Refinement Inference • Fixed points by recursion: • Start with ? for recursive variable. • Infer refinement of argument. • Refine recursive variable to inferred type. • Iterate until you reach a fixed point (must exist, by finiteness). 15-814 Type Refinements
Refinement Inference • Considerfun inc e = o(e) | inc (z m) = (o m) | inc (o m) = z (inc m) • Use inference rules to infer thatinc 2 e! std Æ std! stdpos Æ stdpos! stdpos. 15-814 Type Refinements