Holding greater or equal relation between two terms - coq

H:count k (match d with
|nil=>nil
|s::l=>(s::firstn n l))
end <=
count 0 (match d with
|nil=>nil
|s::l=>(s::firstn n l))
end
Where n is natural number and d is list nat. From above H may i extract information that (s::firstn n l) contains more zeros than k.

Related

COQ: How to use "<=" for Z and R in the same lemma?

Suppose I already defined floor (from R to Z). Now I want to prove that n <= x implies n <= floor(x), where n : Z, x : R.
I tried:
Lemma l: forall (n:Z) (x:R), (IZR n) <= x -> n <= (floor x).
but I'm getting the error The term n has type Z while it is expected to have type R.
How should I write this? Is there a way that I can use <= for Z and R simultaneously?
In order to override the default interpretation of a notation, you can open a notation scope locally using %key:
Lemma l : forall n x, (IZR n <= x)%R -> (n <= floor x)%Z.

How to consider both out puts in list

I have less than relation between two index values and want to esteblish a relation between indexes. Have hypothesis - (nth i2 l d < nth i1 l d). There are two possibilities that (i2 < i1) or (i2> i1). I want to consider both cases. Plz guide me in writing this relation.
Use Nat.lt_gt_cases, which proves n < m \/ n > m given n <> m. In context, that would look like this
Require Import PeanoNat.
Goal forall (d : nat) (l : list nat) (n m : nat), nth n l d < nth m l d -> True.
intros d l n m prf.
assert (ineq : n <> m). (* hypothesis for lt_gt_cases *)
{ intros ->.
now apply Nat.lt_irrefl in prf.
}
destruct (proj1 (Nat.lt_gt_cases n m) ineq) as [ord | ord].
(* two goals left, one with n < m and the other with m > n *)

How to compare two elements of list

I have a list with all elements equal to zero and the length of the list not equal to zero. I want to prove the following and compare both
(length l=?0)=false->
k < length l ->
(forall k, nth k l 0 = 0)->
1<=count 0 l.
(length l=?0)=false->
(forall k, nth k l 0 = 0) ->
(S n) < length l ->
count (S n) l = 0.
count (S n) l < count 0 l.
Fixpoint count (v:nat) (s:list nat) : nat :=
match s with
| [] => 0
| h :: t => (if beq_nat h v then 1 else 0) + (count v t) end.

How to simplify a statement of lemma

I have a Contradictory statements in hypothesis. Want to convert it into true=false. Thanks for guidence in advance. Here is code
n < current_value 0 (n :: l)
current_value 0 (n :: l)<= n.
The question could be a lot more complete. What is the type of n? I'll assume that it is nat.
Starting like this:
Lemma manual:
forall current_value n l P,
n < current_value 0 (n :: l) ->
current_value 0 (n :: l) <= n ->
P.
Proof.
intros.
We arrive at a state that looks like this (omitting things we don't need):
H : n < current_value 0 (n :: l)
H0 : current_value 0 (n :: l) ≤ n
-----
P
The strategy will be to prove that H and H0 together lead to a contradiction from which we can prove any statement P.
We know that n < m (if m stands for the expression current_value 0 (n :: l)) and also m <= n. What can we prove from this? You can search for relevant lemmas using the Search command with a pattern that summarizes what you know:
Search (?n < ?m -> ?m <= ?p -> _).
This query means "given that I know that n < m and also m <= p for the same m, what can I deduce?". The named variables in the query need the ? prefix, they can stand for any expressions. They are not related to any variables you might have in the current environment.
One of the search hits is this (in PeanoNat, which you will have to import):
Nat.lt_le_trans:
forall n m p : nat, n < m -> m <= p -> n < p
So given this lemma we should be able to prove n < n and see if we can make progress from there.
{
apply Nat.lt_le_trans with (m := current_value 0 (n :: l)).
auto.
auto.
}
Now we have:
H1 : n < n
-----
P
So now we have a more "obvious" contradiction in an assumption. Do we have a lemma for proving that this is indeed false?
Search (~ ?n < ?n).
This gives:
Nat.lt_irrefl: forall x : nat, ~ x < x
So then:
apply Nat.lt_irrefl in H1.
We arrive at:
H1 : False
-----
P
This is a tautology that we can prove with tauto:
tauto.
Qed.
Doing such simple arithmetic manually can get very tedious, so there is a lot of automation for doing it. Here's a simpler method using the lia tactic:
Require Import Lia.
Lemma automatic:
forall current_value n l P,
n < current_value 0 (n :: l) ->
current_value 0 (n :: l) <= n ->
P.
Proof.
intros.
lia.
Qed.
Internally this will do some sort of similar reasoning, proving a contradiction in the assumptions.

Modifying, working with, and applying let expressions in Coq

I'm not sure how to apply the let expression in coq. This is from the selection sort example in PF.
Once the select function is defined, this lemma is proved.
Lemma select_perm: forall x l,
let (y,r) := select x l in
Permutation (x::l) (y::r).
These are some use cases to see how it works.
Compute select_perm 3 [10;32;4;6;5].
= select_perm 3 [10; 32; 4; 6; 5]
: let (y, r) := select 3 [10; 32; 4; 6; 5] in
Permutation [3; 10; 32; 4; 6; 5] (y :: r)
Compute select 3 [10; 32; 4; 6; 5].
= (3, [10; 32; 4; 6; 5])
: nat * list nat
How can I further evaluate this to expose the actual Permutation - something along the lines of Compute ((select_perm 3 [10;32;4;6;5]) (select 3 [10; 32; 4; 6; 5]))?
I'm not sure how to use this lemma in applying the below theorem.
Lemma selsort_perm:
forall n,
forall l, length l = n -> Permutation l (selsort l n).
Proof.
intros.
generalize dependent n.
induction l; intros.
- subst.
simpl.
constructor.
- subst. simpl.
destruct (select a l) eqn:?.
With the corresponding goals, I want to apply select_perm somehow (apply (select_perm a l)).
a : nat
l : list nat
IHl : forall n : nat, length l = n -> Permutation l (selsort l n)
n : nat
l0 : list nat
Heqp : select a l = (n, l0)
============================
Permutation (a :: l) (n :: selsort l0 (length l))
Or, correspondingly, prove via transitivity assert (Permutation (a :: l) (n :: l0)) and somehow bring the following Heqp into a let expression in with the new goal .
Is there an easy way to treat let expressions like function application in coq?
Edit:
I have found an adhoc alternative solution by modifying select_perm to select_perm'
Lemma select_perm': forall x l,
Permutation (x::l) ((fst (select x l)) :: (snd (select x l))).
And inducting over the length of the list rather than the list itself (can provide that code if necessary), but would rather just use Appel's original definition...
Yes, this is a tricky matter. Here is the structure I propose. To make a workable, self-example, I just assume the existence of functions select and selsort and of the relation Permutation.
I actually introduce in my goal the instance of the theorem that I wish to use (as you suggested), and then I can rewrite with Heqp. The last two lines are where things actually happen.
Require Import List.
Section playground.
Variable select : nat -> list nat -> nat * list nat.
Variable Permutation : list nat -> list nat -> Prop.
Lemma select_perm: forall x l,
let (y,r) := select x l in
Permutation (x::l) (y::r).
Proof.
Admitted.
Variable selsort : list nat -> nat -> list nat.
Lemma goal_at_hand (a : nat) (l : list nat)
(IHl : forall n : nat, length l = n -> Permutation l (selsort l n))
(n : nat) (l0 : list nat) (Heqp : select a l = (n, l0)):
Permutation (a :: l) (n :: selsort l0 (length l)).
Proof.
generalize (select_perm a l).
rewrite Heqp.
What makes this tricky is that Coq uses the let ... := ... in ... syntax, but this is actually a pattern-matching expression: you need the expression to be explicitly an application of the pair constructor for the let expression to transform itself in a simpler form.
The goal you obtain has the following shape, I suppose you need a lemma stating that Permutation is transitive to proceed.
Permutation (a :: l) (n :: l0) ->
Permutation (a :: l) (n :: selsort l0 (length l))