Section RList.
Require Import List ListSet.
Require Import Bool.
Require Import RUtil.
Require Import Permutation.
Require Import Equivalence.
Require Import Morphisms.
Require Import Setoid.
Require Import EquivDec.
Require Import RelationClasses.
Require Import Omega.
Section misc.
Context {
A:
Type}.
Definition singleton {
A} (
x:
A) :
list A :=
x::
nil.
Lemma is_nil_dec (
l:
list A) : {
l =
nil} + {
l <>
nil}.
Proof.
destruct l.
- eauto.
- right; inversion 1.
Qed.
Fixpoint lflatten (
l:
list (
list A)) :
list A :=
match l with
|
nil =>
nil
|
l1 ::
l' =>
l1 ++ (
lflatten l')
end.
Lemma flat_map_app {
B} (
f:
A->
list B)
l1 l2 :
flat_map f (
l1 ++
l2) =
flat_map f l1 ++
flat_map f l2.
Proof.
induction l1;
simpl;
trivial.
rewrite app_ass.
congruence.
Qed.
Lemma map_nil f l :
map f l = (@
nil A) <->
l = (@
nil A).
Proof.
split; intros.
- induction l; try reflexivity; simpl in *.
congruence.
- rewrite H; reflexivity.
Qed.
Lemma eq_means_same_length :
forall (
l1 l2:
list A),
l1 =
l2 -> (
length l1) = (
length l2).
Proof.
intros; rewrite H; reflexivity.
Qed.
Lemma app_cons_middle (
l1 l2:
list A) (
a:
A) :
l1 ++ (
a::
l2) = (
l1 ++ (
a::
nil))++
l2.
Proof.
induction l1.
reflexivity.
simpl.
rewrite IHl1.
reflexivity.
Qed.
End misc.
Lemma map_app_break {
A B:
Type} (
f:
A->
B) {
a b c} :
map f a =
b ++
c ->
{
b':
list A & {
c' :
list A |
a =
b' ++
c' /\
b =
map f b' /\
c =
map f c'}}.
Proof.
revert a c.
induction b;
simpl;
intros a'
c eqq.
-
exists nil;
exists a';
auto.
-
destruct a';
simpl in eqq;
try discriminate.
invcs eqq.
destruct (
IHb _ _ H1)
as [
b' [
c' [? [??]]]];
subst.
exists (
a0::
b');
exists c';
auto.
Qed.
Lemma map_inj_strong {
A B} (
f g:
A->
B) (
l1 l2:
list A)
(
inj:
forall (
x y:
A),
In (
f x) (
map f l1) ->
In (
g y) (
map g l2) ->
f x =
g y ->
x =
y) :
map f l1 =
map g l2 ->
l1 =
l2.
Proof.
revert l2 inj.
induction l1; simpl; destruct l2; simpl; intros inj eqq; trivial; try discriminate.
invcs eqq.
f_equal; auto.
Qed.
Lemma map_inj {
A B} (
f g:
A->
B) (
l1 l2:
list A)
(
inj:
forall (
x y:
A),
f x =
g y ->
x =
y) :
map f l1 =
map g l2 ->
l1 =
l2.
Proof.
Section folds.
Context {
A B C:
Type}.
Lemma fold_left_map
(
f:
A ->
C ->
A) (
g:
B->
C) (
l:
list B) (
init:
A) :
fold_left f (
map g l)
init =
fold_left (
fun a b =>
f a (
g b))
l init.
Proof.
revert init.
induction l; simpl; trivial.
Qed.
Lemma fold_left_ext
(
f g:
A ->
B ->
A) (
l:
list B) (
init:
A) :
(
forall x y,
f x y =
g x y) ->
fold_left f l init =
fold_left g l init.
Proof.
intros eqq.
revert init.
induction l; simpl; trivial; intros.
rewrite eqq, IHl.
trivial.
Qed.
Lemma fold_right_app_map_singleton l :
fold_right (
fun a b :
list A =>
a ++
b)
nil
(
map (
fun x :
A => (
x::
nil))
l) =
l.
Proof.
induction l; simpl; congruence.
Qed.
Lemma fold_right_perm (
f :
A ->
A ->
A)
(
assoc:
forall x y z :
A,
f x (
f y z) =
f (
f x y)
z)
(
comm:
forall x y :
A,
f x y =
f y x) (
l1 l2:
list A) (
unit:
A)
(
perm:
Permutation l1 l2) :
fold_right f unit l1 =
fold_right f unit l2.
Proof.
revert l1 l2 perm.
apply Permutation_ind_bis;
simpl;
intros.
-
trivial.
-
rewrite H0;
trivial.
-
rewrite assoc, (
comm y x), <-
assoc,
H0;
trivial.
-
rewrite H0,
H2;
trivial.
Qed.
End folds.
Section Forall.
Context {
A:
Type}.
Lemma Forall_dec_defined {
P} :
(
forall x:
A, {
P x} + { ~
P x }) ->
forall l:
list A, {
Forall P l} + {~
Forall P l}.
Proof.
intro Pdec.
induction l as [|
a l'
Hrec].
-
left.
apply Forall_nil.
-
destruct Hrec as [
Hl'|
Hl'].
+
destruct (
Pdec a)
as [
Ha|
Ha].
*
left.
now apply Forall_cons.
*
right.
now inversion_clear 1.
+
right.
now inversion_clear 1.
Defined.
End Forall.
Section filter.
Context {
A:
Type}.
Lemma filter_length :
forall (
p:
A ->
bool),
forall (
l:
list A),
length l >=
length (
filter p l).
Proof.
intros.
induction l;
simpl.
-
auto.
-
elim (
two_cases p a);
intro;
rewrite H;
simpl;
auto with arith.
Qed.
Lemma filter_smaller :
forall (
p:
A ->
bool),
forall (
l:
list A),
forall (
x:
A),
filter p l <>
x::
l.
Proof.
Lemma filter_filter :
forall (
p:
A ->
bool),
forall (
s:
list A),
filter p (
filter p s) =
filter p s.
Proof.
induction s.
-
reflexivity.
-
simpl.
elim (
two_cases p a);
intro.
rewrite H.
simpl.
rewrite H.
rewrite IHs.
reflexivity.
rewrite H;
rewrite IHs;
reflexivity.
Qed.
Lemma filter_not_filter:
forall (
p:
A ->
bool),
forall (
s:
list A),
filter p (
filter (
fun x =>
negb (
p x))
s) =
nil.
Proof.
induction s.
-
simpl;
reflexivity.
-
simpl;
elim (
two_cases p a);
intro;
rewrite H;
simpl.
rewrite IHs;
reflexivity.
rewrite H;
assumption.
Qed.
Lemma filter_id_implies_pred :
forall (
p:
A ->
bool),
forall (
l:
list A),
filter p l =
l ->
forall (
y:
A), (
In y l -> (
p y =
true)).
Proof.
intros.
induction l;
simpl in *;
try contradiction.
elim (
two_cases p a);
intro.
rewrite H1 in H.
elim H0;
intro.
rewrite <-
H2;
assumption.
apply IHl.
inversion H.
rewrite filter_filter;
reflexivity.
assumption.
rewrite H1 in H.
clear H0 IHl H1.
assert False.
apply (
filter_smaller p l a);
assumption.
contradiction.
Qed.
Lemma filter_nil_implies_not_pred :
forall (
p:
A ->
bool),
forall (
l:
list A),
filter p l =
nil ->
forall (
y:
A), (
In y l -> (
p y =
false)).
Proof.
intros.
induction l;
simpl in *;
try contradiction.
elim (
two_cases p a);
intro;
rewrite H1 in H.
elim H0;
intro;
try discriminate.
elim H0;
intro.
rewrite <-
H2;
assumption.
apply IHl;
assumption.
Qed.
Lemma filter_comm:
forall (
x:
list A) (
p1 p2:
A ->
bool),
(
filter p1 (
filter p2 x)) = (
filter p2 (
filter p1 x)).
Proof.
intros.
induction x.
simpl;
reflexivity.
simpl.
generalize (
four_cases p1 p2 a);
intros.
elim H;
intro H1;
elim H1;
intro H2;
elim H2;
intros C1 C2;
clear H H1 H2;
rewrite C1;
rewrite C2;
simpl.
-
rewrite C1;
rewrite C2;
rewrite IHx;
reflexivity.
-
rewrite C2;
rewrite IHx;
reflexivity.
-
rewrite C1;
rewrite IHx;
reflexivity.
-
rewrite IHx;
reflexivity.
Qed.
Lemma filter_and:
forall (
x:
list A) (
p1 p2:
A ->
bool),
(
filter p1 (
filter p2 x)) = (
filter (
fun a =>
andb (
p1 a) (
p2 a))
x).
Proof.
intros.
induction x.
simpl;
reflexivity.
simpl.
generalize (
four_cases p1 p2 a);
intros.
elim H;
intro H1;
elim H1;
intro H2;
elim H2;
intros C1 C2;
clear H H1 H2;
rewrite C1;
rewrite C2;
simpl;
try rewrite C1;
rewrite IHx;
reflexivity.
Qed.
Lemma filter_eq:
forall (
p1 p2:
A ->
bool),
(
forall x:
A,
p1 x =
p2 x) -> (
forall l:
list A,
filter p1 l =
filter p2 l).
Proof.
intros.
induction l.
simpl;
reflexivity.
simpl;
rewrite <-
H.
generalize (
two_cases p1 a);
intros;
elim H0;
intros;
clear H0;
rewrite H1.
rewrite IHl;
reflexivity.
rewrite IHl;
reflexivity.
Qed.
Lemma false_filter_nil {
f} {
l:
list A} :
(
forall x,
In x l ->
f x =
false) ->
filter f l =
nil.
Proof.
induction l; simpl; trivial.
intros.
generalize (H a); intuition.
rewrite H0.
apply IHl; intuition.
Qed.
Lemma filter_app (
f:
A->
bool)
l1 l2 :
filter f (
l1 ++
l2) =
filter f l1 ++
filter f l2.
Proof.
induction l1; simpl; intuition.
match_destr.
rewrite IHl1; simpl; trivial.
Qed.
Lemma Forall_filter {
P} {
l:
list A}
f :
Forall P l ->
Forall P (
filter f l).
Proof.
induction l; simpl; trivial.
inversion 1; subst.
destruct (f a); auto.
Qed.
Lemma find_filter f (
l:
list A) :
find f l =
hd_error (
filter f l).
Proof.
induction l; simpl; trivial.
destruct (f a); simpl; auto.
Qed.
Lemma filter_ext (
f g :
A ->
bool) (
l :
list A) :
(
forall x,
In x l ->
f x =
g x) ->
filter f l =
filter g l.
Proof.
induction l; simpl; trivial; intros.
rewrite IHl by intuition.
rewrite (H a) by intuition.
trivial.
Qed.
Lemma true_filter (
f :
A ->
bool) (
l :
list A) :
(
forall x :
A,
In x l ->
f x =
true) ->
filter f l =
l.
Proof.
induction l; simpl; trivial; intros.
rewrite H, IHl; intuition.
Qed.
End filter.
Lemma forall_in_dec {
A:
Type}
P (
l:
list A)
(
dec:
forall x,
In x l -> {
P x} + {~
P x}):
{
forall x,
In x l ->
P x} + {~
forall x,
In x l ->
P x}.
Proof.
induction l; simpl.
- left; intuition.
- simpl in dec.
destruct (dec a); [intuition | | ].
+ destruct IHl.
* simpl in dec; intuition.
* left; intuition. subst; intuition.
* right. intuition.
+ right. intuition.
Defined.
Lemma exists_in_dec {
A:
Type}
P (
l:
list A)
(
dec:
forall x,
In x l -> {
P x} + {~
P x}):
{
exists x,
In x l /\
P x} + {~
exists x,
In x l /\
P x}.
Proof.
induction l; simpl.
- right. intros [??]; intuition.
- simpl in dec.
destruct (dec a); [intuition | | ].
+ left; eauto.
+ destruct IHl.
* simpl in dec; intuition.
* left. destruct e as [?[??]]; eauto.
* right. intros [?[[?|?]?]]; subst; intuition; eauto.
Defined.
Lemma exists_nforall_in_dec {
A:
Type}
P (
l:
list A)
(
dec:
forall x,
In x l -> {
P x} + {~
P x}):
{
exists x,
In x l /\
P x} + {
forall x,
In x l -> ~
P x}.
Proof.
induction l; simpl.
- right. intuition.
- simpl in dec.
destruct (dec a); [intuition | | ].
+ left; eauto.
+ destruct IHl.
* simpl in dec; intuition.
* left. destruct e as [?[??]]; eauto.
* right. intros ? [?|?]; subst; intuition; eauto.
Defined.
Lemma existsb_ex {
A :
Type} (
f :
A ->
bool) (
l :
list A) :
existsb f l =
true -> {
x :
A |
In x l /\
f x =
true}.
Proof.
induction l;
simpl;
intros.
-
discriminate.
-
case_eq (
existsb f l);
intros exx.
+
destruct (
IHl exx)
as [?[??]].
exists x;
intuition.
+
case_eq (
f a);
intros faa.
*
exists a;
intuition.
*
rewrite exx,
faa in H.
discriminate.
Qed.
Section perm_equiv.
Context {
A:
Type}.
Context {
eqdec:
EqDec A eq}.
Definition ldeqA := (@
Permutation A).
Definition rbag :=
list A.
Global Instance perm_equiv :
Equivalence (@
Permutation A).
Proof.
End perm_equiv.
Section list2.
Context {
A B:
Type}.
Section fb2.
Context (
f:
A->
B->
bool).
Fixpoint forallb2 (
l1:
list A) (
l2:
list B):
bool :=
match l1,
l2 with
|
nil,
nil =>
true
|
a1::
l1,
a2::
l2 =>
f a1 a2 &&
forallb2 l1 l2
|
_,
_ =>
false
end.
Lemma forallb2_forallb :
forall (
l1:
list A) (
l2:
list B),
(
length l1 =
length l2) ->
forallb (
fun xy =>
f (
fst xy) (
snd xy)) (
combine l1 l2) =
forallb2 l1 l2.
Proof.
induction l1; destruct l2; simpl; intuition.
f_equal; auto.
Qed.
Lemma forallb2_forallb_true :
forall (
l1:
list A) (
l2:
list B),
(
length l1 =
length l2 /\
forallb (
fun xy =>
f (
fst xy) (
snd xy)) (
combine l1 l2) =
true)
<->
forallb2 l1 l2 =
true.
Proof.
Hint Unfold iff.
induction l1;
destruct l2;
simpl;
intuition;
repeat rewrite andb_true_iff in *;
firstorder.
Qed.
Lemma forallb2_Forallb :
forall l1 l2,
forallb2 l1 l2 =
true <->
Forall2 (
fun x y =>
f x y =
true)
l1 l2.
Proof.
Hint Constructors Forall2.
Ltac inv :=
try match goal with
| [
H:
Forall2 _ _ (
_::
_) |-
_ ] =>
inversion H;
clear H
| [
H:
Forall2 _ (
_::
_)
_ |-
_ ] =>
inversion H;
clear H
end;
firstorder.
induction l1;
destruct l2;
simpl;
intuition;
inv;
repeat rewrite andb_true_iff in *;
firstorder.
Qed.
End fb2.
Lemma Forall2_incl :
forall (
f1 f2:
A->
B->
Prop)
l1 l2,
(
forall x y,
In x l1 ->
In y l2 ->
f1 x y->
f2 x y) ->
Forall2 f1 l1 l2 ->
Forall2 f2 l1 l2.
Proof.
Hint Constructors Forall2.
intros.
induction H0;
firstorder.
Qed.
Lemma forallb2_eq :
forall (
f1 f2:
A->
B->
bool)
l1 l2,
(
forall x y,
In x l1 ->
In y l2 ->
f1 x y =
f2 x y) ->
forallb2 f1 l1 l2 =
forallb2 f2 l1 l2.
Proof.
induction l1; destruct l2; simpl; intuition.
f_equal; auto.
Qed.
End list2.
Section forall2.
Lemma forallb2_sym {
A B} :
forall (
f:
A->
B->
bool) {
l1 l2},
forallb2 f l1 l2 =
forallb2 (
fun x y =>
f y x)
l2 l1.
Proof.
induction l1; destruct l2; simpl; intuition.
f_equal; trivial.
Qed.
Lemma Forall2_map {
A B C D} (
f:
C->
D->
Prop) (
g:
A->
C) (
h:
B->
D)
a b:
Forall2 (
fun x y =>
f (
g x) (
h y))
a b <->
Forall2 f (
map g a) (
map h b).
Proof.
revert b.
induction a; destruct b; simpl; split; inversion 1;
eauto 2; subst; firstorder.
Qed.
Lemma Forall2_map_f {
A B C D} (
f:
C->
D->
Prop) (
g:
A->
C) (
h:
B->
D)
a b:
Forall2 (
fun x y =>
f (
g x) (
h y))
a b ->
Forall2 f (
map g a) (
map h b).
Proof.
Lemma Forall2_map_b {
A B C D} (
f:
C->
D->
Prop) (
g:
A->
C) (
h:
B->
D)
a b:
Forall2 f (
map g a) (
map h b) ->
Forall2 (
fun x y =>
f (
g x) (
h y))
a b.
Proof.
Lemma Forall2_length {
A B} (
f:
A->
B->
Prop)
a b:
Forall2 f a b ->
length a =
length b.
Proof.
revert b;
induction a; inversion 1; subst; simpl; intuition.
Qed.
Global Instance Forall2_refl {
A}
R `{
Reflexive A R} :
Reflexive (
Forall2 R).
Proof.
red.
induction x; simpl; trivial.
constructor; auto.
Qed.
Global Instance Forall2_sym {
A}
R `{
Symmetric A R} :
Symmetric (
Forall2 R).
Proof.
red.
induction x; simpl; inversion 1; subst; trivial.
constructor; auto.
Qed.
Global Instance Forall2_trans {
A}
R `{
Transitive A R} :
Transitive (
Forall2 R).
Proof.
red.
induction x; simpl; inversion 1; subst; trivial.
inversion 1; subst.
constructor; eauto.
Qed.
Global Instance Forall2_pre {
A}
R `{
PreOrder A R} :
PreOrder (
Forall2 R).
Proof.
Global Instance Forall2_part_eq {
A}
R `{
PartialOrder A eq R } :
PartialOrder eq (
Forall2 R).
Proof.
intros l1 l2.
split;
intros HH.
-
repeat red;
subst;
intuition.
-
repeat red in HH;
intuition.
revert l2 H0 H1.
induction l1;
destruct l2;
trivial;
intros F1 F2;
invcs F1;
invcs F2.
+
f_equal.
*
apply antisymmetry;
trivial.
*
apply IHl1;
trivial.
Qed.
Lemma Forall2_trans_relations_weak {
A B C}
(
R1:
A->
B->
Prop) (
R2:
B->
C->
Prop) (
R3:
A->
C->
Prop):
(
forall a b c,
R1 a b ->
R2 b c ->
R3 a c) ->
forall a b c,
Forall2 R1 a b ->
Forall2 R2 b c ->
Forall2 R3 a c.
Proof.
intros pf.
induction a; intros b c Fab Fbc
; invcs Fab; invcs Fbc; eauto.
Qed.
Lemma Forall2_eq {
A} (
l1 l2:
list A):
Forall2 eq l1 l2 <->
l1 =
l2.
Proof.
split; intros; subst; [ | reflexivity ].
revert l2 H; induction l1; inversion 1; subst; trivial.
f_equal; eauto.
Qed.
Lemma Forall2_flip {
A B} {
P:
A->
B->
Prop} {
l1 l2} :
Forall2 P l1 l2 ->
Forall2 (
fun x y =>
P y x)
l2 l1.
Proof.
revert l2; induction l1; simpl; inversion 1; subst; auto.
Qed.
Lemma Forall2_In_l {
A B} {
P:
A->
B->
Prop} {
l1 l2 a} :
Forall2 P l1 l2 ->
In a l1 ->
exists b,
In b l2 /\
P a b.
Proof.
revert l2 a. induction l1; simpl; [intuition |].
inversion 1; subst; intros.
intuition; subst; simpl; eauto.
destruct (IHl1 _ _ H4 H1); intuition; eauto.
Qed.
Lemma Forall2_In_r {
A B} {
P:
A->
B->
Prop} {
l1 l2 b} :
Forall2 P l1 l2 ->
In b l2 ->
exists a,
In a l1 /\
P a b.
Proof.
Lemma Forall2_app_tail_inv {
A B}
P l1 l2 a1 a2 :
@
Forall2 A B P (
l1 ++ (
a1::
nil)) (
l2 ++ (
a2::
nil)) ->
Forall2 P l1 l2 /\
P a1 a2.
Proof.
intros.
destruct (
Forall2_app_inv_l _ _ H)
as [?[?[
f1 [
f2 eqq]]]].
inversion f2;
subst.
inversion H4;
subst.
apply app_inj_tail in eqq.
destruct eqq;
subst.
auto.
Qed.
Lemma filter_Forall2_same {
A B}
P f g (
l1:
list A) (
l2:
list B) :
Forall2 P l1 l2 ->
map f l1 =
map g l2 ->
Forall2 P (
filter f l1) (
filter g l2).
Proof.
revert l2.
induction l1; simpl; inversion 1; subst; simpl; trivial.
inversion 1.
rewrite H3.
match_destr.
+ constructor; auto.
+ auto.
Qed.
Lemma Forall2_map_Forall {
A B:
Type} (
P:
A->
B->
Prop) (
f:
A->
B)
l :
Forall2 P l (
map f l) <->
Forall (
fun x =>
P x (
f x))
l.
Proof.
split
; induction l; simpl; trivial
; inversion 1; subst; auto.
Qed.
End forall2.
Section forallb_ordpairs.
Fixpoint forallb_ordpairs {
A}
f (
l:
list A)
:=
match l with
|
nil =>
true
|
x::
ls =>
forallb (
f x)
ls &&
forallb_ordpairs f ls
end.
Lemma forallb_ordpairs_ForallOrdPairs {
A}
f (
l:
list A) :
forallb_ordpairs f l =
true <-> (
ForallOrdPairs (
fun x y =>
f x y =
true)
l).
Proof.
Lemma forallb_ordpairs_ext {
A}
f1 f2 (
l:
list A) :
(
forall x y,
In x l ->
In y l ->
f1 x y =
f2 x y) ->
forallb_ordpairs f1 l =
forallb_ordpairs f2 l.
Proof.
induction l;
simpl;
trivial;
intros.
rewrite IHl.
-
f_equal.
apply forallb_ext.
intuition.
-
intuition.
Qed.
Fixpoint forallb_ordpairs_refl {
A} (
f:
A->
A->
bool) (
l:
list A)
:=
match l with
|
nil =>
true
|
x::
ls =>
forallb (
f x) (
x::
ls) &&
forallb_ordpairs_refl f ls
end.
Lemma forallb_ordpairs_refl_conj A f (
l:
list A) :
forallb_ordpairs_refl f l =
forallb_ordpairs f l &&
forallb (
fun x =>
f x x)
l.
Proof.
Lemma forallb_ordpairs_app_cons {
A}
f (
l:
list A)
x :
forallb_ordpairs f l =
true ->
forallb (
fun y =>
f y x)
l =
true ->
forallb_ordpairs f (
l ++
x::
nil) =
true.
Proof.
induction l;
simpl;
trivial.
repeat rewrite andb_true_iff in * .
repeat rewrite forallb_forall in * .
simpl in * .
intuition.
rewrite in_app_iff in H0.
simpl in H0.
intuition.
congruence.
Qed.
Lemma forallb_ordpairs_refl_app_cons {
A}
f (
l:
list A)
x :
forallb_ordpairs_refl f l =
true ->
f x x =
true ->
forallb (
fun y =>
f y x)
l =
true ->
forallb_ordpairs_refl f (
l ++
x::
nil) =
true.
Proof.
End forallb_ordpairs.
Lemma app_cons_cons_expand {
A} (
l:
list A)
a b :
l ++
a::
b::
nil = (
l ++
a ::
nil)++
b::
nil.
Proof.
rewrite app_ass.
simpl.
trivial.
Qed.
Section remove.
Context {
A:
Type}.
Context {
eqdec:
EqDec A eq}.
Lemma remove_in_neq
(
l :
list A) (
x y :
A) :
x <>
y ->
(
In x l <->
In x (
remove eqdec y l)).
Proof.
intros neq.
induction l;
simpl;
intuition;
subst.
-
destruct (
eqdec y x);
subst;
intuition.
-
destruct (
eqdec y a);
subst;
intuition.
-
destruct (
eqdec y a);
subst;
intuition.
simpl in *;
intuition.
Qed.
Lemma list_in_remove_impl_diff x y l:
In x (
remove eqdec y l) ->
x <>
y.
Proof.
case (
equiv_dec x y);
try congruence.
intros Heq;
rewrite Heq in *;
clear Heq.
intros H.
apply remove_In in H.
contradiction.
Qed.
Lemma list_remove_append_distrib:
forall (
v:
A) (
l1 l2:
list A),
remove eqdec v l1 ++
remove eqdec v l2 =
remove eqdec v (
l1 ++
l2).
Proof.
intros.
induction l1;
try reflexivity.
simpl.
destruct (
eqdec v a).
-
assumption.
-
simpl;
rewrite IHl1;
reflexivity.
Qed.
Lemma list_remove_idempotent:
forall v l,
remove eqdec v (
remove eqdec v l) =
remove eqdec v l.
Proof.
intros.
induction l;
try reflexivity.
simpl.
destruct (
eqdec v a).
-
assumption.
-
simpl.
destruct (
eqdec v a);
congruence.
Qed.
Lemma list_remove_commute:
forall v1 v2 l,
remove eqdec v1 (
remove eqdec v2 l) =
remove eqdec v2 (
remove eqdec v1 l).
Proof.
induction l;
try reflexivity.
simpl.
destruct (
eqdec v2 a);
destruct (
eqdec v1 a);
simpl.
-
assumption.
-
rewrite e in *.
destruct (
eqdec a a);
congruence.
-
rewrite e in *.
destruct (
eqdec a a);
congruence.
-
destruct (
eqdec v1 a);
destruct (
eqdec v2 a);
simpl.
+
assumption.
+
congruence.
+
congruence.
+
rewrite IHl;
reflexivity.
Qed.
Remark list_remove_in v1 v2 l1 l2:
(
In v1 l1 ->
In v1 l2) ->
In v1 (
remove eqdec v2 l1) ->
In v1 (
remove eqdec v2 l2).
Proof.
intros Hl1l2 Hl1rm.
case (
eqdec v1 v2).
-
intros Heq;
rewrite Heq in *;
clear Heq.
assert (~
In v2 (
remove eqdec v2 l1));
try contradiction.
apply remove_In.
-
intros Heq.
apply remove_in_neq;
try congruence.
apply remove_in_neq in Hl1rm;
try congruence.
apply Hl1l2.
assumption.
Qed.
Lemma remove_inv v n l:
In v (
remove eqdec n l) ->
In v l /\
v <>
n.
Proof.
induction l;
intros;
simpl in *.
-
contradiction.
-
destruct (
eqdec n a).
elim (
IHl H);
intros;
auto;
simpl in *.
elim H;
clear H;
intros;
subst;
auto.
elim (
IHl H);
intros;
auto.
Qed.
Lemma not_in_remove_impl_not_in:
forall x v l,
x <>
v ->
~
In x (
remove eqdec v l) ->
~
In x l.
Proof.
intros x v l.
intros Hneq Hx.
induction l.
-
simpl.
trivial.
-
simpl.
unfold not.
intros H.
destruct H.
+
rewrite H in *;
clear H.
simpl in Hx.
case (
eqdec v x)
in Hx;
try congruence.
simpl in Hx.
apply Decidable.not_or in Hx.
destruct Hx.
congruence.
+
simpl in Hx.
case (
eqdec v a)
in Hx;
try congruence.
*
simpl in Hx.
apply IHl in Hx.
contradiction.
*
simpl in Hx.
apply Decidable.not_or in Hx.
destruct Hx.
apply IHl in H1.
contradiction.
Qed.
Fixpoint remove_all (
x :
A) (
l :
list A) :
list A :=
match l with
|
nil =>
nil
|
y::
tl =>
if (
x ==
y)
then (
remove_all x tl)
else y::(
remove_all x tl)
end.
Global Instance remove_all_proper :
Proper (
eq ==>
ldeqA ==>
ldeqA)
remove_all.
Proof.
unfold Proper,
respectful.
intros;
rewrite H.
elim H0;
intros;
simpl.
-
reflexivity.
-
destruct (
equiv_dec y x1);
rewrite H2;
reflexivity.
-
destruct (
equiv_dec y x1);
destruct (
equiv_dec y y1);
try reflexivity.
apply perm_swap.
-
rewrite H2;
rewrite H4;
reflexivity.
Qed.
Lemma remove_all_filter x l:
remove_all x l =
filter (
nequiv_decb x)
l.
Proof.
Lemma remove_all_app (
v:
A)
l1 l2
:
remove_all v (
l1 ++
l2) =
remove_all v l1 ++
remove_all v l2.
Proof.
Lemma fold_left_remove_all_In {
l init a} :
In a (
fold_left (
fun (
a :
list A) (
b :
A) =>
filter (
nequiv_decb b)
a)
l init)
->
In a init /\ ~
In a l.
Proof.
End remove.
Lemma nin_remove {
A}
dec (
l:
list A)
a :
~
In a l ->
remove dec a l =
l.
Proof.
induction l; simpl; trivial.
match_destr; intuition; congruence.
Qed.
Section repall.
Context {
A:
Type}.
Context `{
eqdec:
EqDec A eq}.
Definition replace_all l v n
:=
map (
fun x =>
if eqdec x v then n else x)
l.
Lemma replace_all_nin l v n :
~
In v l ->
map (
fun x =>
if eqdec x v then n else x)
l =
l.
Proof.
induction l;
simpl;
intuition.
destruct (
eqdec a v);
congruence.
Qed.
Lemma replace_all_remove_neq l v0 v n:
v <>
v0 ->
n <>
v0 ->
remove eqdec v0
(
map (
fun x =>
if eqdec x v then n else x)
l) =
(
map (
fun x =>
if eqdec x v then n else x)
(
remove eqdec v0 l)).
Proof.
induction l;
simpl;
intuition.
rewrite H2.
destruct (
eqdec a v);
subst;
simpl.
-
destruct (
eqdec v0 n);
subst;
simpl;
intuition.
destruct (
eqdec v0 a);
subst;
simpl; [
congruence|].
rewrite e in *;
clear e.
destruct (
eqdec v v);
intuition.
-
destruct (
eqdec v0 a);
trivial;
simpl.
destruct (
eqdec a v);
subst;
intuition.
Qed.
Lemma remove_replace_all_nin l v v' :
~
In v'
l ->
remove eqdec v' (
replace_all l v v') =
remove eqdec v l.
Proof.
induction l;
simpl;
intuition.
rewrite H.
destruct (
eqdec a v);
simpl;
try (
rewrite e in *;
clear e).
-
destruct (
eqdec v v);
intuition;
destruct (
eqdec v'
v');
intuition.
-
destruct (
eqdec v a);
intuition;
destruct (
eqdec v'
a);
intuition.
Qed.
Definition flat_replace_all l (
v:
A)
n
:=
flat_map (
fun x =>
if eqdec x v then n else (
x::
nil))
l.
Lemma flat_replace_all_nil l (
v:
A) :
flat_replace_all l v nil = @
remove_all A eqdec v l.
Proof.
induction l; simpl; trivial.
match_destr; match_destr; simpl; try congruence.
Qed.
Lemma flat_replace_all_app l1 l2 (
v:
A)
n
:
flat_replace_all (
l1 ++
l2)
v n
=
flat_replace_all l1 v n ++
flat_replace_all l2 v n.
Proof.
Lemma fold_left_remove_all_nil_in_inv {
B} {
x ps l}:
In x (
fold_left
(
fun (
h :
list nat) (
xy :
nat *
B) =>
remove_all (
fst xy)
h)
ps l) ->
In x l.
Proof.
Lemma fold_left_remove_all_nil_in_inv' {
x ps l}:
In x (
fold_left
(
fun (
h :
list nat) (
xy :
nat) =>
remove_all xy h)
ps l) ->
In x l.
Proof.
Lemma fold_left_remove_all_nil_in_not_inv' {
x ps l}:
In x (
fold_left
(
fun (
h :
list nat) (
xy :
nat ) =>
remove_all xy h)
ps l) ->
~
In x ps.
Proof.
revert l.
induction ps;
simpl;
intuition;
subst.
-
simpl in *.
apply fold_left_remove_all_nil_in_inv'
in H.
rewrite remove_all_filter in H.
apply filter_In in H.
unfold nequiv_decb,
equiv_decb in *.
intuition.
match_destr_in H1.
congruence.
-
eauto.
Qed.
Lemma replace_all_remove_eq (
l :
list A) (
v n :
A) :
map (
fun x :
A =>
if eqdec x v then n else x) (
remove eqdec v l) = (
remove eqdec v l).
Proof.
End repall.
Section incl.
Definition cut_down_to {
A B} {
dec:
EqDec A eq} (
l:
list (
A*
B)) (
l2:
list A) :=
filter (
fun a =>
existsb (
fun z => (
fst a) ==
b z)
l2)
l.
Lemma cut_down_to_in
{
A B} {
dec:
EqDec A eq}
(
l:
list (
A*
B))
l2 a :
In a (
cut_down_to l l2) <->
In a l /\
In (
fst a)
l2 .
Proof.
Lemma cut_down_to_app {
A B} {
dec:
EqDec A eq}
(
l l':
list (
A*
B))
l2 :
cut_down_to (
l++
l')
l2 =
cut_down_to l l2 ++
cut_down_to l'
l2.
Proof.
Lemma incl_dec {
A} {
dec:
EqDec A eq} (
l1 l2:
list A) :
{
incl l1 l2} + {~
incl l1 l2}.
Proof.
unfold incl.
induction l1.
-
left;
inversion 1.
-
destruct IHl1.
+
destruct (
in_dec dec a l2).
*
left;
simpl;
intros;
intuition;
congruence.
*
right;
simpl;
intros inn;
apply n;
intuition.
+
right;
simpl;
intros inn;
apply n;
intuition.
Defined.
Global Instance incl_pre A :
PreOrder (@
incl A).
Proof.
unfold incl.
constructor;
red;
intuition.
Qed.
Lemma set_inter_contained {
A}
dec (
l l':
list A):
(
forall a,
In a l ->
In a l') ->
set_inter dec l l' =
l.
Proof.
induction l;
simpl;
intuition.
case_eq (
set_mem dec a l');
trivial.
-
rewrite IHl;
auto.
-
intros ninn.
apply set_mem_complete1 in ninn.
elim ninn.
apply H;
intuition.
Qed.
Lemma set_inter_idempotent {
A}
dec (
l:
list A):
set_inter dec l l =
l.
Proof.
Lemma set_inter_comm_in {
A}
dec a b :
(
forall x,
In x (@
set_inter A dec a b) ->
In x (
set_inter dec b a)) .
Proof.
Lemma nincl_exists {
A} {
dec:
EqDec A eq} (
l1 l2:
list A) :
~
incl l1 l2 -> {
x |
In x l1 /\ ~
In x l2}.
Proof.
unfold incl.
induction l1;
simpl.
-
intuition.
-
intros.
destruct (
in_dec dec a l2).
+
destruct IHl1.
*
intros inn.
apply H.
intuition;
subst;
trivial.
*
exists x;
intuition.
+
exists a;
intuition.
Qed.
End incl.
Section equivlist.
Context {
A:
Type}.
Definition equivlist (
l l':
list A)
:=
forall x,
In x l <->
In x l'.
Global Instance equivlist_equiv :
Equivalence equivlist.
Proof.
constructor;
red;
unfold equivlist;
firstorder.
Qed.
Global Instance Permutation_equivlist :
subrelation (@
Permutation A)
equivlist.
Proof.
Lemma equivlist_in {
l1 l2} :
equivlist l1 l2 -> (
forall x:
A,
In x l1 ->
In x l2).
Proof.
intros e x inn. specialize (e x); intuition.
Qed.
Lemma equivlist_incls (
l1 l2:
list A) :
equivlist l1 l2 <-> (
incl l1 l2 /\
incl l2 l1).
Proof.
Global Instance equivlist_In_proper :
Proper (
eq ==>
equivlist ==>
iff) (@
In A).
Proof.
Lemma equivlist_dec {
dec:
EqDec A eq} (
l1 l2:
list A) :
{
equivlist l1 l2} + {~
equivlist l1 l2}.
Proof.
Lemma equivlist_nil {
l:
list A} :
equivlist l nil ->
l =
nil.
Proof.
destruct l; trivial.
intros inn.
destruct (inn a); simpl in *.
intuition.
Qed.
Lemma app_idempotent_equivlist (
l:
list A) :
equivlist (
l++
l)
l.
Proof.
Lemma app_commutative_equivlist (
l1 l2:
list A) :
equivlist (
l1++
l2) (
l2++
l1).
Proof.
Lemma app_contained_equivlist (
a b:
list A) :
incl b a ->
equivlist (
a ++
b)
a.
Proof.
Lemma set_inter_equivlist dec a b :
equivlist (@
set_inter A dec a b) (
set_inter dec b a) .
Proof.
Global Instance set_inter_equivlist_proper dec :
Proper (
equivlist ==>
equivlist ==>
equivlist) (@
set_inter A dec).
Proof.
Lemma equivlist_cons l1 l2 (
s:
A) :
equivlist l1 l2 ->
equivlist (
s::
l1) (
s::
l2).
Proof.
Global Instance equivlist_filter :
Proper (
eq ==>
equivlist ==>
equivlist) (@
filter A).
Proof.
red;
unfold equivlist;
intros ? ? ? ? ? ? ?;
subst.
repeat rewrite filter_In.
firstorder.
Qed.
Global Instance equivlist_remove_all {
dec:
EqDec A eq} :
Proper (
eq ==>
equivlist ==>
equivlist) (@
remove_all A dec).
Proof.
Lemma incl_list_dec (
dec:
forall x y:
A, {
x =
y} + {
x <>
y}) (
l1 l2:
list A) : {(
forall x,
In x l1 ->
In x l2)} + {~(
forall x,
In x l1 ->
In x l2)}.
Proof.
End equivlist.
Lemma set_inter_assoc {
A}
dec a b c:
@
set_inter A dec (
set_inter dec a b)
c
=
set_inter dec a (
set_inter dec b c).
Proof.
Section Assym_over.
Definition asymmetric_over {
A}
R (
l:
list A) :=
forall x y,
In x l->
In y l -> ~
R x y -> ~
R y x ->
x =
y.
Lemma asymmetric_asymmetric_over {
A} {
R} :
(
forall x y:
A, ~
R x y -> ~
R y x ->
x =
y) ->
forall l,
asymmetric_over R l .
Proof.
red; intuition.
Qed.
Lemma asymmetric_over_incl {
A} {
R} {
l2:
list A}
:
asymmetric_over R l2 ->
forall l1,
(
forall x,
In x l1 ->
In x l2) ->
asymmetric_over R l1.
Proof.
Lemma asymmetric_over_equivlist {
A} {
R} {
l1 l2:
list A} :
equivlist l1 l2 ->
(
asymmetric_over R l1 <->
asymmetric_over R l2).
Proof.
Lemma asymmetric_over_cons_inv {
A} {
R} {
a:
A} {
l1} :
asymmetric_over R (
a::
l1) ->
asymmetric_over R l1.
Proof.
Hint Resolve asymmetric_over_cons_inv.
Lemma asymmetric_over_swap {
A}
R {
a b:
A} {
l1} :
asymmetric_over R (
a::
b::
l1) ->
asymmetric_over R (
b::
a::
l1).
Proof.
End Assym_over.
Global Instance perm_in {
A} :
Proper (
eq ==> (@
Permutation A) ==>
iff) (@
In A).
Proof.
Hint Resolve Permutation_in Permutation_sym.
unfold Proper,
respectful;
intros;
subst;
intuition;
eauto.
Qed.
Lemma NoDup_perm' {
A:
Type} {
a b:
list A} :
NoDup a ->
Permutation a b ->
NoDup b.
Proof.
intros nd p.
revert nd.
revert a b p.
apply (
Permutation_ind_bis (
fun l l' =>
NoDup l ->
NoDup l'));
intuition.
-
inversion H1;
subst.
constructor;
eauto.
-
inversion H1;
subst.
inversion H5;
subst.
rewrite H in H4,
H6.
constructor; [|
constructor];
simpl in *;
intuition;
subst;
eauto.
Qed.
Global Instance NoDup_perm {
A:
Type} :
Proper (@
Permutation A ==>
iff) (@
NoDup A).
Proof.
Hint Resolve NoDup_perm'
Permutation_sym.
unfold Proper,
respectful;
intros;
subst;
intuition;
eauto.
Qed.
Lemma NoDup_Permutation' {
A :
Type} (
l l' :
list A) :
NoDup l ->
NoDup l' ->
equivlist l l' ->
Permutation l l'.
Proof.
Lemma NoDup_rev {
A:
Type} (
l:
list A) :
NoDup (
rev l) <->
NoDup l.
Proof.
Lemma NoDup_app_inv {
A:
Type} {
a b:
list A} :
NoDup (
a++
b) ->
NoDup a.
Proof.
Hint Resolve NoDup_app_inv.
Lemma NoDup_app_inv2 {
A:
Type} {
a b:
list A} :
NoDup (
a++
b) ->
NoDup b.
Proof.
Lemma NoDup_dec {
A:
Type} {
dec:
EqDec A eq} (
l:
list A): {
NoDup l} + {~
NoDup l}.
Proof.
induction l.
-
left;
constructor.
-
destruct (
in_dec equiv_dec a l).
+
right;
inversion 1;
congruence.
+
destruct IHl.
*
left;
constructor;
auto.
*
right;
inversion 1;
congruence.
Defined.
Section disj.
Definition disjoint {
A:
Type} (
l1 l2:
list A)
:=
forall x,
In x l1 ->
In x l2 ->
False.
Lemma NoDup_app_dis {
A:
Type} (
a b:
list A) :
NoDup (
a++
b) ->
disjoint a b.
Proof.
red;
intros.
destruct (
in_split _ _ H0)
as [
a1[
a2 aeq]].
subst.
rewrite <-
app_assoc in H.
apply NoDup_app_inv2 in H.
simpl in H.
inversion H;
subst.
simpl in *;
intuition.
Qed.
Lemma disjoint_cons_inv1 {
A:
Type} {
a:
A} {
l1 l2} :
disjoint (
a ::
l1)
l2 ->
disjoint l1 l2 /\ ~
In a l2.
Proof.
unfold disjoint;
simpl;
intuition.
apply (
H x);
intuition.
specialize (
H a);
intuition.
Qed.
Lemma disjoint_app_l {
A} (
l1 l2 l3:
list A) :
disjoint (
l1 ++
l2)
l3 <-> (
disjoint l1 l3 /\
disjoint l2 l3).
Proof.
Lemma disjoint_app_r {
A} (
l1 l2 l3:
list A) :
disjoint l1 (
l2 ++
l3) <-> (
disjoint l1 l2 /\
disjoint l1 l3).
Proof.
Lemma NoDup_app {
A:
Type} {
a b:
list A} :
disjoint a b ->
NoDup a ->
NoDup b ->
NoDup (
a++
b).
Proof.
revert b;
induction a;
intuition.
simpl;
inversion H0;
subst.
apply disjoint_cons_inv1 in H.
constructor;
intuition.
apply in_app_or in H2.
intuition.
Qed.
Global Instance disjoint_sym {
A:
Type} :
Symmetric (@
disjoint A).
Proof.
End disj.
Lemma unmap_NoDup {
A B} (
f:
A->
B)
l :
NoDup (
map f l) ->
NoDup l.
Proof.
induction l;
simpl.
-
constructor.
-
inversion 1;
subst.
econstructor;
eauto.
intros inn;
apply H2.
apply in_map_iff.
eauto.
Qed.
Lemma map_inj_NoDup {
A B} (
f:
A->
B)
(
inj:
forall x y,
f x =
f y ->
x =
y) (
l:
list A) :
NoDup l ->
NoDup (
map f l).
Proof.
induction l;
simpl.
-
constructor.
-
inversion 1;
subst.
econstructor;
eauto.
intros inn;
apply H2.
apply in_map_iff in inn.
destruct inn as [
x [
xeq xin]].
rewrite <- (
inj _ _ xeq).
trivial.
Qed.
Lemma filter_NoDup {
A} (
f:
A->
bool)
l :
NoDup l ->
NoDup (
filter f l).
Proof.
induction l;
simpl;
trivial.
match_destr;
intros.
-
inversion H;
constructor;
subst;
trivial.
+
rewrite filter_In.
intuition.
+
auto.
-
inversion H;
subst;
auto.
Qed.
Fixpoint zip {
A B} (
l1:
list A) (
l2:
list B) :
option (
list (
A *
B)) :=
match l1 with
|
nil =>
match l2 with
|
nil =>
Some nil
|
_ =>
None
end
|
x1 ::
l1' =>
match l2 with
|
nil =>
None
|
x2 ::
l2' =>
match zip l1'
l2'
with
|
None =>
None
|
Some l3 =>
Some ((
x1,
x2) ::
l3)
end
end
end.
End RList.