renamed example euler003 -> largest_prime_factor

parent ae1ebddf
(*
Euler project Problem 3: Largest prime factor
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
*)
module PrimeFactor
use import int.ComputerDivision
use import number.Divisibility
use import number.Prime
use import number.Coprime
(** returns the smallest divisor of [n] greater than or equal to [d],
assuming no divisor between 2 and [d]. *)
let rec smallest_divisor (d n:int) : int
requires { 2 <= n }
requires { 2 <= d <= n }
requires { forall i:int. 2 <= i < d -> not divides i n }
ensures { d <= result <= n }
ensures { divides result n }
ensures { forall i:int. 2 <= i < result -> not divides i n }
variant { n - d }
= if d * d > n then begin
assert { forall i:int. 2 <= i < n /\ divides i n ->
i >= d && let u = div n i in u * i = n && divides u n &&
u * i = n && (u >= d -> n >= d * i >= d * d && false)
&& u >= 2 && u < n && false } ; n
end else if d >= 2 && mod n d = 0 then d else
smallest_divisor (d+1) n
(* The tests are invalidated by the new precondition. *)
(*let test2 () = smallest_divisor 2 13195 (* 5 *)
let test5 () = smallest_divisor 5 13195 (* 5 *)
let test6 () = smallest_divisor 6 13195 (* 7 *)
let test8 () = smallest_divisor 8 13195 (* 13 *)
let test14 () = smallest_divisor 14 13195 (* 29 *)
let test30 () = smallest_divisor 30 13195 (* 35 *)*)
use import ref.Ref
use import list.List
val factors : ref (list int)
let largest_prime_factor (n:int) : int
requires { 2 <= n }
ensures { prime result }
ensures { divides result n }
ensures { forall i:int. result < i <= n -> not (prime i /\ divides i n) }
= let d = smallest_divisor 2 n in
let factor = ref d in
let target = ref (div n d) in
factors := Cons d Nil;
assert { !target * d = n && divides !target n } ;
assert { forall i:int. prime i /\ divides i n /\ i > d ->
coprime d i && divides i !target };
while !target >= 2 do
invariant { 1 <= !target <= n }
invariant { 2 <= !factor <= n }
invariant { divides !factor n }
invariant { prime !factor }
invariant { forall i:int. divides i !target /\ i >= 2 ->
i >= !factor /\ divides i n }
invariant { forall i:int. prime i /\ divides i n /\ i > !factor ->
divides i !target }
(*invariant { !target = 1 \/ 2 <= !factor <= !target }*)
(* invariant { 2 <= !factor <= n } *)
(* invariant { divides !target n } *)
(*invariant { divides !factor n }*)
(*invariant { prime !factor }*)
variant { !target }
let ghost oldt = !target in
let ghost oldf = !factor in
assert { divides !target !target && !target >= 2 && !target >= !factor };
let d = smallest_divisor !factor !target in
assert { prime d };
factor := d;
factors := Cons d !factors;
target := div !target d;
assert { !target * d = oldt && divides !target oldt } ;
assert { forall i:int. prime i /\ divides i n /\ i > d ->
i > oldf && divides i oldt && 1 <= d < i
&& coprime d i && divides i !target }
done;
!factor
let test () =
largest_prime_factor 13195 (* should be 29 *)
let solve () =
largest_prime_factor 600851475143 (* should be 6857 *)
end
(***
Local Variables:
compile-command: "why3ide euler003.mlw"
End:
*)
(*
Euler project Problem 3: Largest prime factor
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
*)
module PrimeFactor
use import int.ComputerDivision
use import number.Divisibility
use import number.Prime
use import number.Coprime
(** returns the smallest divisor of [n] greater than or equal to [d],
assuming no divisor between 2 and [d]. *)
let rec smallest_divisor (d n:int) : int
requires { 2 <= n }
requires { 2 <= d <= n }
requires { forall i:int. 2 <= i < d -> not divides i n }
ensures { d <= result <= n }
ensures { divides result n }
ensures { forall i:int. 2 <= i < result -> not divides i n }
variant { n - d }
= if d * d > n then begin
assert { forall i:int. 2 <= i < n /\ divides i n ->
i >= d && let u = div n i in u * i = n && divides u n &&
u * i = n && (u >= d -> n >= d * i >= d * d && false)
&& u >= 2 && u < n && false } ; n
end else if d >= 2 && mod n d = 0 then d else
smallest_divisor (d+1) n
use import ref.Ref
use import list.List
val factors : ref (list int)
let largest_prime_factor (n:int) : int
requires { 2 <= n }
ensures { prime result }
ensures { divides result n }
ensures { forall i:int. result < i <= n -> not (prime i /\ divides i n) }
= let d = smallest_divisor 2 n in
let factor = ref d in
let target = ref (div n d) in
factors := Cons d Nil;
assert { !target * d = n && divides !target n } ;
assert { forall i:int. prime i /\ divides i n /\ i > d ->
coprime d i && divides i !target };
while !target >= 2 do
invariant { 1 <= !target <= n }
invariant { 2 <= !factor <= n }
invariant { divides !factor n }
invariant { prime !factor }
invariant { forall i:int. divides i !target /\ i >= 2 ->
i >= !factor /\ divides i n }
invariant { forall i:int. prime i /\ divides i n /\ i > !factor ->
divides i !target }
variant { !target }
let ghost oldt = !target in
let ghost oldf = !factor in
assert { divides !target !target && !target >= 2 && !target >= !factor };
let d = smallest_divisor !factor !target in
assert { prime d };
factor := d;
factors := Cons d !factors;
target := div !target d;
assert { !target * d = oldt && divides !target oldt } ;
assert { forall i:int. prime i /\ divides i n /\ i > d ->
i > oldf && divides i oldt && 1 <= d < i
&& coprime d i && divides i !target }
done;
!factor
let test () =
largest_prime_factor 13195 (* should be 29 *)
let solve () =
largest_prime_factor 600851475143
end
(***
Local Variables:
compile-command: "why3ide largest_prime_factor.mlw"
End:
*)
......@@ -30,18 +30,18 @@
name="Z3"
version="4.3.1"/>
<file
name="../euler003.mlw"
name="../largest_prime_factor.mlw"
verified="true"
expanded="true">
<theory
name="PrimeFactor"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="10" loccnumb="7" loccnume="18"
verified="true"
expanded="true">
<goal
name="WP_parameter smallest_divisor"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="VC for smallest_divisor"
sum="5148e7a4e729dac62919ff35357f7209"
......@@ -56,7 +56,7 @@
expanded="false">
<goal
name="WP_parameter smallest_divisor.1"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="1. assertion"
sum="2bba7a26f99f92d3c4ea1dc601f609c1"
......@@ -71,7 +71,7 @@
expanded="false">
<goal
name="WP_parameter smallest_divisor.1.1"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="1. assertion"
sum="32824234b61f6f792ecbe86bcad17b68"
......@@ -91,7 +91,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.1.2"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="2. assertion"
sum="824f47baa04cd3df43d9dcb51e99b3f6"
......@@ -111,7 +111,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.1.3"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="3. assertion"
sum="5b7e581efce61165047735554f082451"
......@@ -131,7 +131,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.1.4"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="4. assertion"
sum="5b47d7fcdac9483cf68d30335f421854"
......@@ -151,7 +151,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.1.5"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="5. assertion"
sum="c70ecfb1ad31eed9528c50eefe156458"
......@@ -171,7 +171,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.1.6"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="6. assertion"
sum="9bf0bb7ab3f5f9467773de31ba944760"
......@@ -191,7 +191,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.1.7"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="7. assertion"
sum="c7af7194a701d4309049824d3e1466dc"
......@@ -211,7 +211,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.1.8"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="8. assertion"
sum="15327381f18f815e96be50b120184254"
......@@ -231,7 +231,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.1.9"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="9. assertion"
sum="3c395117a2f0534579537ffc48bded06"
......@@ -251,7 +251,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.1.10"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="10. assertion"
sum="985f2f140b6761460b28a6591be4b19c"
......@@ -273,7 +273,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.2"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="2. postcondition"
sum="072ce4e1079be7e064f9622f1293893f"
......@@ -293,7 +293,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.3"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="3. postcondition"
sum="c9b36f9ed2930619d137902fb18cb28c"
......@@ -313,7 +313,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.4"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="4. postcondition"
sum="f8f1bc3d2b3ec3c9ea3d3c43855ba896"
......@@ -333,7 +333,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.5"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="5. postcondition"
sum="0508f6c6aa14b4debc4e3b17955a5157"
......@@ -353,7 +353,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.6"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="6. postcondition"
sum="eb7beeda174cb0da13205390013b5614"
......@@ -373,7 +373,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.7"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="7. postcondition"
sum="38a56fc12089a9862ea11d4a5aec077b"
......@@ -393,7 +393,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.8"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="8. variant decrease"
sum="a34c36c9029a63eadc23b82fc9b92d44"
......@@ -413,7 +413,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.9"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="9. precondition"
sum="33a7c63e98ce9dcd4b93f7aa808f8c23"
......@@ -433,7 +433,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.10"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="10. precondition"
sum="1ebcc1569c43a20bbc7807afd1d1c652"
......@@ -453,7 +453,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.11"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="11. precondition"
sum="941270a17df0ff50bf4e8e180ca13afd"
......@@ -473,7 +473,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.12"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="12. postcondition"
sum="b40e4752e90d7dcd4994487fa3610bf5"
......@@ -493,7 +493,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.13"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="13. postcondition"
sum="b1cbb110b9806fab6ac5b82294c0c0d2"
......@@ -513,7 +513,7 @@
</goal>
<goal
name="WP_parameter smallest_divisor.14"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="19" loccnumb="8" loccnume="24"
expl="14. postcondition"
sum="6e6d618d760df9e27364dd483b70c2f3"
......@@ -535,7 +535,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="VC for largest_prime_factor"
sum="82f51dcf7c5c5cb1cf49fce71e24a4f3"
......@@ -550,7 +550,7 @@
expanded="false">
<goal
name="WP_parameter largest_prime_factor.1"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="1. precondition"
sum="2184826c7f3607d95bb7562d42140d6f"
......@@ -570,7 +570,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.2"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="2. precondition"
sum="15c1756fc611a6d7cc1eeb2c8f58f8e5"
......@@ -590,7 +590,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.3"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="3. precondition"
sum="a171a830f8892bd14bc7f8545888333d"
......@@ -610,7 +610,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.4"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="4. assertion"
sum="926db07d453cb0d3b6ec06ed7cb90533"
......@@ -625,7 +625,7 @@
expanded="false">
<goal
name="WP_parameter largest_prime_factor.4.1"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="1."
sum="c62addf15c2413f67ced057de113c5be"
......@@ -645,7 +645,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.4.2"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="2."
sum="7e599979b410f30b3c85ae3cc56806db"
......@@ -667,7 +667,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.5"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="5. assertion"
sum="7512eb38350192b99784fa6cb4d42bd5"
......@@ -687,7 +687,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.6"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="6. loop invariant init"
sum="20611831a17cb08e735c40b97f58d176"
......@@ -707,7 +707,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.7"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="7. loop invariant init"
sum="35a6cc38a7b41bded0ca32c330868bb4"
......@@ -727,7 +727,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.8"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="8. loop invariant init"
sum="c1d4a6d117eaa6333a354b15c8aae0fc"
......@@ -747,7 +747,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.9"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="9. loop invariant init"
sum="6303afbabc03135f1021dadba130bf7e"
......@@ -767,7 +767,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.10"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="10. loop invariant init"
sum="e59ab4c97bb3f2e19e3107c35695b395"
......@@ -787,7 +787,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.11"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="11. loop invariant init"
sum="5855c54ed35d9657778f3cdd15338b75"
......@@ -807,7 +807,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.12"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="12. assertion"
sum="fc5d0a3abed8d14a15aca3e9e174f922"
......@@ -822,7 +822,7 @@
expanded="false">
<goal
name="WP_parameter largest_prime_factor.12.1"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="1."
sum="341fc55dda37c16291149404e27e2268"
......@@ -842,7 +842,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.12.2"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="2."
sum="443f3bfc28ccbf4125ab6ec6161338dc"
......@@ -862,7 +862,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.12.3"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="3."
sum="0bdd93529eb2f83a1339c024c300d5cb"
......@@ -884,7 +884,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.13"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="13. precondition"
sum="7aa295f86d8f09d3837ae5926f9154f8"
......@@ -904,7 +904,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.14"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="14. precondition"
sum="bc1dac1b80f66c7311bd1733957589e7"
......@@ -924,7 +924,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.15"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="15. precondition"
sum="cea6c5f40c7cbdeedf5ae6e1e8eaa172"
......@@ -944,7 +944,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.16"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="16. assertion"
sum="870fd789c9f4fe3049ed7b246b2cbe74"
......@@ -964,7 +964,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.17"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="17. assertion"
sum="bca106f688e018fdc712421509bd4190"
......@@ -979,7 +979,7 @@
expanded="false">
<goal
name="WP_parameter largest_prime_factor.17.1"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="1."
sum="66180f2f3c4519a6296ee16cb9006037"
......@@ -999,7 +999,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.17.2"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="2."
sum="88737e93d547b633ad2d343d053ae3eb"
......@@ -1021,7 +1021,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.18"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="18. assertion"
sum="fe2600ea387143bc46154547cd58a3d9"
......@@ -1036,7 +1036,7 @@
expanded="false">
<goal
name="WP_parameter largest_prime_factor.18.1"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="1. assertion"
sum="abb143dd3542dda1f1936144c7e790c4"
......@@ -1056,7 +1056,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.18.2"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="2. assertion"
sum="e5fb8d92667f1960b6966f2539a581f9"
......@@ -1076,7 +1076,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.18.3"
locfile="../euler003.mlw"
locfile="../largest_prime_factor.mlw"
loclnum="55" loccnumb="4" loccnume="24"
expl="3. assertion"
sum="610c00ed6f5170d022c19af29b8e3e67"
......@@ -1096,7 +1096,7 @@
</goal>
<goal
name="WP_parameter largest_prime_factor.18.4"
locfile="../euler003.mlw"