How to prove that a number is prime using Znumtheory in Coq - primes

I'm trying to prove that a number is prime using the Znumtheory library.
In Znumtheory primes are defined in terms of relative primes:
Inductive prime (p:Z) : Prop :=
prime_intro :
1 < p -> (forall n:Z, 1 <= n < p -> rel_prime n p) -> prime p.
So to prove that 3 is prime I should apply prime_intro to the goal. Here is my try:
Theorem prime3 : prime 3.
Proof.
apply prime_intro.
- omega.
- intros.
unfold rel_prime. apply Zis_gcd_intro.
+ apply Z.divide_1_l.
+ apply Z.divide_1_l.
+ intros. Abort.
I don't know how to use the hypothesis H : 1 <= n < 3 which says that n is 1 or 2. I could destruct it, apply lt_eq_cases and destruct it again, but I would be stuck with a useless 1 < n in the first case.
I wasn't expecting to have a hard time with something that looks so simple.

I have a variant of #larsr's proof.
Require Import ZArith.
Require Import Znumtheory.
Require Import Omega.
Theorem prime3 : prime 3.
Proof.
constructor.
- omega.
- intros.
assert (n = 1 \/ n = 2) as Ha by omega.
destruct Ha; subst n; apply Zgcd_is_gcd.
Qed.
Like #larsr's proof, we prove that 1 < 3 using omega and then prove that either n=1 or n=2 using omega again.
To prove rel_prime 1 3 and rel_prime 2 3 which are defined in terms of Zis_gcd, we apply Zgcd_is_gcd. This lemma states that computing the gcd is enough. This is trivial on concrete inputs like (1,3) and (2,3).
EDIT: We can generalize this result, using only Gallina. We define a boolean function is_prime that we prove correct w.r.t. the inductive specification prime. I guess this can be done in a more elegant way, but I am confused with all the lemmas related to Z. Moreover, some of the definitions are opaque and cannot be used (at least directly) to define a computable function.
Require Import ZArith.
Require Import Znumtheory.
Require Import Omega.
Require Import Bool.
Require Import Recdef.
(** [for_all] checks that [f] is true for any integer between 1 and [n] *)
Function for_all (f:Z->bool) n {measure Z.to_nat n}:=
if n <=? 1 then true
else f (n-1) && for_all f (n-1).
Proof.
intros.
apply Z.leb_nle in teq.
apply Z2Nat.inj_lt. omega. omega. omega.
Defined.
Lemma for_all_spec : forall f n,
for_all f n = true -> forall k, 1 <= k < n -> f k = true.
Proof.
intros.
assert (0 <= n) by omega.
revert n H1 k H0 H.
apply (natlike_ind (fun n => forall k : Z, 1 <= k < n ->
for_all f n = true -> f k = true)); intros.
- omega.
- rewrite for_all_equation in H2.
destruct (Z.leb_spec0 (Z.succ x) 1).
+ omega.
+ replace (Z.succ x - 1) with x in H2 by omega. apply andb_true_iff in H2.
assert (k < x \/ k = x) by omega.
destruct H3.
* apply H0. omega. apply H2.
* subst k. apply H2.
Qed.
Definition is_prime (p:Z) :=
(1 <? p) && for_all (fun k => Z.gcd k p =? 1) p.
Theorem is_prime_correct : forall z, is_prime z = true -> prime z.
Proof.
intros. unfold is_prime in H.
apply andb_true_iff in H. destruct H as (H & H0).
constructor.
- apply Z.ltb_lt. assumption.
- intros.
apply for_all_spec with (k:=n) in H0; try assumption.
unfold rel_prime. apply Z.eqb_eq in H0. rewrite <- H0.
apply Zgcd_is_gcd.
Qed.
The proof becomes nearly as simple as #Arthur's one.
Theorem prime113 : prime 113.
Proof.
apply is_prime_correct; reflexivity.
Qed.

The lemma you mentioned is actually proved in that library, under the name prime_3. You can look up its proof on GitHub.
You mentioned how strange it is to have such a hard time to prove something so simple. Indeed, the proof in the standard library is quite complicated. Luckily, there are much better ways to work out this result. The Mathematical Components library advocates for a different style of development based on boolean properties. There, prime is not an inductively defined predicate, but a function nat -> bool that checks whether its argument is prime. Because of this, we can prove such simple facts by computation:
From mathcomp Require Import ssreflect ssrbool ssrnat prime.
Lemma prime_3 : prime 3. Proof. reflexivity. Qed.
There is a bit of magic going on here: the library declares a coercion is_true : bool -> Prop that is automatically inserted whenever a boolean is used in a place where a proposition is expected. It is defined as follows:
Definition is_true (b : bool) : Prop := b = true.
Thus, what prime_3 really is proving above is prime 3 = true, which is what makes that simple proof possible.
The library allows you to connect this boolean notion of what a prime number is to a more conventional one via a reflection lemma:
Lemma primeP p :
reflect (p > 1 /\ forall d, d %| p -> xpred2 1 p d) (prime p).
Unpacking notations and definitions, what this statement says is that prime p equals true if and only if p > 1 and every d that divides p is equal to 1 or p. I am afraid it would be a lengthy detour to explain how this reflection lemma works exactly, but if you find this interesting I strongly encourage you to look up more about Mathematical Components.

Here is a proof that I think is quite understandable as one steps through it.
It stays at the level of number theory and doesn't unfold definitions that much. I put in some comments, don't know if it makes it more or less readable. But try to step through it in the IDE, if you care for it...
Require Import ZArith.
Require Import Znumtheory.
Inductive prime (p:Z) : Prop :=
prime_intro :
1 < p -> (forall n:Z, 1 <= n < p -> rel_prime n p) -> prime p.
Require Import Omega.
Theorem prime3 : prime 3.
Proof.
constructor.
omega. (* prove 1 < 3 *)
intros; constructor. (* prove rel_prime n 3 *)
exists n. omega. (* prove (1 | n) *)
exists 3. omega. (* prove (1 | 3) *)
(* our goal is now (x | 1), and we know (x | n) and (x | 3) *)
assert (Hn: n=1 \/ n=2) by omega; clear H. (* because 1 <= n < 3 *)
case Hn. (* consider cases n=1 and n=2 *)
- intros; subst; trivial. (* case n = 1: proves (x | 1) because we know (x | n) *)
- intros; subst. (* case n = 2: we know (x | n) and (x | 3) *)
assert (Hgcd: (x | Z.gcd 2 3)) by (apply Z.gcd_greatest; trivial).
(* Z.gcd_greatest: (x | 2) -> x | 3) -> (x | Z.gcd 2 3) *)
apply Hgcd. (* prove (x | 1), because Z.gcd 2 3 = 1 *)
Qed.

Fun fact: #epoiner's answer can be used together with Ltac in a proof script for any prime number.
Theorem prime113 : prime 113.
Proof.
constructor.
- omega.
- intros n H;
repeat match goal with | H : 1 <= ?n < ?a |- _ =>
assert (Hn: n = a -1 \/ 1 <= n < a - 1) by omega;
clear H; destruct Hn as [Hn | H];
[subst n; apply Zgcd_is_gcd | simpl in H; try omega ]
end.
Qed.
However, the proof term gets unwieldy, and checking becomes slower and slower. This is why it small scale reflection (ssreflect) where computation is moved into the type checking probably is preferrable in the long run. It's hard to beat #Arthur Azevedo De Amorim's proof:
Proof. reflexivity. Qed. :-) Both in terms of computation time, and memory-wise.

Related

How should I implement this algorithm with zarith? Because it only works till 26

Well, I wrote this code and I'm trying to implement the zarith library, to have access to bigger integers, otherwise I'm not able to process the algorithm more than when n=25.
let (~~) = Z.of_int
let (&*) = Z.mul
let (&/) = Z.div
let (&-) = Z.sub
let rec s n chamadas =
if n < 0 || n > 10_000 then invalid_arg "ERRO"
else
match n with
| 0 -> (Z.one , chamadas + 1)
| 1 -> (~~ 2, chamadas + 1)
| _ ->
let (~~ resultado, counter) = s (n - 1) (chamadas + 1) in
let (~~ resultado', counter) = sum_s n 1 counter in
(~~ 3 &* ~~ resultado &+ ~~ resultado', counter)
and sum_s n k chamadas =
let rec aux_sum_s n k chamadas =
if n - 2 < 1 || k > n - 2 then
(0, chamadas)
else
let (~~ resultado, counter) = s k chamadas in
let (~~ resultado', counter) = s (n - k - 1) counter in
let (~~ resultado'', counter) = aux_sum_s n (k + 1) counter in
(~~ resultado &* ~~ resultado' &+ ~~ resultado'', counter)
in
aux_sum_s n 1 chamadas
that's what I understood from the documentation
The first character of an infix operator defines its precedence (priority over other operators) and associativity (how operators with equal precedence are grouped). Therefore, your choice of prefixing the operators that work with Zarith numbers with & is probably the worst possible. Not only does it put all arithmetic operators on the same level, so that the multiplication has no precedence over addition, but it also groups them from right to left!
Therefore,
x &* y &+ z
is parsed as,
x &* (y &+ z)
This basically invalidates all your code.
The right way is to append characters to the infix operator, cf. the floating-point operators, e.g., *., +., etc.
So you can either do,
let ( *& ) = Z.mul
let ( /& ) = Z.div
let ( -& ) = Z.sub
or just use the infix operators that are already provided by the Zarith library together with the local opens, e.g.,
Z.(x * y + z)
is the same as,
x *& y *& +& z
provided you have the above bindings. I believe that the former is much easier to read than the latter.
In addition, you have to keep all numbers in Z.t if you will keep converting them back and forth, then you will lose precision with each conversion to int. It would be much easier if you will keep everything in Z.t.
Finally,
let (~~ resultado, counter) = s (n - 1) (chamadas + 1) in
Is not valid OCaml at all, what you wanted to say could be expressed with the following syntactically valid OCaml
let (resultado, counter) = s (n - 1) (chamadas + 1) in
let resultado = ~~resultado in
But it still doesn't make much sense, since your s function returns the value of type Z.t and applying Z.of_int to doesn't make any sense. And using ~~ for Z.of_int is probably also not the best choice of name, as looks very much like negation. Zarith itself, provides the ~$ operator for that.

Use '->' in prolog

I want to generate a list that is made up by sublists which contains 2 intergers and their sum and product.
The expected result is
A = [[2,3,5,6],[2,4,6,8],[2,5,7,10],[2,6,8,12],
[2,7,9,14],[2,8,10,16],[3,4,7,12],[3,5,8,15],
[3,6,9,18],[3,7,10,21],[4,5,9,20]].
But I kept have some sublists that does not have the sum and product:
?- get(A).
A = [[2,3,5,6],[2,4,6,8],[2,5,7,10],[2,6,8,12],
[2,7,9,14],[2,8,10,16],[2,_G419,_G422,_G425],
[3,4,7,12],[3,5,8,15],[3,6,9,18],[3,7,10,21],
[3,_G530,_G533,_G536],[4,5,9,20]].
Here is my code :
get(4,5,[]):-!.
get(N,M,[[N,Q,S,P]|List]):-
Q is M + 1,
S is N + Q,
S =< 10 ->
P is N * Q,
get(N,Q,List);
X is N + 1,
get(X,X,List).
get(List):-get(2,2,List).
I think the problem is about using -> in my code, but I don't know how to fix it, I think the logic about -> is right: if S=<10, then calculate the product and the other value with N and Q; else calculate N+1 and N+2 and ...
The operator precedence of (->)/2 is higher than the
operator precedence of (,)/2. As a result the (,)/2
are grouped together as an argument for (->)/2.
So your rule:
get(N,M,[[N,Q,S,P]|List]):-
Q is M + 1,
S is N + Q,
S =< 10 ->
P is N * Q,
get(N,Q,List);
X is N + 1,
get(X,X,List).
Is basically read by the interpreter as:
get(N,M,[[N,Q,S,P]|List]):-
(Q is M + 1,
S is N + Q,
S =< 10) ->
P is N * Q,
get(N,Q,List);
X is N + 1,
get(X,X,List).
With the result that Q ans S are unbound when
the if condition is not satisfied and the else
part is executed. You can fix your code by introducing
additional parenthesis:
get(N,M,[[N,Q,S,P]|List]):-
Q is M + 1,
S is N + Q,
(S =< 10 ->
P is N * Q,
get(N,Q,List)
; X is N + 1,
get(X,X,List)).
But even with this fix, there is an issue with P
being unbound in the else branch.
For clarity, you might even try a solution without
if-then-else, see for example here
Prolog removing IF THEN ELSE
I concur with Jan, but I want to inteject a point about formatting. Because ; and -> so strongly affect the meaning of a program, it's poor form (meaning makes it harder to understand) to put those operators at the end of a line.
get(N,M,[[N,Q,S,P]|List]):-
Q is M + 1,
S is N + Q,
S =< 10
->
P is N * Q,
get(N,Q,List)
; X is N + 1,
get(X,X,List).
When you arrange code like this it becomes immediately apparent that the entire clause is an if-then-else, with the first 3 lines being the 'if' portion. (Though I wouldn't object to Jan's layout for the final version.)

Range Update - Range Query using Fenwick Tree

http://ayazdzulfikar.blogspot.in/2014/12/penggunaan-fenwick-tree-bit.html?showComment=1434865697025#c5391178275473818224
For example being told that the value of the function or f (i) of the index-i is an i ^ k, for k> = 0 and always stay on this matter. Given query like the following:
Add value array [i], for all a <= i <= b as v Determine the total
array [i] f (i), for each a <= i <= b (remember the previous function
values ​​clarification)
To work on this matter, can be formed into Query (x) = m * g (x) - c,
where g (x) is f (1) + f (2) + ... + f (x).
To accomplish this, we
need to know the values ​​of m and c. For that, we need 2 separate
BIT. Observations below for each update in the form of ab v. To
calculate the value of m, virtually identical to the Range Update -
Point Query. We can get the following observations for each value of
i, which may be:
i <a, m = 0
a <= i <= b, m = v
b <i, m = 0
By using the following observation, it is clear that the Range Update - Point Query can be used on any of the BIT. To calculate the value of c, we need to observe the possibility for each value of i, which may be:
i <a, then c = 0
a <= i <= b, then c = v * g (a - 1)
b <i, c = v * (g (b) - g (a - 1))
Again, we need Range Update - Point Query, but in a different BIT.
Oiya, for a little help, I wrote the value of g (x) for k <= 3 yes: p:
k = 0 -> x
k = 1 -> x * (x + 1) / 2
k = 2 -> x * (x + 1) * (2x + 1) / 6
k = 3 -> (x * (x + 1) / 2) ^ 2
Now, example problem SPOJ - Horrible Queries . This problem is
similar issues that have described, with k = 0. Note also that
sometimes there is a matter that is quite extreme, where the function
is not for one type of k, but it could be some that polynomial shape!
Eg LA - Alien Abduction Again . To work on this problem, the solution
is, for each rank we make its BIT counter m respectively. BIT combined
to clear the counters c it was fine.
How can we used this concept if:
Given an array of integers A1,A2,…AN.
Given x,y: Add 1×2 to Ax, add 2×3 to Ax+1, add 3×4 to Ax+2, add 4×5 to
Ax+3, and so on until Ay.
Then return Sum of the range [Ax,Ay].

How to get integers from list where sum of them is less than X?

Sorry for the mess that was here.
I wanted a classic greedy algorithm for knapsack problem in haskell for integers.
But there was other question - how to refer to list in list comprehension?
There are several approaches to this:
Generate all lists which are smaller. Take the longest
For every n <= X, generate [1..n] and check whether its sum is lesser x. Take the longest of those sets:
allLists x = takeWhile ( (<=x) . sum) $ inits [1..]
theList = last . allLists
where inits is from Data.List
Alternatively, we remember mathematics
We know that the sum of [1..n] is n*(n+1)/2. We want x >= n * (n+1)/2. We solve for n and get that n should be 0.5 * (sqrt (8 * x + 1) - 1). Since that's not a natural number, we floor it:
theList x = [1..n]
where n = floor $ 0.5 * (sqrt (8 * (fromIntegral x) + 1) - 1)
This will give all the lists that its sum is not greater than 100:
takeWhile (\l -> sum l <= 100) $ inits [1..]

Why does the exponential operator use float variables in OCaml?

Why does the exponential operator use float variables in OCaml?
Shouldn't it allow int variables too?
# 3**3;;
Error: This expression has type int but an expression was expected of type
float
Works:
# 3.0**3.0;;
- : float = 27.
So, the existing answers go into how to get around this, but not into why it is the case. There are two main reasons:
1) OCaml doesn't have operator aliasing. You can't have two operators that do the "same thing", but to different types. This means that only one kind of number, integers or floats (or some other representation) will get to use the standard ** interface.
2) pow(), the exponentiation function has historically been defined on floats (for instance, in Standard C).
Also, for another way to get around the problem, if you're using OCaml Batteries included, there is a pow function defined for integers.
You can use int
let int_exp x y = (float_of_int x) ** (float_of_int y) |> int_of_float
There's a similar question: Integer exponentiation in OCaml
Here's one possible tail-recursive implementation of integer exponentiation:
let is_even n =
n mod 2 = 0
(* https://en.wikipedia.org/wiki/Exponentiation_by_squaring *)
let pow base exponent =
if exponent < 0 then invalid_arg "exponent can not be negative" else
let rec aux accumulator base = function
| 0 -> accumulator
| 1 -> base * accumulator
| e when is_even e -> aux accumulator (base * base) (e / 2)
| e -> aux (base * accumulator) (base * base) ((e - 1) / 2) in
aux 1 base exponent