comp.lang.ada
 help / color / mirror / Atom feed
From: "Yannick Duchêne (Hibou57)" <yannick_duchene@yahoo.fr>
Subject: Re: SPARK
Date: Sun, 16 May 2010 00:48:33 +0200
Date: 2010-05-16T00:48:33+02:00	[thread overview]
Message-ID: <op.vcrqy7isule2fv@garhos> (raw)
In-Reply-To: op.vcl6900wule2fv@garhos

Ok, from some branch of this thread, you may have learned a question have  
raised about which one of “assert” or “check” should be used to write  
in-text proofs where the Simplifier could not prove it it/his/her self.

The answer to this is so much important that I give the answer to it from  
the root of this thread, instead of from the latter leaf.

So it is : Use Check, not Assert.

Here is a concrete example of what you can do with Check and which does  
not work with Assert. The example is detailed, I mean, exposes detailed  
proofs, over what may have been sufficient. This is because I like  
explicit and expressive things, and this was also to be sure nobody could  
miss a single step of the proof and nobody could have any doubt about the  
usefulness of such a approach in software conception. That's also the  
reason why the exercise upon which this is based, was a bit modified (like  
using two intermediate variables instead of subexpressions.. I do that  
oftenly on my side).

Here is :


    procedure Limit
      (X     : in out Integer;
       Lower : in     Integer;
       Upper : in     Integer)
    --# pre    Lower < Upper;
    --# post  ((X~ < Lower) -> (X = Lower)) and
    --#       ((X~ > Upper) -> (X = Upper)) and
    --#       (X in Lower .. Upper);
    is
    begin
       if X < Lower then
          X := Lower;
       elsif X > Upper then
          X := Upper;
       end if;
    end Limit;

    function Percent_Of_Range
      (Data    : Integer;
       Lowest  : Integer;
       Highest : Integer) return Percent_Type
    --# pre    (Lowest < Highest) and
    --#        ((Highest - Lowest) <= Integer'Last) and
    --#        (((Highest - Lowest) * 100) <= Integer'Last);
    is
       Local_Data : Integer;
       Part       : Integer;
       Whole      : Integer;
    begin
       Local_Data := Data;
       -- Local copy of Data to be allowed to modify it. We only need
       -- a modified version locally, the caller does not need this.

       Limit
         (X     => Local_Data, -- in out.
          Lower => Lowest,     -- in
          Upper => Highest);   -- in.

       Part  := Local_Data - Lowest;
       Whole := Highest - Lowest;

       -- We are to prove that ((Part * 100) / Whole) is in 0 .. 100.

       -- (1) Prove that Part >= 0.
       --# check Local_Data in Lowest .. Highest;
       --# check Local_Data >= Lowest;
       --# check (Local_Data - Lowest) >= 0;
       --# check Part >= 0;

       -- Given (1), it's obvious that (Part * 100) >= 0.

       -- (2) Prove that Whole is > 0.
       --# check Lowest < Highest;
       --# check Highest > Lowest;
       --# check (Highest - Lowest) > 0;
       --# check Whole > 0;

       -- Given (2), it's obvious that ((Part * 100) / Whole) is valid.
       -- Given (1) and (2), it's obvious that ((Part * 100) / Whole) >= 0.

       -- (3) Prove that (Whole >= Part). This is required for (4) which is
       --    to come.
       --# check Local_Data in Lowest .. Highest;
       --# check Highest >= Local_Data;
       --# check (Highest - Lowest) >= (Local_Data - Lowest);
       --# check Whole >= Part;

       -- (4) Prove that ((Part * 100) / Whole) is less or equal to 100.
       --# check Part <= Whole;
       --# check (Part * 100) <= (Whole * 100);
       --# check ((Part * 100) / Whole) <= ((Whole * 100) / Whole);
       --# check ((Part * 100) / Whole) <= 100;

       -- (5) Prove that the subexpression (Part * 100) will not
       --     commit an overflow.
       --# check (((Highest - Lowest) * 100) <= Integer'Last);
       --# check (Whole * 100) <= Integer'Last;
       --# check Part <= Whole;
       --# check (Part * 100) <= Integer'Last;

       -- Given (1), we know ((Part * 100) / Whole) >= 0.
       -- Given (4), we know ((Part * 100) / Whole) <= 100.
       -- Given (5), we we know (Part * 100) will not commit an overflow.
       -- Given (1) and (2) and(5), the following statement is then proved  
to
       -- be valid and meaningful.

       return Percent_Type ((Part * 100) / Whole);

    end Percent_Of_Range;

A working example of a step by step proof of every things required to be  
proven.

Waaw... I like it so much, I love it. This is the way I was thinking  
software should be built for so long ! I was waiting for such a thing for  
about 14 years you know !

I use to learn about VDM when I was younger, hire books about it in  
libraries, use to think about creating my own implementation of VDM, but  
failed to find the language specification (and was frightened about the  
idea to setup my own language in this area).

And now, I see SPARK can do nearly the same.

Well, although wonderful, that's still not perfect : why is there a  
Checker (which I didn't used here) and why no provision to write in-text  
what is done with the Checker ? That's what I was attempting to do here.  
It works, but I miss something like explicit “from (1) and (2) infer ....  
” etc. I cannot give names or numbers to Check clauses and cannot  
explicitly refer to these. I cannot nor explicitly refer to precondition  
in inferences (like in (5), where the reference to a precondition is  
implicit, not explicit).

Is there some provision for such a thing ?

Yes, I may wish too much... that's not perfect, while still wonderful. Do  
you feel too ? :)


-- 
There is even better than a pragma Assert: an --# assert (or a --#  
check... question pending)



  parent reply	other threads:[~2010-05-15 22:48 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-12 22:55 SPARK Yannick Duchêne (Hibou57)
2010-05-13  0:52 ` SPARK Yannick Duchêne (Hibou57)
2010-05-13  3:06 ` SPARK Yannick Duchêne (Hibou57)
2010-05-13  9:28   ` SPARK stefan-lucks
2010-05-13 16:48     ` SPARK Yannick Duchêne (Hibou57)
2010-05-15 13:09       ` SPARK Peter C. Chapin
2010-05-14 22:55   ` SPARK Yannick Duchêne (Hibou57)
2010-05-13  4:00 ` SPARK Yannick Duchêne (Hibou57)
2010-05-13 16:54 ` SPARK Yannick Duchêne (Hibou57)
2010-05-13 17:15   ` SPARK Rod Chapman
2010-05-13 19:43     ` SPARK Yannick Duchêne (Hibou57)
2010-05-13 20:05       ` SPARK Rod Chapman
2010-05-13 21:43         ` SPARK Yannick Duchêne (Hibou57)
2010-05-14 14:47         ` SPARK Yannick Duchêne (Hibou57)
2010-05-14  1:20 ` SPARK Yannick Duchêne (Hibou57)
2010-05-14  4:15   ` SPARK Yannick Duchêne (Hibou57)
2010-05-14  8:17     ` SPARK Phil Thornley
2010-05-14  9:32       ` SPARK Rod Chapman
2010-05-14 14:20       ` SPARK Yannick Duchêne (Hibou57)
2010-05-14  3:07 ` SPARK Yannick Duchêne (Hibou57)
2010-05-14  3:26   ` SPARK Yannick Duchêne (Hibou57)
2010-05-14  8:11   ` SPARK Phil Thornley
2010-05-14 14:28     ` SPARK Yannick Duchêne (Hibou57)
2010-05-14 21:45 ` SPARK Yannick Duchêne (Hibou57)
2010-05-15 16:41 ` SPARK Yannick Duchêne (Hibou57)
2010-05-15 18:00   ` SPARK Yannick Duchêne (Hibou57)
2010-05-15 18:14   ` SPARK Yannick Duchêne (Hibou57)
2010-05-15 19:08     ` SPARK Yannick Duchêne (Hibou57)
2010-05-15 20:23       ` SPARK Yannick Duchêne (Hibou57)
2010-05-16 18:13         ` SPARK Peter C. Chapin
2010-05-17  0:59           ` SPARK Yannick Duchêne (Hibou57)
2010-05-16 18:17         ` SPARK Phil Thornley
2010-05-17  1:24           ` SPARK Yannick Duchêne (Hibou57)
2010-05-15 18:43   ` SPARK Phil Clayton
2010-05-15 19:12     ` SPARK Yannick Duchêne (Hibou57)
2010-05-15 21:02       ` SPARK Phil Clayton
2010-05-15 22:48 ` Yannick Duchêne (Hibou57) [this message]
2010-05-16  1:48   ` SPARK Yannick Duchêne (Hibou57)
2010-05-16  1:53     ` SPARK Yannick Duchêne (Hibou57)
2010-05-16  5:28 ` SPARK Yannick Duchêne (Hibou57)
2010-05-18 18:01   ` SPARK Yannick Duchêne (Hibou57)
2010-05-19  8:09     ` SPARK Phil Thornley
2010-05-19 20:38       ` SPARK Simon Wright
2010-05-19 21:27         ` SPARK Yannick Duchêne (Hibou57)
2010-05-20  6:21           ` SPARK Simon Wright
2010-05-20  6:58             ` SPARK Yannick Duchêne (Hibou57)
2010-05-20 21:51               ` SPARK Simon Wright
2010-05-19 21:35       ` SPARK Yannick Duchêne (Hibou57)
  -- strict thread matches above, loose matches on Subject: below --
2009-06-10  9:47 SPARK Robert Matthews
2004-08-18 23:46 timeouts Brian May
2004-08-19  3:40 ` timeouts Steve
2004-08-22  4:18   ` timeouts Brian May
2004-08-22 12:54     ` timeouts Jeff C,
2004-08-26  1:28       ` timeouts Brian May
2004-08-26 13:34         ` timeouts Steve
2004-08-26 14:02           ` timeouts Georg Bauhaus
2004-08-26 23:03             ` SPARK Brian May
2004-08-27 10:11               ` SPARK Georg Bauhaus
2001-08-08  9:46 SPARK Soeren.Henssel-Rasmussen
2001-08-08 20:04 ` SPARK McDoobie
2001-08-06 16:49 SPARK programmer
2001-08-07  7:04 ` SPARK Hambut
2001-08-07  7:18 ` SPARK Hambut
2001-08-07  8:37 ` SPARK Peter Amey
2001-08-07 14:42   ` SPARK McDoobie
2001-08-09 12:36   ` SPARK Peter Amey
2001-08-14  3:14   ` SPARK Prof Karl Kleine
2001-08-14 10:25     ` SPARK Rod Chapman
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox