number theory moved to library number.why

parent 93cf1d36
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
module EuclideanAlgorithm module EuclideanAlgorithm
use import int.Int use import int.Int
use import int.Gcd use import number.Gcd
use import int.ComputerDivision use import int.ComputerDivision
let rec gcd u v variant { v } = let rec gcd u v variant { v } =
...@@ -13,12 +13,12 @@ module EuclideanAlgorithm ...@@ -13,12 +13,12 @@ module EuclideanAlgorithm
u u
else else
gcd v (mod u v) gcd v (mod u v)
{ gcd u v result } { result = gcd u v }
end end
(* (*
Local Variables: Local Variables:
compile-command: "unset LANG; make -C ../.. examples/programs/gcd" compile-command: "unset LANG; make -C ../.. examples/programs/gcd.gui"
End: End:
*) *)
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
(* Beware! Only edit allowed sections below *) (* Beware! Only edit allowed sections below *)
Require Import ZArith. Require Import ZArith.
Require Import Rbase. Require Import Rbase.
Require Import ZOdiv.
Require Import Zdiv. Require Import Zdiv.
Require Import ZOdiv.
Definition unit := unit. Definition unit := unit.
Parameter mark : Type. Parameter mark : Type.
...@@ -16,31 +16,108 @@ Parameter old: forall (a:Type), a -> a. ...@@ -16,31 +16,108 @@ Parameter old: forall (a:Type), a -> a.
Implicit Arguments old. Implicit Arguments old.
Definition divides(a:Z) (b:Z): Prop := exists q:Z, (b = (q * a)%Z). Definition divides(d:Z) (n:Z): Prop := exists q:Z, (n = (q * d)%Z).
Axiom divides_refl : forall (n:Z), (divides n n).
Axiom divides_1 : forall (n:Z), (divides 1%Z n).
Axiom divides_0 : forall (n:Z), (divides n 0%Z).
Axiom divides_left : forall (a:Z) (b:Z) (c:Z), (divides a b) ->
(divides (c * a)%Z (c * b)%Z).
Axiom divides_right : forall (a:Z) (b:Z) (c:Z), (divides a b) ->
(divides (a * c)%Z (b * c)%Z).
Axiom divides_oppr : forall (a:Z) (b:Z), (divides a b) -> (divides a (-b)%Z).
Axiom divides_oppl : forall (a:Z) (b:Z), (divides a b) -> (divides (-a)%Z b).
Axiom divides_oppr_rev : forall (a:Z) (b:Z), (divides (-a)%Z b) -> (divides a
b).
Axiom divides_oppl_rev : forall (a:Z) (b:Z), (divides a (-b)%Z) -> (divides a
b).
Axiom divides_plusr : forall (a:Z) (b:Z) (c:Z), (divides a b) -> ((divides a
c) -> (divides a (b + c)%Z)).
Axiom divides_minusr : forall (a:Z) (b:Z) (c:Z), (divides a b) -> ((divides a
c) -> (divides a (b - c)%Z)).
Axiom divides_multl : forall (a:Z) (b:Z) (c:Z), (divides a b) -> (divides a
(c * b)%Z).
Axiom Divides_x_zero : forall (x:Z), (divides x 0%Z). Axiom divides_multr : forall (a:Z) (b:Z) (c:Z), (divides a b) -> (divides a
(b * c)%Z).
Axiom Divides_one_x : forall (x:Z), (divides 1%Z x). Axiom divides_factorl : forall (a:Z) (b:Z), (divides a (b * a)%Z).
Definition gcd(a:Z) (b:Z) (g:Z): Prop := (divides g a) /\ ((divides g b) /\ Axiom divides_factorr : forall (a:Z) (b:Z), (divides a (a * b)%Z).
forall (x:Z), (divides x a) -> ((divides x b) -> (divides x g))).
Axiom Gcd_sym : forall (a:Z) (b:Z) (g:Z), (gcd a b g) -> (gcd b a g). Axiom divides1 : forall (x:Z), (divides x 1%Z) -> ((x = 1%Z) \/
(x = (-1%Z)%Z)).
Axiom Gcd_0 : forall (a:Z), (gcd a 0%Z a). Axiom divides_antisym : forall (a:Z) (b:Z), (divides a b) -> ((divides b
a) -> ((a = b) \/ (a = (-b)%Z))).
Axiom Gcd_euclid : forall (a:Z) (b:Z) (q:Z) (g:Z), (gcd a (b - (q * a)%Z)%Z Axiom divides_trans : forall (a:Z) (b:Z) (c:Z), (divides a b) -> ((divides b
g) -> (gcd a b g). c) -> (divides a c)).
Axiom Abs_pos : forall (x:Z), (0%Z <= (Zabs x))%Z. Axiom Abs_pos : forall (x:Z), (0%Z <= (Zabs x))%Z.
Axiom divides_bounds : forall (a:Z) (b:Z), (divides a b) -> ((~ (b = 0%Z)) ->
((Zabs a) <= (Zabs b))%Z).
Axiom Div_mod : forall (x:Z) (y:Z), (~ (y = 0%Z)) -> Axiom Div_mod : forall (x:Z) (y:Z), (~ (y = 0%Z)) ->
(x = ((y * (ZOdiv x y))%Z + (ZOmod x y))%Z). (x = ((y * (Zdiv x y))%Z + (Zmod x y))%Z).
Axiom Div_bound : forall (x:Z) (y:Z), ((0%Z <= x)%Z /\ (0%Z < y)%Z) -> Axiom Div_bound : forall (x:Z) (y:Z), ((0%Z <= x)%Z /\ (0%Z < y)%Z) ->
((0%Z <= (ZOdiv x y))%Z /\ ((ZOdiv x y) <= x)%Z). ((0%Z <= (Zdiv x y))%Z /\ ((Zdiv x y) <= x)%Z).
Axiom Mod_bound : forall (x:Z) (y:Z), (~ (y = 0%Z)) -> Axiom Mod_bound : forall (x:Z) (y:Z), (~ (y = 0%Z)) ->
((0%Z <= (Zmod x y))%Z /\ ((Zmod x y) < (Zabs y))%Z).
Axiom Mod_1 : forall (x:Z), ((Zmod x 1%Z) = 0%Z).
Axiom Div_1 : forall (x:Z), ((Zdiv x 1%Z) = x).
Axiom mod_divides : forall (a:Z) (b:Z), (~ (b = 0%Z)) ->
(((Zmod a b) = 0%Z) -> (divides b a)).
Axiom divides_mod : forall (a:Z) (b:Z), (~ (b = 0%Z)) -> ((divides b a) ->
((Zmod a b) = 0%Z)).
Parameter gcd: Z -> Z -> Z.
Axiom gcd_nonneg : forall (a:Z) (b:Z), (0%Z <= (gcd a b))%Z.
Axiom gcd_def1 : forall (a:Z) (b:Z), (divides (gcd a b) a).
Axiom gcd_def2 : forall (a:Z) (b:Z), (divides (gcd a b) b).
Axiom gcd_def3 : forall (a:Z) (b:Z) (x:Z), (divides x a) -> ((divides x b) ->
(divides x (gcd a b))).
Axiom Assoc : forall (x:Z) (y:Z) (z:Z), ((gcd (gcd x y) z) = (gcd x (gcd y
z))).
Axiom Comm : forall (x:Z) (y:Z), ((gcd x y) = (gcd y x)).
Axiom gcd_0 : forall (a:Z), ((gcd a 0%Z) = a).
Axiom gcd_euclid : forall (a:Z) (b:Z) (q:Z), ((gcd a b) = (gcd a
(b - (q * a)%Z)%Z)).
Axiom Div_mod1 : forall (x:Z) (y:Z), (~ (y = 0%Z)) ->
(x = ((y * (ZOdiv x y))%Z + (ZOmod x y))%Z).
Axiom Div_bound1 : forall (x:Z) (y:Z), ((0%Z <= x)%Z /\ (0%Z < y)%Z) ->
((0%Z <= (ZOdiv x y))%Z /\ ((ZOdiv x y) <= x)%Z).
Axiom Mod_bound1 : forall (x:Z) (y:Z), (~ (y = 0%Z)) ->
(((-(Zabs y))%Z < (ZOmod x y))%Z /\ ((ZOmod x y) < (Zabs y))%Z). (((-(Zabs y))%Z < (ZOmod x y))%Z /\ ((ZOmod x y) < (Zabs y))%Z).
Axiom Div_sign_pos : forall (x:Z) (y:Z), ((0%Z <= x)%Z /\ (0%Z < y)%Z) -> Axiom Div_sign_pos : forall (x:Z) (y:Z), ((0%Z <= x)%Z /\ (0%Z < y)%Z) ->
...@@ -58,9 +135,9 @@ Axiom Mod_sign_neg : forall (x:Z) (y:Z), ((x <= 0%Z)%Z /\ ~ (y = 0%Z)) -> ...@@ -58,9 +135,9 @@ Axiom Mod_sign_neg : forall (x:Z) (y:Z), ((x <= 0%Z)%Z /\ ~ (y = 0%Z)) ->
Axiom Rounds_toward_zero : forall (x:Z) (y:Z), (~ (y = 0%Z)) -> Axiom Rounds_toward_zero : forall (x:Z) (y:Z), (~ (y = 0%Z)) ->
((Zabs ((ZOdiv x y) * y)%Z) <= (Zabs x))%Z. ((Zabs ((ZOdiv x y) * y)%Z) <= (Zabs x))%Z.
Axiom Div_1 : forall (x:Z), ((ZOdiv x 1%Z) = x). Axiom Div_11 : forall (x:Z), ((ZOdiv x 1%Z) = x).
Axiom Mod_1 : forall (x:Z), ((ZOmod x 1%Z) = 0%Z). Axiom Mod_11 : forall (x:Z), ((ZOmod x 1%Z) = 0%Z).
Axiom Div_inf : forall (x:Z) (y:Z), ((0%Z <= x)%Z /\ (x < y)%Z) -> Axiom Div_inf : forall (x:Z) (y:Z), ((0%Z <= x)%Z /\ (x < y)%Z) ->
((ZOdiv x y) = 0%Z). ((ZOdiv x y) = 0%Z).
...@@ -74,38 +151,26 @@ Axiom Div_mult : forall (x:Z) (y:Z) (z:Z), ((0%Z < x)%Z /\ ((0%Z <= y)%Z /\ ...@@ -74,38 +151,26 @@ Axiom Div_mult : forall (x:Z) (y:Z) (z:Z), ((0%Z < x)%Z /\ ((0%Z <= y)%Z /\
Axiom Mod_mult : forall (x:Z) (y:Z) (z:Z), ((0%Z < x)%Z /\ ((0%Z <= y)%Z /\ Axiom Mod_mult : forall (x:Z) (y:Z) (z:Z), ((0%Z < x)%Z /\ ((0%Z <= y)%Z /\
(0%Z <= z)%Z)) -> ((ZOmod ((x * y)%Z + z)%Z x) = (ZOmod z x)). (0%Z <= z)%Z)) -> ((ZOmod ((x * y)%Z + z)%Z x) = (ZOmod z x)).
Axiom Gcd_computer_mod : forall (a:Z) (b:Z) (g:Z), (~ (b = 0%Z)) -> ((gcd a Axiom Gcd_computer_mod : forall (a:Z) (b:Z), (~ (b = 0%Z)) -> ((gcd a
(ZOmod a b) g) -> (gcd a b g)). (ZOmod a b)) = (gcd a b)).
Axiom Div_mod1 : forall (x:Z) (y:Z), (~ (y = 0%Z)) ->
(x = ((y * (Zdiv x y))%Z + (Zmod x y))%Z).
Axiom Div_bound1 : forall (x:Z) (y:Z), ((0%Z <= x)%Z /\ (0%Z < y)%Z) ->
((0%Z <= (Zdiv x y))%Z /\ ((Zdiv x y) <= x)%Z).
Axiom Mod_bound1 : forall (x:Z) (y:Z), (~ (y = 0%Z)) ->
((0%Z <= (Zmod x y))%Z /\ ((Zmod x y) < (Zabs y))%Z).
Axiom Mod_11 : forall (x:Z), ((Zmod x 1%Z) = 0%Z).
Axiom Div_11 : forall (x:Z), ((Zdiv x 1%Z) = x).
Axiom Gcd_euclidean_mod : forall (a:Z) (b:Z) (g:Z), (~ (b = 0%Z)) -> ((gcd a Axiom Gcd_euclidean_mod : forall (a:Z) (b:Z), (~ (b = 0%Z)) -> ((gcd a
(Zmod a b) g) -> (gcd a b g)). (Zmod a b)) = (gcd a b)).
Theorem WP_parameter_gcd : forall (u:Z), forall (v:Z), ((0%Z <= u)%Z /\ Theorem WP_parameter_gcd : forall (u:Z), forall (v:Z), ((0%Z <= u)%Z /\
(0%Z <= v)%Z) -> ((~ (v = 0%Z)) -> ((((0%Z <= v)%Z /\ (0%Z <= v)%Z) -> ((~ (v = 0%Z)) -> ((((0%Z <= v)%Z /\
((ZOmod u v) < v)%Z) /\ ((0%Z <= v)%Z /\ (0%Z <= (ZOmod u v))%Z)) -> ((ZOmod u v) < v)%Z) /\ ((0%Z <= v)%Z /\ (0%Z <= (ZOmod u v))%Z)) ->
forall (result:Z), (gcd v (ZOmod u v) result) -> (gcd u v result))). ((gcd v (ZOmod u v)) = (gcd u v)))).
(* YOU MAY EDIT THE PROOF BELOW *) (* YOU MAY EDIT THE PROOF BELOW *)
intuition. intuition.
apply Gcd_sym. symmetry.
apply Gcd_euclid with (q:=(ZOdiv u v)). rewrite Comm.
rewrite gcd_euclid with (q:=(ZOdiv u v)).
assert (u - (ZOdiv u v) * v = ZOmod u v)%Z. assert (u - (ZOdiv u v) * v = ZOmod u v)%Z.
generalize (Div_mod u v); intuition. generalize (Div_mod1 u v); intuition.
replace ((ZOdiv u v) * v) with (v * (ZOdiv u v)) by ring. replace ((ZOdiv u v) * v) with (v * (ZOdiv u v)) by ring.
omega. omega.
rewrite H7; assumption. rewrite H4; auto.
Qed. Qed.
(* DO NOT EDIT BELOW *) (* DO NOT EDIT BELOW *)
......
...@@ -3,39 +3,39 @@ ...@@ -3,39 +3,39 @@
<why3session name="examples/programs/gcd/why3session.xml"> <why3session name="examples/programs/gcd/why3session.xml">
<file name="../gcd.mlw" verified="true" expanded="true"> <file name="../gcd.mlw" verified="true" expanded="true">
<theory name="WP EuclideanAlgorithm" verified="true" expanded="true"> <theory name="WP EuclideanAlgorithm" verified="true" expanded="true">
<goal name="WP_parameter gcd" expl="correctness of parameter gcd" sum="322244ca4eb191447c5e003581d46441" proved="true" expanded="true"> <goal name="WP_parameter gcd" expl="correctness of parameter gcd" sum="a484c5193a5cd03b14a4f295d1e1f03e" proved="true" expanded="true">
<transf name="split_goal" proved="true" expanded="true"> <transf name="split_goal" proved="true" expanded="true">
<goal name="WP_parameter gcd.1" expl="normal postcondition" sum="3893c6278b0c6d2e8a61ff8df2953fcb" proved="true" expanded="true"> <goal name="WP_parameter gcd.1" expl="normal postcondition" sum="5a586460df7b95622e77fbef9bf3b5c9" proved="true" expanded="true">
<proof prover="cvc3" timelimit="2" edited="" obsolete="false"> <proof prover="cvc3" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.00"/> <result status="valid" time="0.02"/>
</proof> </proof>
<proof prover="alt-ergo" timelimit="2" edited="" obsolete="false"> <proof prover="alt-ergo" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.01"/> <result status="valid" time="0.02"/>
</proof> </proof>
<proof prover="simplify" timelimit="2" edited="" obsolete="false"> <proof prover="simplify" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.00"/> <result status="valid" time="0.01"/>
</proof> </proof>
<proof prover="z3" timelimit="2" edited="" obsolete="false"> <proof prover="z3" timelimit="2" edited="" obsolete="false">
<result status="valid" time="1.12"/> <result status="valid" time="0.04"/>
</proof> </proof>
</goal> </goal>
<goal name="WP_parameter gcd.2" expl="precondition" sum="af7096cc1cd7bdcb9f88d52ad341c488" proved="true" expanded="true"> <goal name="WP_parameter gcd.2" expl="precondition" sum="b712e1e03f97fab825d3144c19e74e4b" proved="true" expanded="true">
<proof prover="cvc3" timelimit="2" edited="" obsolete="false"> <proof prover="cvc3" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.01"/> <result status="valid" time="0.03"/>
</proof> </proof>
<proof prover="alt-ergo" timelimit="2" edited="" obsolete="false"> <proof prover="alt-ergo" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.02"/> <result status="valid" time="0.06"/>
</proof> </proof>
<proof prover="simplify" timelimit="2" edited="" obsolete="false"> <proof prover="simplify" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.00"/> <result status="valid" time="0.01"/>
</proof> </proof>
<proof prover="z3" timelimit="2" edited="" obsolete="false"> <proof prover="z3" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.02"/> <result status="valid" time="0.04"/>
</proof> </proof>
</goal> </goal>
<goal name="WP_parameter gcd.3" expl="normal postcondition" sum="9ac7a295784dbed7c5dfdb55575495d7" proved="true" expanded="true"> <goal name="WP_parameter gcd.3" expl="normal postcondition" sum="c6bdc24bc2e3c5380662a3fe96194dd7" proved="true" expanded="true">
<proof prover="coq" timelimit="10" edited="gcd_WP_EuclideanAlgorithm_WP_parameter_gcd_1.v" obsolete="false"> <proof prover="coq" timelimit="10" edited="gcd_WP_EuclideanAlgorithm_WP_parameter_gcd_1.v" obsolete="false">
<result status="valid" time="0.63"/> <result status="valid" time="0.68"/>
</proof> </proof>
</goal> </goal>
</transf> </transf>
......
module M
(* Greatest common divisor, with Bézout coefficients *)
module GcdBezout
use import int.Int use import int.Int
use import int.ComputerDivision use import int.ComputerDivision
use import int.Gcd use import number.Gcd
use import module ref.Ref use import module ref.Ref
let gcd (x:int) (y:int) = let gcd (x:int) (y:int) =
...@@ -13,7 +16,7 @@ module M ...@@ -13,7 +16,7 @@ module M
let c = ref 0 in let d = ref 1 in let c = ref 0 in let d = ref 1 in
while (!y > 0) do while (!y > 0) do
invariant { !x >= 0 /\ !y >= 0 /\ invariant { !x >= 0 /\ !y >= 0 /\
(forall d:int. gcd !x !y d -> gcd (at !x 'Pre) (at !y 'Pre) d) /\ gcd !x !y = gcd (at !x 'Pre) (at !y 'Pre) /\
!a * (at !x 'Pre) + !b * (at !y 'Pre) = !x /\ !a * (at !x 'Pre) + !b * (at !y 'Pre) = !x /\
!c * (at !x 'Pre) + !d * (at !y 'Pre) = !y } !c * (at !x 'Pre) + !d * (at !y 'Pre) = !y }
variant { !y } variant { !y }
...@@ -24,13 +27,13 @@ module M ...@@ -24,13 +27,13 @@ module M
c := ta - !c * q; d := tb - !d * q c := ta - !c * q; d := tb - !d * q
done; done;
!x !x
{ gcd x y result /\ { result = gcd x y /\
exists a b:int. a*x+b*y = result } exists a b:int. a*x+b*y = result }
end end
(* (*
Local Variables: Local Variables:
compile-command: "unset LANG; make -C ../.. examples/programs/gcd_bezout" compile-command: "unset LANG; make -C ../.. examples/programs/gcd_bezout.gui"
End: End:
*) *)
...@@ -58,24 +58,57 @@ Axiom Div_mult : forall (x:Z) (y:Z) (z:Z), ((0%Z < x)%Z /\ ((0%Z <= y)%Z /\ ...@@ -58,24 +58,57 @@ Axiom Div_mult : forall (x:Z) (y:Z) (z:Z), ((0%Z < x)%Z /\ ((0%Z <= y)%Z /\
Axiom Mod_mult : forall (x:Z) (y:Z) (z:Z), ((0%Z < x)%Z /\ ((0%Z <= y)%Z /\ Axiom Mod_mult : forall (x:Z) (y:Z) (z:Z), ((0%Z < x)%Z /\ ((0%Z <= y)%Z /\
(0%Z <= z)%Z)) -> ((ZOmod ((x * y)%Z + z)%Z x) = (ZOmod z x)). (0%Z <= z)%Z)) -> ((ZOmod ((x * y)%Z + z)%Z x) = (ZOmod z x)).
Definition divides(a:Z) (b:Z): Prop := exists q:Z, (b = (q * a)%Z). Definition divides(d:Z) (n:Z): Prop := exists q:Z, (n = (q * d)%Z).
Axiom Divides_x_zero : forall (x:Z), (divides x 0%Z). Axiom divides_refl : forall (n:Z), (divides n n).
Axiom Divides_one_x : forall (x:Z), (divides 1%Z x). Axiom divides_1 : forall (n:Z), (divides 1%Z n).
Definition gcd(a:Z) (b:Z) (g:Z): Prop := (divides g a) /\ ((divides g b) /\ Axiom divides_0 : forall (n:Z), (divides n 0%Z).
forall (x:Z), (divides x a) -> ((divides x b) -> (divides x g))).
Axiom Gcd_sym : forall (a:Z) (b:Z) (g:Z), (gcd a b g) -> (gcd b a g). Axiom divides_left : forall (a:Z) (b:Z) (c:Z), (divides a b) ->
(divides (c * a)%Z (c * b)%Z).
Axiom Gcd_0 : forall (a:Z), (gcd a 0%Z a). Axiom divides_right : forall (a:Z) (b:Z) (c:Z), (divides a b) ->
(divides (a * c)%Z (b * c)%Z).
Axiom Gcd_euclid : forall (a:Z) (b:Z) (q:Z) (g:Z), (gcd a (b - (q * a)%Z)%Z Axiom divides_oppr : forall (a:Z) (b:Z), (divides a b) -> (divides a (-b)%Z).
g) -> (gcd a b g).
Axiom Gcd_computer_mod : forall (a:Z) (b:Z) (g:Z), (~ (b = 0%Z)) -> ((gcd a Axiom divides_oppl : forall (a:Z) (b:Z), (divides a b) -> (divides (-a)%Z b).
(ZOmod a b) g) -> (gcd a b g)).
Axiom divides_oppr_rev : forall (a:Z) (b:Z), (divides (-a)%Z b) -> (divides a
b).
Axiom divides_oppl_rev : forall (a:Z) (b:Z), (divides a (-b)%Z) -> (divides a
b).
Axiom divides_plusr : forall (a:Z) (b:Z) (c:Z), (divides a b) -> ((divides a
c) -> (divides a (b + c)%Z)).
Axiom divides_minusr : forall (a:Z) (b:Z) (c:Z), (divides a b) -> ((divides a
c) -> (divides a (b - c)%Z)).
Axiom divides_multl : forall (a:Z) (b:Z) (c:Z), (divides a b) -> (divides a
(c * b)%Z).
Axiom divides_multr : forall (a:Z) (b:Z) (c:Z), (divides a b) -> (divides a
(b * c)%Z).
Axiom divides_factorl : forall (a:Z) (b:Z), (divides a (b * a)%Z).
Axiom divides_factorr : forall (a:Z) (b:Z), (divides a (a * b)%Z).
Axiom divides1 : forall (x:Z), (divides x 1%Z) -> ((x = 1%Z) \/
(x = (-1%Z)%Z)).
Axiom divides_antisym : forall (a:Z) (b:Z), (divides a b) -> ((divides b
a) -> ((a = b) \/ (a = (-b)%Z))).
Axiom divides_trans : forall (a:Z) (b:Z) (c:Z), (divides a b) -> ((divides b
c) -> (divides a c)).
Axiom divides_bounds : forall (a:Z) (b:Z), (divides a b) -> ((~ (b = 0%Z)) ->
((Zabs a) <= (Zabs b))%Z).
Axiom Div_mod1 : forall (x:Z) (y:Z), (~ (y = 0%Z)) -> Axiom Div_mod1 : forall (x:Z) (y:Z), (~ (y = 0%Z)) ->
(x = ((y * (Zdiv x y))%Z + (Zmod x y))%Z). (x = ((y * (Zdiv x y))%Z + (Zmod x y))%Z).
...@@ -90,8 +123,39 @@ Axiom Mod_11 : forall (x:Z), ((Zmod x 1%Z) = 0%Z). ...@@ -90,8 +123,39 @@ Axiom Mod_11 : forall (x:Z), ((Zmod x 1%Z) = 0%Z).
Axiom Div_11 : forall (x:Z), ((Zdiv x 1%Z) = x). Axiom Div_11 : forall (x:Z), ((Zdiv x 1%Z) = x).
Axiom Gcd_euclidean_mod : forall (a:Z) (b:Z) (g:Z), (~ (b = 0%Z)) -> ((gcd a Axiom mod_divides : forall (a:Z) (b:Z), (~ (b = 0%Z)) ->
(Zmod a b) g) -> (gcd a b g)). (((Zmod a b) = 0%Z) -> (divides b a)).
Axiom divides_mod : forall (a:Z) (b:Z), (~ (b = 0%Z)) -> ((divides b a) ->
((Zmod a b) = 0%Z)).
Parameter gcd: Z -> Z -> Z.
Axiom gcd_nonneg : forall (a:Z) (b:Z), (0%Z <= (gcd a b))%Z.
Axiom gcd_def1 : forall (a:Z) (b:Z), (divides (gcd a b) a).
Axiom gcd_def2 : forall (a:Z) (b:Z), (divides (gcd a b) b).
Axiom gcd_def3 : forall (a:Z) (b:Z) (x:Z), (divides x a) -> ((divides x b) ->
(divides x (gcd a b))).
Axiom Assoc : forall (x:Z) (y:Z) (z:Z), ((gcd (gcd x y) z) = (gcd x (gcd y
z))).
Axiom Comm : forall (x:Z) (y:Z), ((gcd x y) = (gcd y x)).
Axiom gcd_0 : forall (a:Z), ((gcd a 0%Z) = a).
Axiom gcd_euclid : forall (a:Z) (b:Z) (q:Z), ((gcd a b) = (gcd a
(b - (q * a)%Z)%Z)).
Axiom Gcd_computer_mod : forall (a:Z) (b:Z), (~ (b = 0%Z)) -> ((gcd a
(ZOmod a b)) = (gcd a b)).
Axiom Gcd_euclidean_mod : forall (a:Z) (b:Z), (~ (b = 0%Z)) -> ((gcd a
(Zmod a b)) = (gcd a b)).
Inductive ref (a:Type) := Inductive ref (a:Type) :=
| mk_ref : a -> ref a. | mk_ref : a -> ref a.
...@@ -105,26 +169,25 @@ Implicit Arguments contents. ...@@ -105,26 +169,25 @@ Implicit Arguments contents.
Theorem WP_parameter_gcd : forall (x:Z), forall (y:Z), ((0%Z <= x)%Z /\ Theorem WP_parameter_gcd : forall (x:Z), forall (y:Z), ((0%Z <= x)%Z /\
(0%Z <= y)%Z) -> forall (d:Z), forall (c:Z), forall (b:Z), forall (a:Z), (0%Z <= y)%Z) -> forall (d:Z), forall (c:Z), forall (b:Z), forall (a:Z),
forall (y1:Z), forall (x1:Z), ((0%Z <= x1)%Z /\ ((0%Z <= y1)%Z /\ forall (y1:Z), forall (x1:Z), ((0%Z <= x1)%Z /\ ((0%Z <= y1)%Z /\ (((gcd x1
((forall (d1:Z), (gcd x1 y1 d1) -> (gcd x y d1)) /\ y1) = (gcd x y)) /\ ((((a * x)%Z + (b * y)%Z)%Z = x1) /\
((((a * x)%Z + (b * y)%Z)%Z = x1) /\
(((c * x)%Z + (d * y)%Z)%Z = y1))))) -> ((0%Z < y1)%Z -> forall (x2:Z), (((c * x)%Z + (d * y)%Z)%Z = y1))))) -> ((0%Z < y1)%Z -> forall (x2:Z),
(x2 = y1) -> forall (y2:Z), (y2 = (ZOmod x1 y1)) -> forall (a1:Z), (x2 = y1) -> forall (y2:Z), (y2 = (ZOmod x1 y1)) -> forall (a1:Z),
(a1 = c) -> forall (b1:Z), (b1 = d) -> forall (c1:Z), (a1 = c) -> forall (b1:Z), (b1 = d) -> forall (c1:Z),
(c1 = (a - (c * (ZOdiv x1 y1))%Z)%Z) -> forall (d1:Z), (c1 = (a - (c * (ZOdiv x1 y1))%Z)%Z) -> forall (d1:Z),
(d1 = (b - (d * (ZOdiv x1 y1))%Z)%Z) -> forall (d2:Z), (gcd x2 y2 d2) -> (d1 = (b - (d * (ZOdiv x1 y1))%Z)%Z) -> ((gcd x2 y2) = (gcd x y))).
(gcd x y d2)).
(* YOU MAY EDIT THE PROOF BELOW *) (* YOU MAY EDIT THE PROOF BELOW *)
intuition. intuition.
apply H4. rewrite <- H4.
subst x2 y2. subst x2 y2.
apply Gcd_sym. symmetry.
apply Gcd_euclid with (q:=(ZOdiv x1 y1)). rewrite Comm.
rewrite gcd_euclid with (q:=(ZOdiv x1 y1)).
assert (x1 - (ZOdiv x1 y1) * y1 = ZOmod x1 y1)%Z. assert (x1 - (ZOdiv x1 y1) * y1 = ZOmod x1 y1)%Z.
generalize (Div_mod x1 y1); intuition. generalize (Div_mod x1 y1); intuition.
replace ((ZOdiv x1 y1) * y1) with (y1 * (ZOdiv x1 y1)) by ring. replace ((ZOdiv x1 y1) * y1) with (y1 * (ZOdiv x1 y1)) by ring.
omega. omega.
rewrite H6; assumption. rewrite H6; auto.
Qed. Qed.
(* DO NOT EDIT BELOW *) (* DO NOT EDIT BELOW *)
......
...@@ -2,60 +2,60 @@ ...@@ -2,60 +2,60 @@
<!DOCTYPE why3session SYSTEM "why3session.dtd"> <!DOCTYPE why3session SYSTEM "why3session.dtd">
<why3session name="examples/programs/gcd_bezout/why3session.xml"> <why3session name="examples/programs/gcd_bezout/why3session.xml">
<file name="../gcd_bezout.mlw" verified="true" expanded="true"> <file name="../gcd_bezout.mlw" verified="true" expanded="true">
<theory name="WP M" verified="true" expanded="true"> <theory name="WP GcdBezout" verified="true" expanded="true">
<goal name="WP_parameter gcd" expl="correctness of parameter gcd" sum="24b81661726d80251f271d9638c0fba4" proved="true" expanded="true"> <goal name="WP_parameter gcd" expl="correctness of parameter gcd" sum="0fd714786263b647d7092c43fe9130f8" proved="true" expanded="true">
<transf name="split_goal" proved="true" expanded="true"> <transf name="split_goal" proved="true" expanded="true">
<goal name="WP_parameter gcd.1" expl="loop invariant init" sum="f091ff5ed7f20de51efc707bf3edb472" proved="true" expanded="false"> <goal name="WP_parameter gcd.1" expl="loop invariant init" sum="17d25f35ef473e3427180dd08103cf55" proved="true" expanded="false">
<proof prover="cvc3" timelimit="2" edited="" obsolete="false"> <proof prover="cvc3" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.00"/> <result status="valid" time="0.02"/>
</proof> </proof>
<proof prover="alt-ergo" timelimit="2" edited="" obsolete="false"> <proof prover="alt-ergo" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.00"/> <result status="valid" time="0.03"/>
</proof> </proof>
<proof prover="z3" timelimit="2" edited="" obsolete="false"> <proof prover="z3" timelimit="2" edited="" obsolete="false">
<result status="valid" time="0.00"/> <result status="valid" time="0.00"/>
</proof> </proof>
</goal>