Position of elements in list - coq

I am using index function to find the value of element at any location in the list nat. Plz guide me in proving the second part of the lemma, which is illustrated below
Fixpoint index(n: nat) (m: nat) (l: list nat) : nat :=
match l with
| nil => 0
| cons h tl => match (eqb n m) with
| true => h
| false => index (succ n) m tl
end
end.
Theorem a_ref:forall (a:nat),
a <= a.
Proof.
intros. eauto.
Qed.
Theorem n_leq_0 :forall (n:nat),
n <= 0.
Proof.
intros. induction n.
+ simpl. apply a_ref.
+ Admitted.
Theorem n_le_index:forall (n:nat) (l:list nat),
n <= index (succ (succ 0)) 0 l.
Proof.
intros. induction l as [| l'].
+ simpl. apply n_leq_0.
+ simpl in *. inversion IHl.
rewrite <- H.

The theorem you want cannot be proved:
Fixpoint index(n: nat) (m: nat) (l: list nat) : nat :=
match l with
| nil => 0
| cons h tl => match (Nat.eqb n m) with
| true => h
| false => index (Nat.succ n) m tl
end
end.
Theorem n_le_index:forall (n:nat) (l:list nat),
n <= index (Nat.succ (Nat.succ 0)) 0 l.
Admitted.
Require Import Omega.
Goal False.
pose proof (n_le_index 10 nil).
simpl in H.
omega.
Qed.

Related

Can't find a way to 'reverse' a constructor

I try to prove the following simple Lemma :
Lemma wayBack :
forall (a b n:nat) (input:list nat), a <> n -> implist n (a::b::input) -> implist n input.
were implist is as follows :
Inductive implist : nat -> list nat -> Prop :=
| GSSingle : forall (n:nat), implist n [n]
| GSPairLeft : forall (a b n:nat) (l:list nat), implist n l -> implist n ([a]++[b]++l)
| GSPairRight : forall (a b n:nat) (l:list nat), implist n l -> implist n (l++[a]++[b]).
Any idea how to do this ?
Thank you !!
Here it is:
Require Import Program.Equality.
Lemma wayBack :
forall (a b n:nat) (input:list nat), a <> n -> implist n (a::b::input) -> implist n input.
Proof.
intros.
dependent induction H0.
1: eassumption.
assert (exists l', l = a :: b :: l' /\ input = l' ++ [a0 ; b0]) as [l' [-> ->]].
{
clear - x H0 H.
change (l ++ [a0] ++ [b0]) with (l ++ [a0; b0]) in x.
remember [a0; b0] as t in *.
clear Heqt.
induction H0 in input, t, x, H |- *.
+ cbn in *.
inversion x ; subst.
now destruct H.
+ cbn in *.
inversion x ; subst ; clear x.
eexists ; split.
1: reflexivity.
reflexivity.
+ cbn in x.
rewrite <- app_assoc in x.
edestruct IHimplist as [? []] ; try eassumption.
subst.
eexists ; split.
cbn.
2: rewrite app_assoc.
all: reflexivity.
}
econstructor.
eapply IHimplist ; try eassumption.
reflexivity.
Qed.
There are two main difficulties here: the first is that you want to do an induction on you hypothesis implist n (a::b::input), but since a::b::input is not just a variable, there is a need for some fiddling, that standard induction cannot do, but dependent induction from Program can.
The second difficulty, which actually takes up most of my proof, is to be able to decompose the equality you get in the last case, that where you add values at the beginning rather than at the end of the list.

Append and Split is same as doing nothing

I want to prove following lemmas.
Lemma AppendAndSplit {n m}(e:Euc n) (f:Euc m): # (e +++ f) = (e, f).
Proof.
induction e.
reflexivity.
remember (r:::e).
Admitted.
Lemma SplitRule {n m}(e:Euc (n+m)) : (fst (# e)) +++ (snd (# e)) = e.
Proof.
induction n.
reflexivity.
Admitted.
# and +++ are notations of EucAppend and Split_Euc.
I can feel that these hold, but I don't know how prove them.
Please tell me some techniques.
(* There are codes needed below *)
Require Import Coq.Reals.Reals.
Inductive Euc:nat -> Type:=
|RO : Euc 0
|Rn : forall {n:nat}, R -> Euc n -> Euc (S n).
Notation "[ ]" := RO.
Notation "[ r1 , .. , r2 ]" := (Rn r1 .. ( Rn r2 RO ) .. ).
Infix ":::" := Rn (at level 60, right associativity).
Fixpoint EucAppend {n m} (e:Euc n) (f:Euc m) :Euc (n+m):=
match e with
|[] => f
|e' ::: es => e' ::: (EucAppend es f)
end.
Infix "+++" := EucAppend (at level 60, right associativity).
Fixpoint split_Euc {n m : nat} (xi : Euc (n + m)) : Euc n ∧ Euc m.
Proof.
destruct n as [ | n].
- exact (RO, xi).
- inversion_clear xi.
apply split_Euc in H0 as [l r].
exact (Rn H l, r).
Defined.
Notation "# n" := (split_Euc n) (at level 60, right associativity).
The main problem you cannot solve your goals is because of the definitional problem. Split_Euc is defined to perform induction on n, and that's okay however, the definitions perform an inversion on Euc. Inversion is normally a tactic for proofs, once the tactics generate very heavy proofs terms :
Fixpoint split_Euc {n m : nat} (xi : Euc (n + m)) : Euc n * Euc m.
Proof.
destruct n as [ | n].
- exact (RO, xi).
- inversion_clear xi.
Show Proof. (* let see what is actually the problem *)
...
Defined.
You'll see something like that :
eq_rec_r (fun n2 : nat => R -> Euc n2 -> Euc (S n0) * Euc m)
(fun (H6 : R) (H7 : Euc (n0 + m)) =>
?Goal#{n:=n0; H:=H6; H0:=H7}) H5) H3) H1 H H0
Notice your definition uses a proof (induction scheme of equality) term to make the join of the tuple. Proofs terms are not easily normalized and some others don't even get a normalized term (it is the case of Opaque proofs). The solution is to avoid tactics that generate heavy proofs terms and substitute for inductions schemes (like destruct, induction, case...), once they are "free" or almostt of automatic proofs.
Definition rect_euc {n : nat} (v : Euc (S n)) : forall (P : Euc (S n) -> Type) (H : forall ys a, P (a ::: ys)), P v.
refine (
match v with
|#Rn _ _ _ => _
|R0 => _
end).
exact idProp.
intros.
apply : H.
Defined.
Fixpoint split_Euc {n m : nat} (xi : Euc (n + m)) : Euc n * Euc m.
Proof.
destruct n as [ | n].
- exact (RO, xi).
- elim/#rect_euc : xi.
intros.
pose (split_Euc _ _ ys).
exact (Rn a (fst p), (snd p)).
Defined.
Now, as split_euc is defined using induction on n, you should do the same to get a straightforward proof.
Lemma AppendAndSplit {n m}(e:Euc n) (f:Euc m): # (e +++ f) = (e, f).
Proof.
induction n.
- remember 0.
destruct e.
reflexivity.
inversion Heqn.
- apply (rect_euc e).
intros.
assert (forall n (xs ys : Euc n) (x y : R), x = y -> xs = ys -> x ::: xs = y ::: ys).
intros.
rewrite H; rewrite H0; trivial.
pose (IHn ys).
apply : injective_projections.
simpl;apply : H; trivial.
exact (f_equal fst e0).
exact (f_equal snd e0).
Qed.
Lemma SplitRule {n m}(e:Euc (n+m)) : (fst (split_Euc e)) +++ (snd (split_Euc e)) = e.
YOUR_TURN. (* now it's your turn, just do the same and u will get the goal*)
Qed.

Conversion from not equal to equal in nat

I have function,whose output is some natural number.I have proved a lemma,that output of this function cannot be zero. It means output is equal to some natural number S m.I want to convert the above lemma.
Theorem greater:forall (m :nat)(l:list nat),
m=?0=false ->
0=? (f1 + m)=false->
(f1 + m)= S m.
The statement you entered does not type check. Regardless, I don't see how it could hold -- for instance, if by l you mean f1 : nat, then the statement would imply that 3 = 2.
Require Import Coq.Arith.Arith.
Theorem greater:forall (m :nat)(f1:nat),
m=?0=false ->
0=? (f1 + m)=false->
(f1 + m)= S m.
Admitted.
Lemma contra : False.
Proof.
pose proof (greater 1 2 eq_refl eq_refl).
easy.
Qed.
Proving that something that is not zero is a successor can be done as follows:
Require Import Coq.Arith.Arith.
Lemma not_zero_succ :
forall n, n <> 0 ->
exists m, n = S m.
Proof. destruct n as [|n]; eauto; easy. Qed.
Edit The complete statement you wrote below is also contradictory:
Require Import Coq.Arith.Arith.
Require Import Coq.Lists.List.
Import ListNotations.
Fixpoint lt_numb (n: nat) (l: list nat) : nat :=
match l with
| nil => 0
| h::tl =>
if h <? n then S (lt_numb n tl) else lt_numb n tl
end.
Fixpoint greatest (large: nat) (l: list nat) : nat :=
match large with
| O => 0
| S m' => (lt_numb large l) + (greatest m' l)
end.
Definition change (n: nat) (l: list nat) : list nat :=
match l with
| nil => l
| h::tl => if n <? h then l else n::tl
end.
Fixpoint g_value (elements: nat) (l: list nat) : nat :=
match l with
| nil => 0
| [n] => n
| h :: l =>
match elements with
| O => h
| S elements' => g_value elements' (change h l)
end
end.
Theorem no_elements : forall (m n z :nat)(l:list nat),
m=?0=false -> greatest(g_value (length (n :: l)) (n :: l) + m) (n :: l) = (S z).
Proof. Admitted.
Goal False.
pose proof (no_elements 1 0 1 [] eq_refl).
simpl in H.
discriminate.
Qed.

How to find value at different indexes

I have defined a function, which finds the greatest value from the natural number list and move this value to head position of the list. I am sure, all the elements in the list are less or equal to the value at head location. Then I defined index_value function,to find value in the list at any index.For clarification [4,7,11,9,11] list become [11,7,9,11].I have a problem in proving the following lemma. Plz guide me.
` Require Import Coq.Arith.PeanoNat.
Require Import Lia.
Fixpoint index_value (index: nat) (l: list nat) : nat :=
match l with
| nil => 0
| cons h t => match (Nat.eqb index 0) with
| true => h
| false => index_value (index - 1) t
end
end.
Theorem head_value : forall ( n':nat) (l:list nat),
(index_value 0 l)<= n'.
Proof.
Admitted.
Theorem index_value1:forall (n s2:nat) (l:list nat),
index_value (S s2) (n :: l) <=
index_value 0 (n :: l) \/
index_value (S s2) (n :: l) > 0.
Proof.
intros. simpl in *. left . induction s2. simpl.
appply head_value . simpl in *. auto with arith.`
I think your statements do not quite mean what you think they mean. The first one is contradictory, and the second one is trivial: you do not need the definition of index_value at all:
Require Import Coq.Arith.PeanoNat.
Require Import Lia.
Require Import Coq.Lists.List.
Import ListNotations.
Fixpoint index_value (index: nat) (l: list nat) : nat :=
match l with
| nil => 0
| cons h t => match (Nat.eqb index 0) with
| true => h
| false => index_value (index - 1) t
end
end.
Theorem not_head_value :
~ forall ( n':nat) (l:list nat),
(index_value 0 l)<= n'.
Proof.
intros contra.
specialize (contra 0 (1 :: nil)).
simpl in *. lia.
Qed.
Theorem index_value1:forall (n s2:nat) (l:list nat),
index_value (S s2) (n :: l) <=
index_value 0 (n :: l) \/
index_value (S s2) (n :: l) > 0.
Proof. intros n s2 l. lia. Qed.

How to prove StronglySorted list consing in coq?

I am trying to make a tower of Hanoi proof in Coq as a learning exercise. I am stuck with a last goal on my first proof after many hours of fruitless attempts.
Could you please explain why my program is failing, and how to correct it?
Edit: looking back at the code, it seems that I need to prove StronglySorted le (l:list nat) before I can prove ordered_stacking, isn'it?
Require Import List.
Require Import Arith.
Require Import Coq.Sorting.Sorting.
Definition stack_disk :=
fun (n:nat) (l:list nat) =>
match l with
| nil => n::nil
| n'::l' =>
if n' <? n
then n::l
else l
end.
Eval compute in (stack_disk 2 (1::0::nil)).
Eval compute in (stack_disk 2 (2::1::0::nil)).
Lemma ordered_stacking: forall (n:nat) (l:list nat),
StronglySorted le l -> StronglySorted le (stack_disk n l) -> StronglySorted le (n::l).
Proof.
intros n l H.
induction l as [|hl tl];simpl;auto.
destruct (hl <? n).
auto.
constructor.
apply H.
Output:
1 subgoal
n, hl : nat
tl : list nat
H : StronglySorted le (hl :: tl)
IHtl : StronglySorted le tl ->
StronglySorted le (stack_disk n tl) -> StronglySorted le (n :: tl)
H0 : StronglySorted le (hl :: tl)
______________________________________(1/1)
Forall (le n) (hl :: tl)
The problem is that you didn't record the fact that n <= hl after destructing that boolean. Here is a solution:
Require Import List.
Require Import Arith.
Require Import Coq.Sorting.Sorting.
Definition stack_disk :=
fun (n:nat) (l:list nat) =>
match l with
| nil => n::nil
| n'::l' =>
if n' <? n
then n::l
else l
end.
Lemma ordered_stacking: forall (n:nat) (l:list nat),
StronglySorted le l -> StronglySorted le (stack_disk n l) -> StronglySorted le (n::l).
Proof.
intros n [|m l].
- intros _ _; repeat constructor.
- simpl. intros H1 H2.
destruct (Nat.ltb_spec m n); trivial.
constructor; trivial.
apply StronglySorted_inv in H1.
destruct H1 as [_ H1].
constructor; trivial.
revert H1; apply Forall_impl.
now intros p; apply Nat.le_trans.
Qed.