Proving existance by providing an example - coq

If i have a Theorem of the form:
Theorem my_thm (n: nat -> nat): exists t: nat, n t = 0.
Admitted.
If I want to prove it for a function that is such that my_func 0 = 0, how can I tell coq that indeed there exists such t because my_func 0 = 0 ?
This does not have a deep goal but understand how existential proof works in coq.

You can add an argument, here P, that would assert that this property holds, and use it later on in your theorem, using the exists tactic. For instance (I'm using ssreflect, but I guess you'll get the idea):
Theorem my_thm (n: nat -> nat) (P : n 0 = 0) : exists u, n u = 0.
Proof.
exists 0.
exact: P.
Qed.
Of course, you can also change the theorem body to better suit your needs.

Related

How to add "assumed true" statements in Coq

I tried to add a definition of a natural number in CoqIDE.
Inductive nat : Set :=
| O: nat
| S: nat -> nat.
But I couldn't add this as "assumed true":
forall (n m: nat, S n = S m -> n = m).
How do I add this?
I'm not completely clear on what you want to do, but your formula is not syntactically correct. I believe you meant forall (n m: nat), S n = S m -> n = m (note the parenthesis' placement).
Your statement is actually provable, no need to assume it:
Lemma S_inj : forall (n m: nat), S n = S m -> n = m.
Proof. intros n m [=]. assumption. Qed.
The [=] intro pattern expresses the built-in injectivity of the S constructor.

Prove a constant is even

Given the inductive definition of evenness, how is it best proved that, say, 1024 is an even number?
Repeating apply even_S down to zero is certainly not the right approach.
As HTNW pointed out, you can use Ltac automation to produce such a proof. This has the disadvantage of producing a large proof term even_S (even_S ... even_O), thus slowing down proofs. In this case, it is better to reformulate the goal using a boolean decision procedure:
Fixpoint evenb (n : nat) : bool :=
match n with
| 0 => true
| 1 => false
| S (S m) => evenb m
end.
Lemma evenb_correct : forall n, evenb n = true <-> even n.
(* Fun exercise! *)
Coq can prove that evenb 1024 = true simply by evaluating the left-hand side:
Goal (even 1024). apply evenb_correct. reflexivity. Qed.
Repeating apply even_S is not the way. repeat apply even_S is. If even_S is a constructor, there's also repeat constructor.
Inductive even : nat -> Prop :=
| even_O : even O
| even_S : forall n, even n -> even (S (S n)).
Goal (even 1024). repeat apply even_S. exact even_O. Qed.
Goal (even 1024). repeat constructor. Qed. (* also finds even_O, would leave as goal otherwise *)

How to prove a theorem on natural numbers using Coq list

I'm new in Coq. To do practice on list and list of pairs, I used Coq list library to prove a simple theorem of natural numbers. I try to prove the simple property of natural numbers:
forall n, multiplier, a0....an, d1...dn:
((a0*multiplier)=d1)+((a1*multiplier)=d2)+((a2*multiplier)=d3)+...+((an*multiplier)=dn) = result
-> (a0+a1+a2+...+an) * multiplier = d1+d2+...+dn = result
((3*2)=6)+((5*2)=10)+((9*2)=18) = 34 -> (3+5+9)*2 = 6+10+18 = 34 can be an example of this property(i.e. n=3 and multiplier = 2).
I use list of pairs (storing a's in one list and d's in another list) to code this property in Coq as:
Require Import List.
Fixpoint addnumbers (L : list nat) : nat :=
match L with
| nil => 0
| H::tail => H + addnumbers tail
end.
Theorem resultAreEqual : forall (natListofpair :list (nat * nat))
(multiplier : nat) (result : nat),
Forall (fun '(a,d) => a * multiplier = d ) natListofpair ->
addnumbers(List.map (#fst nat nat) natListofpair) * multiplier = result ->
addnumbers (List.map (#snd nat nat) natListofpair) = result.
Proof.
intros.
destruct natListofpair.
subst. simpl. reflexivity.
rewrite <- H0.
inversion H.
destruct p. simpl.
But I don't know how I should continue this prove. I'm stuck in this proving for one week. I'd be thankful for your help.
One reason you are having difficulty is that you have stated your lemma in an indirect way. When proving something in Coq, it is very important that you state it as simple as possible, as this often leads to easier proofs. In this case, the statement can become much simpler by using higher-order functions on lists.
Require Import Coq.Arith.PeanoNat.
Require Import Coq.Lists.List.
Definition sum (l : list nat) := fold_right Nat.add 0 l.
Lemma my_lemma l m : sum (map (Nat.mul m) l) = m * sum l.
The sum function is the equivalent of your addnumbers. The lemma says "the result of multiplying all numbers in l by m and adding them is the same as the result of adding them up first and multiplying by m later".
To prove this result, we need a crucial ingredient that your proof was missing: induction. This is often needed in Coq when we want to reason about objects of unbounded size, such as lists. Here is one possible proof.
Proof.
unfold sum.
induction l as [|x l IH]; simpl.
- (* Nil case *)
now rewrite Nat.mul_0_r.
- (* Cons case *)
now rewrite IH, Nat.mul_add_distr_l.
Qed.

How to check equality of pairs

I want to prove the following theorem on two pairs of type TR:
Definition s:= nat.
Definition d:= nat.
Definition c:= nat.
Definition p:= nat.
Inductive rt: Set :=
|al : rt
|bl : rt.
Definition TR: Set :=
rt* s*d* c* p.
Implicit Types m n : TR.
Theorem eq_TR_dec : forall n m, {n = m} + {n <> m}.
For now, the proof of this theorem begins by intros n. destruct n. destruct m. But I cannot figure out the best tactic to prove this theorem. Any idea how should I prove this theorem? Thank you
As mentionned in the comments, you can use decide equality which basically solve these goals (check the documentation here to learn more).
In this case, just apply it as many times as needed and it works :
Theorem eq_TR_dec : forall n m, {n = m} + {n <> m}.
Proof.
decide equality.
- decide equality.
- decide equality.
* decide equality.
* decide equality.
+ decide equality.
+ {
decide equality.
- decide equality.
- decide equality.
}
Qed.
or more simply using the repeat tactic (as also mentionned in eponier's comment), which basically applies (reccursively in the subgoal generated) the tactic you give it until it fails:
Theorem eq_TR_dec : forall n m, {n = m} + {n <> m}.
Proof.
repeat decide equality.
Qed.
As we saw in the first case, here you only need to solve apply decide equality enough times, so repeat is particularly efficient !

How to apply theorems for definitions with restrictions in coq

I found a number of examples of definitions with restrictions in coq. Here is for example a variation of the pred function:
Lemma Lemma_NotZeroIsNotEqualToZero : ~ 0 <> 0.
Proof.
omega.
Qed.
Definition pred (s : { n : nat | n <> 0 }) : nat :=
match s with
| exist 0 pf => match (Lemma_NotZeroIsNotEqualToZero pf) with end
| exist (S n') _ => n'
end.
But I don't actually understand how to use this definition. Suppose I want to use pred for some natural number and I proved that this number is not zero. Like, for instance, suppose I proved the following lemma:
Lemma Lemma_TenIsNotEqualToZero : 10 <> 0.
Proof.
omega.
Qed.
Now, I want to compute what in essence is "pred 10" using Lemma_TenIsNotEqualToZero:
Eval compute in (pred ??).
How to do it?
pred is a function taking a sig type (try to Print sig.). Simply put, it's an inductive type with one constructor stating that "there exists an x of type A such that P x is true".
If you want to create a term of type {n : nat | n <> 0}, you will have to build it using constructors, like any other inductive type. In your case:
Eval compute in (pred (exist 10 Lemma_TenIsNotEqualToZero)).
It is the exact same syntax you used to pattern match on the s argument of pred.
Hope it helps,
V
PS: using omega for both your proofs is really overkill...
Lemma Lemma_NotZeroIsNotEqualToZero : ~ 0 <> 0.
Proof.
intro h.
apply h; reflexivity.
Qed.
Lemma Lemma_TenIsNotEqualToZero : 10 <> 0.
Proof.
intro h.
discriminate h.
Qed.
Edit: exists takes 3 arguments in practice (use Print to get a clear idea what are they used for). Depending on the status of implicit types, you should write
exists _ 10 Lemma_TenIsNotEqualToZero
with the additional _.