From 9e62ead8d8018f0419adfdd41ee9d25ec257ceeb Mon Sep 17 00:00:00 2001 From: Jean-Christophe <Jean-Christophe.Filliatre@lri.fr> Date: Wed, 14 Dec 2011 20:32:28 +0100 Subject: [PATCH] machine arithmetic: a first experiment --- examples/programs/binary_search.mlw | 42 ++++++++++++ .../programs/binary_search/why3session.xml | 66 ++++++++----------- modules/arith.mlw | 24 +++++++ 3 files changed, 95 insertions(+), 37 deletions(-) diff --git a/examples/programs/binary_search.mlw b/examples/programs/binary_search.mlw index 5bf37b3d15..16cf7e51e9 100644 --- a/examples/programs/binary_search.mlw +++ b/examples/programs/binary_search.mlw @@ -83,6 +83,48 @@ module BinarySearchAnyMidPoint end +(* binary search using 32-bit integers *) + +module BinarySearchInt32 + + use import module arith.Int32 + use import module ref.Ref + use import module array.Array + + (* the code and its specification *) + + exception Break int (* raised to exit the loop *) + exception Not_found (* raised to signal a search failure *) + + let binary_search (a :array int) (v : int) = + { 0 <= length a <= max_int /\ + forall i1 i2 : int. 0 <= i1 <= i2 < length a -> a[i1] <= a[i2] } + try + let l = ref 0 in + let u = ref (length a - 1) in + while !l <= !u do + invariant { + 0 <= !l /\ !u < length a /\ + forall i : int. 0 <= i < length a -> a[i] = v -> !l <= i <= !u } + variant { !u - !l } + let m = !l + div (!u - !l) 2 in + assert { !l <= m <= !u }; + if a[m] < v then + l := m + 1 + else if a[m] > v then + u := m - 1 + else + raise (Break m) + done; + raise Not_found + with Break i -> + i + end + { 0 <= result < length a /\ a[result] = v } + | Not_found -> { forall i:int. 0 <= i < length a -> a[i] <> v } + +end + (* Local Variables: compile-command: "unset LANG; make -C ../.. examples/programs/binary_search.gui" diff --git a/examples/programs/binary_search/why3session.xml b/examples/programs/binary_search/why3session.xml index 9c8456d58f..30919498ea 100644 --- a/examples/programs/binary_search/why3session.xml +++ b/examples/programs/binary_search/why3session.xml @@ -1,63 +1,35 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE why3session SYSTEM "why3session.dtd"> <why3session - name="programs/binary_search/why3session.xml"> + name="examples/programs/binary_search/why3session.xml"> <prover id="alt-ergo" name="Alt-Ergo" - version="0.94"/> - <prover - id="alt-ergo-0.93.1" - name="Alt-Ergo" version="0.93.1"/> <prover id="coq" name="Coq" - version="8.3pl2"/> + version="8.2pl1"/> <prover id="cvc3-2.2" name="CVC3" version="2.2"/> - <prover - id="cvc3-2.4" - name="CVC3" - version="2.4.1"/> - <prover - id="eprover" - name="Eprover" - version="1.4 Namring"/> <prover id="gappa" name="Gappa" - version="0.15.1"/> + version="0.15.0"/> <prover id="simplify" name="Simplify" version="1.5.4"/> - <prover - id="spass" - name="Spass" - version="3.7"/> - <prover - id="vampire" - name="Vampire" - version="0.6"/> - <prover - id="verit" - name="veriT" - version="dev"/> <prover id="yices" name="Yices" - version="1.0.25"/> + version="1.0"/> <prover id="z3-2" name="Z3" version="2.19"/> - <prover - id="z3-3" - name="Z3" - version="3.2"/> <file name="../binary_search.mlw" verified="true" @@ -69,7 +41,7 @@ <goal name="WP_parameter binary_search" expl="parameter binary_search" - sum="05b308271de57dac7bc9311c80a79391" + sum="2d4368f5fd910b1ceb69adef571ead55" proved="true" expanded="true" shape="iainfix <=V4V3iainfix <agetV2ainfix +V4adivainfix -V3V4c2V1ainfix <ainfix -V3V5ainfix -V3V4Aainfix <=c0ainfix -V3V4Aainfix <=V6V3Aainfix <=V5V6Iainfix =agetV2V6V1Iainfix <V6V0Aainfix <=c0V6FAainfix <V3V0Aainfix <=c0V5Iainfix =V5ainfix +ainfix +V4adivainfix -V3V4c2c1Fiainfix >agetV2ainfix +V4adivainfix -V3V4c2V1ainfix <ainfix -V7V4ainfix -V3V4Aainfix <=c0ainfix -V3V4Aainfix <=V8V7Aainfix <=V4V8Iainfix =agetV2V8V1Iainfix <V8V0Aainfix <=c0V8FAainfix <V7V0Aainfix <=c0V4Iainfix =V7ainfix -ainfix +V4adivainfix -V3V4c2c1Fainfix =agetV2ainfix +V4adivainfix -V3V4c2V1Aainfix <ainfix +V4adivainfix -V3V4c2V0Aainfix <=c0ainfix +V4adivainfix -V3V4c2Aainfix <ainfix +V4adivainfix -V3V4c2V0Aainfix <=c0ainfix +V4adivainfix -V3V4c2Aainfix <ainfix +V4adivainfix -V3V4c2V0Aainfix <=c0ainfix +V4adivainfix -V3V4c2Aainfix <=ainfix +V4adivainfix -V3V4c2V3Aainfix <=V4ainfix +V4adivainfix -V3V4c2ainfix =agetV2V9V1NIainfix <V9V0Aainfix <=c0V9FIainfix <=V10V3Aainfix <=V4V10Iainfix =agetV2V10V1Iainfix <V10V0Aainfix <=c0V10FAainfix <V3V0Aainfix <=c0V4FFAainfix <=V11ainfix -V0c1Aainfix <=c0V11Iainfix =agetV2V11V1Iainfix <V11V0Aainfix <=c0V11FAainfix <ainfix -V0c1V0Aainfix <=c0c0Iainfix <=agetV2V12agetV2V13Iainfix <V13V0Aainfix <=V12V13Aainfix <=c0V12FFFF"> @@ -78,14 +50,14 @@ timelimit="10" edited="" obsolete="false"> - <result status="valid" time="0.02"/> + <result status="valid" time="0.08"/> </proof> <proof prover="alt-ergo" timelimit="10" edited="" obsolete="false"> - <result status="valid" time="0.02"/> + <result status="valid" time="0.06"/> </proof> </goal> </theory> @@ -96,7 +68,7 @@ <goal name="WP_parameter binary_search" expl="parameter binary_search" - sum="332e80ad2cab058df73928f0e1009412" + sum="d5cd94966f7526a19692c7d56b842e9f" proved="true" expanded="true" shape="iainfix <=V4V3iainfix <agetV2V5V1ainfix <ainfix -V3V6ainfix -V3V4Aainfix <=c0ainfix -V3V4Aainfix <=V7V3Aainfix <=V6V7Iainfix =agetV2V7V1Iainfix <V7V0Aainfix <=c0V7FAainfix <V3V0Aainfix <=c0V6Iainfix =V6ainfix +V5c1Fiainfix >agetV2V5V1ainfix <ainfix -V8V4ainfix -V3V4Aainfix <=c0ainfix -V3V4Aainfix <=V9V8Aainfix <=V4V9Iainfix =agetV2V9V1Iainfix <V9V0Aainfix <=c0V9FAainfix <V8V0Aainfix <=c0V4Iainfix =V8ainfix -V5c1Fainfix =agetV2V5V1Aainfix <V5V0Aainfix <=c0V5Aainfix <V5V0Aainfix <=c0V5Aainfix <V5V0Aainfix <=c0V5Iainfix <=V5V3Aainfix <=V4V5FAainfix <=V4V3ainfix =agetV2V10V1NIainfix <V10V0Aainfix <=c0V10FIainfix <=V11V3Aainfix <=V4V11Iainfix =agetV2V11V1Iainfix <V11V0Aainfix <=c0V11FAainfix <V3V0Aainfix <=c0V4FFAainfix <=V12ainfix -V0c1Aainfix <=c0V12Iainfix =agetV2V12V1Iainfix <V12V0Aainfix <=c0V12FAainfix <ainfix -V0c1V0Aainfix <=c0c0Iainfix <=agetV2V13agetV2V14Iainfix <V14V0Aainfix <=V13V14Aainfix <=c0V13FFFF"> @@ -105,7 +77,27 @@ timelimit="10" edited="" obsolete="false"> - <result status="valid" time="0.01"/> + <result status="valid" time="0.06"/> + </proof> + </goal> + </theory> + <theory + name="WP BinarySearchInt32" + verified="true" + expanded="true"> + <goal + name="WP_parameter binary_search" + expl="parameter binary_search" + sum="3f43f4cc865166a924a323c51975d7de" + proved="true" + expanded="true" + shape="iainfix <=V4V3Lainfix -V3V4Lainfix +V4adivV5c2iainfix <agetV2V6V1ainfix <ainfix -V3V7ainfix -V3V4Aainfix <=c0ainfix -V3V4Aainfix <=V8V3Aainfix <=V7V8Iainfix =agetV2V8V1Iainfix <V8V0Aainfix <=c0V8FAainfix <V3V0Aainfix <=c0V7Iainfix =V7ainfix +V6c1FAainfix <=ainfix +V6c1amax_intAainfix <=amin_intainfix +V6c1iainfix >agetV2V6V1ainfix <ainfix -V9V4ainfix -V3V4Aainfix <=c0ainfix -V3V4Aainfix <=V10V9Aainfix <=V4V10Iainfix =agetV2V10V1Iainfix <V10V0Aainfix <=c0V10FAainfix <V9V0Aainfix <=c0V4Iainfix =V9ainfix -V6c1FAainfix <=ainfix -V6c1amax_intAainfix <=amin_intainfix -V6c1ainfix =agetV2V6V1Aainfix <V6V0Aainfix <=c0V6Aainfix <V6V0Aainfix <=c0V6Aainfix <V6V0Aainfix <=c0V6Aainfix <=V6V3Aainfix <=V4V6Aainfix <=ainfix +V4adivV5c2amax_intAainfix <=amin_intainfix +V4adivV5c2Aainfix <=ainfix -V3V4amax_intAainfix <=amin_intainfix -V3V4ainfix =agetV2V11V1NIainfix <V11V0Aainfix <=c0V11FIainfix <=V12V3Aainfix <=V4V12Iainfix =agetV2V12V1Iainfix <V12V0Aainfix <=c0V12FAainfix <V3V0Aainfix <=c0V4FFAainfix <=V13ainfix -V0c1Aainfix <=c0V13Iainfix =agetV2V13V1Iainfix <V13V0Aainfix <=c0V13FAainfix <ainfix -V0c1V0Aainfix <=c0c0Aainfix <=ainfix -V0c1amax_intAainfix <=amin_intainfix -V0c1Iainfix <=agetV2V14agetV2V15Iainfix <V15V0Aainfix <=V14V15Aainfix <=c0V14FAainfix <=V0amax_intAainfix <=c0V0FFF"> + <proof + prover="alt-ergo" + timelimit="5" + edited="" + obsolete="false"> + <result status="valid" time="0.59"/> </proof> </goal> </theory> diff --git a/modules/arith.mlw b/modules/arith.mlw index 801f1f25b1..0f2a061746 100644 --- a/modules/arith.mlw +++ b/modules/arith.mlw @@ -11,6 +11,30 @@ module Int end (* machine arithmetic (32-bit integers, etc.) will go here *) +module Int32 + + use export int.Int + + function min_int : int = -2147483648 + function max_int : int = 2147483647 + + let (+) (x: int) (y:int) = + { min_int <= x + y <= max_int } x + y { result = x + y } + let (-) (x: int) (y:int) = + { min_int <= x - y <= max_int } x - y { result = x - y } + + let (-_) (x: int) = + { min_int <= -x <= max_int } -x { result = -x } + + let ( * ) (x: int) (y:int) = + { min_int <= x * y <= max_int } x * y { result = x * y } + + use export int.ComputerDivision + + let (/) (x: int) (y:int) = + { y <> 0 && min_int <= div x y <= max_int } div x y { result = div x y } + +end module Real -- GitLab