Module RRelation
Definition rondcoll2 (f:(list data -> list data -> list data)) (d1 d2:data) : option data :=
lift dcoll (ondcoll2 f d1 d2).
Definition ondnat {A} (f : Z -> A) (d : data) :=
match d with
| dnat n => Some (f n)
| _ => None
end.
Definition ondcoll {A} (f : list data -> A) (d : data) :=
match d with
| dcoll l => Some (f l)
| _ => None
end.
Definition lift_oncoll {A} (f : list data -> option A) (d : data) :=
match d with
| dcoll l => f l
| _ => None
end.
Lemma lift_oncoll_dcoll {A} (f : list data -> option A) (dl : list data) :
lift_oncoll f (dcoll dl) = f dl.
Proof.
reflexivity. Qed.
Lemma olift_on_lift_dcoll (f:list data->option data) (d1:option (list data)):
olift (lift_oncoll f) (lift dcoll d1) =
olift f d1.
Proof.
destruct d1; reflexivity.
Qed.
Lemma olift_lift_dcoll (f:list data -> option (list data)) (d1:option (list data)):
olift (fun c1 : list data => lift dcoll (f c1)) d1 =
lift dcoll (olift f d1).
Proof.
destruct d1; reflexivity.
Qed.
Lemma lift_dcoll_inversion d1 d2:
d1 = d2 -> lift dcoll d1 = lift dcoll d2.
Proof.
intros; rewrite H; reflexivity.
Qed.
Definition rondcoll (f:list data -> list data) (d:data) : option data :=
lift dcoll (ondcoll f d).
Lemma lift_filter_Forall {A} {f:A->option bool} {P} {l x} :
lift_filter f l = Some x ->
Forall P l ->
Forall P x.
Proof.
revert x;
induction l;
simpl.
-
inversion 1;
subst;
eauto.
-
match_case;
intros.
inversion H1;
subst.
destruct (
lift_filter f l);
simpl in *;
try discriminate;
intros.
destruct b;
inversion H0;
subst;
eauto.
Qed.
Fixpoint oflat_map {A B} (f : A -> option (list B)) (l:list A) : option (list B) :=
match l with
| nil => Some nil
| x :: t =>
match f x with
| None => None
| Some x' =>
lift (fun t' => x' ++ t') (oflat_map f t)
end
end.
Fixpoint rmap {A B} (f : A -> option B) (l:list A) : option (list B) :=
match l with
| nil => Some nil
| x :: t =>
match f x with
| None => None
| Some x' =>
lift (fun t' => x' :: t') (rmap f t)
end
end.
Lemma rmap_Forall {A B} {f:A->option B} {P} {l x} :
rmap f l = Some x ->
Forall P l ->
forall (P2:B->Prop),
(forall x z, f x = Some z -> P x -> P2 z) ->
Forall P2 x.
Proof.
revert x.
induction l;
simpl.
-
inversion 1;
subst;
trivial.
-
match_case;
intros.
inversion H1;
subst.
destruct (
rmap f l);
simpl in *;
try discriminate.
inversion H0;
subst.
eauto.
Qed.
Lemma oflat_map_Forall {A B} {f:A->option (list B)} {P} {l x} :
oflat_map f l = Some x ->
Forall P l ->
forall P2,
(forall x z, f x = Some z -> P x -> Forall P2 z) ->
Forall P2 x.
Proof.
revert x.
induction l;
simpl.
-
inversion 1;
subst;
trivial.
-
match_case;
intros.
inversion H1;
subst.
destruct (
oflat_map f l);
simpl in *;
try discriminate.
inversion H0;
subst.
apply Forall_app;
eauto.
Qed.
Lemma rmap_id l:
rmap (fun d : data => Some d) l = Some l.
Proof.
induction l;
try reflexivity.
simpl.
unfold lift.
rewrite IHl;
reflexivity.
Qed.
Lemma rmap_map {A} (f:data -> A) l:
rmap (fun d : data => Some (f d)) l = Some (map f l).
Proof.
induction l;
try reflexivity.
simpl.
unfold lift.
rewrite IHl;
reflexivity.
Qed.
Lemma rmap_map_merge {A} {B} {C} (f1:A -> B) (f2:B -> option C) (l: list A):
(rmap (fun d => f2 (f1 d)) l) =
rmap f2 (map f1 l).
Proof.
induction l; intros; simpl; [reflexivity| ].
destruct (f2 (f1 a)); [|reflexivity].
rewrite IHl.
reflexivity.
Qed.
Lemma lift_dcoll_cons_rmap d l1 l2 :
lift dcoll l1 = lift dcoll l2 ->
lift dcoll (lift (fun t => d :: t) l1) = lift dcoll (lift (fun t => d :: t) l2).
Proof.
intros.
unfold lift in *.
destruct l1;
destruct l2;
congruence.
Qed.
Lemma rmap_over_app {A B} (f:A -> option B) (l1:list A) (l2:list A) :
rmap f (l1 ++ l2) = olift2 (fun x y => Some (x++y)) (rmap f l1) (rmap f l2).
Proof.
revert l2.
induction l1;
intros.
-
simpl;
destruct (
rmap f l2);
reflexivity.
-
simpl.
destruct (
f a);
try reflexivity.
rewrite IHl1.
generalize (
rmap f l1);
generalize (
rmap f l2);
intros.
destruct o0;
destruct o;
reflexivity.
Qed.
Fixpoint listo_to_olist {a: Type} (l: list (option a)) : option (list a) :=
match l with
| nil => Some nil
| Some x :: xs => match listo_to_olist xs with
| None => None
| Some xs => Some (x::xs)
end
| None :: xs => None
end.
Lemma listo_to_olist_simpl_rmap {A B:Type} (f:A -> option B) (l:list A) :
rmap f l = (listo_to_olist (map f l)).
Proof.
induction l; intros.
- reflexivity.
- simpl.
destruct (f a).
* rewrite IHl; reflexivity.
* reflexivity.
Qed.
Lemma listo_to_olist_some {A:Type} (l:list (option A)) (l':list A) :
listo_to_olist l = Some l' ->
l = (map Some l').
Proof.
revert l'.
induction l; simpl; intros l' eqq.
- invcs eqq; simpl; trivial.
- destruct a; try discriminate.
match_destr_in eqq.
invcs eqq.
simpl.
rewrite <- IHl; trivial.
Qed.
Definition rfilter {A} (f:(string*A) -> bool) (l:list (string*A)) : list (string*A) :=
filter f l.
Definition rremove {A} (l:list (string*A)) (s:string) : list (string*A) :=
filter (fun x => if string_dec s (fst x) then false else true) l.
Definition rproject {A} (l:list (string*A)) (s:list string) : list (string*A) :=
filter (fun x => if in_dec string_dec (fst x) s then true else false) l.
Lemma rproject_nil_l {A} (s:list string) :
@rproject A [] s = [].
Proof.
reflexivity.
Qed.
Lemma rproject_nil_r {A} (l:list (string*A)) :
@rproject A l [] = [].
Proof.
induction l. reflexivity.
simpl. apply IHl.
Qed.
Lemma rproject_rec_sort_commute {B} (l1:list (string*B)) sl:
rproject (rec_sort l1) sl = rec_sort (rproject l1 sl).
Proof.
Lemma rproject_map_fst_same {B C} (f:string*B->string*C) (l:list (string*B)) sl
(samedom:forall a, In a l -> fst (f a) = fst a) :
rproject (map f l) sl = map f (rproject l sl).
Proof.
induction l;
simpl;
trivial.
simpl in samedom.
destruct (
in_dec string_dec (
fst (
f a))
sl);
destruct (
in_dec string_dec (
fst a)
sl).
-
rewrite IHl;
intuition.
-
rewrite samedom in i;
intuition.
-
rewrite <-
samedom in i;
intuition.
-
rewrite IHl;
intuition.
Qed.
Lemma rproject_app {B} (l1 l2:list (string*B)) sl:
rproject (l1 ++ l2) sl = (rproject l1 sl) ++ (rproject l2 sl).
Proof.
Lemma rproject_rproject {B} (l:list (string*B)) sl1 sl2:
rproject (rproject l sl2) sl1 = rproject l (set_inter string_dec sl2 sl1).
Proof.
Lemma rproject_Forall2_same_domain {B C} P (l1:list(string*B)) (l2:list (string*C)) ls :
Forall2 P l1 l2 ->
domain l1 = domain l2 ->
Forall2 P (rproject l1 ls) (rproject l2 ls).
Proof.
unfold rproject;
intros.
apply filter_Forall2_same;
trivial.
revert H0;
clear.
revert l2.
induction l1;
destruct l2;
simpl;
trivial;
try discriminate.
inversion 1.
rewrite H1.
match_destr;
f_equal;
auto.
Qed.
Lemma sublist_rproject {A} (l:list(string*A)) sl: sublist (rproject l sl) l.
Proof.
Lemma rproject_remove_all {B} s sl (l1:list(string*B)):
rproject l1 (remove_all s sl) =
filter (fun x => nequiv_decb s (fst x)) (rproject l1 sl).
Proof.
Lemma rec_sort_rproject_remove_all_in {B} s sl l1 l2 :
In s sl ->
In s (@domain _ B l2) ->
rec_sort (rproject l1 sl ++ l2) =
rec_sort (rproject l1 (remove_all s sl) ++ l2).
Proof.
Lemma rec_sort_rproject_remove_in {B} s sl l1 l2 :
In s sl ->
In s (@domain _ B l2) ->
rec_sort (rproject l1 sl ++ l2) =
rec_sort (rproject l1 (remove string_dec s sl) ++ l2).
Proof.
Lemma rondcoll2_dcoll f (l1 l2:list data):
rondcoll2 f (dcoll l1) (dcoll l2) = Some (dcoll (f l1 l2)).
Proof.
reflexivity. Qed.
Lemma rondcoll_dcoll f (l:list data):
rondcoll f (dcoll l) = Some (dcoll (f l)).
Proof.
reflexivity. Qed.
Lemma ondcoll_dcoll {A} (f:list data -> A) (l:list data):
ondcoll f (dcoll l) = Some (f l).
Proof.
reflexivity. Qed.
Lemma dcoll_map_app {A} (f:A -> data) (l1 l2:list A) :
Some (dcoll (map f l1 ++ map f l2)) = rondcoll2 bunion (dcoll (map f l1)) (dcoll (map f l2)).
Proof.
reflexivity. Qed.
Definition orecconcat (a:data) (x:data) :=
match a with
| drec r2 =>
match x with
| drec r1 => Some (drec (rec_concat_sort r2 r1))
| _ => None
end
| _ => None
end.
Definition omap_concat (a:data) (d1:list data) : option (list data) :=
rmap (fun x => orecconcat a x) d1.
Definition oomap_concat
(f:data -> option data)
(a:data) :=
match f a with
| Some (dcoll y) => omap_concat a y
| _ => None
end.
Definition rmap_concat (f:data -> option data) (d:list data) : option (list data) :=
oflat_map (oomap_concat f) d.
Lemma rmap_concat_cons f d a x y :
rmap_concat f d = Some x ->
(oomap_concat f a) = Some y ->
rmap_concat f (a :: d) = Some (y ++ x).
Proof.
intros.
induction d.
-
unfold rmap_concat in *;
simpl in *.
rewrite H0;
inversion H;
reflexivity.
-
unfold rmap_concat in *.
simpl in *.
revert H;
elim (
oomap_concat f a0);
intros;
simpl in *;
try congruence.
rewrite H0 in *;
simpl in *.
rewrite H.
reflexivity.
Qed.
Lemma rmap_concat_cons_none f d a :
rmap_concat f d = None -> rmap_concat f ((drec a) :: d) = None.
Proof.
Lemma rmap_concat_cons_none_first f d a :
(oomap_concat f a) = None -> rmap_concat f (a :: d) = None.
Proof.
Definition rproduct (d1 d2:list data) : option (list data) :=
oflat_map (fun x => omap_concat x d2) d1.
Lemma rproduct_cons (d1 d2:list data) a x y:
rproduct d1 d2 = Some x ->
(omap_concat a d2) = Some y ->
rproduct (a::d1) d2 = Some (y ++ x).
Proof.
intros.
induction d2.
-
unfold rproduct in *;
simpl in *.
rewrite H;
inversion H0;
reflexivity.
-
unfold rproduct in *.
simpl in *.
rewrite H0.
rewrite H in *;
simpl in *;
reflexivity.
Qed.
Definition rflatten (d:list data) : option (list data) :=
oflat_map (fun x =>
match x with
| dcoll y => Some y
| _ => None end) d.
Lemma rflatten_cons (l:list data) rest r' :
rflatten rest = Some r' ->
rflatten ((dcoll l) :: rest) = Some (l ++ r').
Proof.
intros.
induction l;
unfold rflatten in *;
simpl;
rewrite H;
reflexivity.
Qed.
Lemma rflatten_app (l1 l2:list data) r1 r2 :
rflatten l1 = Some r1 ->
rflatten l2 = Some r2 ->
rflatten (l1 ++ l2) = Some (r1 ++ r2).
Proof.
revert l2 r1 r2.
induction l1;
simpl in *;
intros.
-
inversion H;
subst.
simpl.
trivial.
-
destruct a;
simpl in *;
inversion H.
unfold rflatten in *.
simpl in H2.
apply some_lift in H2.
destruct H2 as [?
eqq ?];
subst.
simpl.
erewrite IHl1;
eauto.
simpl.
rewrite ass_app.
trivial.
Qed.
Lemma rflatten_map_dcoll_id coll :
rflatten (map (fun d : data => dcoll (d::nil)) coll) = Some coll.
Proof.
induction coll.
reflexivity.
simpl.
assert (
a::
coll = (
a::
nil)++
coll)
by reflexivity.
rewrite H.
apply rflatten_cons.
assumption.
Qed.
Lemma rflatten_cons_none (d:data) rest :
rflatten rest = None ->
rflatten (d :: rest) = None.
Proof.
intros.
destruct d;
try reflexivity.
unfold rflatten in *;
unfold oflat_map in *;
simpl in *.
rewrite H.
reflexivity.
Qed.
Lemma rflatten_app_none1 l1 l2 :
rflatten l1 = None ->
rflatten (l1 ++ l2) = None.
Proof.
revert l2.
induction l1;
simpl.
-
inversion 1.
-
intros.
destruct a;
simpl;
try reflexivity.
unfold rflatten in *.
simpl in *.
apply none_lift in H.
rewrite IHl1;
eauto.
Qed.
Lemma rflatten_app_none2 l1 l2 :
rflatten l2 = None ->
rflatten (l1 ++ l2) = None.
Proof.
revert l2.
induction l1;
simpl.
-
trivial.
-
intros.
destruct a;
simpl;
try reflexivity.
unfold rflatten in *.
simpl in *.
apply lift_none.
eauto.
Qed.
Definition rif {A} (e:A -> option bool) (a:A) : option (list A) :=
match (e a) with
| None => None
| Some b =>
if b then Some (a::nil) else Some nil
end.
Definition lrflatten {A} : option (list (list A)) -> option (list A) :=
lift lflatten.
Definition orfilter {A} (f:A -> option bool) (ol:option (list A)) : option (list A) :=
olift (lift_filter f) ol.
Lemma filter_eq_flatten_if {A} (e:A -> option bool) (ol:option (list A)) :
orfilter e ol = lrflatten (olift (rmap (rif e)) ol).
Proof.
destruct ol;
try reflexivity.
induction l.
reflexivity.
simpl.
unfold rif in *.
destruct (
e a);
try reflexivity.
destruct b;
simpl in *;
rewrite IHl;
clear IHl;
generalize ((
rmap
(
fun a0 :
A =>
match e a0 with
|
Some true =>
Some [
a0]
|
Some false =>
Some []
|
None =>
None
end)
l));
intros;
destruct o;
reflexivity.
Qed.
Definition oand (x1 x2: option bool) : option bool :=
match x1 with
| None => None
| Some b1 =>
match x2 with
| None => None
| Some b2 => Some (andb b1 b2)
end
end.
Lemma rmap_ext {A B : Type} (f g : A -> option B) (l : list A) :
(forall x, In x l -> f x = g x) ->
rmap f l = rmap g l.
Proof.
induction l; simpl; trivial; intros.
rewrite IHl by intuition.
rewrite (H a) by intuition.
trivial.
Qed.
Lemma oflat_map_ext {A B} (f g:A->option (list B)) l :
(forall x, In x l -> f x = g x) ->
oflat_map f l = oflat_map g l.
Proof.
induction l; simpl; trivial; intros.
rewrite IHl by intuition.
rewrite (H a) by intuition.
trivial.
Qed.
Lemma oomap_concat_ext_weak f g a :
(f a = g a) ->
oomap_concat f a = oomap_concat g a.
Proof.
Lemma rmap_concat_ext f g l :
(forall x, In x l -> f x = g x) ->
rmap_concat f l = rmap_concat g l.
Proof.
Lemma olift_ext {A B : Type} (f g : A -> option B) (x : option A) :
(forall a, x = Some a -> f a = g a) ->
olift f x = olift g x.
Proof.
destruct x; simpl; auto.
Qed.
Lemma lift_oncoll_ext {A : Type} (f g : list data -> option A) (d : data) :
(forall a, d = dcoll a -> f a = g a) ->
lift_oncoll f d = lift_oncoll g d.
Proof.
destruct d; simpl; auto.
Qed.
Lemma lift_filter_ext {A : Type} (f g : A -> option bool) (l : list A) :
(forall x, In x l -> f x = g x) ->
lift_filter f l = lift_filter g l.
Proof.
induction l; simpl; trivial; intros.
rewrite IHl by intuition.
rewrite (H a) by intuition.
trivial.
Qed.
Lemma rmap_map_fusion {A B C}
(f:B->option C) (g:A -> B) (l:list A) :
rmap f (map g l) = rmap (fun x => f (g x)) l.
Proof.
induction l; simpl; trivial.
match_destr. rewrite IHl; trivial.
Qed.
Definition recconcat (r1 r2:list (string*data)) :=
rec_concat_sort r1 r2.
Definition map_concat (r2:list (string*data)) (d:list (list (string*data))) :=
map (fun x => recconcat r2 x) d.
Definition product (d1 d2:list (list (string*data))) :=
(flat_map (fun x => map_concat x d2) d1).
Definition ldeqt := (@Permutation (list (string*data))).
Notation "b1 ⊖ b2" := (bminus b2 b1) (right associativity, at level 70) : rbag_scope.
Lemma lift_empty_dcoll l :
olift rflatten (lift (fun t' : list data => dcoll nil :: t') l) = olift rflatten l.
Proof.
destruct l.
simpl.
unfold rflatten.
simpl.
apply lift_id.
reflexivity.
Qed.
Lemma lift_cons_dcoll a l:
olift rflatten
(lift (fun t' : list data => dcoll [a] :: t') l) =
lift (fun t' => a::t') (olift rflatten l).
Proof.
destruct l; simpl; try reflexivity.
Qed.
Lemma rflatten_through_match l1 l2:
olift rflatten
match lift dcoll (Some l1) with
| Some x' =>
lift (fun t' : list data => x' :: t') l2
| None => None
end =
lift (fun t' : list data => l1 ++ t')
(olift rflatten l2).
Proof.
End RRelation.
Section Misc.
Lemma in_rec_sort_insert {A} `{EqDec A eq} (x:string * A) (s:string) (a:A) l:
In x (insertion_sort_insert rec_field_lt_dec (s, a) l) ->
x = (s, a) \/ In x l.
Proof.
revert x a.
induction l;
simpl; [
intuition | ].
intros x a0.
destruct a;
simpl in *.
destruct (
StringOrder.lt_dec s s0);
simpl;
intros;
trivial.
-
elim H0;
clear H0;
intros; [
left|];
auto.
-
destruct (
StringOrder.lt_dec s0 s);
simpl;
intros;
intuition.
simpl in H0.
elim H0;
clear H0;
intros.
+
intuition.
+
destruct (
IHl _ _ H0);
intuition.
Qed.
End Misc.
Require Import Permutation.
Section MergeBindings.
Definition merge_bindings {A} `{EqDec A eq} (l₁ l₂:list (string * A)) : option (list (string * A)) :=
if compatible l₁ l₂
then Some (rec_concat_sort l₁ l₂)
else None.
Lemma merge_bindings_nil_r {A} `{EqDec A eq} l : merge_bindings l nil = Some (rec_sort l).
Proof.
Lemma merge_bindings_single_nin {A} `{EqDec A eq} b x d :
~ In x (domain b) ->
merge_bindings b ((x,d)::nil) =
Some (rec_concat_sort b ((x,d)::nil)).
Proof.
Lemma merge_bindings_sorted {A} `{EqDec A eq} {g g1 g2} :
Some g = merge_bindings g1 g2 ->
is_list_sorted ODT_lt_dec (@domain string A g) = true.
Proof.
Lemma edot_merge_bindings {A} `{EqDec A eq} (l1 l2:list (string*A)) (s:string) (x:A) :
merge_bindings l1 [(s, x)] = Some l2 ->
edot l2 s = Some x.
Proof.
Lemma merge_bindings_nodup {A} `{EqDec A eq} (l l0 l1:list (string*A)):
merge_bindings l l0 = Some l1 -> NoDup (domain l1).
Proof.
Lemma merge_bindings_compatible {A} `{EqDec A eq} (l l0 l1:list (string*A)):
merge_bindings l l0 = Some l1 -> compatible l l0 = true.
Proof.
Lemma sorted_cons_is_compatible {A} `{EqDec A eq} (l:list (string*A)) (a:string*A):
is_list_sorted ODT_lt_dec (domain (a :: l)) = true ->
compatible_with (fst a) (snd a) l = true.
Proof.
Lemma compatible_self {A} `{EqDec A eq} (l:list (string*A)):
is_list_sorted ODT_lt_dec (domain l) = true ->
compatible l l = true.
Proof.
Lemma merge_self_sorted {A} `{EqDec A eq} (l:list (string*A)):
is_list_sorted ODT_lt_dec (domain l) = true ->
merge_bindings l l = Some l.
Proof.
Lemma merge_self_sorted_r {A} `{EqDec A eq} (l:list (string*A)):
is_list_sorted ODT_lt_dec (domain l) = true ->
merge_bindings l (rec_sort l) = Some (rec_sort l).
Proof.
Lemma same_domain_merge_bindings_eq
{A} `{EqDec A eq} (l₁ l₂ l₃:list (string*A)) :
NoDup (domain l₁) ->
domain l₁ = domain l₂ ->
merge_bindings l₁ l₂ = Some l₃ ->
l₁ = l₂.
Proof.
Definition compatible {A:Type} `{x:EqDec A eq} := @compatible string A _ _ _ _.
Lemma merge_returns_compatible {A} `{equiv:EqDec A eq} (l1 l2 l3:list (string*A)):
is_list_sorted ODT_lt_dec (domain l1) = true ->
is_list_sorted ODT_lt_dec (domain l2) = true ->
compatible l1 l2 = true ->
rec_concat_sort l1 l2 = l3 ->
compatible l1 l3 = true.
Proof.
Lemma merge_idem {A} `{EqDec A eq} (l l0 l1:list (string*A)):
is_list_sorted ODT_lt_dec (domain l) = true ->
is_list_sorted ODT_lt_dec (domain l0) = true ->
merge_bindings l l0 = Some l1 ->
merge_bindings l l1 = Some l1.
Proof.
End MergeBindings.
Section RRemove.
Require Import RBindings.
Lemma is_sorted_rremove {A} (l:list (string * A)) (s:string):
is_list_sorted ODT_lt_dec (domain l) = true ->
is_list_sorted ODT_lt_dec (domain (rremove l s)) = true.
Proof.
Lemma domain_rremove {A} s (l:list (string*A)) :
domain (rremove l s) = remove_all s (domain l).
Proof.
Lemma rremove_rec_sort_commute {B} (l1:list (string*B)) s:
rremove (rec_sort l1) s = rec_sort (rremove l1 s).
Proof.
Lemma rremove_app {B} (l1 l2:list (string*B)) s:
rremove (l1 ++ l2) s = rremove l1 s ++ rremove l2 s.
Proof.
Lemma nin_rremove {B} (l:list (string*B)) s :
~ In s (domain l) ->
rremove l s = l.
Proof.
intros nin.
apply true_filter;
intros ?
inn.
destruct x.
apply in_dom in inn.
simpl.
match_destr.
congruence.
Qed.
End RRemove.
Section RProject.
Lemma rproject_with_lookup {A} (l1 l2:list (string * A)) (s:list string):
is_list_sorted ODT_lt_dec (domain l1) = true ->
is_list_sorted ODT_lt_dec (domain l2) = true ->
sublist l1 l2 ->
(forall x, In x s -> assoc_lookupr string_dec l1 x = assoc_lookupr string_dec l2 x) ->
rproject l1 s = rproject l2 s.
Proof.
Lemma rproject_sublist {A} (l1 l2:list (string * A)) (s:list string) :
is_list_sorted ODT_lt_dec (domain l1) = true ->
is_list_sorted ODT_lt_dec (domain l2) = true ->
sublist s (domain l1) ->
sublist l1 l2 ->
rproject l1 s = rproject l2 s.
Proof.
Lemma rproject_equivlist {B} (l:list (string*B)) sl1 sl2 :
equivlist sl1 sl2 ->
rproject l sl1 = rproject l sl2.
Proof.
induction l;
simpl;
trivial.
intros eqq.
rewrite (
IHl eqq).
destruct (
in_dec string_dec (
fst a)
sl1);
destruct (
in_dec string_dec (
fst a)
sl2);
trivial.
-
apply eqq in i;
intuition.
-
apply eqq in i;
intuition.
Qed.
Lemma rproject_sortfilter {B} (l:list (string*B)) sl1 :
rproject l (insertion_sort ODT_lt_dec sl1) = rproject l sl1.
Proof.
Lemma rproject_concat_dist {A} (l1 l2:list (string * A)) (s:list string) :
rproject (rec_concat_sort l1 l2) s = rec_concat_sort (rproject l1 s) (rproject l2 s).
Proof.
End RProject.
Section SRProject.
Definition sorted_vector (s:list string) : list string :=
insertion_sort ODT_lt_dec s.
Lemma sorted_vector_sorted (s:list string) :
is_list_sorted ODT_lt_dec (sorted_vector s) = true.
Proof.
Definition projected_subset (s1 s2:list string) : list string :=
filter (fun x => if in_dec string_dec x s2 then true else false) s1.
Lemma projected_subst_sorted (s1 s2:list string) :
is_list_sorted ODT_lt_dec s1 = true ->
is_list_sorted ODT_lt_dec (projected_subset s1 s2) = true.
Proof.
Lemma sorted_projected_subset_is_sublist (s1 s2:list string):
is_list_sorted ODT_lt_dec s1 = true ->
is_list_sorted ODT_lt_dec s2 = true ->
sublist (projected_subset s1 s2) s2.
Proof.
Definition srproject {A} (l:list (string*A)) (s:list string) : list (string*A) :=
let ps := (projected_subset (sorted_vector s) (domain l)) in
rproject l ps.
Lemma insertion_sort_insert_equiv_vec (x a:string) (l:list string) :
In x
(RSort.insertion_sort_insert ODT_lt_dec a l) <->
a = x \/ In x l.
Proof.
induction l;
simpl; [
intuition|].
destruct a;
destruct a0;
simpl in *.
split;
intros.
intuition.
intuition.
split;
intros.
intuition.
intuition.
split;
intros.
intuition.
intuition.
destruct (
StringOrder.lt_dec (
String a a1) (
String a0 a2));
simpl; [
intuition|].
destruct (
StringOrder.lt_dec (
String a0 a2) (
String a a1));
simpl; [
intuition|].
split;
intros.
intuition.
intuition.
subst;
clear H0.
revert n n0 H1 H3.
generalize (
String a a1), (
String a0 a2);
intros.
left.
destruct (
trichotemy s s0);
intuition.
Qed.
Lemma sorted_vector_equivlist l :
equivlist (sorted_vector l) l.
Proof.
Lemma equivlist_in_dec (x:string) (s1 s2:list string) :
(equivlist s1 s2) ->
(if (in_dec string_dec x s1) then true else false) =
(if (in_dec string_dec x s2) then true else false).
Proof.
intros.
destruct (
in_dec string_dec x s1);
destruct (
in_dec string_dec x s2);
try reflexivity.
assert (
In x s2).
rewrite <-
H;
assumption.
congruence.
assert (
In x s1).
rewrite H;
assumption.
congruence.
Qed.
Lemma sorted_vector_in_dec (x:string) (s1:list string):
(if (in_dec string_dec x s1) then true else false) =
(if (in_dec string_dec x (sorted_vector s1)) then true else false).
Proof.
Lemma in_intersection_projected (x:string) (s1 s2:list string) :
In x s1 /\ In x s2 -> In x (projected_subset s1 s2).
Proof.
intros.
elim H;
clear H;
intros.
induction s1.
simpl in *.
contradiction.
simpl in *.
elim H;
clear H;
intros.
subst.
destruct (
in_dec string_dec x s2);
try congruence.
simpl;
left;
reflexivity.
specialize (
IHs1 H);
clear H0 H.
destruct (
in_dec string_dec a s2);
auto.
simpl;
right;
assumption.
Qed.
Lemma in_projected (x:string) (s1 s2:list string) :
In x (projected_subset s1 s2) -> In x s1.
Proof.
intros.
induction s1;
simpl in *; [
contradiction|].
destruct (
in_dec string_dec a s2);
simpl in *.
elim H;
clear H;
intros.
left;
assumption.
right;
apply (
IHs1 H).
right;
apply (
IHs1 H).
Qed.
Lemma sproject_in_dec {A} (x:string) (s1:list string) (l:list (string*A)) :
In x (domain l) ->
(if (in_dec string_dec x s1) then true else false) =
(if (in_dec string_dec x (projected_subset s1 (domain l))) then true else false).
Proof.
Lemma rproject_sproject {A} (l:list (string*A)) (s:list string) :
is_list_sorted ODT_lt_dec (domain l) = true ->
rproject l s = srproject l s.
Proof.
Context {fdata:foreign_data}.
Lemma rmap_with_rproject sl l :
(rmap
(fun d1 : data =>
match d1 with
| dunit => None
| dnat _ => None
| dbool _ => None
| dstring _ => None
| dcoll _ => None
| drec r => Some (drec (rproject r sl))
| dleft _ => None
| dright _ => None
| dbrand _ _ => None
| dforeign _ => None
end) l) =
(rmap
(fun d1 : data =>
olift
(fun d0 : data =>
match d0 with
| dunit => None
| dnat _ => None
| dbool _ => None
| dstring _ => None
| dcoll _ => None
| drec r => Some (drec (rproject r sl))
| dleft _ => None
| dright _ => None
| dbrand _ _ => None
| dforeign _ => None
end) (Some d1)) l).
Proof.
apply rmap_ext;
intros.
reflexivity.
Qed.
End SRProject.
Hint Resolve @merge_bindings_sorted.
Hint Rewrite @rondcoll2_dcoll : alg.
Hint Rewrite @rondcoll_dcoll : alg.
Hint Rewrite @ondcoll_dcoll : alg.
Hint Rewrite @lift_oncoll_dcoll : alg.
Hint Rewrite @olift_on_lift_dcoll : alg.
Hint Rewrite @olift_lift_dcoll : alg.
Hint Rewrite @rmap_id : alg.
Hint Rewrite @rmap_map : alg.
Hint Rewrite @lift_dcoll_cons_rmap : alg.
Hint Rewrite @rflatten_map_dcoll_id : alg.
Notation "X ≅ Y" := (ldeq X Y) (at level 70) : rbag_scope.
Notation "b1 ⊎ b2" := (bunion b2 b1) (right associativity, at level 70) : rbag_scope.
Notation "b1 ⊖ b2" := (bminus b2 b1) (right associativity, at level 70) : rbag_scope.
Notation "b1 × b2" := (rproduct b1 b2) (right associativity, at level 70) : rbag_scope.
Notation "b1 min-b b2" := (bmin b1 b2) (right associativity, at level 70) : rbag_scope.
Notation "b1 max-b b2" := (bmax b1 b2) (right associativity, at level 70) : rbag_scope.
Notation "distinct-b b1" := (bdistinct b1) (right associativity, at level 70) : rbag_scope.