Changes between Version 71 and Version 72 of IR


Ignore:
Timestamp:
11/26/15 07:58:45 (10 years ago)
Author:
siegel
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • IR

    v71 v72  
    1313 * a sequence of variable declarations with no initializers
    1414 * a sequence of function definitions
    15  * a sequence of labeled statements.   Each clause in the labeled statement is a `\when` statement with some guard and a primitive statement, followed by a `\goto` statement
     15 * a sequence of labeled statements.   Each clause in the labeled statement is a `\when` statement with some guard and a primitive statement, followed by a `goto` statement
    1616* an array is declared without any length expression.  When it is initialized it can specify length.
    1717* curly braces are used only to indicate scopes, as in { // new scope ... }
    18 * parentheses are used to indicate function invocations, as in \add(x,y)
     18* parentheses are used to indicate function invocations, as in add(x,y)
    1919* angular brackets are used to delimit tuples or sequences
    2020* square brackets are used to delimit parameters in types
    21 * unlike C, there is no "array-pointer pun".   If an array `a` needs to be converted to a pointer, you must use \addr(\asub(a, 0))`.
    22 * there are no automatic conversions.  All conversions must be by explicit casts or other functions.   Operations such as numeric addition (`\add`) require that both operands have the exact same type.
     21* unlike C, there is no "array-pointer pun".   If an array `a` needs to be converted to a pointer, you must use addr(asub(a, 0))`.
     22* there are no automatic conversions.  All conversions must be by explicit casts or other functions.   Operations such as numeric addition (`add`) require that both operands have the exact same type.
    2323
    2424
     
    5959  a: Array[Integer];
    6060L1:
    61   when (\true) ASSIGN x, \mul(3,y); goto L2;
     61  when (\true) ASSIGN x, mul(3,y); goto L2;
    6262L2:
    63   when(\true) ASSIGN a_t, \dytype(Array[Integer, \add(x,1)]); goto L3;
     63  when(\true) ASSIGN a_t, dytype(Array[Integer, add(x,1)]); goto L3;
    6464L3:
    65   when (\true) ASSIGN a, \new(a_t); goto L4;
     65  when (\true) ASSIGN a, new(a_t); goto L4;
    6666L4:
    6767}
     
    103103* `Pointer[T]` : pointer-to-T, subtype of `Pointer`
    104104* `Dytype` : the set of all dynamic types
    105 * `Dytype[T]`: dynamic types refining T.  Values of this type represent dynamic types that refine T.  For example `\dytype(Array[Integer,24])` has type `Dytype[Array[Integer]]`
     105* `Dytype[T]`: dynamic types refining T.  Values of this type represent dynamic types that refine T.  For example `dytype(Array[Integer,24])` has type `Dytype[Array[Integer]]`
    106106
    107107Type facts:
     
    113113A **type name** is a syntactic element that names a (static or value) type.  Examples of type names include `Array[Integer]` and `Array[Integer,24]`.
    114114
    115 The expression `\new(t)` takes a Dytype and returns the initial value for an object of that type.   The initial value of `Integer` and other primitive (non-compound) types is "undefined".   The initial value of `Array[Integer]` is an array of length 0 of `Integer`.  The initial value of `Pointer[Real]` is the undefined pointer to `Real`.    The initial value of `Array[Real, 10]` is the array of length 10 in which each element is undefined.  In general, the initial value of an array of length n is the sequence of length n in which every element is the initial value of the element type of the array.   The initial value of a tuple type is the tuple in which each component is assigned the initial value for its type.
     115The expression `new(t)` takes a Dytype and returns the initial value for an object of that type.   The initial value of `Integer` and other primitive (non-compound) types is "undefined".   The initial value of `Array[Integer]` is an array of length 0 of `Integer`.  The initial value of `Pointer[Real]` is the undefined pointer to `Real`.    The initial value of `Array[Real, 10]` is the array of length 10 in which each element is undefined.  In general, the initial value of an array of length n is the sequence of length n in which every element is the initial value of the element type of the array.   The initial value of a tuple type is the tuple in which each component is assigned the initial value for its type.
    116116
    117117Example:  the C code
     
    137137  when (\true) ASSIGN n, 10; goto L1;
    138138L1:
    139   when (\true) ASSIGN S_d, \dytype(Tuple[<Array[Integer, n]]>); goto L2;
     139  when (\true) ASSIGN S_d, dytype(Tuple[<Array[Integer, n]]>); goto L2;
    140140L2:
    141   when (\true) ASSIGN x1, \new(S_d); goto L3;
     141  when (\true) ASSIGN x1, new(S_d); goto L3;
    142142L3:
    143143  when (\true) ASSIGN n, 20; goto L4;
    144144L4:
    145   when (\true) ASSIGN x2, \new(S_d); goto L5;
     145  when (\true) ASSIGN x2, new(S_d); goto L5;
    146146L5:
    147147}}}
     
    154154Logical
    155155* `\true`, `\false` : literal values of type `Bool`
    156 * `\not(e)` : logical not
    157 * `\and(e1,e2)`, `\or(e1,e2)`: logical and/or operation.  These operators are short-circuiting, which matters because of exception side-effects.
    158 * `\implies(e1,e2)`: logical implication.  Short-circuiting.
    159 * `\eq(e1,e2)`, `\neq(e1,e2)`: equality/inequality test
    160 * `\forall(<i1:T1,i2:T2,...>,e)` : universal quantification.  For all i1 in type T1, i2 in type T2, ..., e2 holds.
    161 * `\exists(<i1:T1,i2:T2,...>,e)`: existential quantification.  There is some i1 in type T1, i2 in type T2, ..., such that e holds.
     156* `not(e)` : logical not
     157* `and(e1,e2)`, `or(e1,e2)`: logical and/or operation.  These operators are short-circuiting, which matters because of exception side-effects.
     158* `implies(e1,e2)`: logical implication.  Short-circuiting.
     159* `eq(e1,e2)`, `neq(e1,e2)`: equality/inequality test
     160* `forall(<i1:T1,i2:T2,...>,e)` : universal quantification.  For all i1 in type T1, i2 in type T2, ..., e2 holds.
     161* `exists(<i1:T1,i2:T2,...>,e)`: existential quantification.  There is some i1 in type T1, i2 in type T2, ..., such that e holds.
    162162Numeric
    163163* 123, -123, 3.1415, etc. : values of type `Integer`, `Int`, `Real`, `Float`.   **NEED TO BE MORE SPECIFIC**
    164 * `\add(e1,e2)` : numeric addition. 
     164* `add(e1,e2)` : numeric addition. 
    165165 * `e1` and `e2` have the same numeric type.  Note that there are no "automatic conversions" as there are in C.  If the original expressions have different types, explicit casts must be inserted. 
    166 * `\sub(e1,e2)` : subtraction
    167 * `\mul(e1,e2)` : multiplication
    168 * `\div(e1,e2)` : division
     166* `sub(e1,e2)` : subtraction
     167* `mul(e1,e2)` : multiplication
     168* `div(e1,e2)` : division
    169169 * If both are integer types, the result is integer division.  Otherwise it is real division.  Need to define what happens for negative integers.
    170 * `\mod(e1,e2)` : integer modulus
    171 * `\neg(e)` : negative
    172 * `\lt(e1,e2)`, `\lte(e1,e2)`: less than/less than or equal to
     170* `mod(e1,e2)` : integer modulus
     171* `neg(e)` : negative
     172* `lt(e1,e2)`, `lte(e1,e2)`: less than/less than or equal to
    173173Characters and Strings
    174174* 'a', 'b', ... : Char values.  **UNICODE?**
    175175* `"abc"` : string literals: value of type `Array[Char, n+1]`, where n is the length of the string (the last element is the character `\0`)
    176176Ranges and Domains
    177 * `\range(e1,e2,e3)` : value of type `Range`.  If `e3` is positive, the integers e1, e1+e3, e1+2*e3, ... that are less than or equal to `e2`.  If `e3` is negative, the integers e1, e1+e3, e1+2*e3, ... that are greater than or equal to `e2`.  Exception if `e3` is 0.
    178 * `\domain(<r1,...,rn>)` : value of type `Domain[n]`, the Cartesian product of the n ranges, with dictionary order
    179 * `\hasnext(dom, <i,j,…>)`: an expression of boolean type, testing if the domain `dom` contains any element after `<i,j,...>`
     177* `range(e1,e2,e3)` : value of type `Range`.  If `e3` is positive, the integers e1, e1+e3, e1+2*e3, ... that are less than or equal to `e2`.  If `e3` is negative, the integers e1, e1+e3, e1+2*e3, ... that are greater than or equal to `e2`.  Exception if `e3` is 0.
     178* `domain(<r1,...,rn>)` : value of type `Domain[n]`, the Cartesian product of the n ranges, with dictionary order
     179* `hasnext(dom, <i,j,…>)`: an expression of boolean type, testing if the domain `dom` contains any element after `<i,j,...>`
    180180Arrays
    181 * `\array(T,<e0,...,en-1>)`: value of type `Array[T, n]`, a literal array
    182 * `\array(T,n,e)`: value of type `Array[T,n]` in which each of the n elements is `e`
    183 * `\asub(e1,e2)` : array subscript expression.  Note that `e1` must have array type, not pointer type. (This is different from C.)   If `e1` has pointer type, use `\deref(\padd(e1, e2))` instead.
    184 * `\seq_add(a,e)` : array obtained by adding element e to the end of the array.  Original array a is not modified.
    185 * `\seq_append(a1,a2)` : array obtained by concatenating two arrays.  Original array not modified.
    186 * `\seq_remove(a,i)` : array obtained by removing element at position i from a.  Original array a not modified.
    187 * `\bit_and(e1, e2)`, `\bit_or(e1, e2)`, `\bit_xor(e1, e2)`, `\bit_comp(e1)` : bit-wise operations: arguments are arrays of booleans of equal length.
     181* `array(T,<e0,...,en-1>)`: value of type `Array[T, n]`, a literal array
     182* `array(T,n,e)`: value of type `Array[T,n]` in which each of the n elements is `e`
     183* `asub(e1,e2)` : array subscript expression.  Note that `e1` must have array type, not pointer type. (This is different from C.)   If `e1` has pointer type, use `deref(padd(e1, e2))` instead.
     184* `seq_add(a,e)` : array obtained by adding element e to the end of the array.  Original array a is not modified.
     185* `seq_append(a1,a2)` : array obtained by concatenating two arrays.  Original array not modified.
     186* `seq_remove(a,i)` : array obtained by removing element at position i from a.  Original array a not modified.
     187* `bit_and(e1, e2)`, `bit_or(e1, e2)`, `bit_xor(e1, e2)`, `bit_comp(e1)` : bit-wise operations: arguments are arrays of booleans of equal length.
    188188Tuples
    189 * `\tuple(S,<e0,e1,...>)` : value of tuple type `S` (tuple literal)
    190 * `\tsel(e1,i)` : tuple selection of component i of e1.  i must be a literal natural number.
     189* `tuple(S,<e0,e1,...>)` : value of tuple type `S` (tuple literal)
     190* `tsel(e1,i)` : tuple selection of component i of e1.  i must be a literal natural number.
    191191Unions
    192 * `\union_inj(U,i,x)` : `x` is in `Ti`, result is in the union type `U`
    193 * `\union_sel(U,i,y)` : `y` is in `U`, result is in `Ti` (or exception if `y` is not in image of injection from `Ti`)
    194 * `\union_test(U,i,y)` : `y` is in `U`; determines if `y` is in the image under injection of `Ti`.  Returns a Boolean.
     192* `union_inj(U,i,x)` : `x` is in `Ti`, result is in the union type `U`
     193* `union_sel(U,i,y)` : `y` is in `U`, result is in `Ti` (or exception if `y` is not in image of injection from `Ti`)
     194* `union_test(U,i,y)` : `y` is in `U`; determines if `y` is in the image under injection of `Ti`.  Returns a Boolean.
    195195Pointers and Memory
    196196* `NULL` : value of type `void*`
    197 * `\deref(e)` : pointer dereference
    198 * `\addr(e)` : address-of operator
    199 * `\padd(e1,e2)`: pointer addition. `e1` has pointer type and `e2` has an integer type or range type.  If `e2` has integer type the result has pointer type.   Otherwise, the result has `Mem` type.
    200 * `\psub(e1,e2)`: pointer subtraction
    201 * `\mem_reach(ptr)`, where `ptr` is an expression with a pointer type.  This represents the set of all memory units reachable from `ptr`, including the memory unit pointed to by `ptr` itself.
    202 * `\mem_union(mem1,mem2)`, where `mem1` and `mem2` are expressions of type `Memory`.  This is the union of the two memory sets.
    203 * `\mem_isect(mem1,mem1)` : set intersection
    204 * `\mem_comp(mem1)` : set complement (everything not in `mem1`)
    205 * `\mem_slice(a,dom)`, where `a` is an expression of array type and `dom` is an expression of `Domain` type.   The dimension of the array must match the dimension of the domain.   This represents all memory units which are the cells in the array indexed by a tuple in `dom`.
     197* `deref(e)` : pointer dereference
     198* `addr(e)` : address-of operator
     199* `padd(e1,e2)`: pointer addition. `e1` has pointer type and `e2` has an integer type or range type.  If `e2` has integer type the result has pointer type.   Otherwise, the result has `Mem` type.
     200* `psub(e1,e2)`: pointer subtraction
     201* `mem_reach(ptr)`, where `ptr` is an expression with a pointer type.  This represents the set of all memory units reachable from `ptr`, including the memory unit pointed to by `ptr` itself.
     202* `mem_union(mem1,mem2)`, where `mem1` and `mem2` are expressions of type `Memory`.  This is the union of the two memory sets.
     203* `mem_isect(mem1,mem1)` : set intersection
     204* `mem_comp(mem1)` : set complement (everything not in `mem1`)
     205* `mem_slice(a,dom)`, where `a` is an expression of array type and `dom` is an expression of `Domain` type.   The dimension of the array must match the dimension of the domain.   This represents all memory units which are the cells in the array indexed by a tuple in `dom`.
    206206Scopes and Processes
    207207* `\root`, `\here` : values of type `Scope`
     
    209209Other
    210210* variables
    211 * `\sizeof_type(t)` : the size of the dynamic type t; `Integer` type
    212 * `\sizeof_expr(e)` : the size of the value of expression `e`; `Integer` type
    213 * `\new(t)` : new (default) value of `Dytype` t
    214 * `\defined(e)` : is `e` defined? `Bool` type
    215 * `\cast(e,T)` : casts `e` to a value of the named type
     211* `sizeof_type(t)` : the size of the dynamic type t; `Integer` type
     212* `sizeof_expr(e)` : the size of the value of expression `e`; `Integer` type
     213* `new(t)` : new (default) value of `Dytype` t
     214* `defined(e)` : is `e` defined? `Bool` type
     215* `cast(e,T)` : casts `e` to a value of the named type
    216216 * need to list all of the legal casts and what they mean exactly
    217217 * cast of integer to array-of-boolean, and vice-versa?
    218218 * **Instead of casts would it be better to have explicit functions for each legal kind of cast?**
    219 * `\ite(e1,e2,e3)`: if-then-else (conditional) expression, like `e1?e2:e3` in C.
     219* `ite(e1,e2,e3)`: if-then-else (conditional) expression, like `e1?e2:e3` in C.
    220220* `call(e0,<e1,...,en>)` : a function invocation where `e0` must evaluate to either an abstract or pure system function
    221221
     
    236236 * `e0` has integer type.
    237237 * Allocates `e0` objects of type `t` on heap `h`, returning pointer to first element in `e`
    238  * To translate the C `malloc` you first need to figure out the type of the elements being malloced.  If the argument to malloc is `n`, then you first need to insert an assertion `\eq(\mod(n, \sizeof_type(t)), 0)`, and then `ALLOCATE e, h, t, \div(n, \sizeof_type(t))`.
     238 * To translate the C `malloc` you first need to figure out the type of the elements being malloced.  If the argument to malloc is `n`, then you first need to insert an assertion `eq(mod(n, sizeof_type(t)), 0)`, and then `ALLOCATE e, h, t, div(n, sizeof_type(t))`.
    239239* `FREE p;`
    240240* `EVAL e;`, where `e` is an expression that might contain exceptions (e.g., array index out of bound, division by zero);
     
    258258
    259259Additional modifiers that may be placed on any of above:
    260 * `\pure` : the function has no side effects, but may be nondeterministic
    261 * `\abstract`: function is a pure, mathematical function: deterministic function of inputs
    262 * `\atomic`: function definition is atomic, and it never blocks **ISN'T THIS TRUE OF EVERY SYSTEM FUNCTION?  IN WHICH CASE, IS THIS ONLY FOR NON-SYSTEM FUNCTIONS?**
     260* `pure` : the function has no side effects, but may be nondeterministic
     261* `abstract`: function is a pure, mathematical function: deterministic function of inputs
     262* `atomic`: function definition is atomic, and it never blocks **ISN'T THIS TRUE OF EVERY SYSTEM FUNCTION?  IN WHICH CASE, IS THIS ONLY FOR NON-SYSTEM FUNCTIONS?**
    263263
    264264System functions:
     
    271271{{{
    272272g(x:Real):Bool { ... }
    273 f(x:Real):Integer \guard g;
     273f(x:Real):Integer guard g;
    274274}}}
    275275
     
    280280{{{
    281281EventSetExpression
    282  : \read(MemorySetExpression)
    283  | \write(MemorySetExpression)
    284  | \access(MemorySetExpression)
    285  | \calls(FunctionCallExpression)
     282 : read(MemorySetExpression)
     283 | write(MemorySetExpression)
     284 | access(MemorySetExpression)
     285 | calls(FunctionCallExpression)
    286286 | \nothing
    287287 | \everything
     
    291291 | EventSetExpression & EventSetExpression
    292292}}}
    293 * depends clause: `\depends [condition] { event1, event2, ...}`
     293* depends clause: `depends [condition] { event1, event2, ...}`
    294294 * Example:
    295295{{{
    296 \depends {
    297   \access(n) - (\calls(inc(MemorySetExpression)) + \calls(dec(MemorySetExpression)))
    298 }
    299 }}}
    300  * **absence of \depends clause**:
     296depends {
     297  access(n) - (calls(inc(MemorySetExpression)) + calls(dec(MemorySetExpression)))
     298}
     299}}}
     300 * **absence of depends clause**:
    301301* assigns-or-reads clause
    302  * assigns clause: `\assigns [condition] {memory-list}`
    303  * reads clause: `\reads [condition] {memory-list}`
    304  * `\reads {\nothing}` implies `\assigns {\nothing}`
    305  * `\reads {\nothing}` is equivalent to: `\reads {\nothing} \assigns {\nothing}`
    306  * `\assigns {X}` where `X != \nothing`, implies `\reads {X}`
    307  * `\assigns {X}` is equivalent to:` \assigns{X} \reads{X}`
     302 * assigns clause: `assigns [condition] {memory-list}`
     303 * reads clause: `reads [condition] {memory-list}`
     304 * `reads {nothing}` implies `assigns {nothing}`
     305 * `reads {\nothing}` is equivalent to: `reads {\nothing} assigns {\nothing}`
     306 * `assigns {X}` where `X != \nothing`, implies `reads {X}`
     307 * `assigns {X}` is equivalent to:` assigns{X} reads{X}`
    308308 * absence:
    309   * absence of `\reads` clause: there is no assumption about the read access of the function, i.e., the function could read anything
    310   * absence of `\assigns` clause: similar to the absence of `\reads` clause
    311  * `\reads/\assigns {\nothing}` doesn’t necessarily means that the function never reads or assigns any variable. The function could still reads/assigns its “local” variables, including function parameters and any variable declared inside the function body.
    312 
    313 * For an independent function which has `\depends {\nothing}`, usually we also need to specify `\reads{nothing}`, for the purpose of reachability analysis.
     309  * absence of `reads` clause: there is no assumption about the read access of the function, i.e., the function could read anything
     310  * absence of `assigns` clause: similar to the absence of `reads` clause
     311 * `reads/assigns {\nothing}` doesn’t necessarily means that the function never reads or assigns any variable. The function could still reads/assigns its “local” variables, including function parameters and any variable declared inside the function body.
     312
     313* For an independent function which has `depends {\nothing}`, usually we also need to specify `reads{nothing}`, for the purpose of reachability analysis.
    314314e.g.,
    315315{{{
    316316/* Returns the size of the given bundle b. */
    317 \bundle_size(Bundle b; Int)
    318   \depends {\nothing}
    319   \reads {\nothing}
     317bundle_size(Bundle b; Int)
     318  depends {\nothing}
     319  reads {\nothing}
    320320  ;
    321321}}}
     
    323323* Example of a function declaration with contracts:
    324324{{{
    325 \atomic_f sendRecv(Int cmd, Pointer buf; Int)
    326   \depends [\eq(cmd, SEND)] {\write(buf)}
    327   \depends [\eq(cmd, RECV)] {\access(\deref(buf))}
    328   \assigns [\eq(cmd, SEND)] {\nothing}
    329   \assigns [\eq(cmd, RECV)] {\deref(buf)}
    330   \reads {\deref(buf)}
     325atomic_f sendRecv(Int cmd, Pointer buf; Int)
     326  depends [eq(cmd, SEND)] {write(buf)}
     327  depends [eq(cmd, RECV)] {access(deref(buf))}
     328  assigns [eq(cmd, SEND)] {\nothing}
     329  assigns [eq(cmd, RECV)] {deref(buf)}
     330  reads {deref(buf)}
    331331{
    332332L0:
    333   when (\eq(cmd, SEND))
    334      send(\deref(buf), ...); goto L1;
    335   when (\eq(cmd, RECV))
    336     \deref(buf):=recv(...); goto L1;
    337   when (\and(\neq(cmd, SEND), \neq(cmd, RECV)))
     333  when (eq(cmd, SEND))
     334     send(deref(buf), ...); goto L1;
     335  when (eq(cmd, RECV))
     336    deref(buf):=recv(...); goto L1;
     337  when (and(neq(cmd, SEND), neq(cmd, RECV)))
    338338    ; goto L1;
    339339L1: