From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,af40877501f46910 X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,UTF8 Path: g2news1.google.com!news4.google.com!feeder.news-service.com!tudelft.nl!txtfeed1.tudelft.nl!zen.net.uk!dedekind.zen.co.uk!aioe.org!not-for-mail From: =?utf-8?Q?Yannick_Duch=C3=AAne_=28Hibou57?= =?utf-8?Q?=29?= Newsgroups: comp.lang.ada Subject: Re: SPARK understand me very well... me neither Date: Sat, 14 Aug 2010 06:57:11 +0200 Organization: Ada At Home Message-ID: References: NNTP-Posting-Host: M2yP1Cx/h9YxW/Ct5b534Q.user.speranza.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes Content-Transfer-Encoding: Quoted-Printable X-Complaints-To: abuse@aioe.org X-Notice: Filtered by postfilter v. 0.8.2 User-Agent: Opera Mail/10.60 (Win32) Xref: g2news1.google.com comp.lang.ada:13264 Date: 2010-08-14T06:57:11+02:00 List-Id: I have looked at it again, and cannot do better than stopping here: package Functions is function Multiply (A, B : Natural) return Natural; --# pre (A /=3D 0) -> (B <=3D (Integer'Last / A)); --# return A * B; -- Implies commutativity on Multiply arguments end Functions; package body Functions is function Multiply (A, B : Natural) return Natural is Result : Natural; begin --# check (A =3D 0) -> ((A * B) =3D 0); --# check (A =3D 0) -> ((B * A) <=3D Integer'Last); --# check not (A =3D 0) -> (B <=3D (Integer'Last / A)); --# check not (A =3D 0) -> ((B * A) <=3D (Integer'Last / A) * = A); --# check not (A =3D 0) -> ((Integer'Last / A) * A <=3D Intege= r'Last); --# check not (A =3D 0) -> ((B * A) <=3D Integer'Last); -- Here is a gap which I cannot cross --# assert (A * B) <=3D Integer'Last; Result :=3D A * B; return Result; end Multiply; end Functions; Where I have marked =E2=80=9CHere is a gap which I cannot cross=E2=80=9D= . A is either 0 or = not 0, as (A =3D 0) -> ((B * A) <=3D Integer'Last) and not (A =3D 0) -> ((B * A) <=3D Integer'Last) is proved, then (A * B) <=3D= = Integer'Last should be proved as well, as this finally turns into Any Ca= se = -> (A * B) <=3D Integer'Last. But no way to do, this only works with an = = if-then statement, and cannot do without it (and I do not want user rule= s = here). I had a look at =E2=80=9CSPARK/lib/checker/rules/LOGIC.RUL=E2=80=9D= to see what = SPARK knowns from inborn, but just found these sole rules about =E2=80=9C= ->=E2=80=9D : /*** Other handy logical equivalences (DeMorgan, etc.) ***/ logical(1): not (A or B) & (not A) and (not B) = are_interchangeable. logical(2): not (A and B) & (not A) or (not B) = are_interchangeable. logical(3): A -> B & (not A) or B = are_interchangeable. logical(4): A <-> B & (A -> B) and (B -> A) = are_interchangeable. logical(5): A -> (B -> C) may_be_replaced_by (A and B= ) = -> C. And I would not want to turn X -> Y into (not X) or Y, as this would not= = create a nice example. Note: you can see a concrete example of what I meant talking about P1 ->= = Pn when removing conditional statements. The four --#check prefixed with= = =E2=80=9Cnot (A =3D 0) -> ... =E2=80=9D match what was beneath the bran= ch in the = conditional statement where A /=3D 0. Do you see ? Well, probably statements with logical branches, like if-then, or case, = = cannot be handle as easily using pure logical expressions. It had far le= ss = difficulties to fill the gap I point above when there was the if-then = statement ; while without it, although with equivalent logical = expressions, it cannot.