Cannot rewrite subterm in Coq - coq

I have a proof in Coq where one of the hypothesis is:
H : m = pred q * n + (r + n)
And I have a proven lemma which states:
Lemma suma_conmutativa: forall m, forall n, m + n = n + m.
Where + is Notation for a function called suma that I defined:
Fixpoint suma (m:nat) (n:nat) : nat :=
match m with
| 0 => n
| S k => S (suma k n)
end.
Notation "m + n" := (suma m n).
For some reason when I try to rewrite suma_conmutativa with r n in H I get the following error:
Error: Found no subterm matching "r + n" in H.
However, there clearly is a subterm matching r + n in H. Why can't Coq find it?
Thank you.

I am not an expert of notations in Coq, but here is how I understand your problem.
Coq replaces the first occurrence of + with suma. suma binds its arguments to scope nat_scope. Classic notation + is bound to nat_scope and is prefered for the second occurrence of +.
The solution I propose is to bound your notation to nat_scope to completely hide the original notation. This gives:
Notation "m + n" := (suma m n) : nat_scope.

Related

First proof over Reals in Coq

I'm new to Coq. I've been working through Pierce's Logical Foundations. I'm stepping out-of-scope of the text into Real numbers and finding myself clueless. I thought I'd prove something easy so I wrote out some formulas for interest calculations. Now I'd like to prove my conversions are correctly written in my Theorem.
I have no idea how to proceed and am in need of hints and guides!!!
From Coq Require Import Reals.Reals.
Definition simple_compound (A r n m : R) : R :=
A * (Rpower (1 + r / m) (m * n)).
Definition continuous_compound (A r n: R) : R :=
A * (exp (r * n)).
Definition simple_to_continuous_interest (Rm n m: R) : R :=
m * ln (1 + Rm).
Definition continuous_to_simple_interest (Rc n m: R) : R :=
m * (exp (Rc / m) - 1).
(** Prove that given Rm n m, then Rc is m * ln (1 + Rm). *)
Theorem continuous_to_simple_works : forall (A Rc n m : R),
continuous_compound A Rc n = simple_compound A (continuous_to_simple_interest Rc n m) n m.
Proof.
intros A Rc n m.
unfold continuous_compound. unfold simple_compound. unfold continuous_to_simple_interest.
simpl. (** ... and I'm stuck. I would know how to do this algebraically but am clueless in Coq. *)
First, I suggest to unfold Rpower.
Second, a useful lemma is f_equal; it states that, to prove f a = f b, it suffices to prove a = b. (There is also a tactic with the exact same name, which will behave similarly.)
Third, you need to perform some algebraic simplifications. To do so, you can use replace foo with bar; as the name implies, it replaces all the occurrences of foo in the goal with bar and it requires you to prove bar = foo. This latter equality can then be discharged with the field tactic, which checks that two expressions are equal by using the rewriting rules of addition, multiplication, division.
Fourth, you should end up with a goal containing a subterm ln (exp baz). Obviously, you want to replace it with baz. You can use the command Search (ln (exp _)) to find the name of the corresponding lemma. It happens to be named ln_exp, so rewrite ln_exp will do the trick.

Coq: Nested(?) subtype defining nonzero rational numbers and their reciprocals

I tried to define the reciprocal of a nonzero rational number, imitating the answers in my another question. I tried to delay the proof, but it seems that I misunderstood.
The following is my code:
1) Integers: define z (= a - b) as a pair (a, b) which is in a setoid with the equiv rel (a, b) ~ (c, d) <-> a + d = b + c
Definition Z_eq (z w: integer): Prop :=
match z with
| (z1, z2) =>
match w with
| (w1, w2) => z1 + w2 = z2 + w1
end
end.
Add Parametric Relation:
integer Z_eq
reflexivity proved by Z_refl
symmetry proved by Z_symm
transitivity proved by Z_tran
as Z. (** proved; omitting the proof *)
(** addition, subtraction, negation, multiplication are well-defined as a morphism *)
Add Morphism Z_plus with signature Z_eq ==> Z_eq ==> Z_eq as Z_plus_morph.
(** etc. *)
2) Positive integers: {n : nat | 0 <? n }
(** as in answers of the previous question *)
Local Coercion is_true : bool >-> Sortclass.
Definition Z_pos: Set := {n : nat | 0 <? n }.
Definition Z_pos__N (p: Z_pos): nat := proj1_sig p.
Coercion Z_pos__N : Z_pos >-> nat.
Definition Z_pos__Z (p: Z_pos): integer := (proj1_sig p, 0).
Coercion Z_pos__Z : Z_pos >-> integer.
Definition Z_pos_plus : Z_pos -> Z_pos -> Z_pos.
intros [x xpos%Nat.ltb_lt] [y ypos%Nat.ltb_lt].
refine (exist _ (x + y) _).
now apply Nat.ltb_lt, Nat.add_pos_pos.
Defined.
Definition Z_pos_mult : Z_pos -> Z_pos -> Z_pos.
intros [x xpos%Nat.ltb_lt] [y ypos%Nat.ltb_lt].
refine (exist _ (x * y) _).
now apply Nat.ltb_lt, Nat.mul_pos_pos.
Defined.
Lemma Z_pos_mult_compat: forall p q: Z_pos, Z_pos__N (Z_pos_mult p q) = Z_pos__N p * Z_pos__N q.
Proof. now intros [x xpos] [y ypos]. Qed.
Definition ZP1: Z_pos.
refine (exist _ 1 _). easy.
Defined.
3) Nonzero integers: {z : integer | z <Z> Z0}
(** nonzero integer *)
Definition Z_nonzero: Set := {z : integer | z <Z> Z0}.
(* abs value of a nonzero integer as an obj of type Z_pos *)
Definition Z_nonzero_abs__Z_pos (z: Z_nonzero): Z_pos.
destruct z as [[z1 z2] z3].
exists ((z1 - z2) + (z2 - z1))%nat.
Admitted. (** proof ommited *)
(* multiplication b/w two nonzero integers *)
Definition Z_nonzero_mult (z w: Z_nonzero): Z_nonzero.
exists (proj1_sig z *Z proj1_sig w).
Admitted.
(* sign of n - m *)
Definition N_sgn_diff__Z (n m: nat): integer :=
if n >? m then Z1 else if n =? m then Z0 else -Z Z1.
(* sign of n - m *)
Definition Z_nonzero_sgn__Z (z: Z_nonzero): Z_nonzero.
destruct z as [[z1 z2] z3].
exists (N_sgn_diff__Z z1 z2).
Admitted.
4) Rational numbers: ( a // b ) (a: integer, b: Z_pos)
Inductive rational: Type :=
| prerat : integer -> Z_pos -> rational.
Notation "( x '//' y )" := (prerat x y).
(* equality *)
Definition Q_eq (p q: rational): Prop :=
match p with
| (p1 // p2) =>
match q with
| (q1 // q2) => (Z_mult p1 (Z_pos__Z q2)) =Z= (Z_mult (Z_pos__Z p2) q1)
end
end.
(* numerator of a rational *)
Definition Q_numerator (q: rational) :=
match q with
| (iq // rq) => iq
end.
(* nonzero rationals *)
Definition Q_nonzero: Set := {q : rational | Q_numerator q <Z> Z0}.
(* numerator and denominator *)
Definition Q_nonzero_numerator (q: Q_nonzero): Z_nonzero.
destruct q as [[q1 q2] q3].
exists q1.
simpl in q3. apply q3.
Qed.
Definition Q_nonzero_denominator (q: Q_nonzero): Z_pos.
destruct q as [[q1 q2] q3].
exact q2.
Qed.
Definition Q_recip (q: Q_nonzero): Q_nonzero.
exists ( proj1_sig (Z_nonzero_mult (Z_nonzero_sgn__Z (Q_nonzero_numerator q)) (Z_pos__Z_nonzero (Q_nonzero_denominator q))) // Z_nonzero_abs__Z_pos (Q_nonzero_numerator q) ).
Admitted. (* proved. *)
(* inherited equality *)
Definition Q_nonzero_eq (p q: Q_nonzero): Prop := (proj1_sig p) =Q= (proj1_sig q).
Add Morphism Q_recip with signature Q_nonzero_eq ==> Q_nonzero_eq as Q_recip_morph.
Proof. (* well-definedness of Q_recip *)
destruct x, y.
unfold Q_nonzero_eq. simpl. intros.
unfold Q_recip. (* <----- unfolded result was very long and complex; not simplified after simpl. *)
Abort.
I think this definitions are somewhat complex, but it was my best try...
Now, how can I prove the consistency of the morphism Q_recip?
(View full code)
I think you forgot to add the definition of Q_nonzero in your development, so I cannot run your code. However, I believe that the issue is that you have used Qed instead of Defined in some of your definitions. This question discusses the issue in more detail. (In any case, as Emilio points out, it is usually better to avoid definitions in proof mode, as they tend to be harder to reason about, as you've probably noticed.)
A note on style: your development mimics common definitions of number systems from first principles in set theory, where we often use equivalence classes to define the integers, the rational numbers, etc. Though elegant, this approach is often inconvenient to use in Coq. The main issue is that, because of the lack of proper quotient types, you are forced to use setoids everywhere, which prevents you from using Coq's much more convenient equality operator =. It is simpler to write these definitions as plain datatypes. For instance, you can define the integers as
Inductive int :=
| Posz : nat -> int
| Negz : nat -> int.
where Posz represents the canonical injection from natural numbers into integers, and Negz maps the natural number n to the integer - n - 1. This is the approach followed in the mathematical components library. Of course, the standard library also has its own definition of the integers (here), so you do not need to replicate it. Defining the rationals is more complicated, but it can still be done: in mathematical components, they are defined as pairs of coprime integers (num, den) such that den > 0 and num.

Pattern Matching with Even and Odd Cases

Suppose I write a Fixpoint algorithm in Coq that sums up all the "halves" of a number:
Fixpoint sum_of_halves (a : nat) : nat :=
match a with
| 0 => 0
| 2 * k => a + (sum_of_halves k)
| S (2 * k) => a + (sum_of_halves k)
end.
Trying to evaluate the algorithm would get: Error: Invalid notation for pattern.
How can I get Coq to recognize that a is either an even or an odd number, and match it with either 2 * k or S (2 * k)?
Coq can only match on constructors. nat has two constructors, O and S, so you cannot match on 2 * k. You will have to use a non-match construct or a non-nat type or a different algorithm.
You need to prove that there are only three cases for a given natural number a. Either a is 0, either a is the double of another number k and k < a, or a is the double k + 1 and k < a, that the three cases are exclusive (this is important, otherwise making pattern matching possible would lead to an inconistency).
Fortunately, all this can be done. It is a bit advanced Coq programming, but it is somehow already done in ZArith. Here is a solution.
First note that the other number is already provided by one of the functions in the Coq library, div2.
Require Import Arith Nat.
Definition cases_div2 (a : nat) :
{k : nat | a = 2 * k /\ k < a}+{k : nat | a = S (2 * k) /\ k < a}+{a=0}.
destruct a as [ | a'].
right; reflexivity.
case_eq (odd (S a')); intros odd_a.
left; right; exists (div2 (S a')); rewrite (div2_odd (S a')) at 1.
split.
rewrite odd_a; simpl b2n; ring.
apply lt_div2; auto with arith.
left; left; exists (div2 (S a')); rewrite (div2_odd (S a')) at 1.
split.
rewrite odd_a; simpl b2n; ring.
apply lt_div2; auto with arith.
Defined.
Now, you can pattern match on your number a using cases_div2, but it is still not enough to define your function, because recursion using Fixpoint relies on recursive calls happening on the predecessor, and here k cannot be written as a predecessor pattern that will work for any input a. You need a stronger kind of recursion. I usually rely on Function or Fix for this kind of strong recursion. Here is an example with Fix
Definition sum_of_halves : nat -> nat :=
Fix Arith.Wf_nat.lt_wf (fun _ => nat)
(fun a (sum_of_halves' : forall y, y < a -> nat) =>
match cases_div2 a with
| inright h => 0
| inleft (inl (exist _ k (conj keq klt))) =>
a + sum_of_halves' k klt
| inleft (inr (exist _ k (conj keq klt))) =>
a + sum_of_halves' k klt
end).
Then to reason about sum_of_halves you will need to reason by well founded induction and use Fix_eq.
This is one possibility.

How can I rewrite "+ 1" (plus one) to "S" (succ) in Coq?

I have the following Lemma with an incomplete proof:
Lemma s_is_plus_one : forall n:nat, S n = n + 1.
Proof.
intros.
reflexivity.
Qed.
This proof fails with
Unable to unify "n + 1" with "S n".
It seems like eq_S would be the way to prove this, but I can't apply it (it doesn't recognize n + 1 as S n: Error: Unable to find an instance for the variable y.). I've also tried ring, but it can't find a relation. When I use rewrite, it just reduces to the same final goal.
How can I finish this proof?
This is related to the way (+) is defined. You can access (+)'s underlying definition by turning notations off (in CoqIDE that's in View > Display notations), seeing that the notation (+) corresponds to the function Nat.add and then calling Print Nat.add which gives you:
Nat.add =
fix add (n m : nat) {struct n} : nat :=
match n with
| O => m
| S p => S (add p m)
end
You can see that (+) is defined by matching on its first argument which in n + 1 is the variable n. Because n does not start with either O or S (it's not "constructor-headed"), the match cannot reduce. Which means you won't be able to prove the equality just by saying that the two things compute to the same normal form (which is what reflexivity claims).
Instead you need to explain to coq why it is the case that for any n the equality will hold true. A classic move in the case of a recursive function like Nat.add is to proceed with a proof by induction. And it does indeed do the job here:
Lemma s_is_plus_one : forall n:nat, S n = n + 1.
Proof.
intros. induction n.
- reflexivity.
- simpl. rewrite <- IHn. reflexivity.
Qed.
Another thing you can do is notice that 1 on the other hand is constructor-headed which means that the match would fire if only you had 1 + n rather than n + 1. Well, we're in luck because in the standard library someone already has proven that Nat.add is commutative so we can just use that:
Lemma s_is_plus_one : forall n:nat, S n = n + 1.
Proof.
intros.
rewrite (Nat.add_comm n 1).
reflexivity.
Qed.
A last alternative: using SearchAbout (?n + 1), we can find all the theorems talking about the pattern ?n + 1 for some variable ?n (the question mark is important here). The first result is the really relevant lemma:
Nat.add_1_r: forall n : nat, n + 1 = S n

How to prove this simple equation in Coq

I want to prove in Coq that:
convert l' + 1 + (convert l' + 1) = convert l' + convert l' + 1 + 1
only some parentheses is redundant and do not let me use reflexivity command; so what should I do?
All of the elements are nat (Natural) type so as convert l' is a function that will return a nat number and I do not want to use some powerful tactics like Omega and so on.
Omega is very useful, as it quickly lets you continue with the more interesting parts of the proof, but when one is learning I personally find it helpful to see a "simpler" proof (the omega-generated proof terms tend to be very long and unreadable).
First note that you will need to use associativity and commutativity of plus. Use Coq's search facilities to find useful lemmas. Use _ as a wild card character. You can find lemmas that contain structures that look like associativity like this:
SearchAbout (_ + (_ + _)= (_ + _) + _).
locates five lemmas that contain, among others, this:
plus_assoc: forall n m p : nat, n + (m + p) = n + m + p
In the same way you can find the commutativity lemma with
SearchAbout (_ + _ = _ + _).
And here it is:
plus_comm: forall n m : nat, n + m = m + n
You cannot apply them directly, but instead you can use the rewrite tactic that lets you work on sub-parts of the terms. I recommend that you play around with it to get a feeling for how it works.
Here is a proof of the desired lemma.
Require Import Arith.
Lemma nat_lemma: forall n, n + 1 + (n + 1) = n + n + 1 + 1.
intro n.
repeat rewrite <- plus_assoc. (* n + (1 + (n + 1)) = n + (n + (1 + 1)) *)
rewrite (plus_comm 1 (n+1)). (* uses (1 + (n + 1) = (n + 1) + 1 *)
repeat rewrite plus_assoc.
reflexivity.
Qed.
Now use this lemma to prove your theorem.
You can use the omega tactic. Just do Require Import Omega. at the beginning of your file and you should be good to go.