Pumping Lemma for CFL a^n b^m c^o for n<m<o - pumping-lemma

Let be: L={an bm co | n < m < o, n natural}
Using Pumping Lemma I have choosen: z = uvwxy = an bn+1 cn+2
|uv|<=n and |v|>0
=> uv2wx2y
If vwx is of a's and / or b's it is okay and we would have more a's and/or b's than c's - but if vwx contains only c's it would be element of L.
As far as I understood all new words have to be not element of L to show that it is not a CFL. How would I do this?

If we have a mix of a's & b's use uv2wx2y
If we have a mix of b's & c's use uv0wx0y
Now all words that are created by pumping z are not element of L.

Related

Define a function based on a relation in Coq

I'm working on a theory in which there is a relation C defined as
Parameter Entity: Set.
Parameter C : Entity -> Entity -> Entity -> Prop.
The relation C is a relation of composition of some entities. Instead of C z x y, I want to be able to write x o y = z. So I have two questions:
I think I should define a "function" (the word is perhaps not the right one) named fC that takes x and y and returns z. This way, I could use it in the Notation. But I don't know how to define this "function". Is it possible?
I find that I can use the command Notation to define an operator. Something like Notation "x o y" := fC x y.. Is this the good way to do it?
I tried Notation "x o y" := exists u, C u x y. but it didn't work. Is there a way to do what I want to do?
Unless your relation C has the property that, given x and y, there is a unique z such that C z x y, you cannot view it as representing a full-fledged function the way you suggest. This is why the notion of a relation is needed in that case.
As for defining a notation for the relation property, you can use:
Notation "x 'o y" := (exists u, C u x y) (at level 10).
Note the ' before the o to help the parser handle the notation and the parentheses after the := sign. The level can be changed to suit your parsing preferences.
If you define x 'o y as a proposition, you will lose the intuition of o being a binary operation on Entity (i.e x o y should have type Entity).
You may write some variation like
Notation "x 'o y '= z" := (unique (fun t => C t x y)) (at level 10).
Otherwise, If your relation satisfies:
Hypothesis C_fun: forall x y, {z : Entity | unique (fun t => C t x y) z}.
then you may define:
Notation "x 'o y" := (proj1_sig (C_fun x y)) (at level 10).
Check fun a b: Entity => a 'o b.
Otherwise (if you have only have a weaker version of C_fun, with existsinstead of sig) and accept to use classical logic and axioms), you may use the Epsilon operator
https://coq.inria.fr/distrib/current/stdlib/Coq.Logic.ClassicalEpsilon.html

What is difference between `destruct` and `case_eq` tactics in Coq?

I understood destruct as it breaks an inductive definition into its constructors. I recently saw case_eq and I couldn't understand what it does differently?
1 subgoals
n : nat
k : nat
m : M.t nat
H : match M.find (elt:=nat) n m with
| Some _ => true
| None => false
end = true
______________________________________(1/1)
cc n (M.add k k m) = true
In the above context, if I do destruct M.find n m it breaks H into true and false whereas case_eq (M.find n m) leaves H intact and adds separate proposition M.find (elt:=nat) n m = Some v, which I can rewrite to get same effect as destruct.
Can someone please explain me the difference between the two tactics and when which one should be used?
The first basic tactic in the family of destruct and case_eq is called case. This tactic modifies only the conclusion. When you type case A and A has a type T which is inductive, the system replaces A in the goal's conclusion by instances of all the constructors of type T, adding universal quantifications for the arguments of these constructors, if needed. This creates as many goals as there are constructors in type T. The formula A disappears from the goal and if there is any information about A in an hypothesis, the link between this information and all the new constructors that replace it in the conclusion gets lost. In spite of this, case is an important primitive tactic.
Loosing the link between information in the hypotheses and instances of A in the conclusion is a big problem in practice, so developers came up with two solutions: case_eq and destruct.
Personnally, when writing the Coq'Art book, I proposed that we write a simple tactic on top of case that keeps a link between A and the various constructor instances in the form of an equality. This is the tactic now called case_eq. It does the same thing as case but adds an extra implication in the goal, where the premise of the implication is an equality of the form A = ... and where ... is an instance of each constructor.
At about the same time, the tactic destruct was proposed. Instead of limiting the effect of replacement in the goal's conclusion, destruct replaces all instances of A appearing in the hypotheses with instances of constructors of type T. In a sense, this is cleaner because it avoids relying on the extra concept of equality, but it is still incomplete because the expression A may be a compound expression f B, and if B appears in the hypothesis but not f B the link between A and B will still be lost.
Illustration
Definition my_pred (n : nat) := match n with 0 => 0 | S p => p end.
Lemma example n : n <= 1 -> my_pred n <= 0.
Proof.
case_eq (my_pred n).
Gives the two goals
------------------
n <= 1 -> my_pred n = 0 -> 0 <= 0
and
------------------
forall p, my_pred n = S p -> n <= 1 -> S p <= 0
the extra equality is very useful here.
In this question I suggested that the developer use case_eq (a == b) when (a == b) has type bool because this type is inductive and not very informative (constructors have no argument). But when (a == b) has type {a = b}+{a <> b} (which is the case for the string_dec function) the constructors have arguments that are proofs of interesting properties and the extra universal quantification for the arguments of the constructors are enough to give the relevant information, in this case a = b in a first goal and a <> b in a second goal.

What's the difference between logical (Leibniz) equality and local definition in Coq?

I am having trouble understanding the difference between an equality and a local definition. For example, when reading the documentation about the set tactic:
remember term as ident
This behaves as set ( ident := term ) in * and
using a logical (Leibniz’s) equality instead of a local definition
Indeed,
set (ca := c + a) in *. e.g. generates ca := c + a : Z in the context, while
remember (c + a ) as ca. generates Heqca : ca = c + a in the context.
In case 2. I can make use of the generated hypothesis like rewrite Heqca., while in case 1., I cannot use rewrite ca.
What's the purpose of case 1. and how is it different from case 2. in terms of practical usage?
Also, if the difference between the two is fundamental, why is remember described as a variant of set in the documentation (8.5p1)?
You could think of set a := b + b in H as rewriting H to be:
(fun a => H[b+b/a]) (b+b)
or
let a := b + b in
H[b+b/a]
That is, it replaces all matched patterns b+b by a fresh variable a, which is then instantiated to the value of the pattern. In this regard, both H and the rewrited hypotheses remain equal by "conversion".
Indeed, remember is in a sense a variant of set, however its implications are very different. In this case, remember will introduce a new proof of equality eq_refl: b + b = b + b, then it will abstract away the left part. This is convenient for having enough freedom in pattern matching etc... This is remember in terms of more atomic tactics:
Lemma U b c : b + b = c + c.
Proof.
assert (b + b = b + b). reflexivity.
revert H.
generalize (b+b) at 1 3.
intros n H.
In addition to #ejgallego's answer.
Yes, you cannot rewrite a (local) definition, but you can unfold it:
set (ca := c + a) in *.
unfold ca.
As for the differences in their practical use -- they are quite different. For example, see this answer by #eponier. It relies on the remember tactic so that induction works as we'd like to. But, if we replace remember with set it fails:
Inductive good : nat -> Prop :=
| g1 : good 1
| g3 : forall n, good n -> good (n * 3)
| g5 : forall n, good n -> good (n + 5).
Require Import Omega.
The variant with remember works:
Goal ~ good 0.
remember 0 as n.
intro contra. induction contra; try omega.
apply IHcontra; omega.
Qed.
and the variant with set doesn't (because we didn't introduce any free variables to work with):
Goal ~ good 0.
set (n := 0). intro contra.
induction contra; try omega.
Fail apply IHcontra; omega.
Abort.

How do I change a concrete variable to an existentially quantified var in a hypothesis?

Say I have a hypothesis like this:
FooProp a b
I want to change the hypothesis to this form:
exists a, FooProp a b
How can I do this?
I know I can do assert (exists a, FooProp a b) by eauto but I'm trying to find a solution that doesn't require me to explicitly write down the entire hypothesis; this is bad for automation and is just generally a headache when the hypothesis are nontrivial. Ideally I'd like to specify intro_exists a in H1 or something; it really should be that simple.
EDIT: Why? Because I have a lemma like this:
Lemma find_instr_in:
forall c i,
In i c <-> (exists z : Z, find_instr z c = Some i).
And a hypothesis like this:
H1: find_instr z c = Some i
And I'm trying to rewrite like this:
rewrite <- find_instr_in in H1
Which fails with the error Found no subterm matching "exists z, ..." .... But if I assert (exists z, find_instr z c = Some i) by eauto. first the rewrite works.
How about something like this:
Ltac intro_exists' a H :=
pattern a in H; apply ex_intro in H.
Tactic Notation "intro_exists" ident(a) "in" ident(H) := intro_exists' a H.
Section daryl.
Variable A B : Type.
Variable FooProp : A -> B -> Prop.
Goal forall a b, FooProp a b -> False.
intros.
intro_exists a in H.
Admitted.
End daryl.
The key to this is the pattern tactic, which finds occurrences of a term and abstracts them into a function applied to an argument. So pattern a converts the type of H from FooProp a b to (fun x => FooProp x b) a. After that, Coq can figure out what you mean when you apply ex_intro.
Edit:
All that being said, in your concrete case I would actually recommend a different approach, which is to not state your lemma like that. Instead it is convenient to split it into two lemmas, one for each direction. The forwards direction is just the same, but the backwards direction should be restated as follows
forall c i z,
find_instr z c = Some i -> In i c.
If you do this, then the rewrite will succeed without needing to introduce the existential.

Stuck in the construction of a very simple function

I am learning Coq. I am stuck on a quite silly problem (which has no motivation, it is really silly). I want to build a function from ]2,+oo] to the set of integers mapping x to x-3. That should be simple... In any language I know, it is simple. But not in Coq. First, I write (I explain with a lot of details so that someone can explain what I don't understand in the behaviour of Coq)
Definition f : forall n : nat, n > 2 -> nat.
I get a subgoal
============================
forall n : nat, n > 2 -> nat
which means that Coq wants a map from a proof of n>2 to the set of integers. Fine. So I want to tell it that n = 3 + p for some integer p, and then return the integer p. I write :
intros n H.
And I get the context/subgoal
n : nat
H : n > 2
============================
nat
Then i suppose that I have proved n = 3 + p for some integer p by
cut(exists p, 3 + p = n).
I get the context/subgoal
n : nat
H : n > 2
============================
(exists p : nat, 3 + p = n) -> nat
subgoal 2 (ID 6) is:
exists p : nat, 3 + p = n
I move the hypothesis in the context by
intro K.
I obtain:
n : nat
H : n > 2
K : exists p : nat, 3 + p = n
============================
nat
subgoal 2 (ID 6) is:
exists p : nat, 3 + p = n
I will prove the existence of p later. Now I want to finish the proof by exact p. So i need first to do a
destruct K as (p,K).
and I obtain the error message
Error: Case analysis on sort Set is not allowed for inductive
definition ex.
And I am stuck.
You are absolutely right! Writing this function should be easy in any reasonable programming language, and, fortunately, Coq is no exception.
In your case, it is much easier to define your function by simply ignoring the proof argument you are supplying:
Definition f (n : nat) : nat := n - 3.
You may then wonder "but wait a second, the natural numbers aren't closed under subtraction, so how can this make sense?". Well, in Coq, subtraction on the natural numbers isn't really subtraction: it is actually truncated. If you try to subtract, say, 3 from 2, you get 0 as an answer:
Goal 2 - 3 = 0. reflexivity. Qed.
What this means in practice is that you are always allowed to "subtract" two natural numbers and get a natural number back, but in order for this subtraction make sense, the first argument needs to be greater than the second. We then get lemmas such as the following (available in the standard library):
le_plus_minus_r : forall n m, n <= m -> n + (m - n) = m
In most cases, working with a function that is partially correct, such as this definition of subtraction, is good enough. If you want, however, you can restrict the domain of f to make its properties more pleasant. I've taken the liberty of doing the following script with the ssreflect library, which makes writing this kind of function easier:
Require Import Ssreflect.ssreflect Ssreflect.ssrfun Ssreflect.ssrbool.
Require Import Ssreflect.ssrnat Ssreflect.eqtype.
Definition f (n : {n | 2 < n}) : nat :=
val n - 3.
Definition finv (m : nat) : {n | 2 < n} :=
Sub (3 + m) erefl.
Lemma fK : cancel f finv.
Proof.
move=> [n Pn] /=; apply/val_inj=> /=.
by rewrite /f /= addnC subnK.
Qed.
Lemma finvK : cancel finv f.
Proof.
by move=> n; rewrite /finv /f /= addnC addnK.
Qed.
Now, f takes as an argument a natural number n that is greater than 2 (the {x : T | P x} form is syntax sugar for the sig type from the standard library, which is used for forming types that work like subsets). By restricting the argument type, we can write an inverse function finv that takes an arbitrary nat and returns another number that is greater than 2. Then, we can prove lemmas fK and finvK, which assert that fK and finvK are inverses of each other.
On the definition of f, we use val, which is ssreflect's idiom for extracting the element out of a member of a type such as {n | 2 < n}. The Sub function on finv does the opposite, packaging a natural number n with a proof that 2 < n and returning an element of {n | 2 < n}. Here, we rely crucially on the fact that the < is expressed in ssreflect as a boolean computation, so that Coq can use its computation rules to check that erefl, a proof of true = true, is also a valid proof of 2 < 3 + m.
To conclude, the mysterious error message you got in the end has to do with Coq's rules governing computational types, with live in Type, and propositional types, which live in Prop. Coq's rules forbid you from using proofs of propositions to build elements that have computational content (such as natural numbers), except in very particular cases. If you wanted, you could still finish your definition by using {p | 3 + p = n} instead of exists p, 3 + p = n -- both mean the same thing, except the former lives in Type while the latter lives in Prop.