* Need help understanding SPARK substitution rules
@ 2012-06-20 18:30 Ben Hocking
2012-06-21 8:47 ` Phil Thornley
2012-06-21 12:56 ` Ben Hocking
0 siblings, 2 replies; 3+ messages in thread
From: Ben Hocking @ 2012-06-20 18:30 UTC (permalink / raw)
I have the following math.ads:
========
package Math is
function IsPositive (InVal : in Integer) return Boolean;
--# return (InVal > 0);
function IsNegative (InVal : in Integer) return Boolean;
--# return (InVal < 0);
function AlwaysTrue (InVal : in Integer) return Boolean;
--# return True;
end Math;
========
and math.adb:
========
package body Math is
function IsPositive (InVal : in Integer) return Boolean is
begin
return (InVal > 0);
end IsPositive;
function IsNegative (InVal : in Integer) return Boolean is
begin
return (InVal < 0);
end IsNegative;
function AlwaysTrue (InVal : in Integer) return Boolean is
begin
--# check not (InVal > 0) -> InVal <= 0;
--# check not IsPositive(InVal) -> InVal <= 0;
--# check not (InVal < 0) -> InVal >= 0;
--# check not IsNegative(InVal) -> InVal >= 0;
return (not IsPositive(InVal) or not IsNegative(InVal));
end AlwaysTrue;
end Math;
========
The statement "check not (InVal > 0) -> InVal <= 0" is proven easily enough, but the next line ("check not IsPositive(InVal) -> InVal <= 0") is not, even though it's functionally equivalent. If I put the following line in math.rlu:
========
math_ispositive: ispositive(inval) may_be_replaced_by (inval > 0)
========
It now can prove it, and if I do the same thing with isnegative, the whole thing proves out (with the "return True" component being proven by ViCToR).
However, this seems like a very fragile way of assuring code correctness, so it reeks from "code smell". What is a better way of achieving this?
Thanks,
-Ben
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Need help understanding SPARK substitution rules
2012-06-20 18:30 Need help understanding SPARK substitution rules Ben Hocking
@ 2012-06-21 8:47 ` Phil Thornley
2012-06-21 12:56 ` Ben Hocking
1 sibling, 0 replies; 3+ messages in thread
From: Phil Thornley @ 2012-06-21 8:47 UTC (permalink / raw)
In article <84581b9d-040b-493b-a8af-ab3499001b5d@googlegroups.com>,
benjaminhocking@gmail.com says...
>
> I have the following math.ads:
[code snipped]
> The statement "check not (InVal > 0) -> InVal <= 0" is proven easily
> enough, but the next line ("check not IsPositive(InVal) -> InVal <=
> 0") is not, even though it's functionally equivalent. If I put the
> following line in math.rlu:
> ========
> math_ispositive: ispositive(inval) may_be_replaced_by (inval > 0)
> ========
> It now can prove it, and if I do the same thing with isnegative, the
> whole thing proves out (with the "return True" component being proven
> by ViCToR).
>
What you need is for the Examiner to include the return expressions in
the hypotheses - it does (now) do this, but only for VCs generated for
code that follows the function call. (See Proof Manual Section 8.4.9 -
bullet point 4)
So if you change your code to
function AlwaysTrue (InVal : in Integer) return Boolean is
Result : Boolean;
begin
Result := (not IsPositive(InVal) or not IsNegative(InVal));
--# check not (InVal > 0) -> InVal <= 0;
--# check not IsPositive(InVal) -> InVal <= 0;
--# check not (InVal < 0) -> InVal >= 0;
--# check not IsNegative(InVal) -> InVal >= 0;
return Result;
end AlwaysTrue;
then the VCs generated for the check annotations include hypotheses such
as:
H7: ispositive(inval) <-> (inval > 0) .
Now the only VC left unproven by the Simplifier is the last one (which
you note is proved by Victor).
For those of us who (so far) find Victor (I loathe that casing they've
adopted) not practicable for anything other than trivial code snippets,
the one remaining VC can be proved by the rule:
boolean(1): not A or not B
may_be_deduced_from
[ A <-> X > 0,
B <-> X < 0 ] .
which has the merit of being universally true and avoiding any "code
smell".
Furthermore this rule can then be validated by proving the corresponding
VC:
H1: a <-> x > 0 .
H2: b <-> x < 0 .
->
C1: not a or not b .
(There are hints that this approach to validating rules will be
described in the next version of the SPARK book).
Cheers,
Phil
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Need help understanding SPARK substitution rules
2012-06-20 18:30 Need help understanding SPARK substitution rules Ben Hocking
2012-06-21 8:47 ` Phil Thornley
@ 2012-06-21 12:56 ` Ben Hocking
1 sibling, 0 replies; 3+ messages in thread
From: Ben Hocking @ 2012-06-21 12:56 UTC (permalink / raw)
That solved the problem without the distaste.
Thanks, Phil.
-Ben
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-06-21 12:56 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-20 18:30 Need help understanding SPARK substitution rules Ben Hocking
2012-06-21 8:47 ` Phil Thornley
2012-06-21 12:56 ` Ben Hocking
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox