-
Notifications
You must be signed in to change notification settings - Fork 27
Spec math modes
Proof modes:
- No overflows, model everything as big ints (unsound)
- Checked overflows (incomplete but sound)
- Java Behaviour (sound and complete but may be hard to close)
Chosen proof mode applies to both code and specification of all contracts used within this proof.
Wording in KeY: 'Arithmetic with overflow checking' also treats integers as mathematical objects, but ensures that no overflow occurs
Current behaviour e.g.:
assignmentAdditionInt {
\find( [ x = a + b ] post )
\replacewith(
{ x :=
\if(inInt(a + b))
\then(a + b)
\else(javaAddIntOverflow(a, b))
} post
)
};
Observation: Current mode does not prevent all overflows, better wording would be: Checks that no overflows occur or that their result does not matter otherwise.
Wording in KeY Book: Mentions overflow being a fixed, but unspecified value.
Old KeY Book 12.4.1:
- Strengthening the precondition of the operations to ensure that the operations only act on the parts of the domain where int actually behaves like integer
- Results in additional proof obligations stating that the result of an operation does not exceed the (finite) range of the expression type
The modifiers java_math
, safe_math
and bigint_math
describe what math modes are used for specifications (spec_*
) and for Java code (code_*
).
Chalin04
These are allowed on class and method level.
-
java_math
: Integral arithmetic can cause silent wrap-around of computations. -
safe_math
: Wrap-around of integral arithmetic causes exceptions. -
bigint_math
: There is no wrap-around, use bigints.
/*@ public normal_behaviour
@ requires x < Integer.MAX_VALUE;
@ ensures \result == x + 1;
@*/
/*@ spec_bigint_math @*/
/*@ code_safe_math @*/
public static int add_one(int x) {
return x + 1;
}
Default here: java_math
but a warning is issued when no modifier is given since this is indeed unexpected.
Problem with code_safe_math
and code_bigint
: Runtime exceptions and BigInts?!
- Use different math mode for code and spec
- This is not possible with the current taclet options
- Proving a stronger version of the code (e.g. with checked overflows) should not change the contract in any observable way
-
code_*
modifiers are a proof detail and can remain a taclet option or similar -
spec_*
modifiers however are not a proof detail- Produces inconsistencies requiring external tooling to check: Am I actually using what I proved?
- This has to be a per method or per contract decision
- Can vary per method, not a global decision
-
code_*
modelling is only for symbolic execution and makes proofs less strong - Modes
java_math
andbigint_math
are already implemented and remain conceptually unchanged - All modes should be callable in specification, e.g.
\java_math(\forall int x; blkjrej; x + y >= 0))
- Problem with
bsum
andbprod
- Some rules assume bigints
-
inInt
should makes sense even without overflows, it should not translate totrue
, use something else for parameters that does this - Parameters and return values should always be
inInt
, not matter the mode- Future work
-
spec_safe_math
makes no sense- Either we want wrapping or no wrapping, but definitely no runtime exceptions
-
code_safe_math
: Deviate from standard: We don't want to use runtime exceptions - This adds a branch for every source code arithmetic operation
- It is clear why this check is necessary and where its proof obligation comes from
- Does not clutter the sequent with if-then-else formulas
- The branch has to be added to ensure the absence of all overflows being proven
- The additional overhead of this simple branch is minuscule, there is no need to split proving overflow and functional properties even for larger projects
- JML Modifiers for methods
-
spec_java_math
andspec_bigint_math
-
spec_safe_math
part of well definedness (optional)
-
- Default spec mode
spec_bigint_math
(deviation from Chalin) - Default code mode checked overflows
- Rebuild taclet option checked overflows
assignmentAdditionInt {
\find(
[ x = a + b ] post
)
"Overflow check": \replacewith (
inInt(a + b)
);
"Usage": \replacewith(
{ x := a + b } post
)
};
- JML operator
\java_math(x + y)
(optional)