See Installing Simplify.
Invariant admissibility
=======================
An invariant declaration in class C is admissible if every field
access, array access, method call and quantification is admissible.
For simplicity, gi and f may refer both to field accesses and method calls.
1. Field access and method call admissibility
Expressions in invariants can contain Confined and StateIndependent
method calls. Ownership information for these methods is derived from
the explicit rep and peer annotations as well as from the Element and
ElementCollection attributes together with the ElemensRep and
ElementsPeer attributes on the receiver object.
Parameters of method calls must be admissible.
Access chains of the following forms are admissible.
(1) this.g1.g2...gn.f, where
either
n=0,
or
g1 is marked rep and each of g2,...,gn is either marked rep
or a peer.
(2) this.g1...gn.f, where n>=1, and
f is a field that mentions C in its Dependent attribute
(visibility-based access),
or
f is a readonly field,
or
f is a field declared in an immutable type,
or
f is a StateIndependent method.
Furthermore, this.g1...gn is admissible.
Additionally:
- In both cases, if g1 is a field access then it must be declared in class
C or a supertype of C. In the latter case the field must be marked
Additive.
- Confined static methods are not admissible. As a consequence,
methods Owner.Is, Owner.Same, Owner.None cannot be used in
invariants.
- There is no admissibility requirement on targets and parameters of
static and StateIndependent methods.
2. Array access admissibility
The admissibility rules for accesses that contain array accesses are as
follows:
(1) this.g1.g2...gn.arr[i], where
either
n=0 and arr is a rep field,
or
g1 is a rep field and each of the fields g2,...,gn,arr is
either a rep or a peer field.
(2) this.g1.g2...gj.arr[i].gj+1...gn, where n>=1 and one of the
following applies:
j=0 and arr is a rep and ElementsRep field and gj+1,...,gn
is admissible,
or
g1 is a rep field and each of the fields g2,...,gj,arr is
either a rep or a peer field and arr is an ElementsRep field
and gj+1,...,gn is admissible. Field arr may be ElementsPeer
too provided the ownership-depth of the array object
is greater than one.
or
C is mentioned in the dependent-clause of gn.
3. Quantification admissibility
(1) forall{int i in (E1:E2); P(i)}, where E1, E2 and P(i) are admissible.
(2) forall{T t in this.g1...gn.f; P(t)}, where the type of f is
array-type or IEnumerable-like type,
and
either n=0 and f is a rep field or g1 is a rep field and each
of the fields g2,...,gn,f is either a rep or a peer field.
and
f is an ElementsRep field or an ElementsPeer field provided
that the ownership-depth of the object refered to by f is
greater than one.
and
P(t) is admissible, where t is considered to be rep.
Admissibility of target objects
-------------------------------
Target-objects of field and array accesses, and method calls must be
the implicit or explicit this-object or a member binding. Expressions
other than type-casts and nonnull-casts are not admissibile.
Specification admissibility of pure methods
===========================================
1. Since axioms are generated from the specification of pure methods,
the specifications are only admissible if they are well-founded.
To ensure the well-foundedness of method specifications, for each
method call occuring in the specification there has to be a measure
that decreases relative to the method being specified.
The following measures are considered:
(1) purity level: a method call with a purity level lower than the
purity level of the method being specified is considered
well-founded.
The levels in decreasing order are: Pure, Confined,
StateIndependent.
(2) ownership of receiver of the method call: if the receiver of
the method call that occurs in the specification is owned by
the this-object then the call is considered well-founded.
(3) the value of RecursionTermination attribute: if the
RecursionTermination value of a method call is less than the
RecurstionTermination value of the method being specified, then
the call is considered well-founded.
In case there is no decreasing measure found, there is a warning
issued, furthermore, the specification is not used for axiom
generation.
2. Besides well-foundedness, the following requirements apply.
The specification of Confined methods must be Confined: the
admissiblity rules are similar as for invariants, except that
visibility-based accesses are not admissible. Only Confined and
StateIndependent method calls may occur in the specification.
The specification of StateIndependent methods must be
StateIndependent: only readonly field accesses and field accesses
on fields declared in immutable types are allowed. Only
StateIndependent method calls may occur in the specification.
3. The following methods may not occur in the specification of
Confined and StateIndependent methods: IsExposable, IsExposed,
IsConsistent, IsPeerConsistent, IsValid, IsPrevalid.