COQ: How to use "<=" for Z and R in the same lemma? - coq

Suppose I already defined floor (from R to Z). Now I want to prove that n <= x implies n <= floor(x), where n : Z, x : R.
I tried:
Lemma l: forall (n:Z) (x:R), (IZR n) <= x -> n <= (floor x).
but I'm getting the error The term n has type Z while it is expected to have type R.
How should I write this? Is there a way that I can use <= for Z and R simultaneously?

In order to override the default interpretation of a notation, you can open a notation scope locally using %key:
Lemma l : forall n x, (IZR n <= x)%R -> (n <= floor x)%Z.

Related

Partial differentiation using Coqelicot on Coq

I want to partially differentiate functions which expects n arguments for arbitrary natural number n. I hope to differentiate arbitrary an argument only once and not the others.
Require Import Reals.
Open Scope R_scope.
Definition myFunc (x y z:R) :R:=
x^2 + y^3 + z^4.
I expect function 3*(y^2) when I differentiate myFunc with y.
I know partial_derive in Coquelicot.
Definition partial_derive (m k : nat) (f : R → R → R) : R → R → R :=
fun x y ⇒ Derive_n (fun t ⇒ Derive_n (fun z ⇒ f t z) k y) m x.
partial_derive can partially differentiate f:R → R → R, but not possible for arbitrary number of arguments.
I thought about using dependent type listR.
Inductive listR :nat -> Type:=
|RO : Euc 0
|Rn : forall {n}, R -> listR n -> listR (S n).
Notation "[ ]" := RO.
Notation "[ r1 , .. , r2 ]" := (Rn r1 .. ( Rn r2 RO ) .. ).
Infix ":::" := Rn (at level 60, right associativity).
Fixpoint partial_derive_nth {n} (k:nat) (f : listR n -> R) (e:listR n): listR n -> R:=
k specifies argument number to differentiate.
We can not define partial_derive_nth like partial_derive because we can not specify the name of arguments of fun in recursion.
Please tell me how to partially differentiate functions which has arbitrary number of arguments.
For your function myFunc, you can write the partial derivative like so:
Definition pdiv2_myFunc (x y z : R) :=
Derive (fun y => myFunc x y z) y.
You can then prove that it has the value you expect for any choice of x, y, and z. Most of the proof can be done automatically, thanks to the tactics provided in Coquelicot.
Lemma pdiv2_myFunc_value (x y z : R) :
pdiv2_myFunc x y z = 3 * y ^ 2.
Proof.
unfold pdiv2_myFunc, myFunc.
apply is_derive_unique.
auto_derive; auto; ring.
Qed.
I am a bit surprised that the automatic tactic auto_derive does not handle a goal of the form Derive _ _ = _, so I have to apply theorem is_derive_unique myself.

How do I describe a multiplication of vectorized matrices?

I want to calculate a product of huge (specific) matrices. From a point complexity of view, the product should be taken the form of an elementwise expression.
I tried to "vectorize" the matrices with mxvec / vec_mx and calculate the product via one dimensional streams. But indices access was blocked by the term of enum ('I_p * 'I_q).
I want to know a nth value of enum ('I_p * 'I_q) because I want to decscribe a multiplication of matrices in the form of a primitive expression in an underlying field.
How do I do this? In particular, how do I prove this statement?
From mathcomp Require Import all_ssreflect.
Lemma nth_enum_prod p q (a : 'I_q) :
val a = index (ord0, a) (enum (prod_finType (ordinal_finType p.+1) (ordinal_finType q))).
I'm surprised you need to vectorize the matrices if your definition is point-wise, usually you should be able to define your result as \matrix_(i, j) op, for example the standard definition of matrix multiplication is:
\matrix_(i, k) \sum_j (A i j * B j k).
By the way, a quick "dirty" proof of your lemma is:
Lemma nth_enum_prod p q (a : 'I_q) : val a = index (#ord0 p, a) (enum predT).
Proof.
have /(_ _ 'I_q) pair_snd_inj: injective [eta pair ord0] by move => n T i j [].
have Hfst : (ord0, a) \in [seq (ord0, x2) | x2 <- enum 'I_q].
by move=> n; rewrite mem_map /= ?mem_enum.
rewrite enumT !unlock /= /prod_enum enum_ordS /= index_cat {}Hfst.
by rewrite index_map /= ?index_enum_ord.
Qed.
but indeed if you find yourself using this it means you are into a different kind of problem. I just posted it as an illustration on how to manipulate this kind of expressions.
edit: based on your comment, a more principled way to manipulate the above is to define a lemma about index and products; I've left the full proof as an exercise, but the outline is:
Lemma index_allpairs (T U : eqType) (x : T) (y : U) r s :
(* TODO: Some conditions are missing here *)
index (x,y) [seq (x,y) | x <- r , y <- s] =
size s * (index x r) + index y s.
Proof.
Admitted.
Lemma index_ord_allpairs p q (x : 'I_p) (y : 'I_q) :
index (x,y) [seq (x,y) | x <- enum 'I_p , y <- enum 'I_q] = q * x + y.
Proof. by rewrite index_allpairs ?mem_enum ?size_enum_ord ?index_enum_ord. Qed.
Lemma nth_enum_prod p q (a : 'I_q) : val a = index (#ord0 p, a) (enum predT).
Proof. by rewrite enumT unlock index_ord_allpairs muln0. Qed.

Equality of proof-carrying dependent functions in Coq

Suppose we have:
Require Import ZArith Program Omega.
Open Scope Z_scope.
Definition Z_to_nat (z : Z) (p : 0 <= z) : nat.
Proof.
dependent destruction z.
- exact (0%nat).
- exact (Pos.to_nat p).
- assert (Z.neg p < 0) by apply Zlt_neg_0.
contradiction.
Qed.
Now I would like to formulate something like this:
Lemma Z_to_nat_pred : forall x y p p', (Z_to_nat x p <= Z_to_nat y p')%nat <-> x <= y.
This doesn't seem quite right to me, because in x <= y, I can have negative x, y, and then I won't have proofs about their positivity. All in all, the dependent Z_to_nat seems extremely difficult to use. How does one formulate that it suffices to show x <= y to conclude (Z_to_nat x p <= Z_to_nat y p')%nat and the other way around?
I've given it a bash to inspect the way I could formulate the proof (although I am fairly sure it can't be proven with this formulation).
I've tried:
Lemma Z_to_nat_pred : forall x y p p',
(Z_to_nat x p <= Z_to_nat y p')%nat <-> x <= y.
Proof.
intros.
split; intros.
- dependent destruction x;
dependent destruction y; try easy; try omega.
Which leads me to the following goal:
p : positive
p0 : 0 <= Z.pos p
p' : 0 <= 0
H : (Z_to_nat (Z.pos p) p0 <= Z_to_nat 0 p')%nat
______________________________________(1/1)
Z.pos p <= 0
Could I here, for example, solve the goal by deriving contradiction from H, as Z.pos p cannot be <= 0? I can't really do much with the Z_to_nat definition.
here are several remarks that are related to your question:
In Coq when one defines functions using tactics and especially when we want to compute with, it is preferable to end the corresponding proof script with Defined., not Qed. (the notion at stake is "transparent definition" vs. "opaque definition", cf. the Coq ref man)
so if you replace Qed with Defined, the tactic simpl in H. will be applicable in your proof of Z_to_nat_pred
EDIT: another tactic that would have been useful in your goal is exfalso.
your function Z_to_nat is a partial function that takes a proof as argument. But in many practical cases, it is simpler to avoid dependent types, and just use a default value (making thus the function "total")
this latter strategy is already that of the two functions below that are available in the the standard library (that you have already imported with Require Import ZArith). These two functions can be viewed as two ways to define your function Z_to_nat in a non-dependently-typed way:
Print Z.abs_nat.
Z.abs_nat =
fun z : Z => match z with
| 0 => 0%nat
| Z.pos p => Pos.to_nat p
| Z.neg p => Pos.to_nat p
end
: Z -> nat
Print Z.to_nat.
Z.to_nat =
fun z : Z => match z with
| 0 => 0%nat
| Z.pos p => Pos.to_nat p
| Z.neg _ => 0%nat
end
: Z -> nat
Finally it appears that for each of these two functions, lemmas similar to yours are available in ZArith:
SearchAbout Z.abs_nat Z.le iff.
Zabs2Nat.inj_le: forall n m : Z, 0 <= n -> 0 <= m -> n <= m <-> (Z.abs_nat n <= Z.abs_nat m)%nat
Zabs2Nat.inj_lt: forall n m : Z, 0 <= n -> 0 <= m -> n < m <-> (Z.abs_nat n < Z.abs_nat m)%nat
SearchAbout Z.to_nat Z.le iff.
Z2Nat.inj_iff: forall n m : Z, 0 <= n -> 0 <= m -> Z.to_nat n = Z.to_nat m <-> n = m
Z2Nat.inj_le: forall n m : Z, 0 <= n -> 0 <= m -> n <= m <-> (Z.to_nat n <= Z.to_nat m)%nat
Z2Nat.inj_lt: forall n m : Z, 0 <= n -> 0 <= m -> n < m <-> (Z.to_nat n < Z.to_nat m)%nat
Best regards

Coq - Proving condition about elements of sequence in Ssreflect

I have a goal that looks like this:
x \in [seq (f v j) | j <- enum 'I_m & P v j] -> 0 < x
In the above, f is a definition generating a solution of an inequality depending on v, j and P v j is a predicate restricting j to indices which satisfy another inequality.
I have already proven that Goal : P v j -> (f v j > 0), but how can I use this to prove that it holds for any x in the sequence? I have found just a few relevant lemmas like nthP which introduce sequence manipulation, which I'm very unfamiliar with.
Thanks in advance!
You need to use the mapP lemma (that characterizes membership wrt map):
Lemma U m (P : rel 'I_m) f v x (hp : forall j, P v j -> f v j > 0) :
x \in [seq f v j | j <- enum 'I_m & P v j] -> 0 < x.
Proof. by case/mapP=> [y]; rewrite mem_filter; case/andP=> /hp ? _ ->. Qed.

Proving x >= a /\ x <= a -> x = a

How would one go about proving the following
Theorem T: forall x, a: nat, x >= a /\ x <= a -> x = a.
in Coq?
If you don't want to use the full power of omega, I would search the standard library for the antisymmetric property of <= using SearchPattern or SearchAbout (or google) and apply le_antisym.
If you want a proof without using lemmas from the library, go by induction on x and a.