How to split the length inequality hypothesis in the pumping lemma? - coq

This is the 5 star exercise from Software Foundations.
Lemma pumping : forall T (re : #reg_exp T) s,
s =~ re ->
pumping_constant re <= length s ->
exists s1 s2 s3,
s = s1 ++ s2 ++ s3 /\
s2 <> [] /\
forall m, s1 ++ napp m s2 ++ s3 =~ re.
Proof.
intros T re s Hmatch.
induction Hmatch
as [ | x | s1 re1 s2 re2 Hmatch1 IH1 Hmatch2 IH2
| s1 re1 re2 Hmatch IH | re1 s2 re2 Hmatch IH
| re | s1 s2 re Hmatch1 IH1 Hmatch2 IH2 ]; simpl; intros.
- omega.
- omega.
-
1 subgoal
T : Type
s1 : list T
re1 : reg_exp
s2 : list T
re2 : reg_exp
Hmatch1 : s1 =~ re1
Hmatch2 : s2 =~ re2
IH1 : pumping_constant re1 <= length s1 ->
exists s2 s3 s4 : list T,
s1 = s2 ++ s3 ++ s4 /\
s3 <> [ ] /\ (forall m : nat, s2 ++ napp m s3 ++ s4 =~ re1)
IH2 : pumping_constant re2 <= length s2 ->
exists s1 s3 s4 : list T,
s2 = s1 ++ s3 ++ s4 /\
s3 <> [ ] /\ (forall m : nat, s1 ++ napp m s3 ++ s4 =~ re2)
H : pumping_constant re1 + pumping_constant re2 <= length (s1 ++ s2)
______________________________________(1/1)
exists s0 s3 s4 : list T,
s1 ++ s2 = s0 ++ s3 ++ s4 /\
s3 <> [ ] /\ (forall m : nat, s0 ++ napp m s3 ++ s4 =~ App re1 re2)
I've spent too much time trying to split that H only to realize that despite day and a half work on this, many of my assumptions on how inequalities work turned out to be wrong. I had some great ideas last night which now that they've been discarded leave me more confused about this problem than ever. I've only been unlearning algebra in the past two days it seems.
I am going to be very embarrassed if the answer turns out to be that I need to match on the ss or length ss or pumping_constant res because I can't find a way to push through there.
The way this problem is set up highly suggests H should be split somehow in order to do the induction. I am still suspicious of it.

Yes, you need to split the H in order to proceed.
Vague hint: Do Search (_ + _ <= _ + _). and look for a theorem that catches your eyes.
Hint:
Nat.add_le_cases: forall n m p q : nat, n + m <= p + q -> n <= p \/ m <= q

Related

I have been stuck on MApp for pumping lemma

I have been trying to solve Pumping lemma in Coq.
I was on the third subgoal, Mapp.
Lemma pumping : forall T (re : reg_exp T) s,
s =~ re ->
pumping_constant re <= length s ->
exists s1 s2 s3,
s = s1 ++ s2 ++ s3 /\
s2 <> [] /\
length s1 + length s2 <= pumping_constant re /\
forall m, s1 ++ napp m s2 ++ s3 =~ re.
My proof on MApp is as follow.
Proof.
intros T re s Hmatch.
induction Hmatch
as [ | x | s1 re1 s2 re2 Hmatch1 IH1 Hmatch2 IH2
| s1 re1 re2 Hmatch IH | re1 s2 re2 Hmatch IH
| re | s1 s2 re Hmatch1 IH1 Hmatch2 IH2 ].
- (* MEmpty -- omitted *)
- (* MChar -- omitted *)
- (* MApp *)
intros T re s Hmatch.
induction Hmatch
as [ | x | s1 re1 s2 re2 Hmatch1 IH1 Hmatch2 IH2
| s1 re1 re2 Hmatch IH | re1 s2 re2 Hmatch IH
| re | s1 s2 re Hmatch1 IH1 Hmatch2 IH2 ].
- (* MEmpty *)
simpl. intros contra. inversion contra.
- (* MChar *)
simpl. intros. inversion H. inversion H1.
- (* MApp *)
simpl. rewrite app_length. intros.
apply add_le_cases in H.
destruct H as [H|H].
+ (*case pumping_constant re1 <= length s1 ommitted*)
+ apply IH2 in H. destruct H as [ss1 [ss2 [ss3 [H1 [H2 [H3 H4]]]]]].
exists (s1++ss1), ss2, ss3. split.
* rewrite H1. rewrite <- app_assoc. reflexivity.
* split. apply H2.
split. rewrite app_length.
assert (Hc: length s1<pumping_constant re1 \/ length s1>=pumping_constant re1).
apply lt_ge_cases.
destruct Hc as [Hc|Hc].
apply le_S in Hc.
apply Sn_le_Sm__n_le_m in Hc.
rewrite <- add_assoc.
apply (Plus.plus_le_compat _ _ _ _ Hc).
apply H3.
(* stuck *)
I am now stuck on case Hc: length s1>=pumping_constant re1
Goal:
2 goals
T : Type
s1 : list T
re1 : reg_exp T
s2 : list T
re2 : reg_exp T
Hmatch1 : s1 =~ re1
Hmatch2 : s2 =~ re2
IH1 : pumping_constant re1 <= length s1 ->
exists s2 s3 s4 : list T,
s1 = s2 ++ s3 ++ s4 /\
s3 <> [ ] /\
length s2 + length s3 <= pumping_constant re1 /\
(forall m : nat, s2 ++ napp m s3 ++ s4 =~ re1)
IH2 : pumping_constant re2 <= length s2 ->
exists s1 s3 s4 : list T,
s2 = s1 ++ s3 ++ s4 /\
s3 <> [ ] /\
length s1 + length s3 <= pumping_constant re2 /\
(forall m : nat, s1 ++ napp m s3 ++ s4 =~ re2)
ss1, ss2, ss3 : list T
H1 : s2 = ss1 ++ ss2 ++ ss3
H2 : ss2 <> [ ]
H3 : length ss1 + length ss2 <= pumping_constant re2
H4 : forall m : nat, ss1 ++ napp m ss2 ++ ss3 =~ re2
Hc : length s1 >= pumping_constant re1
______________________________________(1/2)
length s1 + length ss1 + length ss2 <=
pumping_constant re1 + pumping_constant re2
I tried solving it with cases H: length s1>=pumping_constant -> re1 length s1=pumping_constant re1 \/ length s1>pumping_constatn re1.
It got me somewhere but the right case is tough to crack. How should I proceed?
Intuitively (I didn't install the specific libraries), I would start with a case analysis on length s1 >= pumping_constant re1
If it holds, you can apply IH1, then append s2 to the right of the third component of the decomposition of s1.
If length s1 < pumping_constant re1 and s1 ++ s2is long enough, then length s2 >= pumping_constant re2, and you can apply IH2, then append s1to the left of the first component of the decomposition of s2.
In the sub-goal you display, I didn't find any hypothesis of the form length s1 + length s2 >= pumping_constant re1 + pumping_constant re2, which IMO helps to solve the case where s1is short.

Get stuck at the `MStarApp` case of Software Fundation's pumping Lemma

When proving the pumping Lemma (https://softwarefoundations.cis.upenn.edu/lf-current/IndProp.html#Pumping.pumping), I get stuck at the MStarApp case:
Lemma pumping : forall T (re : reg_exp T) s,
s =~ re ->
pumping_constant re <= length s ->
exists s1 s2 s3,
s = s1 ++ s2 ++ s3 /\
s2 <> [] /\
length s1 + length s2 <= pumping_constant re /\
forall m, s1 ++ napp m s2 ++ s3 =~ re.
Proof.
intros T re s Hmatch.
induction Hmatch
as [ | x | s1 re1 s2 re2 Hmatch1 IH1 Hmatch2 IH2
| s1 re1 re2 Hmatch IH | re1 s2 re2 Hmatch IH
| re | s1 s2 re Hmatch1 IH1 Hmatch2 IH2 ].
- (* Other cases *)
- (* MStarApp *)
simpl. intros H. exists nil, s1, s2. split.
+ reflexivity.
+ split.
* Admitted.
We have the assumptions that:
T: Type
s1, s2: list T
re: reg_exp T
Hmatch1: s1 =~ re
Hmatch2: s2 =~ Star re
IH1: pumping_constant re <= length s1 ->
exists s2 s3 s4 : list T,
s1 = s2 ++ s3 ++ s4 /\
s3 <> [ ] /\
length s2 + length s3 <= pumping_constant re /\
(forall m : nat, s2 ++ napp m s3 ++ s4 =~ re)
IH2: pumping_constant (Star re) <= length s2 ->
exists s1 s3 s4 : list T,
s2 = s1 ++ s3 ++ s4 /\
s3 <> [ ] /\
length s1 + length s3 <= pumping_constant (Star re) /\
(forall m : nat, s1 ++ napp m s3 ++ s4 =~ Star re)
H: pumping_constant re <= length (s1 ++ s2)
I want to pump on s1, but I don't know how to prove that s1 <> []. Could you help me?

How to prove the correction of derive on reg_exp

It's a question in software foundation, logic foundation, IndProp.v
Here is some definitions.
Inductive reg_exp (T : Type) : Type :=
| EmptySet
| EmptyStr
| Char (t : T)
| App (r1 r2 : reg_exp T)
| Union (r1 r2 : reg_exp T)
| Star (r : reg_exp T).
Inductive exp_match {T} : list T -> reg_exp T -> Prop :=
| MEmpty : [] =~ EmptyStr
| MChar x : [x] =~ (Char x)
| MApp s1 re1 s2 re2
(H1 : s1 =~ re1)
(H2 : s2 =~ re2)
: (s1 ++ s2) =~ (App re1 re2)
| MUnionL s1 re1 re2
(H1 : s1 =~ re1)
: s1 =~ (Union re1 re2)
| MUnionR re1 s2 re2
(H2 : s2 =~ re2)
: s2 =~ (Union re1 re2)
| MStar0 re : [] =~ (Star re)
| MStarApp s1 s2 re
(H1 : s1 =~ re)
(H2 : s2 =~ (Star re))
: (s1 ++ s2) =~ (Star re)
where "s =~ re" := (exp_match s re).
Definition derives d := forall a re, is_der re a (d a re).
Fixpoint derive (a : ascii) (re : reg_exp ascii) : reg_exp ascii :=
match re with
| EmptySet => EmptySet
| EmptyStr => EmptySet
| Char c => if (eqb a c) then EmptyStr else EmptySet
| App re1 re2 => Union (App (derive a re1) re2) (if match_eps re1
then derive a re2
else EmptySet)
| Union re1 re2 => Union (derive a re1) (derive a re2)
| Star re => App (derive a re) (Star re)
end.
And the Lemma I have to prove is
Lemma derive_corr : derives derive.
I was struck when the re is Star re.
As a:s =~ Star re -> s1 ++ s2 = a :: s /\ s1 =~ re /\ s2 =~ Star re
If s1 <> [], it can be solved easily.
But when s1 == [], it seems come into a endless loop(I have to same thing again on s2). I guess I can make it by recur, but I don't know how to do.
You should probably prove a "better" inversion that the one that the inversion tactic of your hypothesis gives you, something that intuitively says that the left string of MStarApp cannot be forever empty. Proving such stronger inversions is quite usual in this kind of settings.
Here a possibility is to show that if a :: s =~ Star re, then there exists s1 and s2 such that s = s1 ++ s2 /\ a :: s1 =~ re /\ s2 =~ Star re.

Software Foundations: weak_pumping lemma proof

Continuing my work on Software Foundations, I've reached the weak_pumping lemma. I managed to get through almost everything, but I can't find a solution for MStarApp case.
Here's the Lemma:
s =~ re ->
pumping_constant re <= length s ->
exists s1 s2 s3,
s = s1 ++ s2 ++ s3 /\
s2 <> [] /\
forall m, s1 ++ napp m s2 ++ s3 =~ re.
(** You are to fill in the proof. Several of the lemmas about
[le] that were in an optional exercise earlier in this chapter
may be useful. *)
Proof.
intros T re s Hmatch.
induction Hmatch
as [ | x | s1 re1 s2 re2 Hmatch1 IH1 Hmatch2 IH2
| s1 re1 re2 Hmatch IH | re1 s2 re2 Hmatch IH
| re | s1 s2 re Hmatch1 IH1 Hmatch2 IH2 ].
I've managed to solve every case, except for the last one. Here's the current state:
1 subgoal (ID 918)
T : Type
s1, s2 : list T
re : reg_exp T
Hmatch1 : s1 =~ re
Hmatch2 : s2 =~ Star re
IH1 : pumping_constant re <= length s1 ->
exists s2 s3 s4 : list T,
s1 = s2 ++ s3 ++ s4 /\
s3 <> [ ] /\ (forall m : nat, s2 ++ napp m s3 ++ s4 =~ re)
IH2 : pumping_constant (Star re) <= length s2 ->
exists s1 s3 s4 : list T,
s2 = s1 ++ s3 ++ s4 /\
s3 <> [ ] /\ (forall m : nat, s1 ++ napp m s3 ++ s4 =~ Star re)
H : pumping_constant (Star re) <= length s1 + length s2
============================
exists s0 s4 s5 : list T,
s1 ++ s2 = s0 ++ s4 ++ s5 /\
s4 <> [ ] /\ (forall m : nat, s0 ++ napp m s4 ++ s5 =~ Star re)
It looks to me that if I can find a way to split H into pumping_constant re <= length s1 \/ pumping_constant (Star re) <= length s2 then I have a way forward (by splitting H into H1 and H2 and applying the relevant IHk to the matching Hk then proceeding with a destruct, three exists, and so on).
But I can't find a lemma that allows me to split H as suggested.
Is there anything else I can do here?
Thanks
Try to destruct s1 and look again on lemma napp_star in one of cases.

Proving MStar' in Logical Foundations (IndProp.v)

In Logical Foundations' chapter on Inductive Propositions, the exercise exp_match_ex1 involves the following definitions:
Inductive reg_exp (T : Type) : Type :=
| EmptySet
| EmptyStr
| Char (t : T)
| App (r1 r2 : reg_exp T)
| Union (r1 r2 : reg_exp T)
| Star (r : reg_exp T).
Arguments EmptySet {T}.
Arguments EmptyStr {T}.
Arguments Char {T} _.
Arguments App {T} _ _.
Arguments Union {T} _ _.
Arguments Star {T} _.
Inductive exp_match {T} : list T -> reg_exp T -> Prop :=
| MEmpty : [] =~ EmptyStr
| MChar x : [x] =~ (Char x)
| MApp s1 re1 s2 re2
(H1 : s1 =~ re1)
(H2 : s2 =~ re2)
: (s1 ++ s2) =~ (App re1 re2)
| MUnionL s1 re1 re2
(H1 : s1 =~ re1)
: s1 =~ (Union re1 re2)
| MUnionR re1 s2 re2
(H2 : s2 =~ re2)
: s2 =~ (Union re1 re2)
| MStar0 re : [] =~ (Star re)
| MStarApp s1 s2 re
(H1 : s1 =~ re)
(H2 : s2 =~ (Star re))
: (s1 ++ s2) =~ (Star re)
where "s =~ re" := (exp_match s re).
I'm stuck trying to prove the following lemma:
Lemma MStar' : forall T (ss : list (list T)) (re : reg_exp T),
(forall s, In s ss -> s =~ re) ->
fold app ss [] =~ Star re.
Proof.
intros. induction ss.
- simpl. apply MStar0.
- simpl. pose proof (H x). assert (Hx: In x (x :: ss)). {
simpl. left. reflexivity.
} pose proof (H0 Hx).
(* stuck *)
Which results in:
T: Type
x: list T
ss: list (list T)
re: reg_exp T
H: forall s : list T, In s (x :: ss) -> s =~ re
IHss: (forall s : list T, In s ss -> s =~ re) -> fold app ss [ ] =~ Star re
H0: In x (x :: ss) -> x =~ re
Hx: In x (x :: ss)
H1: x =~ re
====================================
1/1
x ++ fold app ss [ ] =~ Star re
Initially it looked like trying to proceed by induction on ss would allow me to make progress but I can't find any way to transform the hypothesis forall s : list T, In s (x :: ss) -> s =~ re so that I can prove fold app ss [ ] =~ Star re from the inductive hypothesis (forall s : list T, In s ss -> s =~ re) -> fold app ss [ ] =~ Star re.
I think the thing is that you do not need to apply induction hypothesis yet. Just try to see again on your constructors right when you have situation you've described (so, right on your (* stuck *) step).