C.1  Logic Language

The logic language of the RISC ProgramExplorer is based on the language of the RISC ProofNavigator [58]. In the following, we only describe the differences respectively extensions.

C.1.1  Declarations

The logic language allows to introduce by declarations

While the language of RISC ProofNavigator considers both terms and formulas as elements of the syntactic domain (value) expression (formulas are just expressions denoting a Boolean value, mismatches between terms and formulas are detected by the type checker), the RISC ProgramExplorer decomposes expression into two syntactic domains term and formula (which already enables the parser to detect mismatches). Nevertheless, on the semantic level predicates are just considered as functions whose result is a Boolean value.

Object/function/predicate constants can now be defined as follows:

ident:type=term
This definition introduces an object constant ident defined as term. If type denotes the type BOOLEAN, ident can be used as a 0-ary predicate constant.
ident:type<=>formula
This definition introduces a 0-ary predicate constant ident; type must denote the type BOOLEAN.
ident:type=LAMBDA(params):term
This definition introduces a new function constant ident which is defined as a function that binds its concrete arguments to the parameters params and returns as a a result the value of term in the environment set up by the binding. Here type must denote a corresponding function type. If the domain of type denotes the type BOOLEAN, ident can be considered as a predicate constant.
ident:type=PRED(params):formula
This definition introduces a predicate constant ident which is defined as a predicate that binds its concrete arguments to the parameters params and returns as a a result the truth value of formula in the environment set up by the binding. Here type must denote a corresponding function type whose domain denotes the type BOOLEAN; here the is recommended.

C.1.2  Types

The RISC ProgramExplorer introduces the additional types


STRING
PREDICATE(types)
LOGICAL
BIT

STRING is an unspecified type which plays a role in the .

PREDICATE(types) is a synonym of


(types)->BOOLEAN

The use of this type syntactically simplifies the .

Type LOGICAL with constants LOGICALTRUE and LOGICALFALSE is the result type of predicates, respectively the type of those expressions that denote logical formulas (the predicate constants LOGICALTRUE and LOGICALFALSE thus denote formulas).

Type BIT with the constants BITTRUE and BITFALSE and associated operations &, | and ̃ is the type of truth values (the constants BITTRUE and BITFALSE thus denote terms).

Depending on the property settings (see Section 2), type code BOOLEAN is a synom for one of these types (and the constants TRUE and FALSE are synonyms for the corresponding constants). The difference only matters, if the selected logic is first order, because then formulas (denoting logical values) and terms (denoting other kinds of values) are strictly separated.

C.1.3  Mapping Program Types to Logical Types

The subsequent subsections describe how a logical formula may refer to the values of . This requires the mapping of program values to logical values and of program types to logical types. The mapping is based on the automatically generated theory Base in the unnamed top-level package:

theory Base  
{  
  MIN_INT: INT = -2147483648;  
  MAX_INT: INT = 2147483647;  
  minIntAxiom: AXIOM MIN_INT < 0;  
  maxIntAxiom: AXIOM MAX_INT > 0;  
  int: TYPE = [MIN_INT..MAX_INT];  
  nat: TYPE = [0..MAX_INT];  
  char: TYPE;  
  intTrunc: REAL -> INT;  
  intTruncAxiom: AXIOM FORALL(x: REAL):  
    (IF x >= 0 THEN x-1 < intTrunc(x) AND intTrunc(x) <= x  
               ELSE x <= intTrunc(x) AND intTrunc(x) < x+1 ENDIF);  
  intDivOverflow: (int, int) -> int;  
  intDiv0: (int, int) -> INT = LAMBDA(x: int, y: int):  
    (IF y /= 0 THEN intTrunc(x/y) ELSE intDivOverflow(x, y) ENDIF);  
  zero: int = 0;  
  nullChar: char;  
  nullString: STRING;  
  newString: INT -> STRING;  
  IntArray: TYPE =  
    [#value: ARRAY int OF int, length: nat, null: BOOLEAN#];  
  nullIntArray: IntArray =  
    (#value:=ARRAY(y: int): zero, length:=zero, null:=TRUE#);  
  newIntArray: nat -> IntArray = LAMBDA(x: nat):  
    (#value:=ARRAY(y: int): zero, length:=x, null:=FALSE#);  
  CharArray: TYPE =  
    [#value: ARRAY int OF char, length: nat, null: BOOLEAN#];  
  nullCharArray: CharArray =  
    (#value:=ARRAY(y: int): nullChar, length:=zero, null:=TRUE#);  
  newCharArray: nat -> CharArray = LAMBDA(x: nat):  
    (#value:=ARRAY(y: int): nullChar, length:=x, null:=FALSE#);  
  BooleanArray: TYPE =  
    [#value: ARRAY int OF BOOLEAN, length: nat, null: BOOLEAN#];  
  nullBooleanArray: BooleanArray =  
    (#value:=ARRAY(y: int): FALSE, length:=zero, null:=TRUE#);  
  newBooleanArray: nat -> BooleanArray = LAMBDA(x: nat):  
    (#value:=ARRAY(y: int): FALSE, length:=x, null:=FALSE#);  
  StringArray: TYPE =  
    [#value: ARRAY int OF STRING, length: nat, null: BOOLEAN#];  
  nullStringArray: StringArray =  
    (#value:=ARRAY(y: int): nullString, length:=zero, null:=TRUE#);  
  newStringArray: nat -> StringArray = LAMBDA(x: nat):  
    (#value:=ARRAY(y: int): nullString, length:=x, null:=FALSE#);  
}

In detail, program types are mapped to logical types as follows (where we assume that the logical type BOOLEAN is a synonym for the logical type BIT of truth values):

boolean
The program type boolean is mapped to the logical type BOOLEAN:
int
The program type int is mapped to the logical type Base.int (which is a subrange of the type INT of all integer numbers).
char
The program type char is mapped to the logical type Base.char (which is currently unspecified).
class C
Every class C is automatically translated to a theory C that resides in the same package as the class. This theory contains a record type C to which the program type (class) C is mapped. A record of this type contains

The theory also contains an array type Array to which the program type (class) C[] is mapped (see below for the details of array representations).

Additionally the automatically generated theory contains the following constants:

null: C
This constant represents a program value of type C that is null.
newObject: INT->C
This function is used to represent the allocation of a value of type C (the argument is an unspecified integer by which the new field of the object is initialized).
nullArray: Array
This constant represents a program value of type C[] that is null.
newArray: INT->Array
This function is used to represent the allocation of an array of type C[] (the argument represents the length of the array); an axiom newArrayAxiom specifies that all elements in the range of the array are null.

In the translation of an object access object.field, the RISC ProgramExplorer uses the precondition object.null = FALSE. If an object, for which this precondition can be established is updated by an assignment to an object variable, also the new object value satisfies that condition. On the other side, null is just an unspecified value for which the precondition simply can not be established. As a consequence, in method preconditions not the test object /=C.null but the test NOTobject.null must be applied. Therefore also a program test object != null is automatically translated to the logical test object.null = FALSE.

Character strings
If the user provides a program class java.lang.String, string literals in programs are considered as values of this class which is mapped to the logical type java.lang.String.String.

However, if the user does not provide such a class, string literals in programs are considered as values of a pseudo-type that is mapped to the logical type .

T[]
If T denotes a class, then the program type T[] is mapped to the record type Array in the theory of C. If T is boolean, int, char, or String, the theory Base contains a record type TArray (the name of T is capitalized) to which the program type T[] is mapped. Other array types are currently not supported.

The record type contains the following fields:

value: ARRAY Base.int OF T’
This field represents the sequence of array elements; T’ is the type to which the program type T is mapped.
length: Base.nat
This field indicates that in value only the elements at indices from 0 inclusive to length exclusive are defined.
null: BOOLEAN
If set to true, this field indicates that the program value represents the null pointer (then the other fields are meaningless);

A class T contains also constants nullTArray and newTArray that represent array values that are null respectively result from the allocation of a new array (see above).

If T is boolean, int, char, or String, the theory Base contains also constants nullTArray and newTArray (again the name of T is capitalized) that represent array values that are null respectively result from the allocation of a new array.

As for objects, in method preconditions not the test array /=T.null but the test array.null = FALSE must be applied (see the explanation for objects above).

C.1.4  Program Variables

Synopsis


OLD var
VAR var

Description Within the context of a state predicate of a specification (e.g. in a or in a ), both OLD var and VAR var refer to the “current” state of the program variable var.

Within the context of a state relation of a specification (e.g. a or ), OLD var refers to the value of the program variable var in the prestate of the specified execution; VAR var refers to the value of var in the corresponding poststate.

More specifically, OLD var respectively VAR var denotes the logical value to which the value of the program variable is mapped. Therefore the type of OLD var respectively VAR var is the logical type to which the type of the program variable is mapped.

Pragmatics A reference to a program variable var in a formula is tagged with keyword OLD or VAR to explicitly distinguish it from a reference to a logical variable; we thus emphasize that its value actually results from mapping a program value to a logical value.

We choose the keywords and their interpretations in both state conditions and state relations in order to minimize the confusion of programmers:

C.1.5  Program States

The logic language introduces a new kind of values called states with corresponding types, constants, functions, and predicates.

Type STATE

Synopsis


STATE
STATE(type)

Description A type of this family denotes the set of states that may result from the execution of a command. The type STATE indicates that the execution of the command must not return a value (i.e. that the command is executed within a function of result type void); the type STATE(type) indicates that the command may return a value of the denoted type.

State Constants

Synopsis


NOW
NEXT

Description Within the context of a state predicate of a specification (e.g. a ), both constants NOW and NEXT denote the “current” state.

Within the context of a state relation of a specification (e.g. a or ), the constant NOW denotes the prestate of the specified execution while the constant NEXT denotes the corresponding poststate.

Pragmatics To simplify the semantics, NEXT is also defined in the context of a state predicate.

In a loop invariant, NOW refers to the prestate of the loop, while NEXT refers to the poststate of the loop body.

C.1.6  State Functions

Synopsis


VALUE@state
MESSAGE@state

Description These functions are evaluated over state whose type is of form . If state results from the execution of return value, then the term VALUE@next refers to (the logical mapping of) value. The type of state must be of form STATE(result); the type of VALUE@next is result (which is the logical mapping of the type of value).

If state results from the execution of throw new exception(message), the term MESSAGE@next refers to (the logical mapping of) message. Its type is the logical mapping of the program type java.lang.String (which must be the type of message).

State Predicates

Synopsis


EXECUTES@state
CONTINUES@state
BREAKS@state
RETURNS@state
THROWS@state
THROWS(exception)@state

Description These predicates are evaluated over state whose type is of form :

State Equality

Synopsis


state1~state2

Description This predicate is evaluated over two states state1 and state2 which may be of different state types STATE(type1) and STATE(type2) (respectively STATE). The result is true if and only if both states are equal except for their values VALUE@state1 respectively VALUE@state2 (if applicable).

Pragmatics The predicate may be required to express the relationship between the poststate of a called method and the poststate of the calling method (which may have different return types).

State Pair Predicates

Synopsis


READSONLY
WRITESONLY var, 

Description These formulas are evaluated in the context of a pair of execution states (e.g. a or ) called the “prestate” and the “poststate” of the execution.

READSONLY is true if and only if the value of every program variable is in the poststate of the execution the same as in the prestate.

WRITESONLY name, is true if and only if the value of every program variable that is not listed in “var, …” is in the poststate of the execution the same as in the prestate.