Require Import Coqlib Tactics StackADT.
Open Scope Z_scope.
Inductive sizes :
frameinj ->
stack ->
stack ->
Prop :=
|
sizes_nil:
sizes nil nil nil
|
sizes_cons g s1 s2 t1 n t2:
sizes g (
drop (
S n)
s1)
s2 ->
take (
S n)
s1 =
Some t1 ->
Exists (
fun f1 =>
size_frames t2 <=
size_frames f1)
t1 ->
sizes (
S n::
g)
s1 (
t2 ::
s2).
Lemma compat_sizes_tl:
forall g m1 m2,
sizes (1%
nat::
g)
m1 m2 ->
sizes g (
tl m1) (
tl m2).
Proof.
intros g m1 m2 SZ. inv SZ. simpl. simpl in *. auto.
Qed.
Fixpoint sum (
l:
list Z) :=
match l with
nil => 0
|
a::
r =>
a +
sum r
end.
Require Import Permutation.
Lemma size_stack_permut:
forall s s',
Permutation s s' ->
size_stack s =
size_stack s'.
Proof.
induction 1; simpl; intros; eauto; omega.
Qed.
Lemma size_stack_app:
forall s1 s2,
size_stack (
s1 ++
s2) =
size_stack s1 +
size_stack s2.
Proof.
induction s1; simpl; intros; eauto. rewrite IHs1. omega.
Qed.
Lemma size_stack_concat:
forall ss,
size_stack (
concat ss) =
sum (
map size_stack ss).
Proof.
induction ss;
simpl;
intros;
eauto.
rewrite size_stack_app.
omega.
Qed.
Opaque minus.
Lemma list_nats_S:
forall n,
list_nats (
S n) =
map S (
list_nats n) ++
O ::
nil.
Proof.
induction n; simpl; intros; eauto.
rewrite <- IHn. simpl. auto.
Qed.
Lemma map_list_nats_rev:
forall n,
map (
fun m =>
n -
S m)%
nat (
list_nats n) =
rev (
list_nats n).
Proof.
Fixpoint opt_concat {
A} (
l:
list (
option (
list A))) :
option (
list A) :=
match l with
nil =>
Some nil
|
None ::
l =>
None
|
Some a::
l =>
match opt_concat l with
|
None =>
None
|
Some r =>
Some (
a ++
r)
end
end.
Inductive sublist {
A:
Type} :
list A ->
list A ->
Prop :=
|
sublist_intro s:
sublist nil s
|
sublist_skip a s1 s2:
sublist s1 s2 ->
sublist s1 (
a::
s2)
|
sublist_same a s1 s2:
sublist s1 s2 ->
sublist (
a::
s1) (
a::
s2).
Lemma size_stack_sublist:
forall s1 s2,
sublist s1 s2 ->
size_stack s1 <=
size_stack s2.
Proof.
Fixpoint minl (
l:
list nat) :
option nat :=
match l with
|
nil =>
None
|
a::
r =>
match minl r with
Some b =>
Some (
Nat.min a b)
|
None =>
Some a
end
end.
Lemma map_concat:
forall {
A} (
l:
list A),
concat (
map (
fun x =>
x::
nil)
l) =
l.
Proof.
induction l; simpl; intros; eauto. congruence.
Qed.
Lemma partition:
forall {
A}
f
(
l2:
list A)
(
l1:
list A)
(
INCL:
forall i,
In i l2 ->
forall x,
In x (
f i) ->
In x l1)
x
(
IN:
In x (
concat (
map f l2))),
In x l1.
Proof.
induction l2;
simpl;
intros;
eauto.
-
easy.
-
rewrite in_app in IN.
destruct IN;
eauto.
Qed.
Lemma lnr_concat:
forall {
A B} (
f:
A ->
list B)
(
LNRf:
forall i,
list_norepet (
f i))
(
DISJ:
forall i j,
i <>
j ->
list_disjoint (
f i) (
f j))
(
l2:
list A)
(
LNR2:
list_norepet l2),
list_norepet (
concat (
map f l2)).
Proof.
intros A B f LNRf DISJ l2.
induction 1;
simpl.
constructor.
apply list_norepet_app.
split; [|
split];
auto.
red;
intros.
rewrite concat_In in H1.
destruct H1 as (
xx &
INx &
INMAP).
rewrite in_map_iff in INMAP.
destruct INMAP as (
a &
Fa &
INFa).
subst.
eapply DISJ. 2:
apply H0. 2:
apply INx.
congruence.
Qed.
Lemma norepet_incl_perm_sublist:
forall {
A} (
l1:
list A)
(
lnr1:
list_norepet l1)
l2
(
incl:
forall x,
In x l1 ->
In x l2),
exists l2',
sublist l1 l2' /\
Permutation l2 l2'.
Proof.
induction 1;
simpl;
intros.
-
exists l2;
split.
constructor.
reflexivity.
-
edestruct (
in_split hd l2)
as (
l1' &
l2' &
EQ).
apply incl;
auto.
subst.
edestruct (
IHlnr1 (
l1' ++
l2'))
as (
l3' &
SUB &
PERM).
intros.
specialize (
incl _ (
or_intror H0)).
rewrite in_app in incl.
rewrite in_app.
destruct incl as [
IN|[
EQ|
IN]];
auto.
subst.
congruence.
exists (
hd::
l3');
split.
apply sublist_same;
auto.
etransitivity.
symmetry.
apply Permutation_middle.
apply perm_skip.
auto.
Qed.
Lemma filter_norepet:
forall {
A}
f (
l:
list A),
list_norepet l ->
list_norepet (
filter f l).
Proof.
induction 1;
simpl;
intros;
try destr;
econstructor;
eauto.
rewrite filter_In.
intros (
B &
C).
congruence.
Qed.
Lemma sublist_inj:
forall g (
l1 l2:
list nat),
list_norepet l1 ->
list_norepet l2 ->
exists l1',
sublist
(
concat (
map
(
fun j =>
filter (
fun i =>
option_eq Nat.eq_dec (
g i) (
Some j))
l1)
l2))
l1'
/\
Permutation l1 l1'.
Proof.
Lemma lnr_list_nats:
forall n,
list_norepet (
list_nats n).
Proof.
induction n;
simpl;
intros;
constructor;
eauto.
rewrite in_list_nats.
omega.
Qed.
Lemma min_exists:
forall l i,
In i l ->
exists mi,
minl l =
Some mi.
Proof.
destruct l; simpl. easy. intros. destr; eauto.
Qed.
Lemma min_in:
forall l m,
minl l =
Some m ->
In m l /\
forall x,
In x l -> (
m <=
x)%
nat.
Proof.
induction l;
simpl;
intros;
eauto.
easy.
repeat destr_in H.
-
specialize (
IHl _ eq_refl).
destruct IHl as (
IN &
MIN).
split.
destruct (
le_dec a n).
rewrite Nat.min_l;
auto.
rewrite Nat.min_r by omega.
auto.
intros.
destruct H.
subst.
apply Nat.le_min_l.
apply Nat.min_le_iff.
apply MIN in H.
auto.
-
destruct l.
simpl.
split;
auto.
intros x [|[]];
subst;
omega.
simpl in Heqo.
destr_in Heqo.
Qed.
Lemma opt_concat_sizes:
forall l1 l2,
list_forall2 (
fun ol1 ol2 =>
match ol1,
ol2 with
Some l1,
Some l2 =>
size_stack l1 <=
size_stack l2
|
_,
_ =>
False
end)
l1 l2 ->
forall s1 s2,
opt_concat l1 =
Some s1 ->
opt_concat l2 =
Some s2 ->
size_stack s1 <=
size_stack s2.
Proof.
induction 1;
simpl;
intros.
inv H;
inv H0.
omega.
repeat destr_in H.
subst.
repeat destr_in H1.
repeat destr_in H2.
rewrite !
size_stack_app.
specialize (
IHlist_forall2 _ _ eq_refl eq_refl);
omega.
Qed.
Lemma lf2_list_ints_map:
forall {
A B C} (
f1:
A ->
B) (
f2:
A ->
C) (
P:
B ->
C ->
Prop)
(
l:
list A)
(
PROP:
forall x,
In x l ->
P (
f1 x) (
f2 x)),
list_forall2 P (
map f1 l) (
map f2 l).
Proof.
induction l; simpl; intros; constructor; eauto.
Qed.
Lemma size_frames_le_size_stack:
forall f s,
In f s ->
size_frames f <=
size_stack s.
Proof.
induction s;
simpl;
intros;
eauto.
easy.
destruct H;
subst.
generalize (
size_stack_pos s);
omega.
generalize (
size_frames_pos a).
trim IHs;
auto.
omega.
Qed.
Lemma sizes_size_stack:
forall g s1 s2
(
SZ:
sizes g s1 s2),
size_stack s2 <=
size_stack s1.
Proof.
Lemma frame_at_pos_tl:
forall f s i,
f @
s :
S i <->
f @
tl s :
i.
Proof.
Lemma frame_at_pos_tl_iter:
forall f n s i,
f @ (
Nat.iter n (@
tl _)
s) :
i <->
f @
s : (
n +
i)%
nat.
Proof.
induction n;
simpl;
intros.
tauto.
split.
intro H.
apply frame_at_pos_tl in H.
apply IHn in H.
rewrite plus_n_Sm.
auto.
intros.
apply frame_at_pos_tl.
apply IHn.
replace (
n +
S i)%
nat with (
S (
n +
i))%
nat.
auto.
omega.
Qed.
Lemma tl_drop:
forall {
A}
n (
l:
list A),
drop n (
tl l) =
drop (
S n)
l.
Proof.
reflexivity.
Qed.
Lemma drop_app:
forall {
A}
n (
s1 s2:
list A),
length s1 =
n ->
drop n (
s1 ++
s2) =
s2.
Proof.
intros; subst.
revert s1 s2; induction s1; simpl; intros; eauto.
Qed.
Lemma compat_sizes_drop:
forall n g m1 m2
(
SZ:
sizes (
S n ::
g)
m1 m2),
sizes g (
drop (
S n)
m1) (
tl m2).
Proof.
intros.
inv SZ.
simpl.
rewrite tl_drop.
auto.
Qed.
Lemma size_stack_drop:
forall n l,
size_stack (
drop n l) <=
size_stack l.
Proof.
induction n;
simpl;
intros.
reflexivity.
etransitivity.
apply IHn.
apply size_stack_tl.
Qed.
Lemma nat_iter_plus:
forall {
A} (
f:
A ->
A)
n m x,
Nat.iter (
n +
m)
f x =
Nat.iter n f (
Nat.iter m f x).
Proof.
induction n; simpl; intros. auto. rewrite IHn. auto.
Qed.
Lemma size_stack_iter_tl_mono:
forall n m l,
(
m <=
n)%
nat ->
size_stack (
drop n l) <=
size_stack (
drop m l).
Proof.
Lemma length_tl:
forall {
A} (
l:
list A),
length (
tl l) = (
length l - 1)%
nat.
Proof.
destruct l; simpl; auto. omega.
Qed.
Lemma length_drop:
forall {
A}
n (
l:
list A),
(
length (
drop n l) =
length l -
n)%
nat.
Proof.
induction n;
simpl;
intros;
eauto.
omega.
rewrite IHn.
rewrite length_tl.
omega.
Qed.