Trying to prove the following lemma I got stuck. Usully theorems about lists are proven using induction, but I don't know where to move next.
I am trying to prove a statement, which is wrong. Therefore trying to prove it false. Here is lemma statement.Plz guide me in closing this sub-lemma.
Theorem list_length :
forall (l:list nat),
(length l =? 0) = false ->
(length l - length l =? 0) = false.
Proof.
intros. induction (length l).
simpl in *. apply H. simpl.
rewrite IHn0. auto. simpl in H.
The first problem is that forall (l:list nat),
(length l =? 0) = false ->
(length l - length l =? 0) = false is unprovable if you notice the case when the length of the list is 0, is actually true but to others cases is not.
If you're trying to prove the statement but it's wrong, so you just have to negate.
Theorem list_length :
forall (l:list nat),
~ (length l - length l =? 0) = false.
intros.
intro H.
(*now, do your magic here *)
By now, the proof is very trivial.
I will let you finish this proof now.
As you rightly noticed, the hypothesis I named abs in my version of the script is false and you should be able to derive anything from this. The only
difficulty is to make Coq see it.
You need to a theorem to explain that (something - something) is always 0. I give you the search command for this. Then, you have
to know that Coq will finish the proof using computation. Here, 0 =? 0 computes to true. Then abs modulo computation is true = false.
The tactic discriminate has been designed specifically to finish proofs in this case.
Search (?x - ?x).
Theorem index_val_0:
forall (l:list nat), (length l =? 0) = false ->
(length l - length l=?0)=false->
(index_value(length l - length l-1) l =? 0) = true.
Proof.
intros l lnnil abs.
Fail discriminate.
rewrite Nat.sub_diag in abs.
discriminate.
Qed.
Related
I defined even as:
Inductive even : nat -> Prop :=
| ev0: even O
| evSS: forall n, even n -> even (S (S n)).
But now I want to prove:
Lemma add1_diff (x: nat) : even (S x) = ~even x.
Can I prove:
even (S O) = (~ even O)
Thanks in advance.
You usually can't prove the equality of two Props. An equality in Prop means that the proof terms for a logical statement are equal. This is sometimes the case, but rarely. Here are a few examples:
Require Import PeanoNat.
Import Nat.
Inductive even : nat -> Prop :=
| ev0: even O
| evSS: forall n, even n -> even (S (S n)).
Example ex1 (n : nat) : (n >= 1) = (1 <= n).
Proof.
(* The proofs are equal because >= is defined in terms of <= *)
reflexivity.
Qed.
Example ex2: even (2+2) = even 4.
Proof.
(* The proofs are equal because 2+2 can be reduced to 4 *)
reflexivity.
Qed.
Example ex3 (n : nat) : even (2+n) = even (n+2).
Proof.
(* The proofs are equal because 2+n is equal to n+2 *)
rewrite add_comm.
reflexivity.
Qed.
Example ex4 (n : nat): even (S (S n)) = even n.
Proof.
(* The proofs cannot be equal, because the left side proof always
requires one evSS constructor more than the right hand side. *)
Abort.
For this reason one uses the equivalence of two Props, which is <->, rather than the equality. The equivalence of the last statement is provable:
Example ex4 (n : nat): even (S (S n)) <-> even n.
Proof.
split; intros H.
- inversion H.
assumption.
- constructor.
assumption.
Qed.
So to answer your question: the equality of the two statements is most likely not provable, but the equivalence is. In case you need help with that, please ask.
No, you cannot prove your goal: natively there is basically no way to prove equality of propositions. What you can do instead is to use propositional equivalence, rather than equality, that is prove
even (S 0) <-> ~ (even 0)
or more generally
Lemma add1_diff (x : nat) : even (S x) <-> ~ (even x)
I have natural number list. After reduction of one element from the list, I want to prove the following relation.
Theorem reduce_elements:forall (n:nat) (l:list nat),
(length (n :: l) =? 0) = false->
(length l =? 0) = false.
This statement does not hold:
Require Import Coq.Arith.Arith.
Theorem reduce_elements:forall (n:nat) (l:list nat),
(length (n :: l) =? 0) = false->
(length l =? 0) = false.
Admitted.
Goal False.
pose proof (reduce_elements 0 nil eq_refl).
simpl in H.
congruence.
Qed.
I've noticed you've come to Stack Overflow a few times asking help to prove false statements. I suggest you try to sketch those proofs on paper before trying to solve them with Coq: it will help you understand your problem better.
Im trying to prove the following lemma:
Inductive even : nat → Prop :=
| ev_0 : even 0
| ev_SS (n : nat) (H : even n) : even (S (S n)).
Lemma even_Sn_not_even_n : forall n,
even (S n) <-> not (even n).
Proof.
intros n. split.
+ intros H. unfold not. intros H1. induction H1 as [|n' E' IHn].
- inversion H.
- inversion_clear H. apply IHn in H0. apply H0.
+ unfold not. intros H. induction n as [|n' E' IHn].
-
Qed.
Here is what I got at the end:
1 subgoal (ID 173)
H : even 0 -> False
============================
even 1
I want coq to evaluate "even 0" to true and "even 1" to false. I tried simpl, apply ev_0 in H. but they give an error. What to do?
Answer to the title
simpl in H.
Real answer
The above code will not work.
The definition of even from the Logical Foundations book is:
Inductive even : nat → Prop :=
| ev_0 : even 0
| ev_SS (n : nat) (H : even n) : even (S (S n)).
even 0 is a Prop, not a bool. Looks like you're mixing up the types True and False and the booleans true and false. They're totally different things, and not interchangeable under Coq's logic. In short, even 0 does not simplify to true or True or anything. It is just even 0. If you want to show even 0 is logically true, you should construct a value of that type.
I don't remember which tactics are available at that point in LF, but here are some possibilities:
(* Since you know `ev_0` is a value of type `even 0`,
construct `False` from H and destruct it.
This is an example of forward proof. *)
set (contra := H ev_0). destruct contra.
(* ... or, in one step: *)
destruct (H ev_0).
(* We all know `even 1` is logically false,
so change the goal to `False` and work from there.
This is an example of backward proof. *)
exfalso. apply H. apply ev_0.
How do I prove a lemma like the following:
Require Import Coq.Lists.List.
Lemma len_seq_n : forall start n, length (seq start n)=n.
I tried
Proof.
induction n.
simpl. auto. simpl.
and at this point Coq gives me
1 subgoal
start, n : nat
IHn : length (seq start n) = n
______________________________________(1/1)
S (length (seq (S start) n)) = S n
I'm not sure how to proceed from there.
The problem is that your induction hypothesis is not general enough. You need the following statement instead:
IHn : forall start', length (seq start' n) = n
To obtain this hypothesis, simply generalize over start before doing induction on n with the revert tactic.
Proof.
intros start n.
revert start.
induction n.
(* Continue as previously *)
(Next time, please provide a complete example so that we can help you better. Your question was missing the definition of seq.)
I am trying to write an induction hypothesis specifically for proving properties of even numbers. I formulated and proved the following:
Theorem ind_hyp_on_evens:
forall (p : nat -> Prop),
(p 0 -> (forall n, p n -> p (S (S n))) ->
forall n, p (n + n)).
Proof.
intros p P0 P1.
intro n.
assert(p (n + n) /\ p (S (S (n + n)))).
induction n as [| n'].
split. unfold plus. assumption.
unfold plus.
apply (P1 0).
assumption.
destruct IHn' as [A B].
split.
rewrite <- plus_Snm_nSm.
rewrite -> ? plus_Sn_m.
assumption.
rewrite <- plus_Snm_nSm.
rewrite -> ? plus_Sn_m.
apply (P1 (S (S (n' + n')))).
assumption.
destruct H as [H1 H2].
assumption. Qed.
Despite the fact that it's proved, any attempt to use it results in the error message: "Error: Not the right number of induction arguments."
Can someone please tell me what is the problem with the induction hypothesis, or otherwise, how to apply it??
Thanks,
Mayer
I believe induction assumes that any induction principle that will be used has the
fixed form
forall ... (P : SomeType -> Type) ..., (* or ->Set or ->Prop *)
... ->
forall (v : SomeType), P v
Your ind_hyp_on_evens matches only P (plus n n) which seems to confuse induction.
If you have a suitable goal, say forall n, is_even (n+n), you can manually do the
steps that induction normally does and extend that to handle the special form.
intro n0; (* temp. var *)
pattern (n0 + n0); (* restructure as (fun x => (is_even x)) (n0+n0) *)
refine (ind_hyp_on_evens _ _ _ n0); (* apply ind. scheme *)
clear n0; [| intros n IHn ]. (* clear temp., do one 'intros' per branch *)
I don't know if it's possible to pack that up as a general helper tactic for any induction scheme, packing these steps up as a per-scheme Ltac tactic should work however.
You could consider writing an inductive predicate that describes even numbers (code not tested):
Inductive even : nat -> Prop :=
| evenO : even O
| evenSSn : forall n, even n -> even (S (S n))
.
Coq will generate the induction principle automatically.
You would have to prove that even n holds before being able to perform induction on the "evenness" of n.