If I define multiplication like this (drugi_c), how do I prove e.g. X*0=0?
(How to prove something by the definition?)
Fixpoint drugi_c(x y: nat): nat:=
match x, y with
| _, O => O
| O, _ => O
| S O, _ => y
| _,S O => x
| S x', S y' => plus y (drugi_c x' y)
end.
Notation "x * y" := (drugi_c x y) (at level 40, left associativity).
Whenever I use "simpl." in proofs instead of 0 = 0, i get the definition in result.
Lemma neka2 x:
x * 0 = 0.
Proof.
induction x.
-simpl. reflexivity.
-simpl. (*right here*)
Abort.
Result after the last simpl.
1 subgoal
x : nat
IHx : x * 0 = 0
______________________________________(1/1)
match x with
| 0 | _ => 0
end = 0
What to write after that last simpl. to finish the proof?
Your goal has a pattern match on x, but no matter what value x is it will return 0. To force this to simplify, you can destruct x.
Note that you never use the inductive hypothesis here, so you could have done destruct x at the beginning instead of induction x.
Here is what i end up getting:
Lemma neka2 x:
x * 0 = 0.
Proof.
destruct x.
-simpl. reflexivity.
-simpl. (**)
Abort.
Result:
1 subgoal
x : nat
______________________________________(1/1)
x * 0 = 0
I guess you have to prove it with induction because same thing happens when I try to destruct x with predefined mult as well.
Here is x*0=0 proof but with predefined mult:
Theorem mult_0_r : forall n:nat,
n * 0 = 0.
Proof.
intros n.
induction n as [|n'].
Case "n = 0".
simpl.
reflexivity.
Case "n = S n'".
simpl.
rewrite -> IHn'.
reflexivity.
Qed.
As #user138737 pointed out, you don't need induction. It is sufficient to explore three cases : x = 0, x = 1 and x = S (S x')). The shortest proof I can come with is thus the following.
destruct x as [| [|] ]; reflexivity.
Related
Fixpoint num_occ (x : nat)(xs : list nat) : nat :=
match xs with
| [] => 0
| (y :: ys) => if eq_dec x y
then 1 + num_occ x ys
else num_occ x ys
end.
Theorem exercise2
: forall x xs, num_occ x xs <= length xs.
Proof.
I tried, but i have no idea of how can i prove that, i am iniciating in this language....
i tried this:
intros x xs.
induction xs.
simpl.
reflexivity.
case 1.
simpl.
destruct x.
simpl.
and show this:
2 goals
x, n : nat
______________________________________(1/2)
0 = n
______________________________________(2/2)
num_occ x (n0 :: l) = n
I think case 1 is not necessary. Try this:
Theorem exercise2
: forall x xs, num_occ x xs <= length xs.
Proof.
intros x xs. induction xs; simpl.
- reflexivity.
- destruct (eq_dec x a).
+ apply le_n_S. assumption.
+ apply le_le_succ_r. assumption.
Qed.
I am close to ending the proof for Z_3 left id. Here is what I have so far
Require Import Coq.Arith.PeanoNat.
Require Import Coq.Bool.Bool.
Require Import Coq.Logic.Eqdep_dec.
Record Z_3 : Type := Z3
{
n :> nat;
proof : (Nat.ltb n 3) = true
}.
Proposition lt_0_3 : (0 <? 3) = true.
Proof.
simpl. reflexivity.
Qed.
Definition z3_0 : Z_3 := (Z3 0 lt_0_3).
Proposition lt_1_3 : (1 <? 3) = true.
Proof.
reflexivity.
Qed.
Definition z3_1 : Z_3 := (Z3 1 lt_1_3).
Proposition lt_2_3 : (2 <? 3) = true.
Proof.
reflexivity.
Qed.
Definition z3_2 : Z_3 := (Z3 2 lt_2_3).
Proposition three_ne_0 : 3 <> 0.
Proof.
discriminate.
Qed.
Lemma mod_upper_bound_bool : forall (a b : nat), b <> O -> (a mod b <? b) = true.
Proof.
intros a b H. apply (Nat.mod_upper_bound a b) in H. case Nat.ltb_spec0.
- reflexivity.
- intros Hcontr. contradiction.
Qed.
Definition Z3_op (x y: Z_3) : Z_3 :=
let a := (x + y) mod 3 in
Z3 a (mod_upper_bound_bool _ 3 three_ne_0).
Lemma Z3_eq n m p q : n = m -> Z3 n p = Z3 m q.
Proof.
intros H. revert p q. rewrite H. clear H. intros. apply f_equal. apply UIP_dec. apply bool_dec.
Qed.
Proposition Z3_left_id' : forall x: Z_3, (Z3_op z3_0 x) = x.
Proof.
intro. unfold Z3_op. destruct x as [n proof]. apply Z3_eq.
Result:
1 subgoal (ID 46)
n : nat
proof : (n <? 3) = true
============================
(z3_0 + {| n := n; proof := proof |}) mod 3 = n
I found the following theorems that could be useful:
Nat.ltb_spec0
: forall x y : nat, reflect (x < y) (x <? y)
Nat.mod_small: forall a b : nat, a < b -> a mod b = a
Is it possible to get rid of profs in the goal, convert proof from bool to Prop, and then use Nat.mod_small?
Update
Proposition Z3_left_id' : forall x: Z_3, (Z3_op z3_0 x) = x.
Proof.
intro. unfold Z3_op. destruct x as [vx proof]. apply Z3_eq. unfold n, z3_0. rewrite plus_O_n. apply Nat.mod_small.
1 subgoal (ID 67)
vx : nat
proof : (vx <? 3) = true
============================
vx < 3
You need the coercion to execute. Unfortunately,
by naming the bound variable of your proof n and the projection from Z_3 to nat n, you painted yourself in a corner.
Here are four solutions:
1/ this one I mention just for the record: you can talk about the constant n that was defined in this file by using the file name as a module qualifier.
unfold user4035_oct_16.n.
user4035_oct_16 is the name of the current file, this is ugly.
2/ you could call a computation function that computes everything, however computation of modulo leaves unsightly terms in the goal, so you could decide to not compute that particular part.
cbn -[Nat.modulo].
I like this one, but it requires that you spend sometime learning how to use cbn.
3/ You can avoid the name clash by renaming variables in the goal.
rename n into m.
unfold n, Z3_0.
Not very nice either.
4/ Just go back in your script and replace destruct x as [n proof] with destruct x as [vx proof], then you can type:
unfold n, z3_0.
you will be able to use the lemmas you suggest.
Proof:
Proposition Z3_left_id : forall x: Z_3, (Z3_op z3_0 x) = x.
Proof.
intro. unfold Z3_op. destruct x as [vx proof]. apply Z3_eq. unfold n, z3_0. rewrite plus_O_n. apply Nat.mod_small. apply Nat.ltb_lt in proof. assumption.
Qed.
I want to write a function that calculate count of true values of p 0 .. p t in a nat->prop function.
Section count_sc.
Variable p:nat->Prop.
Hypothesis p_dec:forall x:nat , {p x} + { ~ p x }.
Fixpoint count (x : nat) :=
match x with
| 0 => if p_dec(0) then 1 else 0
| S y => if p_dec(x) then 1+count y else count y
end.
End count_sc.
Definition fret (x:nat) := False.
Check count.
Axiom fret_dec : forall x : nat , { fret x } + { ~ fret x }.
Theorem hello_decide : forall x : nat , count fret fret_dec x = 0.
Proof.
intros.
induction x.
unfold count.
replace (fret_dec 0) with false.
Qed.
Before the replace tactic i should proof some goal like this:
(if fret_dec 0 then 1 else 0) = 0
Coq dose not automaticly compute the value of the if statement. and if i try to replace the fret_dec with it's value, i will get this error:
Error: Terms do not have convertible types.
How i can write count function that i can unfold and use it in theorems?
You have declared fret_dec as an axiom. But that means it does not have a definition, or implementation in other words. Thus, Coq cannot compute with it.
You can still prove your theorem like so, using the destruct tactic:
Theorem hello_decide : forall x : nat , count fret fret_dec x = 0.
Proof.
induction x as [| x IH].
- unfold count. destruct (fret_dec 0) as [contra | _].
+ contradiction.
+ reflexivity.
- simpl. rewrite IH. destruct (fret_dec (S x)) as [contra | _].
+ contradiction.
+ reflexivity.
Qed.
But, in this case it is really easy to provide such a decision procedure instead of postulating it. And this simplifies the proof a lot:
Definition fret_dec' (x : nat) : { fret x } + { ~ fret x }.
Proof. right. intros contra. contradiction. Defined.
Theorem hello_decide' : forall x : nat , count fret fret_dec' x = 0.
Proof.
induction x as [|x IH]; simpl.
- reflexivity.
- exact IH.
Qed.
I'm a beginner with Coq so maybe my question will seems to be a dumb question, but here is my problem :
I defined a simple module in which I defined a type T and a function "my_custom_equal" :
Definition T := nat.
Fixpoint my_custom_equal (x y : T) :=
match x, y with
| O, O => true
| O, S _ => false
| S _, O => false
| S sub_x, S sub_y => my_custom_equal sub_x sub_y
end.
Lemma my_custom_reflex : forall x : T, my_custom_equal x x = true.
Proof.
intros.
induction x.
simpl.
reflexivity.
simpl.
rewrite IHx.
reflexivity.
Qed.
Lemma my_custom_unicite : forall x y : T, my_custom_equal x y = true -> x = y.
Proof.
intros.
induction x.
induction y.
reflexivity.
discriminate.
Qed.
As you can see, it is not really complicated but I still got stuck on the my_custom_unicite proof, I always reach the point where I need to prove that "S x = y" and my hypothesis are only :
y : nat
H : my_custom_equal 0 (S y) = true
IHy : my_custom_equal 0 y = true -> 0 = y
______________________________________(1/1)
S x = y
I don't understand how to achieve this proof, could you help me ?
Thanks!
This is a typical trap for beginners. The problem is that you performed induction on x when y was already introduced in your context. Because of that, the induction hypothesis that you obtain is not sufficiently general: what you really want is to have something like
forall y, my_custom_equal x y = true -> x = y
Notice the extra forall. The solution is to put y back into your goal:
Lemma my_custom_unicite : forall x y, my_custom_equal x y = true -> x = y.
Proof.
intros x y. revert y.
induction x as [|x IH].
- intros []; easy.
- intros [|y]; try easy.
simpl.
intros H.
rewrite (IH y H).
reflexivity.
Qed.
Try running this proof interactively and check how the induction hypothesis changes when you reach the second case.
I am not sure whether I am using the right words in the question title, so here is the code:
Lemma In_map_iff :
forall (A B : Type) (f : A -> B) (l : list A) (y : B),
In y (map f l) <->
exists x, f x = y /\ In x l.
Proof.
intros A B f l y.
split.
- intros.
induction l.
+ intros. inversion H.
+ exists x.
simpl.
simpl in H.
destruct H.
* split.
{ apply H. }
{ left. reflexivity. }
* split.
A : Type
B : Type
f : A -> B
x : A
l : list A
y : B
H : In y (map f l)
IHl : In y (map f l) -> exists x : A, f x = y /\ In x l
============================
f x = y
Basically, there is not much to go on with this proof, I can only really use induction on l and after substituting for x in the goal I get the above form. If IHl had a forall instead of exists maybe I could substitute something there, but I am not sure at all what to do here.
I've been stuck on this one for a while now, but unlike the other problems where that has happened, I could not find the solution online for this one. This is a problem as I am going through the book on my own, so have nobody to ask except in places like SO.
I'd appreciate a few hints. Thank you.
Lemma In_map_iff :
forall (A B : Type) (f : A -> B) (l : list A) (y : B),
In y (map f l) <->
exists x, f x = y /\ In x l.
Proof.
intros A B f l y.
split.
- intros.
induction l.
+ intros. inversion H.
+ simpl.
simpl in H.
destruct H.
* exists x.
split.
{ apply H. }
{ left. reflexivity. }
* destruct IHl.
-- apply H.
-- exists x0.
destruct H0.
++ split.
** apply H0.
** right. apply H1.
- intros.
inversion H.
induction l.
+ intros.
inversion H.
inversion H1.
inversion H3.
+ simpl.
right.
apply IHl.
* inversion H.
inversion H0.
inversion H2.
exists x.
split.
-- reflexivity.
-- destruct H3.
A : Type
B : Type
f : A -> B
x0 : A
l : list A
y : B
H : exists x : A, f x = y /\ In x (x0 :: l)
x : A
H0 : f x = y /\ In x (x0 :: l)
IHl : (exists x : A, f x = y /\ In x l) ->
f x = y /\ In x l -> In y (map f l)
x1 : A
H1 : f x1 = y /\ In x1 (x0 :: l)
H2 : f x = y
H3 : x0 = x
H4 : f x = y
============================
In x l
I managed to do one case, but am now stuck in the other. To be honest, since I've already spent 5 hours on a problem that should need like 15 minutes, I am starting to think that maybe I should consider genetic programming at this point.
H can be true on two different ways, try destruct H. From that, the proof follows easily I think, but be careful on the order you destruct H and instantiate the existential thou.
Here is a proof that has the same structure as would have a pen-and-paper proof (at least the first -> part). When you see <tactic>... it means ; intuition (because of Proof with intuition. declaration), i.e. apply the intuition tactic to all the subgoals generated by <tactic>. intuition enables us not to do tedious logical deductions and can be replaced by a sequence of apply and rewrite tactics, utilizing some logical lemmas.
As #ejgallego pointed out the key here is that while proving you can destruct existential hypotheses and get inhabitants of some types out of them. Which is crucial when trying to prove existential goals.
Require Import Coq.Lists.List.
Lemma some_SF_lemma :
forall (A B : Type) (f : A -> B) (l : list A) (y : B),
In y (map f l) <->
exists x, f x = y /\ In x l.
Proof with intuition.
intros A B f l y. split; intro H.
- (* -> *)
induction l as [ | h l'].
+ (* l = [] *)
contradiction.
+ (* l = h :: l' *)
destruct H.
* exists h...
* destruct (IHl' H) as [x H'].
exists x...
- (* <- *)
admit.
Admitted.