Coq fails an apply tactic - apply

I am trying to prove the following simple theorem over natural numbers:
((i + j) = (i + k)) -> (j = k)
Here is what I have in Coq:
Theorem cancel : forall (i j k : nat),
((add i j) = (add i k)) -> (j = k).
Proof.
intros i j k.
induction i.
simpl.
apply A_IMPLIES_A.
simpl.
And after that I have the sub-goal:
S (add i j) = S (add i k) -> j = k
So I thought I'd apply eq_add_S which states that S m = S n -> m = n.
However, when I try to do so with apply eq_add_S I get the following error:
Error:
In environment
i, j, k : nat
IHi : add i j = add i k -> j = k
Unable to unify "k" with "add i k".
So I guess it can't understand that I want is m = (add i j) and n = (add i k). How come Coq can't read my mind? or more seriously, how can I help him do so? thanks!

The problem is not that Coq can't guess what value to use for m and n, but that your goal does not have the right shape for you to instantiate that theorem. When you write apply eq_add_S, Coq tries to unify S n = S m -> n = m with S (add i j) = S (add i k) -> j = k, which cannot be done.
What you need is to apply eq_add_S to the goal's premise, by introducing it into the context.
Proof.
intros i j k H. (* H : add i j = add i k *)
induction i as [|i IH].
- apply H.
- apply eq_add_S in H.
(* ... *)

I'm posting the solution as a separate answer hoping other users can benefit from it. Here it is:
Theorem cancel : forall (i j k : nat),
((add i j) = (add i k)) -> (j = k).
Proof.
intros i j k H.
induction i.
apply H.
simpl in H.
apply eq_add_S in H.
apply IHi in H.
assumption.
Qed.

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.

Gurobi constraints and objective function

I am very new to Gurobi. I am trying to solve the following ILP
minimize \sum_i c_i y_i + \sum_i \sum_j D_{ij} x_{ij}
Here D is stored as a 2D numpy array.
My constraints are as follows
x_{ij} <= y_i
y_i + \sum_j x_{ij} = 1
Here's the image of the algebra :
My code so far is as follows,
from gurobipy import *
def gurobi(D,c):
n = D.shape[0]
m = Model()
X = m.addVars(n,n,vtype=GRB.BINARY)
y = m.addVars(n,vtype=GRB.BINARY)
m.update()
for j in range(D.shape[0]):
for i in range(D.shape[0]):
m.addConstr(X[i,j] <= y[i])
I am not sure about, how to implement the second constraint and specify the objective function, as objective terms includes a numpy array. Any help ?
Unfortunately I don't have GUROBI because it's really expensive...
but, according to this tutorial the second constraint should be implemented like this :
for i in range(n):
m.addConstr(y[i] + quicksum(X[i,j] for j in range(n), i) == 1)
while the objective function can be defined as :
m.setObjective(quicksum(c[i]*y[i] for i in range(n)) + quicksum(quicksum(D[i,j] * x[i,j]) for i in range(n) for j in range(n)), GRB.MINIMIZE)
N.B: I'm assuming D is a matrix n x n
This is a very simple case. You can write the first constraint this way. It is a good habit to name your constraints.
m.addConstrs((x[i,j] <= y[j] for i in range(D.shape[0]) for j in range(D.shape[0])), name='something')
If you want to add the second constraint, you can write it like this
m.addConstrs((y[i] + x.sum(i, '*') <= 1 for i in range(n)), name='something')
you could write the second equations ass well using quicksum as suggested by digEmAll.
The advantage of using quicksum is that you can add if condition so that you don't um over all values of j. Here is how you could do it
m.addConstrs((y[i] + quicksum(x[i, j] for j in range(n)) <= 1 for i in range(n)), name='something')
if you only needed some values of j to sum over then you could:
m.addConstrs((y[i] + quicksum(x[i, j] for j in range(n) if j condition) <= 1 for i in range(n)), name='something')
I hope this helps

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

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.

Map upper triangular matrix on vector skipping the diagonal

I have a problem that could be boiled down to finding a way of mapping a triangular matrix to a vector skipping the diagonal.
Basically I need to translate this C++ code using the Gecode libraries
// implied constraints
for (int k=0, i=0; i<n-1; i++)
for (int j=i+1; j<n; j++, k++)
rel(*this, d[k], IRT_GQ, (j-i)*(j-i+1)/2);
Into this MiniZinc (functional) code
constraint
forall ( i in 1..m-1 , j in i+1..m )
( (differences[?]) >= (floor(int2float(( j-i )*( j-i+1 )) / int2float(2)) ));
And I need to figure out the index in differences[?].
MiniZinc is a functional/mathematical language with no proper for loops.
So I have to map those indexes i and j that are touching all and only the cells of an upper triangular matrix, skipping its diagonal, to a k that numbers those cells from 0 to whatever.
If this was a regular triangular matrix (it's not), a solution like this would do
index = x + (y+1)*y/2
The matrix I'm handling is a square n*n matrix with indexes going from 0 to n-1, but it would be nice to provide a more general solution for an n*m matrix.
Here's the full Minizinc code
% modified version of the file found at https://github.com/MiniZinc/minizinc-benchmarks/blob/master/golomb/golomb.mzn
include "alldifferent.mzn";
int: m;
int: n = m*m;
array[1..m] of var 0..n: mark;
array[int] of var 0..n: differences = [mark[j] - mark[i] | i in 1..m, j in i+1..m];
constraint mark[1] = 0;
constraint forall ( i in 1..m-1 ) ( mark[i] < mark[i+1] );
% this version of the constraint works
constraint forall ( i in 1..m-1 , j in i+1..m )
( (mark[j] - mark[i]) >= (floor(int2float(( j-i )*( j-i+1 )) / int2float(2))) );
%this version does not
%constraint forall ( i in 1..m-1, j in i+1..m )
% ( (differences[(i-1) + ((j-2)*(j-1)) div 2]) >= (floor(int2float(( j-i )*( j-i+1 )) / int2float(2))) );
constraint alldifferent(differences);
constraint differences[1] < differences[(m*(m-1)) div 2];
solve :: int_search(mark, input_order, indomain, complete) minimize mark[m];
output ["golomb ", show(mark), "\n"];
Thanks.
Be careful. The formula you found from that link, index = x + (y+1)*y/2, includes the diagonal entries, and is for a lower triangular matrix, which I gather is not what you want. The exact formula you are looking for is actually index = x + ((y-1)y)/2
(see: https://math.stackexchange.com/questions/646117/how-to-find-a-function-mapping-matrix-indices).
Again, watch out, this formula I gave you assumes your indices: x,y, are zero-based. Your MiniZinc code is using indices i,j that start from 1 (1 <= i <= m), 1 <= j <= m)). For indices that start from 1, the formula is T(i,j) = i + ((j-2)(j-1))/2. So your code should look like:
constraint
forall ( i in 1..m-1 , j in i+1..m )
((distances[(i + ((j-2)*(j-1)) div 2]) >= ...
Note that (j-2)(j-1) will always be a multiple of 2, so we can just use integer division with divisor 2 (no need to worry about converting to/from floats).
The above assumes you are using a square m*m matrix.
To generalise to a M*N rectangular matrix, one formula could be:
where 0 <= i < M, 0<= j < N [If you again, need your indices to start from 1, replace i with i-1 and j with j-1 in the above formula]. This touches all of cells of an upper triangular matrix as well as the 'extra block on the side' of the square that occurs when N > M. That is, it touches all cells (i,j) such that i < j for 0 <= i < M, 0 <= j < N.
Full code:
% original: https://github.com/MiniZinc/minizinc-benchmarks/blob/master/golomb/golomb.mzn
include "alldifferent.mzn";
int: m;
int: n = m*m;
array[1..m] of var 0..n: mark;
array[1..(m*(m-1)) div 2] of var 0..n: differences;
constraint mark[1] = 0;
constraint forall ( i in 1..m-1 ) ( mark[i] < mark[i+1] );
constraint alldifferent(differences);
constraint forall (i,j in 1..m where j > i)
(differences[i + ((j-1)*(j-2)) div 2] = mark[j] - mark[i]);
constraint forall (i,j in 1..m where j > i)
(differences[i + ((j-1)*(j-2)) div 2] >= (floor(int2float(( j-i )*( j-i+1 )) / int2float(2))));
constraint differences[1] < differences[(m*(m-1)) div 2];
solve :: int_search(mark, input_order, indomain, complete)
minimize mark[m];
output ["golomb ", show(mark), "\n"];
Lower triangular version (take previous code and swap i and j where necessary):
% original: https://github.com/MiniZinc/minizinc-benchmarks/blob/master/golomb/golomb.mzn
include "alldifferent.mzn";
int: m;
int: n = m*m;
array[1..m] of var 0..n: mark;
array[1..(m*(m-1)) div 2] of var 0..n: differences;
constraint mark[1] = 0;
constraint forall ( i in 1..m-1 ) ( mark[i] < mark[i+1] );
constraint alldifferent(differences);
constraint forall (i,j in 1..m where i > j)
(differences[j + ((i-1)*(i-2)) div 2] = mark[i] - mark[j]);
constraint forall (i,j in 1..m where i > j)
(differences[j + ((i-1)*(i-2)) div 2] >= (floor(int2float(( i-j )*( i-j+1 )) / int2float(2))));
constraint differences[1] < differences[(m*(m-1)) div 2];
solve :: int_search(mark, input_order, indomain, complete)
minimize mark[m];
output ["golomb ", show(mark), "\n"];

Time Complexity on triple Nested For loops where indexes are dependent on each other

I have this c++ like pseudo code here:
for ( i = 1; i ≤ (n – 2); i++)
for (j = i + 1; j ≤ (n – 1); j ++)
for (k = j + 1; k ≤ n; k++)
Print “Hello World”;
I am fairly certain the time complexity of this particular block of code is O(n^3) because it is triple nested for loop and they are all going to at minimum n - 2 so I generalized (n-2) * (n-1) * n
But I have been trying to solve the actual time complexity function. This is how far I got and could not proceed any further:
summation from i = 1 to n-2, summation from j = (i+1) to n-1, summation from k = (j+1) to n.
I understand that the inner most loop performs n - (j+1) steps, the middle loop performs (n-1)-(i+1) steps, and the outer loop performs (n-2)-i steps. I just need some pointers on how to simplify the summations to come to a time complexity function.
Thank you!
If interested, the loops iterate through every combination of n things taken 3 at a time, starting with (1,2,3), (1,2,4), ... , and ending with (n-2,n-1,n), which is n! / (( 3! )( (n-3)!) ) = (n)(n-1)(n-2)/6 = (n^3 - 3n^2 + 2n) / 6 , which leads to O(n^3).
Don't run the loop from 1 to less or equal a value. Your code is equal to:
for ( i = 0; i < (n – 2); i++)
for (j = i; j < (n – 1); j ++)
for (k = j; k < n; k++)
Print “Hello World”;
So your inner loop runs n-j, the middle one multiplies it with n-1-i and the outer one multiplies it with n-2. So you get (n-j)*(n-1-i)*(n-2). n has O(n) complexity. Because of i runs from 0 to (n-1), you could replace it with O(n) (because sum(0, n) = 0 + 1 + .. + N = 0.5 * n^2 = O(n^2)). It is the same with j. So you get (O(n)-O(n))*(O(n)-1-O(n))*(O(n)-2) = O(n)*(n)*O(n) = O(n^3).
For details why you could replace i with O(n) see "Nested loops" at this.