1 Resource Bound Certification Stephanie Weirich Cornell University Joint work with Karl Crary, CMU.

Slides:



Advertisements
Similar presentations
Dataflow Analysis for Datarace-Free Programs (ESOP 11) Arnab De Joint work with Deepak DSouza and Rupesh Nasre Indian Institute of Science, Bangalore.
Advertisements

Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
Semantics Static semantics Dynamic semantics attribute grammars
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  ML lists are immutable.  Elements.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
1 Dependent Types for Termination Verification Hongwei Xi University of Cincinnati.
Getting started with ML ML is a functional programming language. ML is statically typed: The types of literals, values, expressions and functions in a.
Names and Bindings.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
INF 212 ANALYSIS OF PROG. LANGS Type Systems Instructors: Crista Lopes Copyright © Instructors.
ISBN Chapter 3 Describing Syntax and Semantics.
CS 355 – Programming Languages
Compiler Construction
Compiler Principle and Technology Prof. Dongming LU Mar. 28th, 2014.
CS 4800 By Brandon Andrews.  Specifications  Goals  Applications  Design Steps  Testing.
Typed Assembly Languages COS 441, Fall 2004 Frances Spalding Based on slides from Dave Walker and Greg Morrisett.
ML: a quasi-functional language with strong typing Conventional syntax: - val x = 5; (*user input *) val x = 5: int (*system response*) - fun len lis =
1 A Dependently Typed Assembly Language Hongwei Xi University of Cincinnati and Robert Harper Carnegie Mellon University.
Introduction to ML - Part 2 Kenny Zhu. What is next? ML has a rich set of structured values Tuples: (17, true, “stuff”) Records: {name = “george”, age.
CSE 130 : Winter 2006 Programming Languages Ranjit Jhala UC San Diego Lecture 7: Polymorphism.
ARRAYS AND POINTERS Although pointer types are not integer types, some integer arithmetic operators can be applied to pointers. The affect of this arithmetic.
1 Functional languages (e.g. Scheme, ML) Scheme is a functional language. Scheme is based on lambda calculus. lambda abstraction = function definition.
Review: forward E { P } { P && E } TF { P && ! E } { P 1 } { P 2 } { P 1 || P 2 } x = E { P } { \exists … }
Functional programming: LISP Originally developed for symbolic computing First interactive, interpreted language Dynamic typing: values have types, variables.
Crash course on SML Wojciech Moczydłowski SML – functional programming language Complete formal semantics Extremely convenient for writing compilers, interpreters,
Semantics for MinML COS 441 Princeton University Fall 2004.
Describing Syntax and Semantics
Cs164 Prof. Bodik, Fall Symbol Tables and Static Checks Lecture 14.
Compiling with Dependent Types Hongwei Xi University of Cincinnati.
Chapter TwelveModern Programming Languages1 Memory Locations For Variables.
Imperative Programming
Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top.
ML Datatypes.1 Standard ML Data types. ML Datatypes.2 Concrete Datatypes  The datatype declaration creates new types  These are concrete data types,
© Kenneth C. Louden, Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.
10/16/2015IT 3271 All about binding n Variables are bound (dynamically) to values n values must be stored somewhere in the memory. Memory Locations for.
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
Type Systems CS Definitions Program analysis Discovering facts about programs. Dynamic analysis Program analysis by using program executions.
ISBN Chapter 3 Describing Semantics -Attribute Grammars -Dynamic Semantics.
410/510 1 of 18 Week 5 – Lecture 1 Semantic Analysis Compiler Construction.
CS 363 Comparative Programming Languages Semantics.
Formal Semantics Chapter Twenty-ThreeModern Programming Languages, 2nd ed.1.
Pointers OVERVIEW.
Chapter 9: Functional Programming in a Typed Language.
© Kenneth C. Louden, Chapter 11 - Functional Programming, Part III: Theory Programming Languages: Principles and Practice, 2nd Ed. Kenneth C. Louden.
A Third Look At ML Chapter NineModern Programming Languages, 2nd ed.1.
CS536 Semantic Analysis Introduction with Emphasis on Name Analysis 1.
12/9/20151 Programming Languages and Compilers (CS 421) Elsa L Gunter 2112 SC, UIUC Based in part on slides by Mattox.
Structure of Programming Languages Names, Bindings, Type Checking, and Scopes.
Types and Programming Languages Lecture 11 Simon Gay Department of Computing Science University of Glasgow 2006/07.
Error Example - 65/4; ! Toplevel input: ! 65/4; ! ^^ ! Type clash: expression of type ! int ! cannot have type ! real.
Semantic Analysis II Type Checking EECS 483 – Lecture 12 University of Michigan Wednesday, October 18, 2006.
Advanced Functional Programming Tim Sheard 1 Lecture 17 Advanced Functional Programming Tim Sheard Oregon Graduate Institute of Science & Technology Lecture:
CS412/413 Introduction to Compilers Radu Rugina Lecture 13 : Static Semantics 18 Feb 02.
Types John Mitchell CS 242. Type A type is a collection of computable values that share some structural property. uExamples Integers Strings int  bool.
Dr. M. Al-Mulhem Introduction 1 Chapter 6 Type Systems.
Lecture 3: More Java Basics Michael Hsu CSULA. Recall From Lecture Two  Write a basic program in Java  The process of writing, compiling, and running.
LECTURE 10 Semantic Analysis. REVIEW So far, we’ve covered the following: Compilation methods: compilation vs. interpretation. The overall compilation.
Heath Carroll Bill Hanczaryk Rich Porter.  A Theory of Type Polymorphism in Programming ◦ Robin Milner (1977)  Milner credited with introducing the.
Type Checking and Type Inference
Programming Languages and Compilers (CS 421)
CSE341: Programming Languages Lecture 11 Type Inference
Principles of programming languages 12: Functional programming
Names and Attributes Names are a key programming language feature
ML: a quasi-functional language with strong typing
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 11 Type Inference
Compiler Construction
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 11 Type Inference
Compiler Construction
Presentation transcript:

1 Resource Bound Certification Stephanie Weirich Cornell University Joint work with Karl Crary, CMU

2 Problem Sometimes code runs too long How do we prevent it?

3 Enforcement Methods Run the code, and if it takes too long, kill it Look at the code and decide how long it will take  Annotations on the code can makes this process decidable

4 Dynamic Method Can decide how long is too long on the fly (even while the code is running) Code producer does not have to write code in any particular language (or include annotations) May be expensive to enforce

5 Static Method Guarantee to the user that code will run without being prematurely terminated May provide faster execution Can encompass dynamic checking Static verification that the code executes dynamic checks Makes policy enforcement part of the model

6 Annotations What annotations can we use for execution time verification?

7 Base Language Type-Safe version of C all pointer accesses checked for NULL no pointer arithmetic safe memory-management (garbage- collection or region-based) tagged unions

8 Caveat Most examples in this talk will look like functional programming Intension is to verify a low-level language (such as type-safe assembly language) Don’t have to trust the compiler Hopefully annotation methodologies are general enough that people can be clever

9 Certification of Running Time Simplification: Only count function calls and loop iterations Functions and loops annotated with the cost of execution int add1(int x) { return x+1; } int add3(int x) { x = add1(x); return add1(x); }

10 Example Function-typed arguments can influence the running time int foo(int f(int x) ) { return f(1)*f(3); } But can restrict how the code is used  foo(add1); foo(add3);

11 Abstract Time Useful to abstract the time annotation int foo (int f(int x) ) { return f(1) * f(3); } foo (add1); // k=0, takes 2 steps + 1 for call foo (add3); // k=3, takes 8 steps + 1 for call

12 Static Dependent Cost What if the time depends on a non-function argument? Essential for recursive functions uint fact (uint n) { if (n == 0) return 1; else return (fact (n-1) * n); } Note : Time annotation must be non-negative Ignore underflow/overflow

13 Size What if the argument is not a uint or a function? Option: Pre-defined mapping from structured data values to their “sizes”

14 Example - List struct list { const uint val; const struct list* next; } The size of a list is its length Simplifying assumption - The members of the struct are const so that we do not have to track aliasing.

15 Sumf int sumf (uint f(uint) ; struct list* x; int acc) { if (x == NULL) return acc; else { int acc2 = acc + f (x->val); struct list* x2 = x -> next; sumf (f, x2, acc2); }

16 Calling Sumf sumf(add3, NULL,0); // 0*(3+2) + 1 struct list* x = new { val = 5; next = NULL }; sumf(add3, x,0) // 1*(3+2) + 1

17 Size What if the time of f is dependent? uint sumf (uint f(uint y) ; struct list* x; uint acc) { if (x == null) return acc; else { uint acc2 = acc + f (x->val); struct list* x2 = x -> next; sumf (f, x2, acc2); }

18 User-defined size Need a programming language to express the mapping between datatypes and the time to iterate over them Expressive enough to represent structured data, and functions over that data Not so expressive that equivalence is undecidable Need a way to connect dynamic data with a representation in this language

19 Decidable, Expressive Language Typed-lambda calculus with products, sums and primitive recursion over inductive types Syntax of functional programming language ML Terminology Dynamic language -- Type-safe C Static language -- this annotation language

20 Static Language Natural numbers (of type nat) and arithmetic operations 3+4, 5*x Higher-order functions fn (x : nat) => (fn (y :nat) => x+y) (of type nat  (nat  nat) ) Tuples (3,5) : nat  nat

21 Static Language Sums and recursive types notated with datatypes datatype bool = False | True fun not (b:bool) = case b of True => False | False => True

22 Primitive Recursion datatypes can recursively mention name only in positive positions datatype foo = Bar of foo | Baz of foo * foo  datatype foo = Bar of foo  foo datatype foo = Bar of (foo  int)  foo

23 Primitive Recursion Recursive functions over these datatypes can only call themselves on subterms of their arguments datatype foo = Bar of foo | Baz of foo * foo fun iter (x : foo) = case x of Bar(w) => iter(x)  | Baz(y,z) => iter(y)

24 List Representation datatype list = Null | Cons of nat * list fun time(m : list) = case m of Nil => 0 | Cons(val, next) => val+2+time(next)

25 Decision Procedure We must be able to decide if two terms in the static language are equivalent Algorithm: convert each term to a normal form and compare Need a reduction system for terms that is confluent and strongly normalizing

26 Reduction Rules Sample Reduction rules > 7 M > M case Ci M of C1 x1 => N1 | C2 x2 => N2 --> Ni [M/xi] (fun f x => M ) N --> M[N/x, (fun f x => M)/f]

27 Connecting the Languages We must be able to use this static language to describe the values of the dynamic language Use the type system to enforce that a dynamic term matches a static description

28 Singleton Types nat represents unsigned ints Connect constants in the two languages If m : nat, form singleton type uint uint x; x = 3;  x = 4;

29 Using fact New type of factorial uint fact(uint x) ; fact(3); // takes time 3+1 uint x; fact(x); // takes time n+1

30 Pointer Types Consider pointer types int* Either a reference to an int or null Must be a reference int Must be a null pointer Want to refine the type of a variable // x has type int* if (x == NULL) { // x has type int } else { // x has type }

31 Enforcement types Static representation of integer pointers datatype ptr = Null | Ptr intptr(m) = case m of Null => int | Ptr => If x : intptr(Ptr) then we know x is not NULL

32 Refinement // suppose x : intptr(m) if (x == NULL) { // here we know that x : int // so therefore m must be Null, or // we’d get a contradiction } else { // know that m is Ptr }

33 List Enforcement Type datatype list = Null | Cons( nat, list) replist(m) = case m of Null => int | Cons(val,next) => struct { const uint val; const replist(next) rest

34 Using Enforcement Types // if x has type replist(m) if (x == NULL) { // again x : int } else { // m must be Cons (val, next) // x: {const int val; // const replist(next) rest } We’ve used a comparison in the dynamic code to increase our knowledge of the static representation

35 User-defined Size Iterate over list, calculating a nat to represent execution time fun time(m : list) = case m of Nil => 0 | Cons(val, next) => val+2+time(next)

36 Example : Code uint sumf (uint f(uint y) ; replist(m) x; uint acc) { if (x == null) return acc; else { // m must Cons( val, next) // call to f takes time val + 1 uint acc2 = acc + f (x->val); struct list* x2 = x -> next; // recursive call takes time(next) + 1 sumf (f, x2, acc2); }

37 Other Resources “Effect notation” int f(int ) doesn’t generalize to resources that can be recovered (e.g. space) Alternative: Augment the operational semantics with a virtual clock that winds down as the program executes

38 Virtual Clocks Function types specify starting and ending times (int,12) f(int, 15) starts at time 15 and finishes at time 12 Use polymorphism to abstract starting times (int, n) f(int,n+3) runs in 3 steps - it is equivalent to int f(int)

39 Recoverable Resources Consider: (int, n+12) f (int, n+15) vs. (int, n) f (int,n+3) If the resource is free-space: the first function may allocate as many as 15 units, as long as it releases 12 of them before returning. The second function only requires a minimum of 3 units of free-space to execute.

40 Upper Bound Sometimes it is enough just to know an upper bound of the running time. It is an approximation to help when static analysis fails. Add the instruction waste to the language to increment the virtual clock No run-time effect

41 Waste example bool member (int x; replist(m) w) { if (w == NULL) return false; else // m=Cons( val, next) if (x == w->val) { waste ; return true; } else { return member( w->next ); }

42 TALres We have implemented a similar system within the Typed Assembly Language framework Clock contained in a virtual register, decremented on backwards jumps TAL already has a sophisticated type constructor language Added sum and inductive kinds and refinement procedure for comparison instructions Operations on static natural numbers

43 Source Language Prototype implementation: PopCron Resembles C + timing annotations No separation between static and dynamic languages Compiler to TALres creates representations of datatypes and their enforcement types

44 The real details Static and dynamic language are really two levels of the same language Static language is embedded in the dynamic language as a language of type constructors Types of dynamic language are constants in the static language Types of static language are referred to as kinds

45 More details Building block for refinement is “virtual case analysis”

46 Another Example Dynamic trees union tree { uint Leaf; struct node Node; } struct Node { const left; const right; } Static representation datatype tree = Leaf of nat | Node of tree * tree

47 Tree example size (t : tree) = case t of Leaf(x) => x +1 | Node (left, right) => size(left) + size(right) + 2 uint sumf (uint f(uint ) ; reptree(t) t) { switch t { case Leaf(x): return f(x); case Node(x): return sumf(x.left) + sumf(x.right); }

48 Enforcement type for trees reptree (tree) = case tree of Leaf x => union { uint Leaf; empty Node;} | Node (left, right) => union { empty Leaf; struct { const left; const right; } Node; }

49 Virtual Case switch t { case Leaf(x): // Suppose at runtime we could examine the static // representation case t of Leaf (x) => This is the only branch that could occur Node (x) => … as here x is of type empty

50 Virtual Case switch t { case Leaf(x): // Since one branch is impossible we don’t need to // specify it vcase t of Leaf(x) => // binds x in following code This case statement is virtual because we know what branch will be taken -- no run time effect

51 Related Work FX Reistad and Gifford, 94 Sized Types Hughes, Pareto, Sabry, 96 Chin Khoo, 00 PCC Necula and Lee, 97 DML Xi and Pfenning, 98

52 Future Work Extension of implementation to other resources More flexible enforcement types Stronger equational logic Inference and analysis in source language