Library sset5
Theory of Sets EIII-1 Order relations. Ordered sets
Copyright INRIA (2009-2011) Apics Team (Jose Grimm).Require Import ssreflect ssrbool eqtype ssrnat ssrfun.
Set Implicit Arguments.
Unset Strict Implicit.
Import Prenex Implicits.
Require Export sset4.
Import Correspondence.
Import Bfunction.
Module Border.
We define antisymmetric_r for a relation and is_antisymmetric for a
graph and refkexive_rr for a relation
Definition antisymmetric_r (r:Set -> Set -> Prop) :=
forall x y, r x y -> r y x -> x = y.
Definition is_antisymmetric (r:Set) :=
is_graph r & forall x y, related r x y -> related r y x -> x = y.
Definition reflexive_rr (r:Set -> Set -> Prop) :=
forall x y, r x y -> (r x x & r y y).
We define an order and a preorder relation
Definition order_r (r:Set -> Set -> Prop) :=
transitive_r r & antisymmetric_r r & reflexive_rr r.
Definition preorder_r (r:Set -> Set -> Prop) :=
transitive_r r & reflexive_rr r.
Lemma equality_is_order: order_r(fun x y => x = y).
Proof.
split.
by hnf; intuition; ue.
split;hnf; intuition.
Qed.
Lemma sub_is_order: order_r sub.
Proof.
split; first by move=> x y t xy yz; apply (sub_trans xy yz).
split; first by move=> x y xy yx; apply extensionality.
move=> x y; split; apply sub_refl.
Qed.
Definition opposite_relation (r:Set -> Set -> Prop) := fun x y => r y x.
Lemma opposite_is_preorder_r: forall r,
preorder_r r -> preorder_r (opposite_relation r).
Proof.
rewrite /preorder_r/opposite_relation => r [tr rr].
split.
by move=> x y z xy yz; apply (tr _ _ _ yz xy).
by move=> x y yx /=; move: (rr _ _ yx); intuition.
Qed.
Lemma opposite_is_order_r: forall r,
order_r r -> order_r (opposite_relation r).
Proof.
move=> r [tr [ar rr]].
have pr: preorder_r r by hnf.
move: (opposite_is_preorder_r pr)=> [tr' rr'].
hnf; ee; rewrite/opposite_relation => x y xy yx.
by apply: (ar _ _ yx).
Qed.
An order is either a relation or a graph
Definition order_re (r:Set -> Set -> Prop) x :=
order_r r & reflexive_r r x.
Definition order (r:Set) :=
is_reflexive r & is_transitive r & is_antisymmetric r.
Lemma order_is_graph: forall r, order r -> is_graph r.
Proof. by move => r [[g _] _]. Qed.
Hint Resolve order_is_graph : fprops.
Definition opposite_order := inverse_graph.
Definition preorder (r: Set) :=
is_reflexive r & is_transitive r.
Lemma preorder_graph : forall r, preorder r -> is_graph r.
Proof. by move => r [[g _] _]. Qed.
Lemma order_preorder : forall r, order r -> preorder r.
Proof. by move => r [tr [ar rr]]; hnf. Qed.
Lemma order_has_graph0: forall r x,
order_re r x -> is_graph_of (graph_on r x) r.
Proof.
move=> r x [ [_ [_ rrr]] rr].
move => u v ; rewrite /related/graph_on.
apply iff_eq ; rewrite Z_rw; aw; last by intuition.
move=> ruv; split=>//; split; fprops.
move: (rrr _ _ ruv) => [ruu rvv].
by rewrite 2! rr.
Qed.
Lemma graph_on_rw3: forall r x u v,
order_re r x ->
related (graph_on r x) u v = r u v.
Proof. move=> r x u v hyp; symmetry; apply (order_has_graph0 hyp).
Qed.
Lemma order_has_graph: forall r x,
order_re r x -> exists g, is_graph_of g r.
Proof.
move=> r x hyp; exists (graph_on r x).
by apply order_has_graph0.
Qed.
Lemma order_if_has_graph: forall r g,
is_graph g -> is_graph_of g r ->
order_r r -> order_re r (domain g).
Proof.
move=> r g gg gor or; split=>//.
move : gor; rewrite /is_graph_of/related => gor.
move => x; apply iff_eq; dw.
move => [y]; rewrite -gor=> rxy.
by move: or=> [_ [_ rr]]; move: (rr _ _ rxy); case.
by move=> h; exists x;rewrite - gor.
Qed.
Lemma order_if_has_graph2: forall r g,
is_graph g -> is_graph_of g r ->
order_r r -> order g.
Proof.
move=> r g gg gor or.
move: gor; rewrite /is_graph_of/related => gor.
move: or => [tr [ar rer]].
split.
split=>//.
move=> y; rewrite inc_substrate_rw /related // -gor.
by case; move=> [z]; rewrite - gor => aux; move: (rer _ _ aux); intuition.
split; split=>//.
move=> x y z; rewrite /related -3! gor; apply tr.
move=> x y; rewrite /related -2! gor; apply ar.
Qed.
Lemma order_has_graph2: forall r x,
order_re r x -> exists g,
g = graph_on r x &
order g & (forall u v, r u v = related g u v).
Proof.
move=> r x or; exists (graph_on r x).
have gg: is_graph (graph_on r x) by apply graph_on_graph.
have gor: is_graph_of (graph_on r x) r by apply order_has_graph0.
move: or => [or1 or2].
ee; apply (order_if_has_graph2 gg gor or1).
Qed.
Lemma preorder_from_rel: forall r x,
preorder_r r -> preorder (graph_on r x).
Proof.
move=> r x pr.
have gg: (is_graph (graph_on r x)) by apply graph_on_graph.
move: pr=> [tr rr].
split; split=>//.
move=> y; rewrite inc_substrate_rw // /related.
case; move=> [z]; rewrite 2! graph_on_rw0;
move=> [yx [zx ryz]];move: (rr _ _ ryz); intuition.
move=> a b c; rewrite 3! graph_on_rw1.
move=> [ax [bx rab]] [_ [cx rbc]]; intuition; apply (tr _ _ _ rab rbc).
Qed.
Lemma order_from_rel: forall r x,
order_r r -> order (graph_on r x).
Proof.
move=> r x or.
have po: preorder (graph_on r x) .
by apply preorder_from_rel; red in or; hnf; intuition.
move: po => [tr rr].
hnf; intuition.
split; first by move: tr => [g _].
move=> a b; rewrite 2! graph_on_rw1.
move=> [ax [bx rab]] [_ [_ rba]].
by move: or=> [_ [ta _]]; apply ta.
Qed.
Lemma order_reflexivity_pr: forall r x u v,
order_re r x -> r u v -> (inc u x & inc v x).
Proof.
move=> r x u v [ [_ [_ rrr]] rr] ruv.
by rewrite 2!rr; apply rrr.
Qed.
Lemma order_symmetricity_pr: forall r x u v,
order_re r x -> (r u v & r v u) = (inc u x & inc v x & u = v).
Proof.
move=> r x u v or.
apply iff_eq.
move=> [ruv rvu].
move: (order_reflexivity_pr or ruv)=> [ux vx].
by intuition; move: or => [[ _ [asy _]] _]; apply asy.
move=> [ux [vx]] ->.
by move: or=> [_ rr]; rewrite rr in vx.
Qed.
Lemma order_reflexivity: forall r a,
order r -> inc a (substrate r) = related r a a.
Proof.
move=> r a [[_ or] _].
apply iff_eq => h; first by apply or.
substr_tac.
Qed.
Lemma order_antisymmetry: forall r a b,
order r -> related r a b -> related r b a -> a = b.
Proof.
move=> r a b [ _ [_ [_]]]; apply.
Qed.
Lemma order_transitivity: forall r a b c,
order r -> related r a b -> related r b c -> related r a c.
Proof.
by move=> r a b c [ _ [[ _ t] _]]; apply t.
Qed.
Lemma inter_rel_order : forall z,
nonempty z -> (forall r, inc r z -> order r) ->
order (intersection z).
Proof.
move=> z nez alo.
have ri: (is_reflexive (intersection z)) .
apply inter_rel_reflexive=> //.
by move=> r rz; move: (alo _ rz) => [re _].
split =>//.
split.
apply inter_rel_transitive=> //.
by move=> r rz; move: (alo _ rz) => [_ [tr _]].
split; first by move: ri => [g _].
move=> x y xi yi; move: nez => [t tz].
move: (intersection_forall xi tz)(intersection_forall yi tz).
by move: (alo _ tz)=> [ _ [ _ [_ ra] ]]; apply ra.
Qed.
Definition gle (r x y:Set) := related r x y.
Definition gge (r x y:Set) := gle r y x.
Definition glt (r x y:Set) := gle r x y & x <> y.
Definition ggt (r x y:Set) := gge r x y & x <> y.
Lemma lt_leq_trans : forall r x y z,
order r -> glt r x y -> gle r y z -> glt r x z.
Proof.
move=> r x y z or [le1 nxy] le2; split.
by apply order_transitivity with y.
dneg xz.
rewrite -xz in le2.
apply (order_antisymmetry or le1 le2).
Qed.
Lemma leq_lt_trans : forall r x y z,
order r -> gle r x y -> glt r y z -> glt r x z.
Proof.
move=> r x y z or le1 [le2 nxy]; split.
by apply order_transitivity with y.
dneg xz.
rewrite xz in le1.
apply (order_antisymmetry or le2 le1).
Qed.
Lemma lt_lt_trans: forall r a b c, order r ->
glt r a b -> glt r b c -> glt r a c.
Proof. move=> r x y z or [le1 nxy] le2. apply (leq_lt_trans or le1 le2).
Qed.
Lemma not_le_gt: forall r x y, order r -> gle r x y -> glt r y x -> False.
Proof.
move=> r x y or le1 le2.
move: (leq_lt_trans or le1 le2) => [_ xx].
by elim xx.
Qed.
Ltac order_tac:=
match goal with
| H1: gle ?r ?x _ |- inc ?x (substrate ?r)
=> exact (inc_arg1_substrate H1)
| H1: glt ?r ?x _ |- inc ?x (substrate ?r)
=> move: H1 => [H1 _] ; order_tac
| H1:gle ?r _ ?x |- inc ?x (substrate ?r)
=> exact (inc_arg2_substrate H1)
| H1:glt ?r _ ?x |- inc ?x (substrate ?r)
=> move: H1 => [H1 _]; order_tac
| H: order ?r, H1: inc ?u (substrate ?r) |- related ?r ?u ?u
=> rewrite - order_reflexivity //
| H: order ?r |- inc (J ?u ?u) ?r
=> change (related r u u); rewrite - order_reflexivity //
| H: order ?r |- gle ?r ?u ?u
=> rewrite /gle -order_reflexivity //
| H1: gle ?r ?x ?y, H2: gle ?r ?y ?x, H:order ?r |-
?x = ?y => exact (order_antisymmetry H H1 H2)
| H:order ?r, H1:related ?r ?x ?y, H2: related ?r ?y ?x |- ?x = ?y
=> apply (order_antisymmetry H H1 H2)
| H:order ?r, H1: inc (J ?x ?y) ?r , H2: inc (J ?y ?x) ?r |- ?x = ?y
=> apply (order_antisymmetry H H1 H2)
| H:order ?r, H1:related ?r ?u ?v, H2: related ?r ?v ?w
|- related ?r ?u ?w
=> apply (order_transitivity H H1 H2)
| H:order ?r, H1:gle ?r ?u ?v, H2: gle ?r ?v ?w
|- gle ?r ?u ?w
=> apply (order_transitivity H H1 H2)
| H: order ?r, H1: inc (J ?u ?v) ?r, H2: inc (J ?v ?w) ?r |-
inc (J ?u ?w) ?r
=> change (related r u w); apply (order_transitivity H H1 H2)
| H1: gle ?r ?x ?y, H2: glt ?r ?y ?x, H: order ?r |- _
=> elim (not_le_gt H H1 H2)
| H1:glt ?r ?x ?y, H2: glt ?r ?y ?x, H:order ?r |- _
=> destruct H1 as [H1 _] ; elim (not_le_gt H H1 H2)
| H1:order ?r, H2:glt ?r ?x ?y, H3: gle ?r ?y ?z |- glt ?r ?x ?z
=> exact (lt_leq_trans H1 H2 H3)
| H1:order ?r, H2:gle ?r ?x ?y, H3: glt ?r ?y ?z |- glt ?r ?x ?z
=> exact (leq_lt_trans H1 H2 H3)
| H1:order ?r, H2:glt ?r ?x ?y, H3: glt ?r ?y ?z |- glt ?r ?x ?z
=> exact (lt_lt_trans H1 H2 H3)
| H1:order ?r, H2:gle ?r ?x ?y |- glt ?r ?x ?y
=> split =>//
| H:glt ?r ?x ?y |- gle ?r ?x ?y
=> by move: H=> []
end.
Lemma le_antisym: forall r a b,
order r -> gle r a b -> gle r b a -> a = b.
Proof.
move=> r a b [ _ [_ [_]]]; apply.
Qed.
Lemma order_is_order: forall r,
order r -> order_r (related r).
Proof.
move => r [[g rr] [[_ t] [_ s]]].
hnf; ee; move=> x y xy.
by move: (rr _ (inc_arg1_substrate xy)) (rr _ (inc_arg2_substrate xy)).
Qed.
Lemma substrate_opposite_order: forall r,
order r -> substrate (opposite_order r) = substrate r.
Proof.
move=> r or.
have gr: is_graph r by fprops.
have go: is_graph (opposite_order r) by fprops.
set_extens x; do 2 rewrite inc_substrate_rw //.
case; move=> [y]; aw => h; [ right | left ]; ex_tac.
case; move=> [y]; [ right | left ]; exists y; aw.
Qed.
Hint Rewrite substrate_opposite_order : aw.
Lemma substrate_domain_order: forall f,
order f -> substrate f = domain f.
Proof.
move=> f or.
set_extens x => xs.
have Jf: inc (J x x) f by order_tac.
by rewrite /domain; aw; exists (J x x); aw; auto.
by rewrite /substrate; apply union2_first.
Qed.
Lemma opposite_is_order: forall r,
order r -> order (opposite_order r).
Proof.
move=> r or;
set (g:= opposite_order r).
have gg: is_graph g by rewrite /g; fprops.
have go: is_graph_of g (opposite_relation (related r)).
move=> x y.
by rewrite/ opposite_relation/g/related ; aw.
have ori: order_r (opposite_relation (related r)).
by apply opposite_is_order_r; apply order_is_order.
by apply (order_if_has_graph2 gg go ori).
Qed.
Hint Resolve opposite_is_order: fprops.
Lemma diagonal_order : forall x,
order (identity_g x).
Proof.
move=> x.
move: (diagonal_equivalence x) => [ir [it _]].
hnf; intuition.
split; first by move: ir=> [h _].
move=> a b; rewrite /related;aw. intuition.
Qed.
Order induced by a relation on a set
Lemma order_from_rel1: forall r x,
transitive_r r ->
(forall u v, inc u x -> inc v x -> r u v -> r v u -> u = v) ->
(forall u, inc u x -> r u u) ->
order (graph_on r x).
Proof.
move=> r x tr sy re.
have go: (graph_on r x = graph_on (fun a b => inc a x & inc b x & r a b) x).
rewrite /graph_on.
set_extens w; rewrite Z_rw Z_rw; aw; intuition.
rewrite go; apply order_from_rel.
split.
move => a b c [ax [bx rab]] [_ [cx rbc]]; intuition; apply(tr _ _ _ rab rbc).
split=>//.
by move=> a b [ax [bx rab]] [_ [cx rbc]]; apply sy.
by move=> a b [ax [bx rab]]; intuition.
Qed.
Lemma substrate_graph_on: forall (r:Set -> Set -> Prop) x,
(forall a, inc a x -> r a a) ->
substrate (graph_on r x) = x.
Proof.
move=> r x rr.
apply extensionality; first by apply graph_on_substrate.
move => t xt; move: (rr _ xt) => rtt.
have aux: (related (graph_on r x) t t).
by rewrite /graph_on /related Z_rw; aw; fprops.
substr_tac.
Qed.
Inclusion order on the powerset of a set, or a part of it
Definition inclusion_suborder (b:Set) :=
graph_on sub b.
Definition inclusion_order (a:Set) := inclusion_suborder (powerset a).
Lemma subinclusion_is_order: forall a,
order (inclusion_suborder a).
Proof.
rewrite /inclusion_suborder => a.
apply order_from_rel; apply sub_is_order.
Qed.
Lemma inclusion_is_order: forall a,
order (inclusion_order a).
Proof.
rewrite /inclusion_order => a. apply subinclusion_is_order.
Qed.
Lemma substrate_subinclusion_order:forall a,
substrate (inclusion_suborder a) = a.
Proof.
rewrite /inclusion_suborder => a.
apply substrate_graph_on.
move=> x; fprops.
Qed.
Lemma substrate_inclusion_order: forall a,
substrate (inclusion_order a) = powerset a.
Proof. rewrite /inclusion_order=> a. apply substrate_subinclusion_order.
Qed.
Lemma subinclusion_order_rw: forall a u v ,
related (inclusion_suborder a) u v = (inc u a & inc v a & sub u v).
Proof. by move=> a u v; rewrite /inclusion_suborder graph_on_rw1.
Qed.
Lemma inclusion_order_rw: forall a u v,
related (inclusion_order a) u v = (sub u a & sub v a & sub u v).
Proof. move => a u v; rewrite /inclusion_order subinclusion_order_rw; aw.
Qed.
Hint Rewrite substrate_inclusion_order : aw.
Hint Rewrite substrate_subinclusion_order : aw.
Hint Resolve inclusion_is_order subinclusion_is_order: fprops.
Hint Rewrite subinclusion_order_rw inclusion_order_rw: aw.
graph_on sub b.
Definition inclusion_order (a:Set) := inclusion_suborder (powerset a).
Lemma subinclusion_is_order: forall a,
order (inclusion_suborder a).
Proof.
rewrite /inclusion_suborder => a.
apply order_from_rel; apply sub_is_order.
Qed.
Lemma inclusion_is_order: forall a,
order (inclusion_order a).
Proof.
rewrite /inclusion_order => a. apply subinclusion_is_order.
Qed.
Lemma substrate_subinclusion_order:forall a,
substrate (inclusion_suborder a) = a.
Proof.
rewrite /inclusion_suborder => a.
apply substrate_graph_on.
move=> x; fprops.
Qed.
Lemma substrate_inclusion_order: forall a,
substrate (inclusion_order a) = powerset a.
Proof. rewrite /inclusion_order=> a. apply substrate_subinclusion_order.
Qed.
Lemma subinclusion_order_rw: forall a u v ,
related (inclusion_suborder a) u v = (inc u a & inc v a & sub u v).
Proof. by move=> a u v; rewrite /inclusion_suborder graph_on_rw1.
Qed.
Lemma inclusion_order_rw: forall a u v,
related (inclusion_order a) u v = (sub u a & sub v a & sub u v).
Proof. move => a u v; rewrite /inclusion_order subinclusion_order_rw; aw.
Qed.
Hint Rewrite substrate_inclusion_order : aw.
Hint Rewrite substrate_subinclusion_order : aw.
Hint Resolve inclusion_is_order subinclusion_is_order: fprops.
Hint Rewrite subinclusion_order_rw inclusion_order_rw: aw.
Extension order on partial functions from x to y
Definition extension_order x y :=
graph_on extends (set_of_sub_functions x y).
Hint Rewrite set_of_sub_functions_rw : bw.
Lemma extends_in_prop: forall x y,
order_r extends &
(forall u, inc u (set_of_sub_functions x y) -> extends u u).
Proof.
move=> x y; rewrite /extends.
split; last by move=> u; bw; intuition.
split.
move=> a b c [fb [fa [gba tba]]] [fc [_ [gcb tcb]]].
intuition.
by apply sub_trans with (graph b).
by apply sub_trans with (target b).
split; last by red; intuition.
move=> a b [fb [fa [gba tba]]] [_ [_ [gab tab]]].
have grab: graph a = graph b by apply extensionality.
have tgab: target a = target b by apply extensionality.
by apply function_exten1.
Qed.
Lemma extension_is_order: forall x y,
order (extension_order x y).
Proof.
rewrite /extension_order=> x y.
move: (extends_in_prop x y) => [p1 _].
by apply order_from_rel.
Qed.
Lemma substrate_extension_order: forall x y,
substrate (extension_order x y) = (set_of_sub_functions x y).
Proof.
rewrite /extension_order => x y.
by move: (extends_in_prop x y)=> [_ p1]; apply substrate_graph_on.
Qed.
Lemma extension_order_rw : forall E F f g,
gle (extension_order E F) g f =
(inc g (set_of_sub_functions E F) & inc f (set_of_sub_functions E F)
& extends g f).
Proof.
by move=> E F f g; rewrite /gle/related /extension_order graph_on_rw0.
Qed.
Lemma extension_order_pr1 : forall E F f g,
gle (extension_order E F) g f =
(inc g (set_of_sub_functions E F) & inc f (set_of_sub_functions E F)
& sub (graph f) (graph g)).
Proof.
move=> E F f g; rewrite extension_order_rw /extends.
apply iff_eq; first by intuition.
move=> [p1 [p2 sh]]; split=>//; split=>//.
move: p1 p2; bw; move=> [fg [_ tg]] [ff [_ tf]]; rewrite tg tf.
fprops.
Qed.
Lemma extension_order_pr2 : forall E F f g,
gle (opposite_order (extension_order E F)) g f =
(inc g (set_of_sub_functions E F) & inc f (set_of_sub_functions E F)
& sub (graph g) (graph f)).
Proof.
move=> E F f g. rewrite /gle/related; aw.
rewrite -[inc (J f g) (extension_order E F)]/(gle (extension_order E F) f g).
rewrite extension_order_pr1.
by apply iff_eq; intuition.
Qed.
Hint Rewrite extension_order_rw: aw.
Hint Resolve extension_is_order: fprops.
Lemma extension_order_pr : forall E F f g x,
gle (opposite_order (extension_order E F)) f g ->
inc x (source f) -> W x f = W x g.
Proof.
move=> E F f g x; rewrite /opposite_order; bw; aw.
move => [gs [fs et]] xsf.
apply (W_extends et xsf).
Qed.
Hint Rewrite substrate_extension_order: aw.
Example 4. Order between partitions on a set
Definition set_of_partition_set x :=
Zo(powerset(powerset x)) (fun z => partition z x).
Definition partition_fun_of_set y x:=
canonical_injection y (powerset x).
Lemma partition_set_in_double_powerset: forall y x,
partition y x -> inc y (powerset (powerset x)).
Proof.
move=> y x [pa _]; aw; move => t ty; aw; move => z zt.
move: (union_inc zt ty); ue.
Qed.
Lemma set_of_partition_rw: forall x y,
inc y (set_of_partition_set x) = partition y x.
Proof.
move=> x y; rewrite /set_of_partition_set.
apply iff_eq; rewrite Z_rw; intuition.
by apply partition_set_in_double_powerset.
Qed.
Lemma pfs_function: forall y x,
partition y x -> is_function (partition_fun_of_set y x).
Proof.
move=> y x pa; rewrite/partition_fun_of_set.
by apply ci_function; apply powerset_sub; apply partition_set_in_double_powerset.
Qed.
Lemma pfs_W: forall y x a,
partition y x -> inc a y ->
W a (partition_fun_of_set y x) = a.
Proof.
rewrite /partition_fun_of_set=> y x a pa ay.
by apply ci_W => //; apply powerset_sub; apply partition_set_in_double_powerset.
Qed.
Lemma pfs_partition: forall y x,
partition y x -> partition_fam (graph (partition_fun_of_set y x)) x.
Proof.
move=> y x pa.
move: (pfs_function pa) => fpa.
move: (pa)=> [ux [_ di]].
have Wp: forall i, inc i y -> V i (graph (partition_fun_of_set y x)) = i.
by move => i iy; apply pfs_W.
have dg: domain (graph (partition_fun_of_set y x)) = y.
by rewrite f_domain_graph// /partition_fun_of_set /canonical_injection; aw.
split; fprops; split.
move=> i j; rewrite dg => iy jy; rewrite Wp // Wp //.
by apply di.
set_extens v => vs.
move: (unionb_exists vs)=> [w]; rewrite dg.
move=> [wy]; rewrite Wp // -ux => vW; union_tac.
rewrite -ux in vs; move: (union_exists vs)=> [w [vw wy]].
by srw; exists w; rewrite dg (Wp _ wy).
Qed.
All these lemmas say that, essentially, a partition is a partition set
Definition coarser x := graph_on coarser_c (set_of_partition_set x).
Lemma coarser_related: forall x y y',
related (coarser x) y y' =
(partition y x & partition y' x & coarser_c y y').
Proof.
rewrite /coarser/graph_on/related=> x y y'.
apply iff_eq; rewrite Z_rw product_pair_rw 2! set_of_partition_rw ; aw;
intuition.
Qed.
Lemma coarser_related_bis: forall x y y',
related (coarser x) y y' =
(partition y x & partition y' x &
forall a, inc a y' -> exists b, inc b y & sub a b).
Proof. by move=> x y y'; rewrite coarser_related.
Qed.
Lemma coarser_substrate : forall x,
substrate (coarser x) = set_of_partition_set x.
Proof.
move=> x; rewrite /coarser.
apply extensionality; first by apply graph_on_substrate.
move => t ts.
apply inc_arg1_substrate with t.
rewrite /related/graph_on Z_rw product_pair_rw; aw.
intuition; apply coarser_reflexive.
Qed.
Lemma coarser_order : forall x, order (coarser x).
Proof.
move=> x.
have gc: is_graph (coarser x) by rewrite /coarser; apply graph_on_graph.
hnf; intuition; split=>//.
move=> y; rewrite coarser_related coarser_substrate set_of_partition_rw.
intuition; apply coarser_reflexive.
move=> a b c; rewrite 3! coarser_related.
by intuition; apply coarser_transitive with b.
move=> a b;rewrite 2!coarser_related. intuition.
by apply coarser_antisymmetric with x.
Qed.
Lemma smallest_partition_is_smallest: forall x y,
nonempty x ->
partition y x -> related (coarser x) (smallest_partition x) y.
Proof.
move=> x y nex pa; rewrite coarser_related.
intuition; first by apply partition_smallest.
move=> u uy; rewrite /smallest_partition.
ex_tac.
move: (partition_set_in_double_powerset pa); aw => yp.
by apply powerset_sub; apply yp.
Qed.
Lemma largest_partition_is_largest: forall x y,
partition y x -> related (coarser x) y (largest_partition x).
Proof.
move=> x y pa; rewrite coarser_related.
intuition; first by apply partition_largest.
move=> u; rewrite /largest_partition; aw.
move=> [b [bx]] <-.
move: pa=> [ux _]; move: bx; rewrite -ux; srw.
by move=> [z [bz zy]]; ex_tac; move=> t; aw=> ->.
Qed.
Definition partition_relation_set y x :=
partition_relation (partition_fun_of_set y x) x.
Lemma prs_is_equivalence: forall y x,
partition y x -> is_equivalence (partition_relation_set y x).
Proof.
move=> y x pa; rewrite /partition_relation_set.
apply partition_is_equivalence.
by apply pfs_function.
by apply pfs_partition.
Qed.
Definition partition_relation_set_aux y x :=
Zo (powerset (coarse x)) (fun z => exists a, inc a y & z = coarse a).
Lemma partition_relation_set_pr1: forall y x a,
partition y x ->
inc a y -> inc (coarse a) (partition_relation_set_aux y x).
Proof.
move=> y x a pa ay.
move: (partition_set_in_double_powerset pa).
rewrite powerset_inc_rw=> yp.
have ap: (inc a (powerset x)) by apply yp.
rewrite /partition_relation_set_aux /coarse Z_rw; aw.
split; first by awi ap; apply product_monotone.
ex_tac.
Qed.
Lemma partition_relation_set_pr: forall y x,
partition y x ->
partition_relation_set y x =
union (partition_relation_set_aux y x).
Proof.
move=> y x pa.
have pfa: (partition_fam (graph(partition_fun_of_set y x)) x).
by apply pfs_partition.
move: (partition_set_in_double_powerset pa) => ypp.
have sp:source (partition_fun_of_set y x) = y.
by rewrite /partition_fun_of_set /canonical_injection; aw.
awi ypp.
have p1: is_function (partition_fun_of_set y x) by apply pfs_function.
have p2: partition_fam (graph (partition_fun_of_set y x)) x.
by move: (prs_is_equivalence pa); fprops.
have p3: is_graph (partition_relation (partition_fun_of_set y x) x).
by rewrite /partition_relation; apply graph_on_graph.
have p4:is_graph (union (partition_relation_set_aux y x)).
move=> t tp; move: (union_exists tp); rewrite/partition_relation_set_aux.
move=> [z]; rewrite Z_rw powerset_inc_rw /coarse.
by move=> [tz [zp _]]; move: (zp _ tz); aw; intuition.
rewrite /partition_relation_set graph_exten //.
move=> u v; rewrite partition_relation_pr /in_same_coset // sp.
apply iff_eq.
move=> [i [iy []]]; rewrite pfs_W // /related => ui vi.
apply union_inc with (coarse i).
rewrite/coarse; fprops.
by apply partition_relation_set_pr1.
rewrite /related; srw; move=> [z [Jz]].
rewrite/ partition_relation_set_aux Z_rw; move => [zp [a [ay zc]]].
ex_tac.
by rewrite pfs_W //; move: Jz; rewrite zc /coarse product_pair_rw.
Qed.
Lemma sub_partition_relation_set_coarse: forall y x,
partition y x -> sub (partition_relation_set y x) (coarse x).
Proof.
move=> y x pa; rewrite partition_relation_set_pr //.
move=> t tu.
move: (union_exists tu) => [z [tz]].
rewrite /partition_relation_set_aux Z_rw.
by move=> [zp _ ]; awi zp; apply zp.
Qed.
Lemma nondisjoint :forall a b c, inc a b -> inc a c -> disjoint b c -> False.
Proof.
by move=> a b c ab ac dg; red in dg; empty_tac1 a; apply intersection2_inc.
Qed.
Lemma partition_relation_set_order: forall x y y',
partition y x -> partition y' x ->
sub (partition_relation_set y' x)(partition_relation_set y x) =
related (coarser x) y y'.
Proof.
move=> x y y' pa pa'.
do 2 rewrite partition_relation_set_pr //.
rewrite coarser_related /coarser_c; apply iff_eq.
move => suu; split=>//; split=>//; move=> a ay.
have nea: (nonempty a) by move: pa'=> [_ [ne _]]; apply ne.
move: nea=> [b ba].
have p: (forall u,inc u a -> exists c, (inc c y & inc b c & inc u c)).
move=> u ua.
have q: (inc (J b u) (union (partition_relation_set_aux y' x))).
apply union_inc with (coarse a)=>//; rewrite /coarse; fprops.
apply(partition_relation_set_pr1 pa' ay).
move: (union_exists (suu _ q)) => [z [Jbb]].
rewrite /partition_relation_set_aux Z_rw; move=> [zp [c [cy zc]]].
by ex_tac; move: Jbb; rewrite zc /coarse product_pair_rw.
move: (p _ ba) => [c [cy [bc _]]].
ex_tac.
move=> d da.
move: (p _ da)=> [f [fy [bf df]]].
move:pa => [_ [_ aux ]]; case:(aux _ _ cy fy).
by move => ->.
by move=> dcf;elim (nondisjoint bc bf dcf).
move=> [_ [_ hyp]] z zu.
move: (union_exists zu)=> [t [zt]].
rewrite /partition_relation_set_aux Z_rw; move => [tp [a [ay tc]]].
move: (hyp _ ay)=> [b [iby ab]].
apply union_inc with (coarse b); last by apply partition_relation_set_pr1.
have scab: (sub (coarse a) (coarse b)) by apply product_monotone.
apply scab; ue.
Qed.
Lemma partition_relation_set_order_antisymmetric: forall x y y',
partition y x -> partition y' x ->
(partition_relation_set y' x = partition_relation_set y x) ->
y = y'.
Proof.
suff: (forall x y y',
partition y x -> partition y' x ->
(partition_relation_set y' x = partition_relation_set y x) ->
sub y y').
move=> aux a b c p1 p2 eq. apply extensionality.
apply (aux _ _ _ p1 p2 eq). apply (aux _ _ _ p2 p1 (sym_eq eq)).
move=> x y y' pa pa'.
rewrite (partition_relation_set_pr pa) (partition_relation_set_pr pa').
move=> eq a ay.
move: (partition_relation_set_pr1 pa ay)=> cpy.
have nea: (nonempty a) by move: pa=> [_ [ne _]]; apply ne.
move: nea=> [b ba].
have p: (forall u v,inc u a -> inc v a->
exists c, (inc c y' & inc u c & inc v c)).
move=> u v ua va.
have p1: inc (J u v) (coarse a) by rewrite /coarse; fprops.
have p2: (inc (J u v) (union (partition_relation_set_aux y' x))).
rewrite eq; union_tac.
move: (union_exists p2) => [z [Jbb]].
rewrite /partition_relation_set_aux Z_rw; move=> [zp [c [cy zc]]].
by ex_tac; move: Jbb; rewrite zc /coarse product_pair_rw.
move: (p _ _ ba ba) => [c [cy [bc _]]].
suff: a = c by move=> ->.
set_extens t => ta.
move: (p _ _ ta ta) => [c' [cy' [tc' _]]].
move: (p _ _ ba ta) => [c'' [cy'' [bc'' tc'']]].
move: pa' => [_ [_ aux ]]; case:(aux _ _ cy cy'').
move => ->; case:(aux _ _ cy'' cy'); first by move => ->.
by move=> dcf;elim (nondisjoint tc'' tc' dcf).
by move=> dcf;elim (nondisjoint bc bc'' dcf).
have p1: (inc (J b t) (coarse c)) by rewrite/coarse; fprops.
have p2: (inc (J b t) (union (partition_relation_set_aux y' x))).
apply union_inc with (coarse c) => //.
apply (partition_relation_set_pr1 pa' cy).
move: p2; rewrite eq /partition_relation_set_aux => p2.
move: (union_exists p2)=> [z [Jbb]]; rewrite Z_rw;move=> [zp [d [dy zx]]].
move: Jbb; rewrite zx /coarse; aw; move=> [_ [bd td]].
move: pa => [_ [_ aux ]]; case:(aux _ _ ay dy).
by move=> ->.
move=> dfc; elim (nondisjoint ba bd dfc).
Qed.
Lemma preorder_prop1: forall g,
is_graph g ->
sub (identity_g (substrate g)) g -> sub (compose_graph g g) g ->
compose_graph g g = g.
Proof.
move=> g gg sig scg.
apply extensionality; first by aw.
move => x xg; aw; split; first by apply gg.
exists (Q x); rewrite (gg _ xg); ee; apply sig; aw; ee; substr_tac.
Qed.
Theorem order_pr: forall r,
order r =
(compose_graph r r = r &
intersection2 r (opposite_order r) = identity_g (substrate r)).
Proof.
move=> r.
apply iff_eq.
move=> or.
set (d:= identity_g (substrate r)).
have i2: (intersection2 r (opposite_order r) = d).
set_extens t.
aw; move=> [tr].
rewrite inverse_graph_rw;fprops; move=> [pt Jr].
have px: (J (P t) (Q t) = t) by aw.
rewrite - px in tr.
move: (order_antisymmetry or tr Jr)=> pq.
by rewrite /d -px pq; aw; split=>//; substr_tac.
rewrite/d; rewrite inc_diagonal_rw; move=> [pt [Ps pq]].
have Jpq: (J (P t) (Q t) = t) by aw.
rewrite -Jpq -pq.
have rpp: (related r (P t) (P t)) by order_tac.
by apply intersection2_inc=>//; aw.
have gr: (is_graph r) by fprops.
have sd: (sub d r) by rewrite -i2; apply intersection2sub_first.
have sc: (sub (compose_graph d r) (compose_graph r r)).
by apply composition_increasing; fprops.
have crrr: (sub (compose_graph r r) r).
by move: or => [_[t _]];rewrite -idempotent_graph_transitive //.
by split =>//; apply preorder_prop1.
move=> [crrr iro].
have gr: is_graph r by rewrite -crrr; apply composition_is_graph.
hnf; intuition; split=>//.
- move=> y ys.
have: (inc (J y y) (identity_g (substrate r))) by aw; auto.
by rewrite -iro; move=> Ji; apply (intersection2_first Ji).
- have: sub (compose_graph r r) r by rewrite crrr; fprops.
by rewrite -idempotent_graph_transitive //; move=> [_].
- move => x y rxy ryx.
have p1: (inc (J x y) (opposite_order r)) by aw.
have: (inc (J x y) (identity_g (substrate r))).
by rewrite - iro; apply intersection2_inc.
aw ; intuition.
Qed.
Lemma coarser_related: forall x y y',
related (coarser x) y y' =
(partition y x & partition y' x & coarser_c y y').
Proof.
rewrite /coarser/graph_on/related=> x y y'.
apply iff_eq; rewrite Z_rw product_pair_rw 2! set_of_partition_rw ; aw;
intuition.
Qed.
Lemma coarser_related_bis: forall x y y',
related (coarser x) y y' =
(partition y x & partition y' x &
forall a, inc a y' -> exists b, inc b y & sub a b).
Proof. by move=> x y y'; rewrite coarser_related.
Qed.
Lemma coarser_substrate : forall x,
substrate (coarser x) = set_of_partition_set x.
Proof.
move=> x; rewrite /coarser.
apply extensionality; first by apply graph_on_substrate.
move => t ts.
apply inc_arg1_substrate with t.
rewrite /related/graph_on Z_rw product_pair_rw; aw.
intuition; apply coarser_reflexive.
Qed.
Lemma coarser_order : forall x, order (coarser x).
Proof.
move=> x.
have gc: is_graph (coarser x) by rewrite /coarser; apply graph_on_graph.
hnf; intuition; split=>//.
move=> y; rewrite coarser_related coarser_substrate set_of_partition_rw.
intuition; apply coarser_reflexive.
move=> a b c; rewrite 3! coarser_related.
by intuition; apply coarser_transitive with b.
move=> a b;rewrite 2!coarser_related. intuition.
by apply coarser_antisymmetric with x.
Qed.
Lemma smallest_partition_is_smallest: forall x y,
nonempty x ->
partition y x -> related (coarser x) (smallest_partition x) y.
Proof.
move=> x y nex pa; rewrite coarser_related.
intuition; first by apply partition_smallest.
move=> u uy; rewrite /smallest_partition.
ex_tac.
move: (partition_set_in_double_powerset pa); aw => yp.
by apply powerset_sub; apply yp.
Qed.
Lemma largest_partition_is_largest: forall x y,
partition y x -> related (coarser x) y (largest_partition x).
Proof.
move=> x y pa; rewrite coarser_related.
intuition; first by apply partition_largest.
move=> u; rewrite /largest_partition; aw.
move=> [b [bx]] <-.
move: pa=> [ux _]; move: bx; rewrite -ux; srw.
by move=> [z [bz zy]]; ex_tac; move=> t; aw=> ->.
Qed.
Definition partition_relation_set y x :=
partition_relation (partition_fun_of_set y x) x.
Lemma prs_is_equivalence: forall y x,
partition y x -> is_equivalence (partition_relation_set y x).
Proof.
move=> y x pa; rewrite /partition_relation_set.
apply partition_is_equivalence.
by apply pfs_function.
by apply pfs_partition.
Qed.
Definition partition_relation_set_aux y x :=
Zo (powerset (coarse x)) (fun z => exists a, inc a y & z = coarse a).
Lemma partition_relation_set_pr1: forall y x a,
partition y x ->
inc a y -> inc (coarse a) (partition_relation_set_aux y x).
Proof.
move=> y x a pa ay.
move: (partition_set_in_double_powerset pa).
rewrite powerset_inc_rw=> yp.
have ap: (inc a (powerset x)) by apply yp.
rewrite /partition_relation_set_aux /coarse Z_rw; aw.
split; first by awi ap; apply product_monotone.
ex_tac.
Qed.
Lemma partition_relation_set_pr: forall y x,
partition y x ->
partition_relation_set y x =
union (partition_relation_set_aux y x).
Proof.
move=> y x pa.
have pfa: (partition_fam (graph(partition_fun_of_set y x)) x).
by apply pfs_partition.
move: (partition_set_in_double_powerset pa) => ypp.
have sp:source (partition_fun_of_set y x) = y.
by rewrite /partition_fun_of_set /canonical_injection; aw.
awi ypp.
have p1: is_function (partition_fun_of_set y x) by apply pfs_function.
have p2: partition_fam (graph (partition_fun_of_set y x)) x.
by move: (prs_is_equivalence pa); fprops.
have p3: is_graph (partition_relation (partition_fun_of_set y x) x).
by rewrite /partition_relation; apply graph_on_graph.
have p4:is_graph (union (partition_relation_set_aux y x)).
move=> t tp; move: (union_exists tp); rewrite/partition_relation_set_aux.
move=> [z]; rewrite Z_rw powerset_inc_rw /coarse.
by move=> [tz [zp _]]; move: (zp _ tz); aw; intuition.
rewrite /partition_relation_set graph_exten //.
move=> u v; rewrite partition_relation_pr /in_same_coset // sp.
apply iff_eq.
move=> [i [iy []]]; rewrite pfs_W // /related => ui vi.
apply union_inc with (coarse i).
rewrite/coarse; fprops.
by apply partition_relation_set_pr1.
rewrite /related; srw; move=> [z [Jz]].
rewrite/ partition_relation_set_aux Z_rw; move => [zp [a [ay zc]]].
ex_tac.
by rewrite pfs_W //; move: Jz; rewrite zc /coarse product_pair_rw.
Qed.
Lemma sub_partition_relation_set_coarse: forall y x,
partition y x -> sub (partition_relation_set y x) (coarse x).
Proof.
move=> y x pa; rewrite partition_relation_set_pr //.
move=> t tu.
move: (union_exists tu) => [z [tz]].
rewrite /partition_relation_set_aux Z_rw.
by move=> [zp _ ]; awi zp; apply zp.
Qed.
Lemma nondisjoint :forall a b c, inc a b -> inc a c -> disjoint b c -> False.
Proof.
by move=> a b c ab ac dg; red in dg; empty_tac1 a; apply intersection2_inc.
Qed.
Lemma partition_relation_set_order: forall x y y',
partition y x -> partition y' x ->
sub (partition_relation_set y' x)(partition_relation_set y x) =
related (coarser x) y y'.
Proof.
move=> x y y' pa pa'.
do 2 rewrite partition_relation_set_pr //.
rewrite coarser_related /coarser_c; apply iff_eq.
move => suu; split=>//; split=>//; move=> a ay.
have nea: (nonempty a) by move: pa'=> [_ [ne _]]; apply ne.
move: nea=> [b ba].
have p: (forall u,inc u a -> exists c, (inc c y & inc b c & inc u c)).
move=> u ua.
have q: (inc (J b u) (union (partition_relation_set_aux y' x))).
apply union_inc with (coarse a)=>//; rewrite /coarse; fprops.
apply(partition_relation_set_pr1 pa' ay).
move: (union_exists (suu _ q)) => [z [Jbb]].
rewrite /partition_relation_set_aux Z_rw; move=> [zp [c [cy zc]]].
by ex_tac; move: Jbb; rewrite zc /coarse product_pair_rw.
move: (p _ ba) => [c [cy [bc _]]].
ex_tac.
move=> d da.
move: (p _ da)=> [f [fy [bf df]]].
move:pa => [_ [_ aux ]]; case:(aux _ _ cy fy).
by move => ->.
by move=> dcf;elim (nondisjoint bc bf dcf).
move=> [_ [_ hyp]] z zu.
move: (union_exists zu)=> [t [zt]].
rewrite /partition_relation_set_aux Z_rw; move => [tp [a [ay tc]]].
move: (hyp _ ay)=> [b [iby ab]].
apply union_inc with (coarse b); last by apply partition_relation_set_pr1.
have scab: (sub (coarse a) (coarse b)) by apply product_monotone.
apply scab; ue.
Qed.
Lemma partition_relation_set_order_antisymmetric: forall x y y',
partition y x -> partition y' x ->
(partition_relation_set y' x = partition_relation_set y x) ->
y = y'.
Proof.
suff: (forall x y y',
partition y x -> partition y' x ->
(partition_relation_set y' x = partition_relation_set y x) ->
sub y y').
move=> aux a b c p1 p2 eq. apply extensionality.
apply (aux _ _ _ p1 p2 eq). apply (aux _ _ _ p2 p1 (sym_eq eq)).
move=> x y y' pa pa'.
rewrite (partition_relation_set_pr pa) (partition_relation_set_pr pa').
move=> eq a ay.
move: (partition_relation_set_pr1 pa ay)=> cpy.
have nea: (nonempty a) by move: pa=> [_ [ne _]]; apply ne.
move: nea=> [b ba].
have p: (forall u v,inc u a -> inc v a->
exists c, (inc c y' & inc u c & inc v c)).
move=> u v ua va.
have p1: inc (J u v) (coarse a) by rewrite /coarse; fprops.
have p2: (inc (J u v) (union (partition_relation_set_aux y' x))).
rewrite eq; union_tac.
move: (union_exists p2) => [z [Jbb]].
rewrite /partition_relation_set_aux Z_rw; move=> [zp [c [cy zc]]].
by ex_tac; move: Jbb; rewrite zc /coarse product_pair_rw.
move: (p _ _ ba ba) => [c [cy [bc _]]].
suff: a = c by move=> ->.
set_extens t => ta.
move: (p _ _ ta ta) => [c' [cy' [tc' _]]].
move: (p _ _ ba ta) => [c'' [cy'' [bc'' tc'']]].
move: pa' => [_ [_ aux ]]; case:(aux _ _ cy cy'').
move => ->; case:(aux _ _ cy'' cy'); first by move => ->.
by move=> dcf;elim (nondisjoint tc'' tc' dcf).
by move=> dcf;elim (nondisjoint bc bc'' dcf).
have p1: (inc (J b t) (coarse c)) by rewrite/coarse; fprops.
have p2: (inc (J b t) (union (partition_relation_set_aux y' x))).
apply union_inc with (coarse c) => //.
apply (partition_relation_set_pr1 pa' cy).
move: p2; rewrite eq /partition_relation_set_aux => p2.
move: (union_exists p2)=> [z [Jbb]]; rewrite Z_rw;move=> [zp [d [dy zx]]].
move: Jbb; rewrite zx /coarse; aw; move=> [_ [bd td]].
move: pa => [_ [_ aux ]]; case:(aux _ _ ay dy).
by move=> ->.
move=> dfc; elim (nondisjoint ba bd dfc).
Qed.
Lemma preorder_prop1: forall g,
is_graph g ->
sub (identity_g (substrate g)) g -> sub (compose_graph g g) g ->
compose_graph g g = g.
Proof.
move=> g gg sig scg.
apply extensionality; first by aw.
move => x xg; aw; split; first by apply gg.
exists (Q x); rewrite (gg _ xg); ee; apply sig; aw; ee; substr_tac.
Qed.
Theorem order_pr: forall r,
order r =
(compose_graph r r = r &
intersection2 r (opposite_order r) = identity_g (substrate r)).
Proof.
move=> r.
apply iff_eq.
move=> or.
set (d:= identity_g (substrate r)).
have i2: (intersection2 r (opposite_order r) = d).
set_extens t.
aw; move=> [tr].
rewrite inverse_graph_rw;fprops; move=> [pt Jr].
have px: (J (P t) (Q t) = t) by aw.
rewrite - px in tr.
move: (order_antisymmetry or tr Jr)=> pq.
by rewrite /d -px pq; aw; split=>//; substr_tac.
rewrite/d; rewrite inc_diagonal_rw; move=> [pt [Ps pq]].
have Jpq: (J (P t) (Q t) = t) by aw.
rewrite -Jpq -pq.
have rpp: (related r (P t) (P t)) by order_tac.
by apply intersection2_inc=>//; aw.
have gr: (is_graph r) by fprops.
have sd: (sub d r) by rewrite -i2; apply intersection2sub_first.
have sc: (sub (compose_graph d r) (compose_graph r r)).
by apply composition_increasing; fprops.
have crrr: (sub (compose_graph r r) r).
by move: or => [_[t _]];rewrite -idempotent_graph_transitive //.
by split =>//; apply preorder_prop1.
move=> [crrr iro].
have gr: is_graph r by rewrite -crrr; apply composition_is_graph.
hnf; intuition; split=>//.
- move=> y ys.
have: (inc (J y y) (identity_g (substrate r))) by aw; auto.
by rewrite -iro; move=> Ji; apply (intersection2_first Ji).
- have: sub (compose_graph r r) r by rewrite crrr; fprops.
by rewrite -idempotent_graph_transitive //; move=> [_].
- move => x y rxy ryx.
have p1: (inc (J x y) (opposite_order r)) by aw.
have: (inc (J x y) (identity_g (substrate r))).
by rewrite - iro; apply intersection2_inc.
aw ; intuition.
Qed.
Lemma preorder_is_preorder: forall r,
preorder r -> preorder_r (related r).
Proof.
move=> r [[gr rr] [_ tr]].
split=>//.
move=> x y rxy.
have p1: (inc x (substrate r)) by substr_tac.
have p2: (inc y (substrate r)) by substr_tac.
by split; apply rr.
Qed.
Lemma opposite_is_preorder1: forall r,
preorder r -> preorder (opposite_order r).
Proof.
move=> r [[gr rr] [_ tr]].
have go: (is_graph (opposite_order r)) by fprops.
have ss: (sub (substrate (opposite_order r)) (substrate r)).
move=> t; rewrite inc_substrate_rw //inc_substrate_rw //.
by case;move=> [y]; aw =>h; [ right | left ] ;ex_tac.
split.
by split=>//; move=> y ys; red; aw; apply rr; apply ss.
split=>//; move => x y z; rewrite /related;aw.
move =>p1 p2; apply (tr _ _ _ p2 p1).
Qed.
Lemma equivalence_preorder: forall r,
preorder_r r ->
equivalence_r (fun x y => r x y & r y x).
Proof.
move=> r [ tr _]; split; first by move=> x y [rxy ryx].
move=> x y z [xy yx] [yz zy].
split; [ apply (tr _ _ _ xy yz) | apply (tr _ _ _ zy yx)].
Qed.
Lemma compatible_equivalence_preorder: forall r,
let s := (fun x y => r x y & r y x) in
preorder_r r -> forall x y x' y', r x y -> s x x' -> s y y' -> r x' y'.
Proof.
move=> r s [tr _] x y x' y' rxy [rxx' rx'x] [ryy' ry'y].
move: (tr _ _ _ rx'x rxy)=> rx'y.
apply (tr _ _ _ rx'y ryy').
Qed.
Equivalence relation associated to a preorder
Definition equivalence_associated_o r:= intersection2 r (opposite_order r).
Lemma equivalence_preorder1: forall r,
preorder r ->
is_equivalence (equivalence_associated_o r).
Proof.
move=> r pr.
rewrite /equivalence_associated_o.
have gr: is_graph r by apply preorder_graph.
have gi: is_graph (opposite_order r) by fprops.
move: (inter2_is_graph2 gr (x:=r)) => gi2.
have gi3: is_graph (intersection2 r (opposite_order r)).
by move=> x xi; apply (gr _ (intersection2_first xi)).
apply symmetric_transitive_equivalence.
split=>//; move=> x y; rewrite /related; aw; intuition.
split=>//; move=> x y z;rewrite /related; aw.
move=> [xy yx][yz zy]; move: pr=> [_ [_ tr]].
split; [apply (tr _ _ _ xy yz) | apply (tr _ _ _ zy yx) ].
Qed.
Lemma substrate_equivalence_associated_o: forall r,
preorder r ->
substrate (equivalence_associated_o r) = substrate r.
Proof.
move=> r pr.
move: (equivalence_preorder1 pr)=> eq.
set_extens x => xs.
move: (reflexivity_e eq xs).
rewrite/related /equivalence_associated_o=> h.
by move:(intersection2_first h)=> h1; substr_tac.
move: pr=> [[gr rr] _].
move: (rr _ xs); rewrite /related=> Js.
have Je: (inc (J x x) (equivalence_associated_o r)).
rewrite /equivalence_associated_o; apply intersection2_inc =>//; aw.
substr_tac.
Qed.
Lemma compatible_equivalence_preorder1: forall r u v x y,
preorder r -> related r x y ->
related (equivalence_associated_o r) x u ->
related (equivalence_associated_o r) y v->
related r u v.
Proof.
rewrite /related /equivalence_associated_o=> r u v x y pr rxy.
aw.
move: pr => [_ [_ tr]] [_ ux] [yv _].
move: (tr _ _ _ ux rxy)=> uy.
apply (tr _ _ _ uy yv).
Qed.
Lemma preorder_prop: forall g,
is_graph g ->
preorder g = (sub (identity_g (substrate g)) g & sub (compose_graph g g) g).
Proof.
move=> g gg.
apply iff_eq.
move=> [[_ rr] tr].
split; move=> x.
rewrite inc_diagonal_rw; move=> [px [Px pq]].
have : (J (P x) (Q x) = x) by aw.
by move=> <-; rewrite -pq; apply rr.
rewrite idempotent_graph_transitive // in tr.
apply tr.
move=> [s1 s2].
split.
split=>//.
move=> y ys; rewrite /related; apply s1.
by rewrite inc_diagonal_rw; aw; fprops.
by rewrite idempotent_graph_transitive.
Qed.
Lemma preorder_prop2: forall g,
preorder g -> compose_graph g g = g.
Proof.
move=> g pg.
have gg: is_graph g by apply preorder_graph.
rewrite (preorder_prop gg) in pg.
by apply preorder_prop1; intuition.
Qed.
Lemma preorder_reflexivity: forall r a,
preorder r -> inc a (substrate r) = related r a a.
Proof.
move=> r a [[g pr] _].
apply iff_eq; first by apply pr.
move=> h; substr_tac.
Qed.
Compare with fun_on_quotients
Definition order_associated (r:Set) :=
let s := (graph(canon_proj (equivalence_associated_o r))) in
compose_graph (compose_graph s r) (opposite_order s).
Lemma order_associated_graph: forall r,
is_graph (order_associated r).
Proof.
rewrite /order_associated=> r; apply composition_is_graph.
Qed.
Lemma compose3_related: forall s r u v,
related (compose_graph (compose_graph s r) (opposite_order s)) u v =
exists x, exists y, related s x u & related s y v & related r x y.
Proof.
move=> s r u v; rewrite compose_related ;apply iff_eq.
move=> [y []]; aw; bw; move=> yu [z [yz zv]].
by exists y; exists z.
move=> [x [y [xu [yv xy]]]]; exists x.
aw; bw; ee.
by exists y.
Qed.
Lemma order_associated_related1: forall r u v,
preorder r->
related (order_associated r) u v =
( inc u (quotient (equivalence_associated_o r)) &
inc v (quotient (equivalence_associated_o r)) &
exists x, exists y, inc x u & inc y v & related r x y).
Proof.
move=> r u v pr.
set (s:= equivalence_associated_o r).
set (p:= graph (canon_proj s)).
rewrite /order_associated -/s -/p.
have es:is_equivalence s by rewrite /s; apply equivalence_preorder1.
rewrite compose3_related.
apply iff_eq.
move=> [x [y [xu [yv xy]]]].
have fc: is_function (canon_proj s) by apply canon_proj_function.
move: (inc_pr1graph_source fc xu); aw => xs.
move: (inc_pr1graph_source fc yv); aw => ys.
have: (u = W x (canon_proj s)) by symmetry; apply W_pr=>//.
have: (v = W y (canon_proj s)) by symmetry; apply W_pr=>//.
rewrite canon_proj_W // canon_proj_W //.
move=> -> ->; ee.
exists x; exists y; split; first by apply inc_itself_class.
by split=>//; apply inc_itself_class.
move=> [uq [vq [x [y [xu [yv xy]]]]]].
exists x; exists y.
split.
rewrite /p/related related_graph_canon_proj //.
apply (inc_in_quotient_substrate es xu uq).
split =>//.
rewrite /p/related related_graph_canon_proj //.
apply (inc_in_quotient_substrate es yv vq).
Qed.
Lemma order_associated_related2: forall r u v,
preorder r->
related (order_associated r) u v =
( inc u (quotient (equivalence_associated_o r)) &
inc v (quotient (equivalence_associated_o r)) &
forall x y, inc x u -> inc y v -> related r x y).
Proof.
move=> r u v pr; rewrite order_associated_related1 //.
set (s:= equivalence_associated_o r).
have es: is_equivalence s by rewrite /s; apply equivalence_preorder1.
apply iff_eq.
move=> [uq [vq [x [y [xu [yv xy]]]]]].
ee.
move=> a b au bv.
have xa: (related s x a).
by rewrite in_class_related //; exists u; intuition; rewrite - inc_quotient.
have yb: (related s y b).
by rewrite in_class_related //; exists v; intuition; rewrite - inc_quotient.
apply (compatible_equivalence_preorder1 pr xy xa yb).
move => [uq [vq hyp]]; split =>//; split=>//.
move: (non_empty_in_quotient es uq)=> [x xu].
move: (non_empty_in_quotient es vq)=> [y yv].
by exists x; exists y ; auto.
Qed.
Lemma eao_related: forall r a b,
related (equivalence_associated_o r) a b -> related r a b.
Proof.
by move=> r a b; rewrite/equivalence_associated_o/related; aw; case.
Qed.
Lemma order_associated_substrate: forall r,
preorder r-> substrate (order_associated r) =
(quotient (equivalence_associated_o r)).
Proof.
move=> r pr.
have ea:is_equivalence (equivalence_associated_o r).
by apply equivalence_preorder1.
set eao:= (equivalence_associated_o r).
have prop: forall a b, inc (J a b) (order_associated r)->
(inc a (quotient eao) & inc b (quotient eao)).
move=> a b Jab.
have: (related (order_associated r) a b) by done.
by rewrite order_associated_related2//; intuition.
set_extens x.
rewrite inc_substrate_rw; last by apply order_associated_graph.
by case; move=> [y yp]; move: (prop _ _ yp); intuition.
move=> xq.
suff: (related (order_associated r) x x) by move => w; substr_tac.
rewrite order_associated_related2 //; ee.
move=> z y zx yx.
have: (related (equivalence_associated_o r) z y).
rewrite in_class_related //; exists x.
by intuition; rewrite - inc_quotient.
apply eao_related.
Qed.
Lemma order_associated_order: forall r,
preorder r-> order (order_associated r).
Proof.
move=> r pr.
have go: is_graph (order_associated r) by apply order_associated_graph.
have eea:is_equivalence (equivalence_associated_o r)
by apply equivalence_preorder1.
have gr: is_graph r by move: pr=> [[]].
hnf; intuition;split =>//.
- move=> y; rewrite order_associated_substrate // => ys.
move: pr=> [rr rt].
rewrite order_associated_related2; split=>//; split=>//.
move=> x z xy zy.
have: (related (equivalence_associated_o r) x z).
by rewrite in_class_related//; exists y; split=>//; rewrite - inc_quotient.
apply eao_related.
- move=> x y z; do 3 rewrite order_associated_related2 //.
move=>[xq [yq rxy]][_ [zq ryz]]; split=>//; split=>//.
move => a b ax bz; move: (non_empty_in_quotient eea yq)=> [c cy].
move:pr => [_ [_ tr]].
apply (tr _ _ _ (rxy _ _ ax cy) (ryz _ _ cy bz)).
- move=> x y; do 2 rewrite order_associated_related2 //.
move=> [xq [yq rxy]][_ [_ ryx]].
move: (non_empty_in_quotient eea xq)=> [a ax].
move: (non_empty_in_quotient eea yq)=> [b biy].
move: (rxy _ _ ax biy)(ryx _ _ biy ax)=> rab rba;
have reab: (related (equivalence_associated_o r) a b).
rewrite /related /equivalence_associated_o; apply intersection2_inc =>//.
aw.
move: xq yq; srw => // xq yq.
have bx: inc b x.
move: xq; rewrite is_class_rw //.
by move=> [_ [_ h]]; rewrite -(h a b ax) in reab.
case (class_dichot xq yq) =>// hyp.
elim (nondisjoint bx biy hyp).
Qed.
Lemma order_associated_pr: forall r,
preorder r ->
order_associated r = image_by_fun (
ext_to_prod(canon_proj (equivalence_associated_o r))
(canon_proj (equivalence_associated_o r))) r.
Proof.
move=> r pr.
set (s:= equivalence_associated_o r).
have es:is_equivalence s by rewrite /s; apply equivalence_preorder1.
have ss:substrate s = substrate r.
by rewrite /s substrate_equivalence_associated_o.
have fep: is_function (ext_to_prod (canon_proj s) (canon_proj s)).
by apply ext_to_prod_function; apply canon_proj_function=>//.
have gi:
is_graph (image_by_fun (ext_to_prod (canon_proj s) (canon_proj s)) r).
move=> t; rewrite /image_by_fun; aw; move=> [x [xr Jg]].
by move:(inc_pr2graph_target fep Jg); rewrite /ext_to_prod; aw; intuition.
rewrite graph_exten //; last by apply order_associated_graph.
move=> u v; rewrite order_associated_related2 //.
fold s; rewrite /related/image_by_fun; apply iff_eq.
move=> [uq [vq hyp]].
aw;exists (J (rep u) (rep v)).
split; first by apply hyp; apply (inc_rep_itself es).
have p1: (class s (rep u) =u) by apply class_rep.
have p2: (class s (rep v) =v) by apply class_rep.
have : (J u v = J (class s (rep u)) (class s (rep v))) by rewrite p1 p2.
rewrite - ext_to_prod_rel_W; fprops; move =>->.
apply W_pr3=> //.
by rewrite /ext_to_prod; aw; fprops.
aw; move=> [x [xr]].
rewrite/related=> Jg; move: (W_pr fep Jg)=> Wx.
have px: (is_pair x) by move: pr=> [[g _] _]; apply g.
have Jpq: J (P x) (Q x) = x by aw.
have ps: (inc (P x) (substrate s)) by rewrite ss; substr_tac.
have qs: (inc (Q x) (substrate s)) by rewrite ss; substr_tac.
move: Wx; rewrite -Jpq ext_to_prod_rel_W // => JJ.
move: (pr1_def JJ) (pr2_def JJ) => e1 e2.
have uq: inc u (quotient s) by rewrite - e1; gprops.
have vq: inc v (quotient s) by rewrite - e2; gprops.
ee; move=> a b au bv.
suff: (related (order_associated r) u v).
by rewrite order_associated_related2 //; move=> [_ [_ h]]; apply (h _ _ au bv).
rewrite order_associated_related1 //;ee.
exists (P x); exists (Q x).
rewrite -e1 -e2; split; first by apply inc_itself_class.
split; first by apply inc_itself_class.
by red; rewrite px.
Qed.
let s := (graph(canon_proj (equivalence_associated_o r))) in
compose_graph (compose_graph s r) (opposite_order s).
Lemma order_associated_graph: forall r,
is_graph (order_associated r).
Proof.
rewrite /order_associated=> r; apply composition_is_graph.
Qed.
Lemma compose3_related: forall s r u v,
related (compose_graph (compose_graph s r) (opposite_order s)) u v =
exists x, exists y, related s x u & related s y v & related r x y.
Proof.
move=> s r u v; rewrite compose_related ;apply iff_eq.
move=> [y []]; aw; bw; move=> yu [z [yz zv]].
by exists y; exists z.
move=> [x [y [xu [yv xy]]]]; exists x.
aw; bw; ee.
by exists y.
Qed.
Lemma order_associated_related1: forall r u v,
preorder r->
related (order_associated r) u v =
( inc u (quotient (equivalence_associated_o r)) &
inc v (quotient (equivalence_associated_o r)) &
exists x, exists y, inc x u & inc y v & related r x y).
Proof.
move=> r u v pr.
set (s:= equivalence_associated_o r).
set (p:= graph (canon_proj s)).
rewrite /order_associated -/s -/p.
have es:is_equivalence s by rewrite /s; apply equivalence_preorder1.
rewrite compose3_related.
apply iff_eq.
move=> [x [y [xu [yv xy]]]].
have fc: is_function (canon_proj s) by apply canon_proj_function.
move: (inc_pr1graph_source fc xu); aw => xs.
move: (inc_pr1graph_source fc yv); aw => ys.
have: (u = W x (canon_proj s)) by symmetry; apply W_pr=>//.
have: (v = W y (canon_proj s)) by symmetry; apply W_pr=>//.
rewrite canon_proj_W // canon_proj_W //.
move=> -> ->; ee.
exists x; exists y; split; first by apply inc_itself_class.
by split=>//; apply inc_itself_class.
move=> [uq [vq [x [y [xu [yv xy]]]]]].
exists x; exists y.
split.
rewrite /p/related related_graph_canon_proj //.
apply (inc_in_quotient_substrate es xu uq).
split =>//.
rewrite /p/related related_graph_canon_proj //.
apply (inc_in_quotient_substrate es yv vq).
Qed.
Lemma order_associated_related2: forall r u v,
preorder r->
related (order_associated r) u v =
( inc u (quotient (equivalence_associated_o r)) &
inc v (quotient (equivalence_associated_o r)) &
forall x y, inc x u -> inc y v -> related r x y).
Proof.
move=> r u v pr; rewrite order_associated_related1 //.
set (s:= equivalence_associated_o r).
have es: is_equivalence s by rewrite /s; apply equivalence_preorder1.
apply iff_eq.
move=> [uq [vq [x [y [xu [yv xy]]]]]].
ee.
move=> a b au bv.
have xa: (related s x a).
by rewrite in_class_related //; exists u; intuition; rewrite - inc_quotient.
have yb: (related s y b).
by rewrite in_class_related //; exists v; intuition; rewrite - inc_quotient.
apply (compatible_equivalence_preorder1 pr xy xa yb).
move => [uq [vq hyp]]; split =>//; split=>//.
move: (non_empty_in_quotient es uq)=> [x xu].
move: (non_empty_in_quotient es vq)=> [y yv].
by exists x; exists y ; auto.
Qed.
Lemma eao_related: forall r a b,
related (equivalence_associated_o r) a b -> related r a b.
Proof.
by move=> r a b; rewrite/equivalence_associated_o/related; aw; case.
Qed.
Lemma order_associated_substrate: forall r,
preorder r-> substrate (order_associated r) =
(quotient (equivalence_associated_o r)).
Proof.
move=> r pr.
have ea:is_equivalence (equivalence_associated_o r).
by apply equivalence_preorder1.
set eao:= (equivalence_associated_o r).
have prop: forall a b, inc (J a b) (order_associated r)->
(inc a (quotient eao) & inc b (quotient eao)).
move=> a b Jab.
have: (related (order_associated r) a b) by done.
by rewrite order_associated_related2//; intuition.
set_extens x.
rewrite inc_substrate_rw; last by apply order_associated_graph.
by case; move=> [y yp]; move: (prop _ _ yp); intuition.
move=> xq.
suff: (related (order_associated r) x x) by move => w; substr_tac.
rewrite order_associated_related2 //; ee.
move=> z y zx yx.
have: (related (equivalence_associated_o r) z y).
rewrite in_class_related //; exists x.
by intuition; rewrite - inc_quotient.
apply eao_related.
Qed.
Lemma order_associated_order: forall r,
preorder r-> order (order_associated r).
Proof.
move=> r pr.
have go: is_graph (order_associated r) by apply order_associated_graph.
have eea:is_equivalence (equivalence_associated_o r)
by apply equivalence_preorder1.
have gr: is_graph r by move: pr=> [[]].
hnf; intuition;split =>//.
- move=> y; rewrite order_associated_substrate // => ys.
move: pr=> [rr rt].
rewrite order_associated_related2; split=>//; split=>//.
move=> x z xy zy.
have: (related (equivalence_associated_o r) x z).
by rewrite in_class_related//; exists y; split=>//; rewrite - inc_quotient.
apply eao_related.
- move=> x y z; do 3 rewrite order_associated_related2 //.
move=>[xq [yq rxy]][_ [zq ryz]]; split=>//; split=>//.
move => a b ax bz; move: (non_empty_in_quotient eea yq)=> [c cy].
move:pr => [_ [_ tr]].
apply (tr _ _ _ (rxy _ _ ax cy) (ryz _ _ cy bz)).
- move=> x y; do 2 rewrite order_associated_related2 //.
move=> [xq [yq rxy]][_ [_ ryx]].
move: (non_empty_in_quotient eea xq)=> [a ax].
move: (non_empty_in_quotient eea yq)=> [b biy].
move: (rxy _ _ ax biy)(ryx _ _ biy ax)=> rab rba;
have reab: (related (equivalence_associated_o r) a b).
rewrite /related /equivalence_associated_o; apply intersection2_inc =>//.
aw.
move: xq yq; srw => // xq yq.
have bx: inc b x.
move: xq; rewrite is_class_rw //.
by move=> [_ [_ h]]; rewrite -(h a b ax) in reab.
case (class_dichot xq yq) =>// hyp.
elim (nondisjoint bx biy hyp).
Qed.
Lemma order_associated_pr: forall r,
preorder r ->
order_associated r = image_by_fun (
ext_to_prod(canon_proj (equivalence_associated_o r))
(canon_proj (equivalence_associated_o r))) r.
Proof.
move=> r pr.
set (s:= equivalence_associated_o r).
have es:is_equivalence s by rewrite /s; apply equivalence_preorder1.
have ss:substrate s = substrate r.
by rewrite /s substrate_equivalence_associated_o.
have fep: is_function (ext_to_prod (canon_proj s) (canon_proj s)).
by apply ext_to_prod_function; apply canon_proj_function=>//.
have gi:
is_graph (image_by_fun (ext_to_prod (canon_proj s) (canon_proj s)) r).
move=> t; rewrite /image_by_fun; aw; move=> [x [xr Jg]].
by move:(inc_pr2graph_target fep Jg); rewrite /ext_to_prod; aw; intuition.
rewrite graph_exten //; last by apply order_associated_graph.
move=> u v; rewrite order_associated_related2 //.
fold s; rewrite /related/image_by_fun; apply iff_eq.
move=> [uq [vq hyp]].
aw;exists (J (rep u) (rep v)).
split; first by apply hyp; apply (inc_rep_itself es).
have p1: (class s (rep u) =u) by apply class_rep.
have p2: (class s (rep v) =v) by apply class_rep.
have : (J u v = J (class s (rep u)) (class s (rep v))) by rewrite p1 p2.
rewrite - ext_to_prod_rel_W; fprops; move =>->.
apply W_pr3=> //.
by rewrite /ext_to_prod; aw; fprops.
aw; move=> [x [xr]].
rewrite/related=> Jg; move: (W_pr fep Jg)=> Wx.
have px: (is_pair x) by move: pr=> [[g _] _]; apply g.
have Jpq: J (P x) (Q x) = x by aw.
have ps: (inc (P x) (substrate s)) by rewrite ss; substr_tac.
have qs: (inc (Q x) (substrate s)) by rewrite ss; substr_tac.
move: Wx; rewrite -Jpq ext_to_prod_rel_W // => JJ.
move: (pr1_def JJ) (pr2_def JJ) => e1 e2.
have uq: inc u (quotient s) by rewrite - e1; gprops.
have vq: inc v (quotient s) by rewrite - e2; gprops.
ee; move=> a b au bv.
suff: (related (order_associated r) u v).
by rewrite order_associated_related2 //; move=> [_ [_ h]]; apply (h _ _ au bv).
rewrite order_associated_related1 //;ee.
exists (P x); exists (Q x).
rewrite -e1 -e2; split; first by apply inc_itself_class.
split; first by apply inc_itself_class.
by red; rewrite px.
Qed.
Same axioms as in Bourbaki
Definition order_axioms (r s:Set) :=
(forall x y z, gle r x y -> gle r y z -> gle r x z) &
(forall x y, gle r x y -> gle r y x -> x = y) &
(forall x y, gle r x y -> (inc x s & inc y s)) &
(forall x, gle r x x = inc x s) &
is_graph r.
Lemma axioms_of_order: forall r,
order r = (order_axioms r (substrate r)).
Proof.
move=> r; rewrite/order_axioms; apply iff_eq.
move=>or; intuition; try order_tac.
apply iff_eq=> H; order_tac.
move=> [h1 [h2 [h3 [h4 gr]]]].
hnf. intuition; split=>//.
by move=> y; rewrite -h4.
Qed.
Lemma le_pr: forall r x y,
inc x (substrate r) ->
order r -> gle r x y = (glt r x y \/ x = y).
Proof.
move=> r x y xr or; rewrite /glt.
apply iff_eq.
case (equal_or_not x y); auto.
case=>//; first by intuition.
by move=> <-; order_tac.
Qed.
(forall x y z, gle r x y -> gle r y z -> gle r x z) &
(forall x y, gle r x y -> gle r y x -> x = y) &
(forall x y, gle r x y -> (inc x s & inc y s)) &
(forall x, gle r x x = inc x s) &
is_graph r.
Lemma axioms_of_order: forall r,
order r = (order_axioms r (substrate r)).
Proof.
move=> r; rewrite/order_axioms; apply iff_eq.
move=>or; intuition; try order_tac.
apply iff_eq=> H; order_tac.
move=> [h1 [h2 [h3 [h4 gr]]]].
hnf. intuition; split=>//.
by move=> y; rewrite -h4.
Qed.
Lemma le_pr: forall r x y,
inc x (substrate r) ->
order r -> gle r x y = (glt r x y \/ x = y).
Proof.
move=> r x y xr or; rewrite /glt.
apply iff_eq.
case (equal_or_not x y); auto.
case=>//; first by intuition.
by move=> <-; order_tac.
Qed.
Order morphisms and isomorphisms.
In the second definition we do not assume the function surjective
Definition order_isomorphism f r r':=
(order r) & (order r') &
(bijection f) & (substrate r = source f) & (substrate r' = target f) &
(forall x y, inc x (source f) -> inc y (source f) ->
gle r x y = gle r' (W x f) (W y f)).
Definition order_morphism f r r':=
(order r) & (order r') &
(injection f) & (substrate r = source f) & (substrate r' = target f) &
(forall x y, inc x (source f) -> inc y (source f) ->
gle r x y = gle r' (W x f) (W y f)).
Order induced by r on a
Definition induced_order (r a:Set):=
intersection2 r (coarse a).
Lemma relation_induced_order: forall r a,
is_graph r -> is_graph (induced_order r a).
Proof.
rewrite /induced_order=> r a gr; apply (inter2_is_graph1 gr (y:=coarse a)).
Qed.
Lemma iorder_gle: forall r a x y, inc x a -> inc y a ->
gle (induced_order r a) x y = gle r x y.
Proof.
rewrite /gle/related/induced_order=> r a x y xa ya.
apply iff_eq; aw; first by case.
move=> h; split=>//; rewrite /coarse; fprops.
Qed.
Lemma iorder_gle1: forall r a x y,
gle (induced_order r a) x y -> gle r x y.
Proof.
move=> r a x y; rewrite/induced_order.
by rewrite /gle/related; aw; case.
Qed.
Lemma iorder_gle2: forall r a x y,
glt (induced_order r a) x y -> glt r x y.
Proof.
move=> r a x y [lexy nxy]; split =>//.
apply (iorder_gle1 lexy).
Qed.
Lemma iorder_gle3: forall r a x y,
gle (induced_order r a) x y -> (inc x a & inc y a).
Proof.
rewrite /induced_order/gle/related/coarse => r x a y.
by aw; intuition.
Qed.
Lemma iorder_gle4: forall r a x y,
glt(induced_order r a) x y -> (inc x a & inc y a).
Proof.
move=> r a x y [glexy nexy]; apply (iorder_gle3 glexy).
Qed.
Hint Rewrite iorder_gle : aw.
Lemma iorder_gle5: forall r a x y,
gle (induced_order r a) x y = (inc x a & inc y a & gle r x y).
Proof.
move=> r a x y; apply iff_eq.
move=> h; move: (iorder_gle1 h)(iorder_gle3 h).
intuition.
move=> [h1 [h2 h3]]; aw.
Qed.
Lemma iorder_gle6: forall r a x y,
glt (induced_order r a) x y = (inc x a & inc y a & glt r x y).
Proof.
move=> r a x y; rewrite /glt iorder_gle5.
apply iff_eq; intuition.
Qed.
Lemma substrate_induced_order1: forall r a,
is_reflexive r ->
sub a (substrate r) -> substrate (induced_order r a) = a.
Proof.
move=> r a rr sasr.
have gi: is_graph (induced_order r a).
by apply relation_induced_order; move: rr => [g].
rewrite /induced_order/coarse.
set_extens x.
rewrite inc_substrate_rw //.
by case; move=> [y]; aw; intuition.
move=> h.
apply inc_arg1_substrate with x.
red; aw; intuition.
move: (sasr _ h); rewrite reflexive_inc_substrate //.
Qed.
Lemma substrate_induced_order :forall r a,
order r ->
sub a (substrate r) -> substrate (induced_order r a) = a.
Proof.
move=> r a or ar; apply substrate_induced_order1=>//.
by move: or=> [].
Qed.
Hint Rewrite substrate_induced_order : aw.
Lemma reflexive_induced_order: forall r a,
sub a (substrate r) ->
is_reflexive r -> is_reflexive (induced_order r a).
Proof.
move=> r a ar [gr rr].
split; first by apply relation_induced_order.
move=> y ys.
have ya: (inc y a) by rewrite substrate_induced_order1 in ys.
have ysr: (inc y (substrate r)) by apply ar.
by rewrite -[related]/(gle); aw; apply rr.
Qed.
Lemma transitive_induced_order: forall r a,
sub a (substrate r) ->
is_transitive r -> is_transitive (induced_order r a).
Proof.
move=> r a ar [gr tr].
split; first by apply relation_induced_order.
move=> x y z; rewrite /related/induced_order/coarse; aw.
move => [J1r [_ [xa ya]]][J2r [_ [_ za]]].
intuition; apply (tr _ _ _ J1r J2r).
Qed.
Lemma preorder_induced_order: forall r a,
sub a (substrate r) ->
preorder r -> preorder (induced_order r a).
Proof.
move=> r a ar [rr tr].
by split; [ apply reflexive_induced_order | apply transitive_induced_order].
Qed.
Lemma order_induced_order: forall r a,
sub a (substrate r) ->
order r -> order (induced_order r a).
Proof.
move=> r a ar or.
have: preorder (induced_order r a).
by apply preorder_induced_order =>//; apply order_preorder.
move=> [rio tio].
hnf; intuition.
split; first by move: rio => [g _].
move=> x y; rewrite /related /induced_order.
aw;move=> [J1 _][J2 _]; order_tac.
Qed.
Hint Resolve order_induced_order: fprops.
Lemma induced_order_substrate: forall r,
order r ->
induced_order r (substrate r) = r.
Proof.
move=> r o; rewrite /induced_order -intersection2_sub.
apply sub_graph_coarse_substrate; fprops.
Qed.
Lemma opposite_induced: forall r x, order r ->
induced_order (opposite_order r) x = opposite_order (induced_order r x).
Proof.
move=> r x or; rewrite /induced_order/opposite_order/inverse_graph/coarse.
have gr: is_graph r by fprops.
move:(inter2_is_graph1 gr (y:=coarse x)) => gi.
set_extens y; rewrite Z_rw; aw; rewrite Z_rw.
move=> [[yp Jr] [py [Px Qx]]].
dw;intuition; [ exists(Q y) |exists (P y)];aw; fprops.
move=> [[py [ [u J1i][b J2i]]] [Jr [_ [Qx Qy]]]].
intuition; aw; intuition; ex_tac.
Qed.
intersection2 r (coarse a).
Lemma relation_induced_order: forall r a,
is_graph r -> is_graph (induced_order r a).
Proof.
rewrite /induced_order=> r a gr; apply (inter2_is_graph1 gr (y:=coarse a)).
Qed.
Lemma iorder_gle: forall r a x y, inc x a -> inc y a ->
gle (induced_order r a) x y = gle r x y.
Proof.
rewrite /gle/related/induced_order=> r a x y xa ya.
apply iff_eq; aw; first by case.
move=> h; split=>//; rewrite /coarse; fprops.
Qed.
Lemma iorder_gle1: forall r a x y,
gle (induced_order r a) x y -> gle r x y.
Proof.
move=> r a x y; rewrite/induced_order.
by rewrite /gle/related; aw; case.
Qed.
Lemma iorder_gle2: forall r a x y,
glt (induced_order r a) x y -> glt r x y.
Proof.
move=> r a x y [lexy nxy]; split =>//.
apply (iorder_gle1 lexy).
Qed.
Lemma iorder_gle3: forall r a x y,
gle (induced_order r a) x y -> (inc x a & inc y a).
Proof.
rewrite /induced_order/gle/related/coarse => r x a y.
by aw; intuition.
Qed.
Lemma iorder_gle4: forall r a x y,
glt(induced_order r a) x y -> (inc x a & inc y a).
Proof.
move=> r a x y [glexy nexy]; apply (iorder_gle3 glexy).
Qed.
Hint Rewrite iorder_gle : aw.
Lemma iorder_gle5: forall r a x y,
gle (induced_order r a) x y = (inc x a & inc y a & gle r x y).
Proof.
move=> r a x y; apply iff_eq.
move=> h; move: (iorder_gle1 h)(iorder_gle3 h).
intuition.
move=> [h1 [h2 h3]]; aw.
Qed.
Lemma iorder_gle6: forall r a x y,
glt (induced_order r a) x y = (inc x a & inc y a & glt r x y).
Proof.
move=> r a x y; rewrite /glt iorder_gle5.
apply iff_eq; intuition.
Qed.
Lemma substrate_induced_order1: forall r a,
is_reflexive r ->
sub a (substrate r) -> substrate (induced_order r a) = a.
Proof.
move=> r a rr sasr.
have gi: is_graph (induced_order r a).
by apply relation_induced_order; move: rr => [g].
rewrite /induced_order/coarse.
set_extens x.
rewrite inc_substrate_rw //.
by case; move=> [y]; aw; intuition.
move=> h.
apply inc_arg1_substrate with x.
red; aw; intuition.
move: (sasr _ h); rewrite reflexive_inc_substrate //.
Qed.
Lemma substrate_induced_order :forall r a,
order r ->
sub a (substrate r) -> substrate (induced_order r a) = a.
Proof.
move=> r a or ar; apply substrate_induced_order1=>//.
by move: or=> [].
Qed.
Hint Rewrite substrate_induced_order : aw.
Lemma reflexive_induced_order: forall r a,
sub a (substrate r) ->
is_reflexive r -> is_reflexive (induced_order r a).
Proof.
move=> r a ar [gr rr].
split; first by apply relation_induced_order.
move=> y ys.
have ya: (inc y a) by rewrite substrate_induced_order1 in ys.
have ysr: (inc y (substrate r)) by apply ar.
by rewrite -[related]/(gle); aw; apply rr.
Qed.
Lemma transitive_induced_order: forall r a,
sub a (substrate r) ->
is_transitive r -> is_transitive (induced_order r a).
Proof.
move=> r a ar [gr tr].
split; first by apply relation_induced_order.
move=> x y z; rewrite /related/induced_order/coarse; aw.
move => [J1r [_ [xa ya]]][J2r [_ [_ za]]].
intuition; apply (tr _ _ _ J1r J2r).
Qed.
Lemma preorder_induced_order: forall r a,
sub a (substrate r) ->
preorder r -> preorder (induced_order r a).
Proof.
move=> r a ar [rr tr].
by split; [ apply reflexive_induced_order | apply transitive_induced_order].
Qed.
Lemma order_induced_order: forall r a,
sub a (substrate r) ->
order r -> order (induced_order r a).
Proof.
move=> r a ar or.
have: preorder (induced_order r a).
by apply preorder_induced_order =>//; apply order_preorder.
move=> [rio tio].
hnf; intuition.
split; first by move: rio => [g _].
move=> x y; rewrite /related /induced_order.
aw;move=> [J1 _][J2 _]; order_tac.
Qed.
Hint Resolve order_induced_order: fprops.
Lemma induced_order_substrate: forall r,
order r ->
induced_order r (substrate r) = r.
Proof.
move=> r o; rewrite /induced_order -intersection2_sub.
apply sub_graph_coarse_substrate; fprops.
Qed.
Lemma opposite_induced: forall r x, order r ->
induced_order (opposite_order r) x = opposite_order (induced_order r x).
Proof.
move=> r x or; rewrite /induced_order/opposite_order/inverse_graph/coarse.
have gr: is_graph r by fprops.
move:(inter2_is_graph1 gr (y:=coarse x)) => gi.
set_extens y; rewrite Z_rw; aw; rewrite Z_rw.
move=> [[yp Jr] [py [Px Qx]]].
dw;intuition; [ exists(Q y) |exists (P y)];aw; fprops.
move=> [[py [ [u J1i][b J2i]]] [Jr [_ [Qx Qy]]]].
intuition; aw; intuition; ex_tac.
Qed.
Example 1. The function that associates to a partial function its graph.
Is an isomorphism for extends and inclusion
Definition set_of_fgraphs (x y :Set):=
(Zo(powerset (product x y)) (fun z => functional_graph z)).
Definition graph_of_function (x y:Set):=
BL graph (set_of_sub_functions x y)
(set_of_fgraphs x y).
Lemma graph_of_function_sub: forall x y z,
inc z (set_of_sub_functions x y) -> sub (graph z) (product x y).
Proof.
move=> x y z; bw; move=> [fz [sz]] <-.
move: fz=> [[_ p] _].
apply (@sub_trans _ _ (product x (target z)) p).
apply product_monotone; fprops.
Qed.
Lemma set_of_graphs_pr: forall x y z,
inc z (set_of_sub_functions x y) -> inc (graph z) (set_of_fgraphs x y).
Proof.
move=> x y z zs; rewrite /set_of_fgraphs Z_rw; split.
by aw; apply graph_of_function_sub.
move: zs; bw; move => [[cz [fz _]] _].
by move: fz; rewrite - is_functional; case.
Qed.
Lemma graph_of_function_axioms: forall x y,
transf_axioms(fun g => (graph g)) (set_of_sub_functions x y)
(set_of_fgraphs x y).
Proof. by move=> x y z zs; apply set_of_graphs_pr.
Qed.
Lemma graph_of_function_fonction: forall x y,
is_function (graph_of_function x y).
Proof.
move=> x y; rewrite/graph_of_function.
by apply bl_function; apply graph_of_function_axioms.
Qed.
Lemma graph_of_function_W: forall x y f,
inc f (set_of_sub_functions x y) -> W f (graph_of_function x y) = graph f.
Proof.
by rewrite /graph_of_function=> x y f fs; aw; apply graph_of_function_axioms.
Qed.
Lemma graph_of_function_bijective: forall x y,
bijection (graph_of_function x y).
Proof.
rewrite /graph_of_function=> x y.
apply bl_bijective.
by apply graph_of_function_axioms.
move=> u v; bw; move=> [fu [ssu tu]][fv [sv tv]] sg.
by apply function_exten1=>//; ue.
move=> z; rewrite /set_of_fgraphs Z_rw; aw; move=> [zp fgz].
move: (sub_product_is_graph zp) => gz.
have fgz': fgraph z by rewrite - is_functional.
exists (corresp (domain z) y z); bw; aw; intuition.
apply is_function_pr=>//.
move => t; dw; move => [u Jz]; move: (zp _ Jz); aw; intuition.
move => t; dw; move => [u Jz]; move: (zp _ Jz); aw; intuition.
Qed.
Lemma graph_of_function_isomorphism: forall x y,
order_isomorphism (graph_of_function x y)
(opposite_order (extension_order x y))
(inclusion_suborder (set_of_fgraphs x y)).
Proof.
move=> x y.
move: (extension_is_order x y) => eo.
red; aw.
have <- :set_of_sub_functions x y = source (graph_of_function x y).
rewrite /graph_of_function; aw.
ee.
by apply graph_of_function_bijective.
by rewrite /graph_of_function; aw.
move=> a b ass bss.
rewrite graph_of_function_W // graph_of_function_W // extension_order_pr2.
by aw; apply iff_eq; move=> [aas' [bss' sg]]; ee ; apply set_of_graphs_pr.
Qed.
(Zo(powerset (product x y)) (fun z => functional_graph z)).
Definition graph_of_function (x y:Set):=
BL graph (set_of_sub_functions x y)
(set_of_fgraphs x y).
Lemma graph_of_function_sub: forall x y z,
inc z (set_of_sub_functions x y) -> sub (graph z) (product x y).
Proof.
move=> x y z; bw; move=> [fz [sz]] <-.
move: fz=> [[_ p] _].
apply (@sub_trans _ _ (product x (target z)) p).
apply product_monotone; fprops.
Qed.
Lemma set_of_graphs_pr: forall x y z,
inc z (set_of_sub_functions x y) -> inc (graph z) (set_of_fgraphs x y).
Proof.
move=> x y z zs; rewrite /set_of_fgraphs Z_rw; split.
by aw; apply graph_of_function_sub.
move: zs; bw; move => [[cz [fz _]] _].
by move: fz; rewrite - is_functional; case.
Qed.
Lemma graph_of_function_axioms: forall x y,
transf_axioms(fun g => (graph g)) (set_of_sub_functions x y)
(set_of_fgraphs x y).
Proof. by move=> x y z zs; apply set_of_graphs_pr.
Qed.
Lemma graph_of_function_fonction: forall x y,
is_function (graph_of_function x y).
Proof.
move=> x y; rewrite/graph_of_function.
by apply bl_function; apply graph_of_function_axioms.
Qed.
Lemma graph_of_function_W: forall x y f,
inc f (set_of_sub_functions x y) -> W f (graph_of_function x y) = graph f.
Proof.
by rewrite /graph_of_function=> x y f fs; aw; apply graph_of_function_axioms.
Qed.
Lemma graph_of_function_bijective: forall x y,
bijection (graph_of_function x y).
Proof.
rewrite /graph_of_function=> x y.
apply bl_bijective.
by apply graph_of_function_axioms.
move=> u v; bw; move=> [fu [ssu tu]][fv [sv tv]] sg.
by apply function_exten1=>//; ue.
move=> z; rewrite /set_of_fgraphs Z_rw; aw; move=> [zp fgz].
move: (sub_product_is_graph zp) => gz.
have fgz': fgraph z by rewrite - is_functional.
exists (corresp (domain z) y z); bw; aw; intuition.
apply is_function_pr=>//.
move => t; dw; move => [u Jz]; move: (zp _ Jz); aw; intuition.
move => t; dw; move => [u Jz]; move: (zp _ Jz); aw; intuition.
Qed.
Lemma graph_of_function_isomorphism: forall x y,
order_isomorphism (graph_of_function x y)
(opposite_order (extension_order x y))
(inclusion_suborder (set_of_fgraphs x y)).
Proof.
move=> x y.
move: (extension_is_order x y) => eo.
red; aw.
have <- :set_of_sub_functions x y = source (graph_of_function x y).
rewrite /graph_of_function; aw.
ee.
by apply graph_of_function_bijective.
by rewrite /graph_of_function; aw.
move=> a b ass bss.
rewrite graph_of_function_W // graph_of_function_W // extension_order_pr2.
by aw; apply iff_eq; move=> [aas' [bss' sg]]; ee ; apply set_of_graphs_pr.
Qed.
Example 2. The mapping that associates to a partition the graph of
the equivalence is an order isomorphism
Definition graph_of_partition x :=
BL(fun y => partition_relation_set y x)
(set_of_partition_set x)(powerset (coarse x)).
Lemma gop_axioms: forall x,
transf_axioms (fun y => partition_relation_set y x)
(set_of_partition_set x) (powerset (coarse x)).
Proof.
move=>x y; rewrite set_of_partition_rw; aw.
apply sub_partition_relation_set_coarse.
Qed.
Lemma gop_W: forall x y,
partition y x ->
W y (graph_of_partition x) = partition_relation_set y x.
Proof.
rewrite /graph_of_partition=> x y pa; aw.
apply gop_axioms.
by rewrite set_of_partition_rw.
Qed.
Lemma gop_morphism: forall x,
order_morphism (graph_of_partition x) (coarser x)
(opposite_order (inclusion_order (coarse x))).
Proof.
move=> x.
have oi: (order (inclusion_order (coarse x))) by intuition.
have gi: (is_graph (inclusion_order (coarse x))) by fprops.
have sg: source (graph_of_partition x) = (set_of_partition_set x).
by rewrite /graph_of_partition; aw.
have oc: order (coarser x) by apply coarser_order.
have ig: injection (graph_of_partition x).
apply bl_injective; first by apply gop_axioms.
move=> u v; rewrite 2! set_of_partition_rw => pu pv pp.
apply (order_antisymmetry (coarser_order x) (a:=u) (b:=v)).
rewrite - partition_relation_set_order // pp; fprops.
rewrite - partition_relation_set_order // pp; fprops.
red; rewrite sg coarser_substrate; ee.
rewrite /graph_of_partition; aw.
rewrite /gle=> a b.
do 2 rewrite set_of_partition_rw;move => pa pb.
rewrite - partition_relation_set_order // gop_W // gop_W //.
bw; aw; apply iff_eq; last by move=> [_ [_ h]].
by move=> p; ee; apply sub_partition_relation_set_coarse.
Qed.
Example 3: Compare preorder relations
Definition set_of_preorders x :=
Zo (powerset (coarse x))(fun z => substrate z = x & preorder z).
Lemma set_of_preorders_rw: forall x z,
inc z (set_of_preorders x) = (substrate z = x & preorder z).
Proof.
move=> x z; rewrite/set_of_preorders; apply iff_eq; rewrite Z_rw.
intuition.
move=> [sz p]; intuition.
by aw; rewrite -sz; apply sub_graph_coarse_substrate; apply preorder_graph.
Qed.
Definition coarser_preorder x :=
inclusion_suborder (set_of_preorders x).
Lemma coarser_preorder_order: forall x,
order (coarser_preorder x).
Proof. rewrite /coarser_preorder=> x; apply subinclusion_is_order.
Qed.
Lemma coarser_preorder_substrate: forall x,
substrate (coarser_preorder x) = set_of_preorders x.
Proof. by rewrite /coarser_preorder=> x; apply substrate_subinclusion_order.
Qed.
Lemma coarser_preorder_related: forall x u v,
related (coarser_preorder x) u v =
(preorder u & preorder v & substrate u = x & substrate v = x & sub u v).
Proof.
move=> x u v; rewrite /coarser_preorder subinclusion_order_rw.
rewrite 2!set_of_preorders_rw.
apply iff_eq; intuition.
Qed.
Lemma coarser_preorder_related1: forall x u v,
related (coarser_preorder x) u v =
(preorder u & preorder v & substrate u = x & substrate v = x &
forall a b, inc a x -> inc b x -> related u a b -> related v a b).
Proof.
move=> x u v; rewrite coarser_preorder_related.
apply iff_eq; move=> [pu [pv [su [sv hyp]]]]; ee.
by move=> a b ax bx; rewrite /related => J1; apply hyp.
move => t tu.
have gu:is_graph u by apply preorder_graph.
move: (gu _ tu) => p.
rewrite -p in tu |- *; apply hyp =>//; rewrite -su; substr_tac.
Qed.
If g is a family of orders, it induces an order of the product of f,
the family of susbtrates of g
Definition fam_of_substrates g :=
L (domain g) (fun i => substrate (V i g)).
Definition prod_of_substrates g := productb (fam_of_substrates g).
Definition product_order_r (g:Set): Set -> Set -> Prop :=
fun x x' => forall i, inc i (domain g) -> gle (V i g) (V i x) (V i x').
Definition product_order g :=
graph_on (product_order_r g)(prod_of_substrates g).
Definition product_order_axioms g:=
fgraph g & (forall i, inc i (domain g) -> order (V i g)).
Lemma prod_of_substrates_rw: forall g x,
product_order_axioms g ->
(inc x (prod_of_substrates g) = (fgraph x & domain x = domain g &
forall i, inc i (domain g) -> inc (V i x) (substrate (V i g)))).
Proof.
move=> g x [fg ao].
rewrite /prod_of_substrates/fam_of_substrates; aw; bw; gprops.
apply iff_eq; move => [fgx [dx asu]]; ee; move=> i idg.
rewrite dx in asu; move: (asu _ idg); bw.
by rewrite dx in idg; bw; apply asu.
Qed.
Hint Rewrite prod_of_substrates_rw : aw.
Lemma product_order_order: forall g,
product_order_axioms g -> order (product_order g).
Proof.
move=> g poa; move: (poa) => [fg oa].
have ffg: fgraph (fam_of_substrates g) by rewrite /fam_of_substrates; gprops.
rewrite /product_order/product_order_r.
apply order_from_rel1.
- move=> /= x y z pxy pyz i idg.
move: (pxy _ idg) (pyz _ idg)(oa _ idg)=> *; order_tac.
- move=> x y; rewrite /prod_of_substrates => xp yp p1 p2.
apply (productb_exten ffg xp yp).
rewrite /fam_of_substrates; bw.
move=> i idg; move: (p2 _ idg) (p1 _ idg)(oa _ idg)=> *; order_tac.
- move=> u up i idg; move: (oa _ idg) => oi.
by order_tac; move: up; aw; intuition.
Qed.
Lemma product_order_related: forall g x x',
product_order_axioms g ->
gle (product_order g) x x' =
(inc x (prod_of_substrates g) & inc x' (prod_of_substrates g) &
forall i, inc i (domain g) -> gle (V i g) (V i x)(V i x')).
Proof.
move=> g x x' pa; rewrite /product_order/gle/related graph_on_rw0.
by apply iff_eq.
Qed.
Hint Rewrite product_order_related : bw.
Hint Resolve product_order_order: fprops.
Lemma product_order_substrate: forall g,
product_order_axioms g -> substrate (product_order g) = prod_of_substrates g.
Proof.
move=> g pa; rewrite /product_order.
apply substrate_graph_on.
move: (pa)=> [fg oa] a ap i idg; move: (oa _ idg) => oi.
order_tac; move: ap; aw; intuition.
Qed.
Hint Rewrite product_order_substrate : aw.
Lemma product_order_def: forall g,
let f := fam_of_substrates g in
product_order_axioms g ->
image_by_fun (prod_of_products_canon f f) (product_order g)= (productb g).
Proof.
move=> g f pa. move: (pa)=> [fg oa].
have dfdg: domain f = domain g by rewrite /f/fam_of_substrates; bw.
set (F:= corresp (domain f) (range f) f).
have ff: fgraph f by rewrite /f/fam_of_substrates; gprops.
have fF: is_function F by rewrite /F; apply is_function_pr;fprops.
have gF: graph F = f by rewrite /F; aw.
have fp: is_function (prod_of_products_canon f f).
move: (popc_bijection fF fF (refl_equal (source F))); rewrite gF=> h; fct_tac.
move:(product_order_order pa) => poo.
have spgs: sub (product_order g) (source (prod_of_products_canon f f)).
rewrite /prod_of_products_canon; aw.
have gpo: is_graph (product_order g) by fprops.
move: (sub_graph_coarse_substrate gpo).
by rewrite (product_order_substrate pa).
set_extens x.
aw; move=> [u [upo]].
move: (spgs _ upo); rewrite {1} /prod_of_products_canon bl_source- gF => upob.
rewrite popc_W //; move => <-.
move: upob. rewrite gF product_inc_rw productb_rw // productb_rw //.
move => [pu [[fgP [dPu alp]] [fgQ [dQu alq]]]].
rewrite /prod_of_function dPu dfdg; bw.
ee; move=> i idg; bw.
have: (gle (product_order g) (P u) (Q u)) by red; red; rewrite pu.
rewrite product_order_related //.
by move=> [_ [_ h]]; move: (h _ idg).
move=> wp; aw.
set (x1 := L (domain g) (fun i => P (V i x))).
set (x2:= (L (domain g) (fun i => Q (V i x)))).
move: (wp); aw; move =>[fgx [dxdg idx]]; rewrite dxdg in idx.
have p1: inc x1 (prod_of_substrates g).
rewrite/x1; aw; ee;bw.
by move => i idg; bw; apply inc_pr1_substrate; apply idx.
have p2: inc x2 (prod_of_substrates g).
rewrite/x2; aw; ee;bw.
by move => i idg; bw; apply inc_pr2_substrate; apply idx.
have p3: forall i, inc i (domain g) -> is_pair (V i x).
move=> i idg; apply (order_is_graph (oa _ idg) (idx _ idg)).
exists (J x1 x2) ; split.
move: (product_order_related x1 x2 pa); rewrite /gle /related.
move=> ->; ee.
by move=> i idg; rewrite/x1/x2; bw;aw; rewrite (p3 _ idg); apply idx.
rewrite -gF popc_W //.
aw; rewrite /prod_of_function.
rewrite /x1 /x2; apply fgraph_exten=> //; gprops.
symmetry; rewrite /x1; bw.
by bw; move=> i idg; bw; aw; apply p3.
by rewrite gF; apply product_pair_inc.
Qed.
Order on graphs of functions x->y,
induced by an order g on the target.
This is a special case of product order.
Definition graph_order_r (x g:Set): Set -> Set -> Prop :=
fun z z' => forall i, inc i x -> gle g (V i z) (V i z').
Definition graph_order x y g :=
graph_on (graph_order_r x g) (set_of_gfunctions x y).
Lemma product_order_axioms_x:forall x g, order g ->
product_order_axioms (cst_graph x g).
Proof.
rewrite /cst_graph=> x g og; split;gprops.
bw; move=> i id; bw.
Qed.
Lemma graph_order_r_pr: forall x g z z',
graph_order_r x g z z' =
product_order_r (cst_graph x g) z z'.
Proof.
move=>x g z z'.
have dc: (domain (cst_graph x g) = x) by rewrite /cst_graph; bw.
rewrite /product_order_r dc /cst_graph.
apply iff_eq; first by move=> go i ix; bw; apply go.
move=> h y yx; move: (h _ yx); bw.
Qed.
Lemma graph_order_pr1:forall x y g, substrate g = y ->
(set_of_gfunctions x y) = prod_of_substrates (cst_graph x g).
Proof.
move=> x y g sg.
rewrite -cst_graph_pr /prod_of_substrates /fam_of_substrates /cst_graph.
symmetry.
bw; apply f_equal; apply L_exten1=>//; move=> v vs; bw.
Qed.
Lemma graph_order_pr:forall x y g, substrate g = y ->
graph_order x y g = product_order (cst_graph x g).
Proof.
move=> x y g sg; rewrite/graph_order/product_order.
rewrite (graph_order_pr1 x sg).
rewrite {2}/cst_graph.
rewrite /graph_on/product_order_r L_domain.
set_extens t; rewrite !Z_rw; move=> [t1 h];split =>// i ix; move: (h _ ix); bw.
Qed.
Lemma graph_order_order: forall x y g, order g -> substrate g = y ->
order (graph_order x y g).
Proof.
move=> x y g og sg; rewrite graph_order_pr =>//.
apply product_order_order.
by apply product_order_axioms_x.
Qed.
Lemma graph_order_substrate: forall x y g, order g -> substrate g = y ->
substrate (graph_order x y g) = set_of_gfunctions x y.
Proof.
move=> x y g ogf sg; rewrite graph_order_pr=>//.
rewrite product_order_substrate.
by rewrite (graph_order_pr1 x sg).
by apply product_order_axioms_x.
Qed.
fun z z' => forall i, inc i x -> gle g (V i z) (V i z').
Definition graph_order x y g :=
graph_on (graph_order_r x g) (set_of_gfunctions x y).
Lemma product_order_axioms_x:forall x g, order g ->
product_order_axioms (cst_graph x g).
Proof.
rewrite /cst_graph=> x g og; split;gprops.
bw; move=> i id; bw.
Qed.
Lemma graph_order_r_pr: forall x g z z',
graph_order_r x g z z' =
product_order_r (cst_graph x g) z z'.
Proof.
move=>x g z z'.
have dc: (domain (cst_graph x g) = x) by rewrite /cst_graph; bw.
rewrite /product_order_r dc /cst_graph.
apply iff_eq; first by move=> go i ix; bw; apply go.
move=> h y yx; move: (h _ yx); bw.
Qed.
Lemma graph_order_pr1:forall x y g, substrate g = y ->
(set_of_gfunctions x y) = prod_of_substrates (cst_graph x g).
Proof.
move=> x y g sg.
rewrite -cst_graph_pr /prod_of_substrates /fam_of_substrates /cst_graph.
symmetry.
bw; apply f_equal; apply L_exten1=>//; move=> v vs; bw.
Qed.
Lemma graph_order_pr:forall x y g, substrate g = y ->
graph_order x y g = product_order (cst_graph x g).
Proof.
move=> x y g sg; rewrite/graph_order/product_order.
rewrite (graph_order_pr1 x sg).
rewrite {2}/cst_graph.
rewrite /graph_on/product_order_r L_domain.
set_extens t; rewrite !Z_rw; move=> [t1 h];split =>// i ix; move: (h _ ix); bw.
Qed.
Lemma graph_order_order: forall x y g, order g -> substrate g = y ->
order (graph_order x y g).
Proof.
move=> x y g og sg; rewrite graph_order_pr =>//.
apply product_order_order.
by apply product_order_axioms_x.
Qed.
Lemma graph_order_substrate: forall x y g, order g -> substrate g = y ->
substrate (graph_order x y g) = set_of_gfunctions x y.
Proof.
move=> x y g ogf sg; rewrite graph_order_pr=>//.
rewrite product_order_substrate.
by rewrite (graph_order_pr1 x sg).
by apply product_order_axioms_x.
Qed.
Order on functions x->y, induced by an order r on the target
Definition function_order_r x y r f g :=
is_function f & is_function g & source f = x & target f = y
& source g =x & target g = y &
forall i, inc i x -> gle r (W i f) (W i g).
Definition function_order x y r :=
graph_on(fun u v => function_order_r x y r u v)
(set_of_functions x y).
Lemma function_order_reflexive: forall x y r u,
order r -> substrate r = y ->
inc u (set_of_functions x y) -> gle (function_order x y r) u u.
Proof.
move=> x y r u or sr us.
red; red; rewrite /function_order /graph_on Z_rw.
split;fprops; aw.
move: us; rewrite set_of_functions_rw; move => [fu [su tu]].
red; ee. move=> i ix; order_tac.
rewrite sr -tu; apply inc_W_target =>//; ue.
Qed.
Lemma function_order_substrate: forall x y r,
order r -> substrate r = y ->
substrate (function_order x y r) = set_of_functions x y.
Proof.
move=> x y r or sr.
have gf: is_graph (function_order x y r).
by rewrite /function_order; apply graph_on_graph.
set_extens t.
rewrite inc_substrate_rw //.
case; move=> [z]; rewrite/function_order/graph_on Z_rw product_pair_rw;
intuition.
move=> ts.
have a: inc (J t t) (function_order x y r) by apply function_order_reflexive.
substr_tac.
Qed.
Lemma function_order_pr:forall x y r f f',
order r -> substrate r = y ->
gle (function_order x y r) f f' =
(inc f (set_of_functions x y) &
inc f' (set_of_functions x y) &
forall i, inc i x -> gle r (W i f) (W i f')).
Proof.
move=> x y r f f' or sr.
rewrite /gle/related/function_order/graph_on/function_order_r.
apply iff_eq; aw; rewrite Z_rw; aw; intuition.
Qed.
Lemma function_order_order: forall x y r,
order r -> substrate r = y -> order (function_order x y r).
Proof.
move=> x y r or sr.
have go: (is_graph (function_order x y r)).
rewrite /function_order;apply graph_on_graph.
red; ee; split=>//.
- rewrite function_order_substrate //.
move=> z zs; apply function_order_reflexive =>//.
- move=> a b c; rewrite -[related]/(gle); do 3 rewrite function_order_pr //.
move=> [afs [bfs leab]][_ [cfs lebc]]; ee.
move=> i id; move: (leab _ id) (lebc _ id) => lab lbc.
order_tac.
- move=> a b; rewrite -[related]/(gle); do 2 rewrite function_order_pr //.
move=> [afs [bfs leab]][_ [_ leba]].
move: afs bfs; aw; move => [fa [sa ta]] [fb [sb tb]].
apply function_exten=>//; try ue.
rewrite sa; move=> i ix; move: (leab _ ix) (leba _ ix)=> lab lba.
order_tac.
Qed.
is_function f & is_function g & source f = x & target f = y
& source g =x & target g = y &
forall i, inc i x -> gle r (W i f) (W i g).
Definition function_order x y r :=
graph_on(fun u v => function_order_r x y r u v)
(set_of_functions x y).
Lemma function_order_reflexive: forall x y r u,
order r -> substrate r = y ->
inc u (set_of_functions x y) -> gle (function_order x y r) u u.
Proof.
move=> x y r u or sr us.
red; red; rewrite /function_order /graph_on Z_rw.
split;fprops; aw.
move: us; rewrite set_of_functions_rw; move => [fu [su tu]].
red; ee. move=> i ix; order_tac.
rewrite sr -tu; apply inc_W_target =>//; ue.
Qed.
Lemma function_order_substrate: forall x y r,
order r -> substrate r = y ->
substrate (function_order x y r) = set_of_functions x y.
Proof.
move=> x y r or sr.
have gf: is_graph (function_order x y r).
by rewrite /function_order; apply graph_on_graph.
set_extens t.
rewrite inc_substrate_rw //.
case; move=> [z]; rewrite/function_order/graph_on Z_rw product_pair_rw;
intuition.
move=> ts.
have a: inc (J t t) (function_order x y r) by apply function_order_reflexive.
substr_tac.
Qed.
Lemma function_order_pr:forall x y r f f',
order r -> substrate r = y ->
gle (function_order x y r) f f' =
(inc f (set_of_functions x y) &
inc f' (set_of_functions x y) &
forall i, inc i x -> gle r (W i f) (W i f')).
Proof.
move=> x y r f f' or sr.
rewrite /gle/related/function_order/graph_on/function_order_r.
apply iff_eq; aw; rewrite Z_rw; aw; intuition.
Qed.
Lemma function_order_order: forall x y r,
order r -> substrate r = y -> order (function_order x y r).
Proof.
move=> x y r or sr.
have go: (is_graph (function_order x y r)).
rewrite /function_order;apply graph_on_graph.
red; ee; split=>//.
- rewrite function_order_substrate //.
move=> z zs; apply function_order_reflexive =>//.
- move=> a b c; rewrite -[related]/(gle); do 3 rewrite function_order_pr //.
move=> [afs [bfs leab]][_ [cfs lebc]]; ee.
move=> i id; move: (leab _ id) (lebc _ id) => lab lbc.
order_tac.
- move=> a b; rewrite -[related]/(gle); do 2 rewrite function_order_pr //.
move=> [afs [bfs leab]][_ [_ leba]].
move: afs bfs; aw; move => [fa [sa ta]] [fb [sb tb]].
apply function_exten=>//; try ue.
rewrite sa; move=> i ix; move: (leab _ ix) (leba _ ix)=> lab lba.
order_tac.
Qed.
The mapping that associates to a function its graph is an isomorphism for the two orders defined above
Lemma function_order_isomorphism: forall x y r,
order r -> substrate r = y ->
order_isomorphism (BL graph (set_of_functions x y)(set_of_gfunctions x y))
(function_order x y r)(graph_order x y r).
Proof.
move=> x y r or sr; red; ee.
- apply function_order_order =>//.
- apply graph_order_order =>//.
- apply graph_bijective.
- rewrite function_order_substrate=>//; aw.
- rewrite graph_order_substrate=>//; aw.
- move: (graph_axioms (x:=x) (y:=y))=> ax;aw=> a b ass bss.
rewrite function_order_pr // bl_W // bl_W //.
rewrite /gle/related/ graph_order/graph_on/graph_order_r
Z_rw pr1_pair pr2_pair.
apply iff_eq; intuition.
Qed.
Definition order_isomorphic r r':=
exists f, order_isomorphism f r r'.
Notation "x \Is y" := (order_isomorphic x y) (at level 50).
Lemma function_order_isomorphic: forall x y r,
order r -> substrate r = y ->
(function_order x y r) \Is (graph_order x y r).
Proof.
move=> x y r or sr.
exists (BL graph (set_of_functions x y)(set_of_gfunctions x y)).
by apply function_order_isomorphism.
Qed.
Special case of a product of 2 orders
Definition product2_order f g:=
graph_on (fun x x' => gle f (P x) (P x') & gle g (Q x) (Q x'))
(product (substrate f)(substrate g)).
Lemma product2_order_pr: forall f g x x',
gle (product2_order f g) x x' =
(inc x (product (substrate f)(substrate g)) &
inc x' (product (substrate f)(substrate g)) &
gle f (P x) (P x') & gle g (Q x) (Q x')).
Proof.
move=> f g x x'.
rewrite /product2_order/graph_on/gle/related Z_rw.
rewrite pr1_pair pr2_pair product_pair_rw.
apply iff_eq; intuition.
Qed.
Lemma product2_order_preorder_substrate: forall f g,
preorder f -> preorder g -> substrate (product2_order f g) =
product (substrate f) (substrate g).
Proof.
move=> f g [[_ rf] _] [[_ rg] _ ]; rewrite /product2_order.
apply substrate_graph_on.
move => a; aw; move=> [pa [Ps Qs]].
by split; [apply rf | apply rg].
Qed.
Lemma product2_order_substrate: forall f g,
order f -> order g -> substrate (product2_order f g) =
product (substrate f) (substrate g).
Proof.
move=> *.
apply product2_order_preorder_substrate.
by apply order_preorder.
by apply order_preorder.
Qed.
Lemma product2_order_preorder: forall f g,
preorder f -> preorder g -> preorder (product2_order f g).
Proof.
rewrite /product2_order => f g [[_ rf][_ tf]] [[_ rg][_ tg]].
apply preorder_from_rel.
split.
move => x y z[pxy qxy][pyz qyz].
split; [ apply (tf _ _ _ pxy pyz) | apply (tg _ _ _ qxy qyz)].
move=> x y [pxy qxy]; red in pxy; red in qxy.
split; split; try apply rf; try apply rg; substr_tac.
Qed.
Lemma product2_order_order: forall f g,
order f -> order g -> order (product2_order f g).
Proof.
move=> f g orf og.
have [rr tr]: preorder(product2_order f g).
by apply product2_order_preorder; apply order_preorder.
hnf; intuition.
split; first by move: rr => [gr _].
move=> x y; rewrite -[related]/gle 2! product2_order_pr.
move=> [xp [yp [g1 g2]]] [_ [_ [p3 p4]]].
move: xp yp; aw; move => [px _] [qx _].
apply pair_exten => //; order_tac.
Qed.
Definition increasing_fun f r r':=
is_function f & order r & order r' & substrate r = source f
& substrate r' = target f &
forall x y, gle r x y -> gle r' (W x f) (W y f).
Definition decreasing_fun f r r':=
is_function f & order r & order r' & substrate r = source f
& substrate r' = target f &
forall x y, gle r x y -> gge r' (W x f) (W y f).
Definition monotone_fun f r r':=
increasing_fun f r r' \/ decreasing_fun f r r'.
Lemma opposite_gle: forall r x y, order r ->
gle (opposite_order r) x y = gle r y x.
Proof. rewrite /gle/related=> r x y; aw. Qed.
Lemma opposite_gge: forall r x y, order r ->
gge (opposite_order r) x y = gle r x y.
Proof. rewrite /gge/gle/related=> r x y; aw.
Qed.
Hint Rewrite opposite_gle opposite_gge: aw.
Monotonicity and opposite order
Lemma increasing_fun_reva : forall f r r',
increasing_fun f r r' -> decreasing_fun f r (opposite_order r').
Proof.
rewrite /increasing_fun/decreasing_fun=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y xy; aw; apply rel.
Qed.
Lemma increasing_fun_revb : forall f r r',
increasing_fun f r r' -> decreasing_fun f (opposite_order r) r'.
Proof.
rewrite /increasing_fun/decreasing_fun=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y ; aw => xy; apply rel.
Qed.
Lemma decreasing_fun_reva : forall f r r',
decreasing_fun f r r' -> increasing_fun f r (opposite_order r').
Proof.
rewrite /increasing_fun/decreasing_fun=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y ; aw => xy; apply rel.
Qed.
Lemma decreasing_fun_revb : forall f r r',
decreasing_fun f r r' -> increasing_fun f (opposite_order r) r'.
Proof.
rewrite /increasing_fun/decreasing_fun=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y ; aw => xy; apply rel.
Qed.
Lemma monotone_fun_reva : forall f r r',
monotone_fun f r r' -> monotone_fun f r (opposite_order r').
Proof.
rewrite /monotone_fun=> f r r'; case.
by right; apply increasing_fun_reva.
by left; apply decreasing_fun_reva.
Qed.
Lemma monotone_fun_revb : forall f r r',
monotone_fun f r r' -> monotone_fun f (opposite_order r) r'.
Proof.
rewrite /monotone_fun=> f r r'; case.
by right; apply increasing_fun_revb.
by left; apply decreasing_fun_revb.
Qed.
increasing_fun f r r' -> decreasing_fun f r (opposite_order r').
Proof.
rewrite /increasing_fun/decreasing_fun=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y xy; aw; apply rel.
Qed.
Lemma increasing_fun_revb : forall f r r',
increasing_fun f r r' -> decreasing_fun f (opposite_order r) r'.
Proof.
rewrite /increasing_fun/decreasing_fun=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y ; aw => xy; apply rel.
Qed.
Lemma decreasing_fun_reva : forall f r r',
decreasing_fun f r r' -> increasing_fun f r (opposite_order r').
Proof.
rewrite /increasing_fun/decreasing_fun=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y ; aw => xy; apply rel.
Qed.
Lemma decreasing_fun_revb : forall f r r',
decreasing_fun f r r' -> increasing_fun f (opposite_order r) r'.
Proof.
rewrite /increasing_fun/decreasing_fun=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y ; aw => xy; apply rel.
Qed.
Lemma monotone_fun_reva : forall f r r',
monotone_fun f r r' -> monotone_fun f r (opposite_order r').
Proof.
rewrite /monotone_fun=> f r r'; case.
by right; apply increasing_fun_reva.
by left; apply decreasing_fun_reva.
Qed.
Lemma monotone_fun_revb : forall f r r',
monotone_fun f r r' -> monotone_fun f (opposite_order r) r'.
Proof.
rewrite /monotone_fun=> f r r'; case.
by right; apply increasing_fun_revb.
by left; apply decreasing_fun_revb.
Qed.
Strict monotone functions
Definition strict_increasing_fun f r r':=
is_function f & order r & order r' & substrate r = source f
& substrate r' = target f &
forall x y, glt r x y -> glt r' (W x f) (W y f).
Definition strict_decreasing_fun f r r':=
is_function f & order r & order r' & substrate r = source f
& substrate r' = target f &
forall x y, glt r x y -> ggt r' (W x f) (W y f).
Definition strict_monotone_fun f r r':=
strict_increasing_fun f r r' \/ strict_decreasing_fun f r r'.
Lemma glt_inva: forall r x y,
order r -> glt r x y = ggt (opposite_order r) x y.
Proof. rewrite /ggt/glt=> r x y or; aw.
Qed.
Lemma ggt_inva: forall r x y,
order r -> ggt r x y = glt (opposite_order r) x y.
Proof. rewrite /ggt/glt=> r x y or; aw.
Qed.
Lemma ggt_invb: forall r x y,
ggt r x y = glt r y x.
Proof. rewrite /ggt/glt/gge=> r x y; by apply iff_eq; intuition.
Qed.
Lemma strict_increasing_fun_reva : forall f r r',
strict_increasing_fun f r r' -> strict_decreasing_fun f r (opposite_order r').
Proof.
rewrite/ strict_increasing_fun/strict_decreasing_fun.
move=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y; rewrite -glt_inva// ; apply rel.
Qed.
Lemma strict_increasing_fun_revb : forall f r r',
strict_increasing_fun f r r' -> strict_decreasing_fun f (opposite_order r) r'.
Proof.
rewrite/ strict_increasing_fun/strict_decreasing_fun.
move=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y; rewrite -ggt_inva// ggt_invb// ggt_invb//; apply rel.
Qed.
Lemma strict_decreasing_fun_reva : forall f r r',
strict_decreasing_fun f r r' -> strict_increasing_fun f r (opposite_order r').
Proof.
rewrite/ strict_increasing_fun/strict_decreasing_fun.
move=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
by move=> x y; rewrite -ggt_inva// ; apply rel.
Qed.
Lemma strict_decreasing_fun_revb : forall f r r',
strict_decreasing_fun f r r' -> strict_increasing_fun f (opposite_order r) r'.
Proof.
rewrite/ strict_increasing_fun/strict_decreasing_fun.
move=> f r r' [ff [or [or' [sr [sr' rel]]]]].
ee; first by aw.
move=> x y; rewrite -ggt_inva// ggt_invb//.
by move=> hyp; rewrite -ggt_invb//; apply rel.
Qed.
Lemma strict_monotone_fun_reva : forall f r r',
strict_monotone_fun f r r' -> strict_monotone_fun f r (opposite_order r').
Proof.
rewrite /strict_monotone_fun=> f r r'; case.
by right; apply strict_increasing_fun_reva.
by left; apply strict_decreasing_fun_reva.
Qed.
Lemma strict_monotone_fun_revb : forall f r r',
strict_monotone_fun f r r' -> strict_monotone_fun f (opposite_order r) r'.
Proof.
rewrite /strict_monotone_fun=> f r r'; case.
by right; apply strict_increasing_fun_revb.
by left; apply strict_decreasing_fun_revb.
Qed.
Example of monotone functions
Lemma constant_fun_increasing: forall f r r',
order r -> order r' -> substrate r = source f ->
substrate r' = target f -> is_constant_function f ->
increasing_fun f r r'.
Proof.
move=> f r r' or or' sr sr' [ff cf].
red; ee.
move=> x y rxy.
have xs: (inc x (source f)) by rewrite -sr; order_tac.
have ys: (inc y (source f)) by rewrite -sr;order_tac.
rewrite (cf _ _ xs ys); order_tac.
ue.
Qed.
Lemma constant_fun_decreasing: forall f r r',
order r -> order r' -> substrate r = source f ->
substrate r' = target f -> is_constant_function f ->
decreasing_fun f r r'.
Proof.
move=> f r r' or or' sr sr' [ff cf].
red; ee.
move=> x y rxy.
have xs: (inc x (source f)) by rewrite -sr; order_tac.
have ys: (inc y (source f)) by rewrite -sr;order_tac.
rewrite (cf _ _ xs ys); red;order_tac.
ue.
Qed.
Lemma identity_increasing_decreasing : forall x,
let r := identity_g x in
(increasing_fun (identity x) r r &decreasing_fun (identity x) r r).
Proof.
move=> x r.
move: (diagonal_order x)(diagonal_substrate x) => oi si.
move:(identity_function x)=> fi.
split; red;ee; aw.
move=> a b rab; srw; rewrite -si; order_tac.
move=> a b rab;red.
srw; try (rewrite -si; order_tac).
move: rab; rewrite /r /gle/related. aw.
move=> [ax] <-; intuition.
Qed.
Lemma complementary_decreasing: forall E,
strict_decreasing_fun(BL (fun X => complement E X)(powerset E)(powerset E))
(inclusion_order E) (inclusion_order E).
Proof.
move=> E.
set (r:=inclusion_order E).
have or: order r by rewrite /r; fprops.
have sr: substrate r = powerset E by rewrite /r; aw.
have ta: transf_axioms (fun X => complement E X)
(powerset E) (powerset E).
by move=> c cE; aw;apply sub_complement.
red; aw; ee.
by apply bl_function.
move=> x y; rewrite /r /glt; move=> xy; awi xy; move: xy => [[xE [yE xy]] nxy].
rewrite /ggt/gge; aw.
ee; try apply sub_complement.
by move=> t; srw; move=> [tE nty]; split=> //; dneg tx; apply xy.
dneg cc; move:(f_equal (complement E) cc); srw.
Qed.
Definition set_of_majorants1 x r:=
Zo (substrate r)(fun y => gle r x y).
Lemma set_of_majorants1_pr: forall x y r,
order r -> inc x (substrate r) -> inc y (substrate r) ->
(gle r x y = sub (set_of_majorants1 y r) (set_of_majorants1 x r)).
Proof.
rewrite /set_of_majorants1 => x y r or xs ys.
apply iff_eq.
move=> lexy t; rewrite 2! Z_rw; move => [ts yt]; ee; order_tac.
set s:= Zo _ _; move=> ss.
have yss: inc y s by rewrite /s Z_rw; ee; order_tac.
by move: (ss _ yss); rewrite Z_rw; case.
Qed.
Lemma set_of_majorants1_decreasing: forall r,
order r ->
strict_decreasing_fun(BL (fun x=> (set_of_majorants1 x r))
(substrate r)(powerset (substrate r))) r (inclusion_order (substrate r)).
Proof.
move=> r or; red; bw; aw.
set E:= substrate r.
have oe: order (inclusion_order E) by fprops.
have si: substrate (inclusion_order E) = powerset E by aw.
have ta: transf_axioms (fun x => set_of_majorants1 x r) E (powerset E).
move=> x xE; aw.
by move=> t; rewrite /set_of_majorants1 Z_rw; case.
ee; first by apply bl_function.
rewrite /ggt/gge => x y ltxy.
have xE: inc x E by rewrite /E;order_tac.
have yE: inc y E by rewrite /E;order_tac.
move: ltxy=> [lexy nxy].
move:(lexy); rewrite set_of_majorants1_pr //; move=> sxy.
aw; ee.
by move: (ta _ yE); aw.
by move: (ta _ xE); aw.
move=> s_eq.
have yx: gle r y x by rewrite set_of_majorants1_pr // s_eq; fprops.
elim nxy;order_tac.
Qed.
Lemma strict_increasing_from_injective: forall f r r',
injection f -> increasing_fun f r r' -> strict_increasing_fun f r r'.
Proof.
move=> f r r' [_ inf] [ff [or [or' [sr [sr' hyp]]]]].
red; ee; move=> x y [lexy neq].
split; first by apply hyp.
dneg Wxy; apply inf=>//; rewrite -sr; order_tac.
Qed.
Lemma strict_decreasing_from_injective: forall f r r',
injection f ->decreasing_fun f r r' -> strict_decreasing_fun f r r'.
Proof.
move=> f r r' [_ inf] [ff [or [or' [sr [sr' hyp]]]]].
red; ee; move=> x y [lexy neq].
split; first by apply hyp.
dneg Wxy; apply inf=>//; rewrite -sr; order_tac.
Qed.
Lemma strict_monotone_from_injective: forall f r r',
injection f -> monotone_fun f r r' -> strict_monotone_fun f r r'.
Proof.
move=> f r r' inf; case.
by left; apply strict_increasing_from_injective.
by right; apply strict_decreasing_from_injective.
Qed.
Lemma order_isomorphism_increasing: forall f r r',
order_isomorphism f r r' ->
strict_increasing_fun f r r'.
Proof.
move=> f r r' [or [or' [[injf surjf] [sr [sr' hyp]]]]].
apply strict_increasing_from_injective => //.
red; ee.
fct_tac.
rewrite -sr in hyp.
move=> x y xy; rewrite - hyp //; order_tac.
Qed.
Lemma order_morphism_increasing: forall f r r',
order_morphism f r r' ->
strict_increasing_fun f r r'.
Proof.
move=> f r r' [or [or' [injf [sr [sr' hyp]]]]].
apply strict_increasing_from_injective =>//.
red; ee.
fct_tac.
rewrite -sr in hyp.
move=> x y xy; rewrite - hyp //; order_tac.
Qed.
Lemma order_isomorphism_pr: forall f r r',
order r -> order r' ->
bijection f -> substrate r = source f -> substrate r' = target f ->
(order_isomorphism f r r' =
(increasing_fun f r r' & increasing_fun (inverse_fun f) r' r)).
Proof.
move=> f r r' or or' bf sr sr'.
rewrite /order_isomorphism.
move: (bijective_inv_function bf)=> bif.
have sf: source f = target (inverse_fun f) by rewrite /inverse_fun; aw.
have tf:target f = source (inverse_fun f) by rewrite /inverse_fun; aw.
apply iff_eq.
move=> [_ [_ [_ [_ [ _ hyp]]]]].
split;red; ee; aw.
fct_tac.
by rewrite -sr in hyp; move=> x y xy; rewrite - hyp //; order_tac.
move=>x y rxy.
have xt: inc x (target f) by rewrite -sr'; order_tac.
have yt: inc y (target f) by rewrite -sr'; order_tac.
rewrite hyp; try (rewrite sf ; apply inc_W_target=>//; ue).
rewrite - (W_inverse bf xt (refl_equal (W x (inverse_fun f)))).
by rewrite - (W_inverse bf yt (refl_equal (W y (inverse_fun f)))).
move=> [inf inif]; ee.
move=> x y xsf ysf.
move: inf inif=> [_ [_ [_ [_ [_ h1]]]]] [_ [_ [_ [_ [_ h2]]]]].
apply iff_eq.
move=> hy; by apply h1.
move=> hyp.
rewrite (W_inverse2 bf xsf (refl_equal (W x f))).
rewrite (W_inverse2 bf ysf (refl_equal (W y f))).
by apply h2.
Qed.
Theorem decreasing_composition: forall u v r r',
decreasing_fun u r r' -> decreasing_fun v r' r ->
(forall x, inc x (substrate r) -> gle r (W (W x u) v) x) ->
(forall x', inc x' (substrate r') -> gle r' (W (W x' v) u) x') ->
(u \co (v \co u) = u & v \co (u \co v) = v).
Proof.
move=> u v r r' [fu [or [or' [sr [sr' du]]]]] [fv [_ [_ [svr [svr' dv]]]]] h h'.
have cvu: v \coP u by red; hnf; ue.
have fvu: is_function (v \co u) by fct_tac.
have cuvu: u \coP (v \co u) by hnf; aw; ue.
have cuv: u \coP v by red; hnf; ue.
have fuv: is_function (u \co v) by fct_tac.
have cvuv: v \coP (u \co v) by hnf; aw; ue.
split.
apply function_exten;aw; first by fct_tac.
move=> x xs.
rewrite -sr in xs; move:(h _ xs)=> rel1; move: (du _ _ rel1)=> rel2.
have p: inc (W x u) (substrate r') by rewrite sr';apply inc_W_target=> //; ue.
move: (h' _ p)=> rel3; aw; try ue.
red in rel2; order_tac.
apply function_exten; aw; first by fct_tac.
move=> x xs.
rewrite -svr in xs; move:(h' _ xs)=> rel1; move: (dv _ _ rel1)=> rel2.
have p: inc (W x v) (substrate r) by rewrite svr';apply inc_W_target=> //; ue.
move: (h _ p)=> rel3; aw; try ue.
red in rel2; order_tac.
Qed.
Lemma order_isomorphism_opposite: forall g r r',
order_isomorphism g r r' ->
order_isomorphism g (opposite_order r) (opposite_order r').
Proof. rewrite /order_isomorphism=> g r r'.
intuition; aw. intuition.
Qed.
order r -> order r' -> substrate r = source f ->
substrate r' = target f -> is_constant_function f ->
increasing_fun f r r'.
Proof.
move=> f r r' or or' sr sr' [ff cf].
red; ee.
move=> x y rxy.
have xs: (inc x (source f)) by rewrite -sr; order_tac.
have ys: (inc y (source f)) by rewrite -sr;order_tac.
rewrite (cf _ _ xs ys); order_tac.
ue.
Qed.
Lemma constant_fun_decreasing: forall f r r',
order r -> order r' -> substrate r = source f ->
substrate r' = target f -> is_constant_function f ->
decreasing_fun f r r'.
Proof.
move=> f r r' or or' sr sr' [ff cf].
red; ee.
move=> x y rxy.
have xs: (inc x (source f)) by rewrite -sr; order_tac.
have ys: (inc y (source f)) by rewrite -sr;order_tac.
rewrite (cf _ _ xs ys); red;order_tac.
ue.
Qed.
Lemma identity_increasing_decreasing : forall x,
let r := identity_g x in
(increasing_fun (identity x) r r &decreasing_fun (identity x) r r).
Proof.
move=> x r.
move: (diagonal_order x)(diagonal_substrate x) => oi si.
move:(identity_function x)=> fi.
split; red;ee; aw.
move=> a b rab; srw; rewrite -si; order_tac.
move=> a b rab;red.
srw; try (rewrite -si; order_tac).
move: rab; rewrite /r /gle/related. aw.
move=> [ax] <-; intuition.
Qed.
Lemma complementary_decreasing: forall E,
strict_decreasing_fun(BL (fun X => complement E X)(powerset E)(powerset E))
(inclusion_order E) (inclusion_order E).
Proof.
move=> E.
set (r:=inclusion_order E).
have or: order r by rewrite /r; fprops.
have sr: substrate r = powerset E by rewrite /r; aw.
have ta: transf_axioms (fun X => complement E X)
(powerset E) (powerset E).
by move=> c cE; aw;apply sub_complement.
red; aw; ee.
by apply bl_function.
move=> x y; rewrite /r /glt; move=> xy; awi xy; move: xy => [[xE [yE xy]] nxy].
rewrite /ggt/gge; aw.
ee; try apply sub_complement.
by move=> t; srw; move=> [tE nty]; split=> //; dneg tx; apply xy.
dneg cc; move:(f_equal (complement E) cc); srw.
Qed.
Definition set_of_majorants1 x r:=
Zo (substrate r)(fun y => gle r x y).
Lemma set_of_majorants1_pr: forall x y r,
order r -> inc x (substrate r) -> inc y (substrate r) ->
(gle r x y = sub (set_of_majorants1 y r) (set_of_majorants1 x r)).
Proof.
rewrite /set_of_majorants1 => x y r or xs ys.
apply iff_eq.
move=> lexy t; rewrite 2! Z_rw; move => [ts yt]; ee; order_tac.
set s:= Zo _ _; move=> ss.
have yss: inc y s by rewrite /s Z_rw; ee; order_tac.
by move: (ss _ yss); rewrite Z_rw; case.
Qed.
Lemma set_of_majorants1_decreasing: forall r,
order r ->
strict_decreasing_fun(BL (fun x=> (set_of_majorants1 x r))
(substrate r)(powerset (substrate r))) r (inclusion_order (substrate r)).
Proof.
move=> r or; red; bw; aw.
set E:= substrate r.
have oe: order (inclusion_order E) by fprops.
have si: substrate (inclusion_order E) = powerset E by aw.
have ta: transf_axioms (fun x => set_of_majorants1 x r) E (powerset E).
move=> x xE; aw.
by move=> t; rewrite /set_of_majorants1 Z_rw; case.
ee; first by apply bl_function.
rewrite /ggt/gge => x y ltxy.
have xE: inc x E by rewrite /E;order_tac.
have yE: inc y E by rewrite /E;order_tac.
move: ltxy=> [lexy nxy].
move:(lexy); rewrite set_of_majorants1_pr //; move=> sxy.
aw; ee.
by move: (ta _ yE); aw.
by move: (ta _ xE); aw.
move=> s_eq.
have yx: gle r y x by rewrite set_of_majorants1_pr // s_eq; fprops.
elim nxy;order_tac.
Qed.
Lemma strict_increasing_from_injective: forall f r r',
injection f -> increasing_fun f r r' -> strict_increasing_fun f r r'.
Proof.
move=> f r r' [_ inf] [ff [or [or' [sr [sr' hyp]]]]].
red; ee; move=> x y [lexy neq].
split; first by apply hyp.
dneg Wxy; apply inf=>//; rewrite -sr; order_tac.
Qed.
Lemma strict_decreasing_from_injective: forall f r r',
injection f ->decreasing_fun f r r' -> strict_decreasing_fun f r r'.
Proof.
move=> f r r' [_ inf] [ff [or [or' [sr [sr' hyp]]]]].
red; ee; move=> x y [lexy neq].
split; first by apply hyp.
dneg Wxy; apply inf=>//; rewrite -sr; order_tac.
Qed.
Lemma strict_monotone_from_injective: forall f r r',
injection f -> monotone_fun f r r' -> strict_monotone_fun f r r'.
Proof.
move=> f r r' inf; case.
by left; apply strict_increasing_from_injective.
by right; apply strict_decreasing_from_injective.
Qed.
Lemma order_isomorphism_increasing: forall f r r',
order_isomorphism f r r' ->
strict_increasing_fun f r r'.
Proof.
move=> f r r' [or [or' [[injf surjf] [sr [sr' hyp]]]]].
apply strict_increasing_from_injective => //.
red; ee.
fct_tac.
rewrite -sr in hyp.
move=> x y xy; rewrite - hyp //; order_tac.
Qed.
Lemma order_morphism_increasing: forall f r r',
order_morphism f r r' ->
strict_increasing_fun f r r'.
Proof.
move=> f r r' [or [or' [injf [sr [sr' hyp]]]]].
apply strict_increasing_from_injective =>//.
red; ee.
fct_tac.
rewrite -sr in hyp.
move=> x y xy; rewrite - hyp //; order_tac.
Qed.
Lemma order_isomorphism_pr: forall f r r',
order r -> order r' ->
bijection f -> substrate r = source f -> substrate r' = target f ->
(order_isomorphism f r r' =
(increasing_fun f r r' & increasing_fun (inverse_fun f) r' r)).
Proof.
move=> f r r' or or' bf sr sr'.
rewrite /order_isomorphism.
move: (bijective_inv_function bf)=> bif.
have sf: source f = target (inverse_fun f) by rewrite /inverse_fun; aw.
have tf:target f = source (inverse_fun f) by rewrite /inverse_fun; aw.
apply iff_eq.
move=> [_ [_ [_ [_ [ _ hyp]]]]].
split;red; ee; aw.
fct_tac.
by rewrite -sr in hyp; move=> x y xy; rewrite - hyp //; order_tac.
move=>x y rxy.
have xt: inc x (target f) by rewrite -sr'; order_tac.
have yt: inc y (target f) by rewrite -sr'; order_tac.
rewrite hyp; try (rewrite sf ; apply inc_W_target=>//; ue).
rewrite - (W_inverse bf xt (refl_equal (W x (inverse_fun f)))).
by rewrite - (W_inverse bf yt (refl_equal (W y (inverse_fun f)))).
move=> [inf inif]; ee.
move=> x y xsf ysf.
move: inf inif=> [_ [_ [_ [_ [_ h1]]]]] [_ [_ [_ [_ [_ h2]]]]].
apply iff_eq.
move=> hy; by apply h1.
move=> hyp.
rewrite (W_inverse2 bf xsf (refl_equal (W x f))).
rewrite (W_inverse2 bf ysf (refl_equal (W y f))).
by apply h2.
Qed.
Theorem decreasing_composition: forall u v r r',
decreasing_fun u r r' -> decreasing_fun v r' r ->
(forall x, inc x (substrate r) -> gle r (W (W x u) v) x) ->
(forall x', inc x' (substrate r') -> gle r' (W (W x' v) u) x') ->
(u \co (v \co u) = u & v \co (u \co v) = v).
Proof.
move=> u v r r' [fu [or [or' [sr [sr' du]]]]] [fv [_ [_ [svr [svr' dv]]]]] h h'.
have cvu: v \coP u by red; hnf; ue.
have fvu: is_function (v \co u) by fct_tac.
have cuvu: u \coP (v \co u) by hnf; aw; ue.
have cuv: u \coP v by red; hnf; ue.
have fuv: is_function (u \co v) by fct_tac.
have cvuv: v \coP (u \co v) by hnf; aw; ue.
split.
apply function_exten;aw; first by fct_tac.
move=> x xs.
rewrite -sr in xs; move:(h _ xs)=> rel1; move: (du _ _ rel1)=> rel2.
have p: inc (W x u) (substrate r') by rewrite sr';apply inc_W_target=> //; ue.
move: (h' _ p)=> rel3; aw; try ue.
red in rel2; order_tac.
apply function_exten; aw; first by fct_tac.
move=> x xs.
rewrite -svr in xs; move:(h' _ xs)=> rel1; move: (dv _ _ rel1)=> rel2.
have p: inc (W x v) (substrate r) by rewrite svr';apply inc_W_target=> //; ue.
move: (h _ p)=> rel3; aw; try ue.
red in rel2; order_tac.
Qed.
Lemma order_isomorphism_opposite: forall g r r',
order_isomorphism g r r' ->
order_isomorphism g (opposite_order r) (opposite_order r').
Proof. rewrite /order_isomorphism=> g r r'.
intuition; aw. intuition.
Qed.
Definition maximal_element r a:=
inc a (substrate r) & forall x, gle r a x -> x = a.
Definition minimal_element r a:=
inc a (substrate r) & forall x, gle r x a -> x = a.
Lemma maximal_element_opp: forall r a,
order r -> maximal_element r a -> minimal_element (opposite_order r) a.
Proof.
move=> r a or [ar hyp].
split; first by aw.
move=> x; aw; apply hyp.
Qed.
Lemma minimal_element_opp: forall r a,
order r -> minimal_element r a -> maximal_element (opposite_order r) a.
Proof.
move=> r a or [ar hyp].
split; first by aw.
move=> x; aw; apply hyp.
Qed.
Lemma maximal_opposite: forall r x,
order r -> maximal_element (opposite_order r) x = minimal_element r x.
Proof.
move=> r x or.
have oo: (order (opposite_order r)) by fprops.
apply iff_eq.
move=> hyp; move: (maximal_element_opp oo hyp).
rewrite /opposite_order inverse_graph_involutive; fprops.
by apply minimal_element_opp.
Qed.
Lemma minimal_inclusion: forall E y,
let F:= complement (powerset E) (singleton emptyset) in
inc y F -> (minimal_element (inclusion_suborder F) y = is_singleton y).
Proof.
move=> E y F yF.
have Fp: forall x, inc x F = (sub x E & nonempty x).
rewrite /F=>w; srw; aw.
apply iff_eq; move => [wE h]; split=>//.
case (emptyset_dichot w)=>//; contradiction.
by move=> aux; rewrite aux in h; apply not_nonempty_empty.
apply iff_eq.
rewrite /minimal_element; aw; rewrite Fp; move=>[[yE [z zy]] sp].
have stF: inc (singleton z) F.
rewrite Fp; split; first by apply sub_singleton; apply yE.
by apply nonempty_singleton.
have sty: singleton z = y by apply sp; aw; ee; apply sub_singleton.
by exists z.
move=> sy.
split; first by aw.
move=> x; aw; move=> [xF [_ xy]].
apply extensionality=>//.
move: xF; rewrite Fp; move=> [xE [t tx]]; move: (xy _ tx)=> ty.
move: sy; rewrite is_singleton_rw; move => [_ hyp].
by move=> z zy; rewrite - (hyp _ _ ty zy).
Qed.
Maximal partial function for extension order are total functions
Lemma maximal_prolongation: forall E F x,
nonempty F -> inc x (set_of_sub_functions E F) ->
maximal_element (opposite_order (extension_order E F)) x = (source x = E).
Proof.
move=> E F x [t tF] xs; rewrite maximal_opposite; fprops.
apply iff_eq.
move: xs; bw; move=>[fx [sx tx]] [_ h].
apply extensionality=>// => y yE.
ex_middle yns.
have aux: gle (extension_order E F) (tack_on_f x y t) x.
rewrite extension_order_pr1 //; bw; ee.
rewrite /tack_on_f; aw.
by move=> z zt; case (tack_on_or zt); [apply sx |move=>->].
rewrite /tack_on_f -tx;aw.
set_extens z => zs; last by fprops.
by rewrite tack_on_rw in zs; case zs =>//; move=> ->; ue.
by rewrite /tack_on_f; aw; fprops.
by rewrite -(h _ aux); rewrite /tack_on_f; aw; intuition.
move=> sx.
red; aw; split=>//.
move=> y; rewrite extension_order_rw; move => [ys [_ et]].
move: xs ys; bw; move => [fx [_ tx]] [fy [sy ty]].
move: (source_extends et)=> sy'.
symmetry;apply function_exten=>//; try ue.
apply extensionality=>//; ue.
move=> z zs; apply (W_extends et zs).
Qed.
nonempty F -> inc x (set_of_sub_functions E F) ->
maximal_element (opposite_order (extension_order E F)) x = (source x = E).
Proof.
move=> E F x [t tF] xs; rewrite maximal_opposite; fprops.
apply iff_eq.
move: xs; bw; move=>[fx [sx tx]] [_ h].
apply extensionality=>// => y yE.
ex_middle yns.
have aux: gle (extension_order E F) (tack_on_f x y t) x.
rewrite extension_order_pr1 //; bw; ee.
rewrite /tack_on_f; aw.
by move=> z zt; case (tack_on_or zt); [apply sx |move=>->].
rewrite /tack_on_f -tx;aw.
set_extens z => zs; last by fprops.
by rewrite tack_on_rw in zs; case zs =>//; move=> ->; ue.
by rewrite /tack_on_f; aw; fprops.
by rewrite -(h _ aux); rewrite /tack_on_f; aw; intuition.
move=> sx.
red; aw; split=>//.
move=> y; rewrite extension_order_rw; move => [ys [_ et]].
move: xs ys; bw; move => [fx [_ tx]] [fy [sy ty]].
move: (source_extends et)=> sy'.
symmetry;apply function_exten=>//; try ue.
apply extensionality=>//; ue.
move=> z zs; apply (W_extends et zs).
Qed.
Definition greatest_element r a:=
inc a (substrate r) & forall x, inc x (substrate r) -> gle r x a.
Definition least_element r a:=
inc a (substrate r) & forall x, inc x (substrate r) -> gle r a x.
Lemma unique_greatest: forall a b r,
order r -> greatest_element r a -> greatest_element r b -> a = b.
Proof.
move=> a b r or [asr h] [bsr bh].
apply (order_antisymmetry or (bh _ asr) (h _ bsr)).
Qed.
Lemma unique_least: forall a b r,
order r -> least_element r a -> least_element r b -> a = b.
Proof.
move=> a b r or [asr h] [bsr bh].
apply (order_antisymmetry or (h _ bsr) (bh _ asr)).
Qed.
Definition the_least_element r := choose [eta least_element r].
Lemma the_least_element_pr: forall r,
order r -> (exists u, least_element r u) ->
least_element r (the_least_element r).
Proof.
by rewrite /the_least_element=> r or h; apply choose_pr.
Qed.
Definition the_greatest_element r:= choose [eta greatest_element r].
Lemma the_greatest_element_pr: forall r,
order r -> (exists u, greatest_element r u) ->
greatest_element r (the_greatest_element r).
Proof.
by rewrite /the_greatest_element=> r or h; apply choose_pr.
Qed.
Lemma the_least_element_pr2: forall r x, order r ->
least_element r x -> the_least_element r = x.
Proof.
move=> r x or le.
have exu: (exists u, least_element r u) by exists x.
move: (the_least_element_pr or exu)=> le1.
apply (unique_least or le1 le).
Qed.
Lemma the_greatest_element_pr2: forall r x, order r ->
greatest_element r x -> the_greatest_element r = x.
Proof.
move=> r x or le.
have exu: (exists u, greatest_element r u) by exists x.
move: (the_greatest_element_pr or exu)=> le1.
apply (unique_greatest or le1 le).
Qed.
Lemma greatest_induced: forall r s x, order r ->
sub s (substrate r) -> inc x s ->
greatest_element r x ->
the_greatest_element r = the_greatest_element (induced_order r s).
Proof.
move=> r s x or ssr xs grx.
rewrite (the_greatest_element_pr2 or grx).
symmetry; apply the_greatest_element_pr2;fprops.
split; aw.
by move => y yxs; aw; move: grx=> [_ h]; apply h; apply ssr.
Qed.
Lemma least_induced: forall r s x, order r ->
sub s (substrate r) -> inc x s ->
least_element r x ->
the_least_element r = the_least_element (induced_order r s).
Proof.
move=> r s x or ssr xs grx.
rewrite (the_least_element_pr2 or grx).
symmetry; apply the_least_element_pr2;fprops.
split; aw.
by move => y yxs; aw; move: grx=> [_ h]; apply h; apply ssr.
Qed.
Lemma least_not_greatest: forall r x , order r ->
least_element r x -> greatest_element r x ->
is_singleton (substrate r).
Proof.
move => r x or [xs lex][_ gex]; exists x.
apply is_singleton_pr; split=>//.
move=> z zs; move: (lex _ zs)(gex _ zs)=> xy yx.
order_tac.
Qed.
Lemma greatest_reverse: forall a r,
order r -> greatest_element r a -> least_element (opposite_order r) a.
Proof.
move=> a r or [asr hy]; split;aw.
by move=> x xs; aw; apply hy.
Qed.
Lemma least_reverse: forall a r,
order r -> least_element r a -> greatest_element (opposite_order r) a.
Proof.
move=> a r or [asr hy]; split;aw.
by move=> x xs; aw; apply hy.
Qed.
Lemma the_least_reverse: forall r, order r ->
(exists a, greatest_element r a) ->
the_least_element (opposite_order r) = the_greatest_element r.
Proof.
move=> r or hy.
move: (the_greatest_element_pr or hy) => gr.
move: (greatest_reverse or gr) => le.
by apply the_least_element_pr2; fprops.
Qed.
Lemma greatest_maximal: forall a r,
order r -> greatest_element r a -> maximal_element r a.
Proof.
move=> a r or [asr h]; split=>//.
move => x ax;
have xsr: inc x (substrate r) by order_tac.
move: (h _ xsr)=> xa; order_tac.
Qed.
Lemma least_minimal: forall a r,
order r -> least_element r a -> minimal_element r a.
Proof.
move=> a r or [asr h]; split=>//.
move => x ax;
have xsr: inc x (substrate r) by order_tac.
move: (h _ xsr)=> xa; order_tac.
Qed.
Lemma greatest_unique_maximal: forall a b r,
greatest_element r a -> maximal_element r b -> a = b.
Proof.
by move=> a b r [ar ha][br hb]; apply hb; apply ha.
Qed.
Lemma least_unique_minimal: forall a b r,
least_element r a -> minimal_element r b -> a = b.
Proof.
by move=> a b r [ar ha][br hb]; apply hb; apply ha.
Qed.
Lemma least_is_intersection: forall s a,
least_element (inclusion_suborder s) a ->
nonempty s -> a = intersection s.
Proof.
move=> s a []; aw =>asr h nes.
set_extens x => xs.
apply intersection_inc =>//.
by move => y ys; move: (h _ ys); aw; move=> [_ [_ ]]; apply.
by apply intersection_forall with s.
Qed.
Lemma greatest_is_union: forall s a,
greatest_element (inclusion_suborder s) a -> a = union s.
Proof.
move=> s a []; aw=> asr h.
set_extens x => xs; first by union_tac.
move: (union_exists xs)=> [y [xy ys]].
by move: (h _ ys); aw; move=> [_ [_ ]]; apply.
Qed.
Lemma intersection_is_least: forall s,
inc (intersection s) s ->
least_element (inclusion_suborder s) (intersection s) .
Proof.
move=> s iis; split; aw.
move=> x xs; aw; ee.
by apply intersection_sub.
Qed.
Lemma union_is_greatest: forall s,
inc (union s) s -> greatest_element (inclusion_suborder s) (union s).
Proof.
move=> s iis; split; aw.
move=> x xs; aw; ee.
by apply union_sub.
Qed.
Lemma emptyset_is_least: forall E,
least_element (inclusion_order E) emptyset.
Proof.
move=> E;split; first by aw; apply emptyset_sub_any.
move=> x; aw => xE.
ee; apply emptyset_sub_any.
Qed.
Lemma wholeset_is_greatest: forall E,
greatest_element (inclusion_order E) E.
Proof.
move=> E;split; first by aw.
move=> x; aw=> xE; ee.
Qed.
Definition empty_function_tg F := BL id emptyset F.
Lemma empty_function_tg_function: forall F,
is_function (empty_function_tg F).
Proof.
move => F; apply bl_function => t; case; case.
Qed.
Lemma least_prolongation: forall E F,
least_element (opposite_order (extension_order E F))
(empty_function_tg F).
Proof.
move=> E F; red.
have <-: set_of_sub_functions E F =
substrate (opposite_order (extension_order E F)) by aw; fprops.
have p1:inc (empty_function_tg F) (set_of_sub_functions E F).
bw;rewrite /empty_function_tg; aw.
ee; [ apply empty_function_tg_function | apply emptyset_sub_any].
split=>//.
move=> x xs; rewrite opposite_gle; fprops.
rewrite extension_order_pr1; ee.
rewrite /empty_function_tg. rewrite /BL;aw; rewrite trivial_fgraph.
apply emptyset_sub_any.
Qed.
Lemma greatest_prolongation: forall E F x,
greatest_element (opposite_order (extension_order E F)) x ->
nonempty E -> small_set F.
Proof.
move=> E F x ge [t tE].
case (emptyset_dichot F).
by move=> -> u v uF vF; elim (emptyset_pr vF).
move=> neF.
set (r:= opposite_order (extension_order E F)).
have oe: order (extension_order E F) by fprops.
have or: order r by rewrite /r; fprops.
have alc: forall u (Ha:inc u F), x = constant_function E F u Ha.
move=> u Ha.
set (f:=constant_function E F u Ha).
have sF: source f = E by rewrite /f/constant_function; aw.
have fsf:inc f (set_of_sub_functions E F). bw.
split; first by apply constant_function_fun.
split; first by ue.
by rewrite /f/constant_function; aw.
rewrite - (maximal_prolongation neF fsf) in sF.
apply (greatest_unique_maximal ge sF).
move=> u v uF vF.
move: (alc _ vF); rewrite (alc _ uF) => eq.
move: (f_equal [eta W t] eq).
do 2 rewrite constant_W //.
Qed.
Lemma least_equivalence: forall r,
is_reflexive r -> sub (identity_g (substrate r)) r.
Proof.
move=> r [ge rr] t. rewrite inc_diagonal_rw.
by move=> [pt [Ps PQ]]; rewrite -pt -PQ; apply rr.
Qed.
Lemma order_transportation: forall f r,
let r':= image_by_fun (ext_to_prod f f) r in
bijection f -> order r -> substrate r = source f ->
(order r' & substrate r' = target f).
Proof.
move=> f r r' bf or sr.
set (E:= source f).
have ff: is_function f by fct_tac.
have fe: is_function (ext_to_prod f f) by apply ext_to_prod_function.
have zr': (forall z,inc z r' = (exists x, exists y, inc x E & inc y E &
inc (J x y) r & z = J (W x f)(W y f))).
have gr: is_graph r by fprops.
move => z; rewrite /r'; apply iff_eq.
rewrite /image_by_fun; aw; move=> [x [xr Jg]].
move: (W_pr fe Jg)=> Wz.
have xJ: J (P x) (Q x) = x by aw; apply gr.
rewrite -xJ in Wz.
have: inc (P x) (substrate r) by substr_tac.
have: inc (Q x) (substrate r) by substr_tac.
rewrite sr=> Qs Ps.
rewrite ext_to_prod_W // in Wz.
by exists (P x); exists (Q x); ee; ue.
move=> [x [y [xE [yE [Jr zJ]]]]].
rewrite /image_by_fun; aw; ex_tac.
have xs: inc x (source f) by rewrite -sr; substr_tac.
have ys: inc y (source f) by rewrite -sr; substr_tac.
have xys: (inc (J x y) (source (ext_to_prod f f))).
by rewrite /ext_to_prod; aw; ee.
have zW: z = W (J x y) (ext_to_prod f f) by rewrite ext_to_prod_W //.
by rewrite zW; graph_tac.
have gr': is_graph r'.
by move=> z; rewrite zr'; move=> [x [y [_ [_ [_]]]]] ->; fprops.
have sr': substrate r' = target f.
set_extens t => tr.
move: tr; rewrite /substrate; aw;dw.
case; move=> [y]; rewrite zr'; move=>[u [v [uE [vE [Jr zJ]]]]].
by rewrite (pr1_def zJ); apply inc_W_target.
by rewrite (pr2_def zJ); apply inc_W_target.
move: bf=> [_ sj]; move: (surjective_pr2 sj tr) => [x [xsf Wt]].
have Jr: (inc (J t t) r').
rewrite zr'; exists x; exists x; ee; [ order_tac; ue | ue].
by substr_tac.
split=>//.
split.
split=>//; rewrite sr'; move=> y yr; red; rewrite zr'.
move: bf=> [_ sj]; move: (surjective_pr2 sj yr) => [x [xsf Wt]].
by exists x; exists x; rewrite Wt; ee; order_tac; ue.
split.
split=>//.
move=> x y z; rewrite /related 3! zr'.
move=> [a [b [aE [bE [J1r Jab]]]]] [c [d [cE [dE [J2r Jcd]]]]].
exists a; exists d.
have bc: (b = c).
move: bf=> [[_ ij] _ ]; apply ij =>//.
by rewrite - (pr2_def Jab) - (pr1_def Jcd).
rewrite bc in J1r.
rewrite - (pr1_def Jab)- (pr2_def Jcd); ee.
by order_tac.
split=>//.
move=> x y; rewrite /related 2! zr'.
move=> [a [b [aE [bE [J1r Jab]]]]] [c [d [cE [dE [J2r Jcd]]]]].
have Wbc: W b f = W c f by rewrite - (pr2_def Jab) - (pr1_def Jcd).
have Wad: W a f = W d f by rewrite - (pr1_def Jab) - (pr2_def Jcd).
move: bf=> [[_ ij] _ ].
have bc: b = c by apply ij =>//.
have ad: a = d by apply ij =>//.
rewrite bc in J1r; rewrite ad in J1r.
have cd: c = d by order_tac.
by rewrite (pr1_def Jab) (pr1_def Jcd) cd ad.
Qed.
Any ordered set can be extended by adjoining a greatest element
Definition order_with_greatest r a :=
union2 r (product (tack_on (substrate r) a) (singleton a)).
Lemma order_with_greatest_pr: forall r a,
let r':=order_with_greatest r a in
order r -> ~ (inc a (substrate r)) ->
(order r' & substrate r' = tack_on (substrate r) a &
r = intersection2 r' (coarse (substrate r)) & greatest_element r' a).
Proof.
simpl; rewrite /order_with_greatest.
move=> r a or nas.
set (E:=substrate r).
set r':= union2 r _.
have src:sub r (coarse E)
by rewrite /E; apply sub_graph_coarse_substrate; fprops.
have gr': is_graph r' by rewrite /r'; apply union2_is_graph; fprops.
have sr': substrate r'=tack_on E a.
set_extens x.
rewrite /r'/substrate /E;aw; dw.
case; move=>[y]; aw;case => hyp; intuition; left ;substr_tac.
move=> xt.
have Jg:inc (J x x) r'.
move: xt; rewrite tack_on_rw /r'.
case => hyp.
apply union2_first; order_tac.
by apply union2_second; rewrite hyp; aw;intuition.
by substr_tac.
have or': order r'.
split.
split=>//.
rewrite sr' /r'/related; move=> y; aw.
case; first by move=> hyp; left; order_tac.
by move=> ->; intuition.
split.
split=>//.
move=> x y z; rewrite /related/r'; aw.
case=> h.
case => h'; first by left; order_tac.
right;move: h'=> [_ [_ za]]; ee; left; rewrite /E; substr_tac.
move: h=> [_ [h1 ya]].
case => h'; first by elim nas; rewrite -ya; substr_tac.
by intuition.
split=>//.
move=> x y; rewrite /related/r'; aw.
case=> h.
case => h'; first by order_tac.
move: h'=> [_ [_ xa]]; elim nas; rewrite -xa; substr_tac.
move: h=> [_ [_ ya]]; rewrite ya.
case => h'; first by elim nas; substr_tac.
intuition.
ee.
rewrite /r'; set_extens x => xr.
by apply intersection2_inc; [aw; auto | apply src].
move: xr; aw; move=> [p1 p2];case p1 =>//.
move: p2; rewrite /coarse; aw.
by move=> [_ [_ Qa]][_ [_ Qb]]; elim nas; by rewrite -Qb.
red; rewrite sr'.
split; fprops.
move=> x; rewrite /r'; red; red; aw; intuition.
Qed.
Theorem adjoin_greatest: forall r a E,
order r -> substrate r = E -> ~ (inc a E) ->
exists_unique (fun r' => order r' & substrate r' = tack_on E a &
r = intersection2 r' (coarse E) & greatest_element r' a).
Proof.
move=> r a E or sr naE.
set(E':=tack_on E a).
set(r':= union2 r (product E' (singleton a))).
split.
exists (order_with_greatest r a).
rewrite -sr in naE; move: (order_with_greatest_pr or naE).
by rewrite sr.
pose p x := (order x &
substrate x = E' & r = intersection2 x (coarse E) & greatest_element x a).
suff : forall x y, p x -> p y -> sub x y.
move=> hyp x y px py.
apply extensionality; [ apply (hyp _ _ px py) | apply (hyp _ _ py px)].
move=> x y [ox [sx [ix gx]]] [oy [sy [iy gy]]] z zx.
have pz: is_pair z.
have grx: is_graph x by fprops.
by apply grx.
have PzE: inc (P z) E' by rewrite -sx; substr_tac.
have QzE: inc (Q z) E' by rewrite -sx; substr_tac.
move: PzE QzE; rewrite /E'; aw; move=> PzE QzE.
case PzE=> Pz.
case QzE=> Qz.
have: (inc z r) by rewrite ix /coarse;apply intersection2_inc; aw; fprops.
by rewrite iy; aw; case.
move: gy=>[ay ga].
rewrite -pz Qz; apply ga; rewrite sy; rewrite/ E'; aw.
case QzE => Qz.
have rel2 : gle x (Q z) (P z).
move: gx=>[ax ga].
have qe: (inc (Q z) E') by rewrite /E'; fprops.
by rewrite -sx in qe; move: (ga _ qe); ue.
have rel1 : gle x (P z) (Q z) by red; red; rewrite pz .
have PQ: P z = Q z by order_tac.
by elim naE; rewrite -Pz PQ.
rewrite -pz Qz.
by move: gy=>[ax ga]; apply ga; ue.
Qed.
union2 r (product (tack_on (substrate r) a) (singleton a)).
Lemma order_with_greatest_pr: forall r a,
let r':=order_with_greatest r a in
order r -> ~ (inc a (substrate r)) ->
(order r' & substrate r' = tack_on (substrate r) a &
r = intersection2 r' (coarse (substrate r)) & greatest_element r' a).
Proof.
simpl; rewrite /order_with_greatest.
move=> r a or nas.
set (E:=substrate r).
set r':= union2 r _.
have src:sub r (coarse E)
by rewrite /E; apply sub_graph_coarse_substrate; fprops.
have gr': is_graph r' by rewrite /r'; apply union2_is_graph; fprops.
have sr': substrate r'=tack_on E a.
set_extens x.
rewrite /r'/substrate /E;aw; dw.
case; move=>[y]; aw;case => hyp; intuition; left ;substr_tac.
move=> xt.
have Jg:inc (J x x) r'.
move: xt; rewrite tack_on_rw /r'.
case => hyp.
apply union2_first; order_tac.
by apply union2_second; rewrite hyp; aw;intuition.
by substr_tac.
have or': order r'.
split.
split=>//.
rewrite sr' /r'/related; move=> y; aw.
case; first by move=> hyp; left; order_tac.
by move=> ->; intuition.
split.
split=>//.
move=> x y z; rewrite /related/r'; aw.
case=> h.
case => h'; first by left; order_tac.
right;move: h'=> [_ [_ za]]; ee; left; rewrite /E; substr_tac.
move: h=> [_ [h1 ya]].
case => h'; first by elim nas; rewrite -ya; substr_tac.
by intuition.
split=>//.
move=> x y; rewrite /related/r'; aw.
case=> h.
case => h'; first by order_tac.
move: h'=> [_ [_ xa]]; elim nas; rewrite -xa; substr_tac.
move: h=> [_ [_ ya]]; rewrite ya.
case => h'; first by elim nas; substr_tac.
intuition.
ee.
rewrite /r'; set_extens x => xr.
by apply intersection2_inc; [aw; auto | apply src].
move: xr; aw; move=> [p1 p2];case p1 =>//.
move: p2; rewrite /coarse; aw.
by move=> [_ [_ Qa]][_ [_ Qb]]; elim nas; by rewrite -Qb.
red; rewrite sr'.
split; fprops.
move=> x; rewrite /r'; red; red; aw; intuition.
Qed.
Theorem adjoin_greatest: forall r a E,
order r -> substrate r = E -> ~ (inc a E) ->
exists_unique (fun r' => order r' & substrate r' = tack_on E a &
r = intersection2 r' (coarse E) & greatest_element r' a).
Proof.
move=> r a E or sr naE.
set(E':=tack_on E a).
set(r':= union2 r (product E' (singleton a))).
split.
exists (order_with_greatest r a).
rewrite -sr in naE; move: (order_with_greatest_pr or naE).
by rewrite sr.
pose p x := (order x &
substrate x = E' & r = intersection2 x (coarse E) & greatest_element x a).
suff : forall x y, p x -> p y -> sub x y.
move=> hyp x y px py.
apply extensionality; [ apply (hyp _ _ px py) | apply (hyp _ _ py px)].
move=> x y [ox [sx [ix gx]]] [oy [sy [iy gy]]] z zx.
have pz: is_pair z.
have grx: is_graph x by fprops.
by apply grx.
have PzE: inc (P z) E' by rewrite -sx; substr_tac.
have QzE: inc (Q z) E' by rewrite -sx; substr_tac.
move: PzE QzE; rewrite /E'; aw; move=> PzE QzE.
case PzE=> Pz.
case QzE=> Qz.
have: (inc z r) by rewrite ix /coarse;apply intersection2_inc; aw; fprops.
by rewrite iy; aw; case.
move: gy=>[ay ga].
rewrite -pz Qz; apply ga; rewrite sy; rewrite/ E'; aw.
case QzE => Qz.
have rel2 : gle x (Q z) (P z).
move: gx=>[ax ga].
have qe: (inc (Q z) E') by rewrite /E'; fprops.
by rewrite -sx in qe; move: (ga _ qe); ue.
have rel1 : gle x (P z) (Q z) by red; red; rewrite pz .
have PQ: P z = Q z by order_tac.
by elim naE; rewrite -Pz PQ.
rewrite -pz Qz.
by move: gy=>[ax ga]; apply ga; ue.
Qed.
A set A is cofinal if every element of E is bounded by an element of A
Definition cofinal_set r a :=
sub a (substrate r) &
(forall x, inc x (substrate r) -> exists y, inc y a & gle r x y).
Definition coinitial_set r a :=
sub a (substrate r) &
(forall x, inc x (substrate r) -> exists y, inc y a & gle r y x).
Lemma exists_greatest_cofinal: forall r,
(exists x, greatest_element r x) =
(exists a, cofinal_set r a & is_singleton a).
Proof.
move=> r; apply iff_eq.
move=> [a [asr h]]; exists (singleton a).
split.
split; first by move=> t; aw; move=>->.
by move=> x xr; exists a; aw; split=>//; apply h.
by red; exists a.
move=> [a [[asr h] [b bp]]].
exists b;split.
by apply asr; rewrite bp; aw.
move=> x xsr; move:(h _ xsr)=> [y []]; rewrite bp; aw.
by move=>->.
Qed.
Lemma exists_least_coinitial: forall r,
(exists x, least_element r x) =
(exists a, coinitial_set r a & is_singleton a).
Proof.
move=> r; apply iff_eq.
move=> [a [asr h]]; exists (singleton a).
split.
split; first by move=> t; aw; move=>->.
by move=> x xr; exists a; aw; split=>//; apply h.
by red; exists a.
move=> [a [[asr h] [b bp]]].
exists b;split.
by apply asr; rewrite bp; aw.
move=> x xsr; move:(h _ xsr)=> [y []]; rewrite bp; aw.
by move=>->.
Qed.
sub a (substrate r) &
(forall x, inc x (substrate r) -> exists y, inc y a & gle r x y).
Definition coinitial_set r a :=
sub a (substrate r) &
(forall x, inc x (substrate r) -> exists y, inc y a & gle r y x).
Lemma exists_greatest_cofinal: forall r,
(exists x, greatest_element r x) =
(exists a, cofinal_set r a & is_singleton a).
Proof.
move=> r; apply iff_eq.
move=> [a [asr h]]; exists (singleton a).
split.
split; first by move=> t; aw; move=>->.
by move=> x xr; exists a; aw; split=>//; apply h.
by red; exists a.
move=> [a [[asr h] [b bp]]].
exists b;split.
by apply asr; rewrite bp; aw.
move=> x xsr; move:(h _ xsr)=> [y []]; rewrite bp; aw.
by move=>->.
Qed.
Lemma exists_least_coinitial: forall r,
(exists x, least_element r x) =
(exists a, coinitial_set r a & is_singleton a).
Proof.
move=> r; apply iff_eq.
move=> [a [asr h]]; exists (singleton a).
split.
split; first by move=> t; aw; move=>->.
by move=> x xr; exists a; aw; split=>//; apply h.
by red; exists a.
move=> [a [[asr h] [b bp]]].
exists b;split.
by apply asr; rewrite bp; aw.
move=> x xsr; move:(h _ xsr)=> [y []]; rewrite bp; aw.
by move=>->.
Qed.
Definition upper_bound r X x :=
inc x (substrate r) & forall y, inc y X -> gle r y x.
Definition lower_bound r X x :=
inc x (substrate r) & forall y, inc y X -> gle r x y.
Lemma opposite_upper_bound: forall x X r, order r ->
upper_bound r X x = lower_bound (opposite_order r) X x.
Proof.
rewrite /upper_bound/lower_bound=> x R r or; aw.
apply iff_eq; move=> [xsr h]; split=>//; move=> y yR; move: (h _ yR); aw.
Qed.
Lemma opposite_lower_bound: forall x X r, order r ->
lower_bound r X x = upper_bound (opposite_order r) X x.
Proof.
rewrite /upper_bound/lower_bound=> x R r or; aw.
apply iff_eq; move=> [xsr h]; split=>//; move=> y yR; move: (h _ yR); aw.
Qed.
Lemma smaller_lower_bound: forall x y X r, preorder r ->
lower_bound r X x -> gle r y x -> lower_bound r X y.
Proof.
rewrite /lower_bound=> x y X r [rr [_ tr]] [xH h] yx.
split. red in yx;substr_tac.
move=> z zX; apply (tr _ _ _ yx (h _ zX)).
Qed.
Lemma greater_upper_bound: forall x y X r, preorder r ->
upper_bound r X x -> gle r x y -> upper_bound r X y.
Proof.
rewrite /lower_bound=> x y X r [rr [_ tr]] [xH h] yx.
split. red in yx;substr_tac.
move=> z zX; apply (tr _ _ _ (h _ zX) yx).
Qed.
Lemma sub_lower_bound: forall x X Y r,
lower_bound r X x -> sub Y X-> lower_bound r Y x.
Proof.
rewrite /lower_bound=>x X Y r [xR lo] YX .
split=>//; move=> y yY; apply (lo _ (YX _ yY)).
Qed.
Lemma sub_upper_bound: forall x X Y r,
upper_bound r X x -> sub Y X -> upper_bound r Y x.
Proof.
rewrite /lower_bound=>x X Y r [xR lo] YX .
split=>//; move=> y yY; apply (lo _ (YX _ yY)).
Qed.
Lemma least_element_pr: forall X r, order r -> sub X (substrate r) ->
(exists a, least_element (induced_order r X) a) =
(exists x, lower_bound r X x & inc x X).
Proof.
rewrite /lower_bound/least_element=> X r or Xr.
apply iff_eq.
move=> [a []]; aw=> aX h; exists a; ee.
by move=> y yX; move: (h _ yX); aw.
by move=> [x [[xsr hyp] xX]]; exists x; aw; ee; move=> y yX; aw; apply hyp.
Qed.
Lemma greatest_element_pr: forall X r, order r -> sub X (substrate r) ->
(exists a, greatest_element (induced_order r X) a) =
(exists x, upper_bound r X x & inc x X).
Proof.
rewrite /upper_bound/greatest_element=> X r or Xr.
apply iff_eq.
move=> [a []]; aw=> aX h; exists a; ee.
by move=> y yX; move: (h _ yX); aw.
by move=> [x [[xsr hyp] xX]]; exists x; aw; ee; move=> y yX; aw; apply hyp.
Qed.
inc x (substrate r) & forall y, inc y X -> gle r y x.
Definition lower_bound r X x :=
inc x (substrate r) & forall y, inc y X -> gle r x y.
Lemma opposite_upper_bound: forall x X r, order r ->
upper_bound r X x = lower_bound (opposite_order r) X x.
Proof.
rewrite /upper_bound/lower_bound=> x R r or; aw.
apply iff_eq; move=> [xsr h]; split=>//; move=> y yR; move: (h _ yR); aw.
Qed.
Lemma opposite_lower_bound: forall x X r, order r ->
lower_bound r X x = upper_bound (opposite_order r) X x.
Proof.
rewrite /upper_bound/lower_bound=> x R r or; aw.
apply iff_eq; move=> [xsr h]; split=>//; move=> y yR; move: (h _ yR); aw.
Qed.
Lemma smaller_lower_bound: forall x y X r, preorder r ->
lower_bound r X x -> gle r y x -> lower_bound r X y.
Proof.
rewrite /lower_bound=> x y X r [rr [_ tr]] [xH h] yx.
split. red in yx;substr_tac.
move=> z zX; apply (tr _ _ _ yx (h _ zX)).
Qed.
Lemma greater_upper_bound: forall x y X r, preorder r ->
upper_bound r X x -> gle r x y -> upper_bound r X y.
Proof.
rewrite /lower_bound=> x y X r [rr [_ tr]] [xH h] yx.
split. red in yx;substr_tac.
move=> z zX; apply (tr _ _ _ (h _ zX) yx).
Qed.
Lemma sub_lower_bound: forall x X Y r,
lower_bound r X x -> sub Y X-> lower_bound r Y x.
Proof.
rewrite /lower_bound=>x X Y r [xR lo] YX .
split=>//; move=> y yY; apply (lo _ (YX _ yY)).
Qed.
Lemma sub_upper_bound: forall x X Y r,
upper_bound r X x -> sub Y X -> upper_bound r Y x.
Proof.
rewrite /lower_bound=>x X Y r [xR lo] YX .
split=>//; move=> y yY; apply (lo _ (YX _ yY)).
Qed.
Lemma least_element_pr: forall X r, order r -> sub X (substrate r) ->
(exists a, least_element (induced_order r X) a) =
(exists x, lower_bound r X x & inc x X).
Proof.
rewrite /lower_bound/least_element=> X r or Xr.
apply iff_eq.
move=> [a []]; aw=> aX h; exists a; ee.
by move=> y yX; move: (h _ yX); aw.
by move=> [x [[xsr hyp] xX]]; exists x; aw; ee; move=> y yX; aw; apply hyp.
Qed.
Lemma greatest_element_pr: forall X r, order r -> sub X (substrate r) ->
(exists a, greatest_element (induced_order r X) a) =
(exists x, upper_bound r X x & inc x X).
Proof.
rewrite /upper_bound/greatest_element=> X r or Xr.
apply iff_eq.
move=> [a []]; aw=> aX h; exists a; ee.
by move=> y yX; move: (h _ yX); aw.
by move=> [x [[xsr hyp] xX]]; exists x; aw; ee; move=> y yX; aw; apply hyp.
Qed.
A set can be bounded above, below, or both
Definition bounded_above r X := exists x, upper_bound r X x.
Definition bounded_below r X := exists x, lower_bound r X x.
Definition bounded_both r X := bounded_above r X & bounded_below r X.
Lemma bounded_above_sub: forall X Y r,
sub Y X -> bounded_above r X -> bounded_above r Y.
Proof.
move=> X Y r YX [x ux]; exists x; apply (sub_upper_bound ux YX).
Qed.
Lemma bounded_below_sub: forall X Y r,
sub Y X -> bounded_below r X -> bounded_below r Y.
Proof.
move=> X Y r YX [x ux]; exists x; apply (sub_lower_bound ux YX).
Qed.
Lemma bounded_both_sub: forall X Y r,
sub Y X ->bounded_both r X -> bounded_both r Y.
Proof.
rewrite /bounded_both=> X Y r YX [p1 p2].
split; [ apply (bounded_above_sub YX p1) | apply (bounded_below_sub YX p2)].
Qed.
Lemma singleton_bounded:forall x r,
is_singleton x -> order r -> sub x (substrate r) -> bounded_both r x.
Proof.
move=> x r [y yp] or xsr.
have ysr: inc y (substrate r) by apply xsr;rewrite yp; aw.
have yy: gle r y y by order_tac.
by split; exists y; split=>//; rewrite yp; move=> z; aw => ->.
Qed.
Definition greatest_lower_bound r X x :=
greatest_element (induced_order r (Zo (substrate r) (lower_bound r X))) x.
Definition least_upper_bound r X x :=
least_element (induced_order r (Zo (substrate r) (upper_bound r X))) x.
Lemma greatest_lower_bound_pr: forall r X x,
order r -> sub X (substrate r) ->
greatest_lower_bound r X x = (lower_bound r X x
& forall z, lower_bound r X z -> gle r z x).
Proof.
rewrite /greatest_lower_bound/greatest_element=> r X x or Xr.
set T:= Zo _ _.
have sT: sub T (substrate r) by rewrite /T; apply Z_sub.
aw.
apply iff_eq.
move=> [xT hyp]; move: (xT); rewrite /T Z_rw; move=> [xsr lb]; split=>//.
move=> z lbz.
have zT: inc z T by rewrite /T Z_rw; split=>//; move: lbz=> [].
by move: (hyp _ zT); aw.
move=> [lbx hyp].
have xT: inc x T by rewrite /T Z_rw; split=>//; move: lbx=> [].
split=>//; move=> y yT; aw; apply hyp.
move: yT; rewrite /T Z_rw; move=> [_ ]; apply.
Qed.
Lemma least_upper_bound_pr: forall r X x,
order r -> sub X (substrate r) ->
least_upper_bound r X x = (upper_bound r X x
& forall z, upper_bound r X z -> gle r x z).
Proof.
rewrite /least_upper_bound/least_element=> r X x or Xr.
set T:= Zo _ _.
have sT: sub T (substrate r) by rewrite /T; apply Z_sub.
aw.
apply iff_eq.
move=> [xT hyp]; move: (xT); rewrite /T Z_rw; move=> [xsr lb]; split=>//.
move=> z lbz.
have zT: inc z T by rewrite /T Z_rw; split=>//; move: lbz=> [].
by move: (hyp _ zT); aw.
move=> [lbx hyp].
have xT: inc x T by rewrite /T Z_rw; split=>//; move: lbx=> [].
split=>//; move=> y yT; aw; apply hyp.
move: yT; rewrite /T Z_rw; move=> [_ ]; apply.
Qed.
Hint Rewrite greatest_lower_bound_pr least_upper_bound_pr: aw.
Lemma supremum_unique: forall x y X r, order r ->
least_upper_bound r X x -> least_upper_bound r X y -> x = y.
Proof.
rewrite /least_upper_bound => x y X r or.
set oi := induced_order r _.
have ooi: order oi by rewrite /oi; apply order_induced_order =>// ; apply Z_sub.
apply (unique_least ooi).
Qed.
Lemma infimum_unique: forall x y X r, order r ->
greatest_lower_bound r X x -> greatest_lower_bound r X y -> x = y.
Proof.
rewrite /greatest_lower_bound => x y X r or.
set oi := induced_order r _.
have ooi: order oi by rewrite /oi; apply order_induced_order =>// ; apply Z_sub.
apply (unique_greatest ooi).
Qed.
Definition of the supremum or infimum or a set or a pair
Definition supremum r X := choose (least_upper_bound r X).
Definition infimum r X := choose (greatest_lower_bound r X).
Definition sup r x y := supremum r (doubleton x y).
Definition inf r x y := infimum r (doubleton x y).
Definition has_supremum r X := (exists x, least_upper_bound r X x).
Definition has_infimum r X := (exists x, greatest_lower_bound r X x).
Lemma supremum_pr1: forall X r,
has_supremum r X ->
least_upper_bound r X (supremum r X).
Proof. rewrite /supremum=> *; apply choose_pr =>//. Qed.
Lemma infimum_pr1: forall X r,
has_infimum r X ->
greatest_lower_bound r X (infimum r X).
Proof. rewrite /infimum=> *; apply choose_pr =>//. Qed.
Hint Resolve supremum_pr1 infimum_pr1: fprops.
Lemma supremum_pr2: forall r X a, order r ->
least_upper_bound r X a -> a = supremum r X.
Proof.
move=> r X a or le.
have hs: has_supremum r X by exists a.
move: (supremum_pr1 hs).
apply (supremum_unique or le).
Qed.
Lemma infimum_pr2: forall r X a, order r ->
greatest_lower_bound r X a -> a = infimum r X.
Proof.
move=> r X a or le.
have hs: has_infimum r X by exists a.
move: (infimum_pr1 hs).
apply (infimum_unique or le).
Qed.
Lemma inc_supremum_substrate : forall X r,
order r -> sub X (substrate r) -> has_supremum r X ->
inc (supremum r X) (substrate r).
Proof.
move=> X r or Xsr hs.
move: (supremum_pr1 hs); aw; by move=> [[aa _] _].
Qed.
Lemma inc_infimum_substrate : forall X r,
order r -> sub X (substrate r) -> has_infimum r X ->
inc (infimum r X) (substrate r).
Proof.
move=> X r or Xsr hs.
move: (infimum_pr1 hs); aw; by move=> [[aa _] _].
Qed.
Lemma supremum_pr: forall X r,
order r -> sub X (substrate r) -> has_supremum r X ->
(upper_bound r X (supremum r X) &
forall z, upper_bound r X z -> gle r (supremum r X) z).
Proof. move=> X r or Xsr hs; move: (supremum_pr1 hs); aw. Qed.
Lemma infimum_pr: forall X r,
order r -> sub X (substrate r) -> has_infimum r X ->
(lower_bound r X (infimum r X) &
forall z, lower_bound r X z -> gle r z (infimum r X)).
Proof. move=> X r or Xsr hs; move: (infimum_pr1 hs); aw. Qed.
Properties of sup and inf of pairs
Lemma sup_pr: forall a b r,
order r -> inc a (substrate r) -> inc b (substrate r)
-> has_supremum r (doubleton a b) ->
(gle r a (sup r a b) & gle r b (sup r a b) &
forall z, gle r a z -> gle r b z -> gle r (sup r a b) z).
Proof.
move=> a b r or ast bsr hs.
have sd: sub (doubleton a b) (substrate r) by apply sub_doubleton.
move: (supremum_pr or sd hs) => [[sr h1] h2].
ee.
move=> z az bz; apply h2.
split; first by order_tac.
by move=>y; aw;case; move=> ->.
Qed.
Lemma inf_pr: forall a b r,
order r -> inc a (substrate r) -> inc b (substrate r)
-> has_infimum r (doubleton a b) ->
(gle r (inf r a b) a & gle r (inf r a b) b&
forall z, gle r z a -> gle r z b -> gle r z (inf r a b)).
Proof.
move=> a b r or ast bsr hs.
have sd: sub (doubleton a b) (substrate r) by apply sub_doubleton.
move: (infimum_pr or sd hs) => [[sr h1] h2].
ee.
move=> z az bz; apply h2.
split; first by order_tac.
by move=>y; rewrite doubleton_rw; case; move=> ->.
Qed.
Lemma least_upper_bound_doubleton: forall r x y z,
order r -> gle r x z -> gle r y z ->
(forall t, gle r x t -> gle r y t -> gle r z t) ->
least_upper_bound r (doubleton x y) z.
Proof.
move=> r x y z or xz yz h.
move:(inc_arg1_substrate xz) => xsr.
move:(inc_arg1_substrate yz) => ysr.
aw.
split.
split; first by order_tac.
by move=>t; rewrite doubleton_rw; case; move=> ->.
move=> t tb; apply h; apply tb; fprops.
by move=>t; rewrite doubleton_rw; case; move=> ->.
Qed.
Lemma greatest_lower_bound_doubleton: forall r x y z,
order r -> gle r z x -> gle r z y ->
(forall t, gle r t x -> gle r t y -> gle r t z) ->
greatest_lower_bound r (doubleton x y) z.
Proof.
move=> r x y z or xz yz h.
move:(inc_arg2_substrate xz) => xsr.
move:(inc_arg2_substrate yz) => ysr.
aw.
split.
split; first by order_tac.
by move=>t; rewrite doubleton_rw; case; move=> ->.
move=> t tb; apply h; apply tb; fprops.
by move=>t; rewrite doubleton_rw; case; move=> ->.
Qed.
Link between supremum and greatest element
Lemma greatest_is_sup: forall r X a,
order r -> sub X (substrate r) ->
greatest_element (induced_order r X) a -> least_upper_bound r X a.
Proof.
move=>r X a or Xsr []; aw => aX h.
split.
split; first by apply Xsr.
by move=> y yX; move: (h _ yX); aw.
by move=> z [zs h2]; apply (h2 _ aX).
Qed.
Lemma least_is_inf: forall r X a,
order r -> sub X (substrate r) ->
least_element (induced_order r X) a -> greatest_lower_bound r X a.
Proof.
move=>r X a or Xsr []; aw => aX h.
split.
split; first by apply Xsr.
by move=> y yX; move: (h _ yX); aw.
by move=> z [zs h2]; apply (h2 _ aX).
Qed.
Lemma inf_sup_opp: forall r X a,
order r -> sub X (substrate r) ->
greatest_lower_bound r X a = least_upper_bound (opposite_order r) X a.
Proof.
move=> e X a or Xsr; aw; fprops.
rewrite -opposite_lower_bound //.
apply iff_eq; move=> [lb albe];
split =>//; move => z; move: (albe z); rewrite -opposite_lower_bound //; aw.
Qed.
Lemma sup_inf_opp: forall r X a,
order r -> sub X (substrate r) ->
least_upper_bound r X a = greatest_lower_bound (opposite_order r) X a.
Proof.
move=> r X a or Xsr; rewrite inf_sup_opp; fprops; try (solve [aw]).
have ->: (opposite_order (opposite_order r) = r) =>//.
by rewrite /opposite_order; apply inverse_graph_involutive; fprops.
Qed.
Supremum and infimum of the empty set
Lemma set_of_lower_bounds_emptyset: forall r,
Zo (substrate r) (lower_bound r emptyset) = substrate r.
Proof.
move=> r;apply extensionality; first by apply Z_sub.
move=> x xsr; rewrite Z_rw; split=>//; split=>//.
move=> y;case; case.
Qed.
Lemma set_of_upper_bounds_emptyset: forall r ,
Zo (substrate r) (upper_bound r emptyset) = substrate r.
Proof.
move=> r;apply extensionality; first by apply Z_sub.
move=> x xsr; rewrite Z_rw; split=>//; split=>//.
move=> y;case; case.
Qed.
Lemma least_upper_bound_emptyset: forall r x, order r ->
least_upper_bound r emptyset x = least_element r x.
Proof.
move=> r x or; rewrite /least_upper_bound set_of_upper_bounds_emptyset.
by rewrite induced_order_substrate.
Qed.
Lemma greatest_lower_bound_emptyset: forall r x, order r ->
greatest_lower_bound r emptyset x = greatest_element r x.
Proof.
move=> r x or; rewrite /greatest_lower_bound set_of_lower_bounds_emptyset.
by rewrite induced_order_substrate.
Qed.
Zo (substrate r) (lower_bound r emptyset) = substrate r.
Proof.
move=> r;apply extensionality; first by apply Z_sub.
move=> x xsr; rewrite Z_rw; split=>//; split=>//.
move=> y;case; case.
Qed.
Lemma set_of_upper_bounds_emptyset: forall r ,
Zo (substrate r) (upper_bound r emptyset) = substrate r.
Proof.
move=> r;apply extensionality; first by apply Z_sub.
move=> x xsr; rewrite Z_rw; split=>//; split=>//.
move=> y;case; case.
Qed.
Lemma least_upper_bound_emptyset: forall r x, order r ->
least_upper_bound r emptyset x = least_element r x.
Proof.
move=> r x or; rewrite /least_upper_bound set_of_upper_bounds_emptyset.
by rewrite induced_order_substrate.
Qed.
Lemma greatest_lower_bound_emptyset: forall r x, order r ->
greatest_lower_bound r emptyset x = greatest_element r x.
Proof.
move=> r x or; rewrite /greatest_lower_bound set_of_lower_bounds_emptyset.
by rewrite induced_order_substrate.
Qed.
Supremum and infimum for inclusion order
Lemma intersection_is_inf: forall s E, sub s (powerset E) ->
greatest_lower_bound (inclusion_order E) s
(Yo (nonempty s) (intersection s) E).
move=> s E sp.
have oi: order (inclusion_order E) by fprops.
have nnee: ~ nonempty emptyset by move=>h; apply not_nonempty_empty.
case (emptyset_dichot s)=> h.
rewrite h Y_if_not_rw // greatest_lower_bound_emptyset //.
by apply wholeset_is_greatest.
Ytac0.
have si: sub (intersection s) E.
move: h=> [y ys]; apply sub_trans with y.
by apply intersection_sub.
move: (sp _ ys); aw.
aw; split.
split; first by aw.
move=> y ys; aw; split=>//.
split; [ move:(sp _ ys); aw | apply (intersection_sub ys)].
move=> z []; aw=> zE hyp.
ee.
move=> t tz; apply intersection_inc =>//.
move=> y ys; move: (hyp _ ys); aw.
by move=> [_[_]]; apply.
Qed.
Lemma union_is_sup: forall s E, sub s (powerset E) ->
least_upper_bound (inclusion_order E) s (union s).
Proof.
move=> s E sp.
have oi: order (inclusion_order E) by apply inclusion_is_order.
have su:sub (union s) E.
by apply sub_union; move=> y ys; move: (sp _ ys); aw.
aw; rewrite /upper_bound; aw.
split.
split=>// y ys.
have sy: sub y (union s) by apply union_sub.
aw; ee; move: (sp _ ys); aw.
move=> z []; aw; move=> zE hyp; ee.
apply sub_union => y ys; by move: (hyp _ ys); aw; move=> [_[_]]; apply.
Qed.
Lemma union_is_sup1: forall s F E, sub F (powerset E) ->
sub s F -> inc (union s) F ->
least_upper_bound (inclusion_suborder F) s (union s).
Proof.
move=> s F E Fp sF uF.
have oi: order (inclusion_suborder F) by apply subinclusion_is_order.
have sss: sub s (substrate (inclusion_suborder F)).
by rewrite substrate_subinclusion_order.
rewrite least_upper_bound_pr //.
split.
by red; aw; ee; move=> y ys; aw; ee; apply union_sub.
move=> z []; aw => zF hyp; ee.
apply sub_union => y ys; by move: (hyp _ ys); aw; move=> [_[_]]; apply.
Qed.
Lemma intersection_is_inf1: forall s F E, sub F (powerset E) ->
sub s F -> inc (Yo (nonempty s) (intersection s) E) F ->
greatest_lower_bound (inclusion_suborder F) s
(Yo (nonempty s) (intersection s) E).
Proof.
move=> s F E Fp sF ssF.
have oi: order (inclusion_suborder F) by apply subinclusion_is_order.
have sss: sub s (substrate (inclusion_suborder F)).
by rewrite substrate_subinclusion_order.
rewrite greatest_lower_bound_pr //.
split.
red; aw; split =>//.
move=> y ys; aw; ee.
have nes: (nonempty s) by exists y.
Ytac0;apply intersection_sub=>//.
move=>z []; aw => zF hyp;ee.
case (emptyset_dichot s) => sp.
rewrite Y_if_not_rw.
by apply powerset_sub; apply Fp.
by rewrite sp=> h; apply not_nonempty_empty.
Ytac0;move=> t tz; apply intersection_inc=>//.
by move=> y ys; move: (hyp _ ys); aw; move=> [_ [_]]; apply.
Qed.
Supremum for extension order: is least common extension
Lemma sup_extension_order1: forall E F T f,
sub T (set_of_sub_functions E F) ->
least_upper_bound (opposite_order (extension_order E F)) T f ->
forall u v x, inc u T -> inc v T -> inc x (source u) -> inc x (source v) ->
W x u = W x v.
Proof.
move=> E F T f Ts lef.
have oe: order (extension_order E F) by fprops.
have oo: order (opposite_order (extension_order E F)) by fprops.
have sTe: sub T (substrate (extension_order E F)) by aw.
have sT:sub T (substrate (opposite_order (extension_order E F))) by aw; fprops.
move: lef; aw.
move=> [[fs ub] hyp] u v x uT vT xs ys.
by rewrite (extension_order_pr (ub _ uT) xs) (extension_order_pr (ub _ vT) ys).
Qed.
Lemma sup_extension_order2: forall E F T,
sub T (set_of_sub_functions E F) ->
(forall u v x, inc u T -> inc v T -> inc x (source u) -> inc x (source v) ->
W x u = W x v) ->
exists x, least_upper_bound (opposite_order (extension_order E F)) T x &
(source x = unionf T source) &
(range (graph x) = unionf T (fun u => (range (graph u))))&
(graph x) = unionf T graph.
Proof.
move=> E F T Ts ag.
have fp: forall i, inc i T -> function_prop i (source i) F.
by move=> i iT; move: (Ts _ iT); bw; rewrite / function_prop; intuition.
have ag1: forall i j, inc i T -> inc j T ->
agrees_on (intersection2 (source i) (source j)) i j.
move=> i j iT jT; split; first by apply intersection2sub_first.
split; first by apply intersection2sub_second.
move=> a; aw; move=> [ai aj]; by apply ag.
move:(extension_covering1 fp ag1)=> [g [[fg [sf tg]] [gg [rg vg]]]].
have eo: order (extension_order E F) by fprops.
have oo: order (opposite_order (extension_order E F)) by fprops.
have ssEF:set_of_sub_functions E F =
substrate (opposite_order (extension_order E F)) by aw.
have Tso: sub T (substrate (opposite_order (extension_order E F))) by aw.
have sTe: sub T (substrate (extension_order E F)) by aw.
have xss:inc g (set_of_sub_functions E F).
bw; ee.
rewrite sf; move=> t; srw; move=> [y [yT ty]].
by move: (Ts _ yT);bw; move=> [_ [yE _]]; apply yE.
exists g;ee; aw.
split.
red;rewrite -ssEF; ee.
move=> y yT; move:(Ts _ yT) => yss.
rewrite extension_order_pr2; ee.
by move => t ta; rewrite gg; union_tac.
move=> z; rewrite /upper_bound -ssEF.
rewrite extension_order_pr2; move=> [zss hyp]; ee.
move=> t; rewrite gg; srw; move=> [y [yT tgg]].
by move: (hyp _ yT); rewrite extension_order_pr2; move => [_[_]]; apply.
Qed.
Supremum and infinum of the range of a function
Definition is_sup_fun r f x := least_upper_bound r (image_of_fun f) x.
Definition is_inf_fun r f x := greatest_lower_bound r (image_of_fun f) x.
Lemma is_sup_fun_pr: forall r f x, order r -> substrate r = target f ->
is_function f ->
is_sup_fun r f x = (inc x (target f)
& (forall a, inc a (source f) -> gle r (W a f) x)
& forall z, inc z (target f) -> (forall a, inc a (source f)
-> gle r (W a f) z) -> gle r x z).
Proof.
move=> r f x or sr ff.
have si: sub (image_of_fun f) (substrate r).
by rewrite sr; apply sub_image_target.
rewrite /is_sup_fun; aw.
rewrite /upper_bound sr /image_of_fun.
have gf: is_graph (graph f) by fprops.
apply iff_eq.
move=> [[xt p1] p2].
split=>//; split.
by move=> a afs; apply p1; aw; ex_tac; graph_tac.
move=> z zt sh; apply p2; ee.
by move=> y; aw; move => [u [usf JG]]; rewrite -(W_pr ff JG); apply sh.
move=> [xt [p1 p2]]; split.
split=>//.
by move=> y; aw; move=> [u [usf JG]]; rewrite -(W_pr ff JG); apply p1.
move=> z [ztg p3].
apply p2=>//; move=> a asf; apply p3; aw; ex_tac; graph_tac.
Qed.
Lemma is_inf_fun_pr: forall r f x, order r -> substrate r = target f ->
is_function f ->
is_inf_fun r f x
= (inc x (target f)
& (forall a, inc a (source f) -> gle r x (W a f))
& forall z, inc z (target f) -> (forall a, inc a (source f)
-> gle r z (W a f)) -> gle r z x).
Proof.
move=> r f x or sr ff.
have si: sub (image_of_fun f) (substrate r).
by rewrite sr; apply sub_image_target.
rewrite /is_inf_fun; aw.
rewrite /lower_bound sr /image_of_fun.
have gf: is_graph (graph f) by fprops.
apply iff_eq.
move=> [[xt p1] p2].
split=>//; split.
by move=> a afs; apply p1; aw; ex_tac; graph_tac.
move=> z zt sh; apply p2; ee.
by move=> y; aw; move => [u [usf JG]]; rewrite -(W_pr ff JG); apply sh.
move=> [xt [p1 p2]]; split.
split=>//.
by move=> y; aw; move=> [u [usf JG]]; rewrite -(W_pr ff JG); apply p1.
move=> z [ztg p3].
apply p2=>//; move=> a asf; apply p3; aw; ex_tac; graph_tac.
Qed.
Definition is_inf_fun r f x := greatest_lower_bound r (image_of_fun f) x.
Lemma is_sup_fun_pr: forall r f x, order r -> substrate r = target f ->
is_function f ->
is_sup_fun r f x = (inc x (target f)
& (forall a, inc a (source f) -> gle r (W a f) x)
& forall z, inc z (target f) -> (forall a, inc a (source f)
-> gle r (W a f) z) -> gle r x z).
Proof.
move=> r f x or sr ff.
have si: sub (image_of_fun f) (substrate r).
by rewrite sr; apply sub_image_target.
rewrite /is_sup_fun; aw.
rewrite /upper_bound sr /image_of_fun.
have gf: is_graph (graph f) by fprops.
apply iff_eq.
move=> [[xt p1] p2].
split=>//; split.
by move=> a afs; apply p1; aw; ex_tac; graph_tac.
move=> z zt sh; apply p2; ee.
by move=> y; aw; move => [u [usf JG]]; rewrite -(W_pr ff JG); apply sh.
move=> [xt [p1 p2]]; split.
split=>//.
by move=> y; aw; move=> [u [usf JG]]; rewrite -(W_pr ff JG); apply p1.
move=> z [ztg p3].
apply p2=>//; move=> a asf; apply p3; aw; ex_tac; graph_tac.
Qed.
Lemma is_inf_fun_pr: forall r f x, order r -> substrate r = target f ->
is_function f ->
is_inf_fun r f x
= (inc x (target f)
& (forall a, inc a (source f) -> gle r x (W a f))
& forall z, inc z (target f) -> (forall a, inc a (source f)
-> gle r z (W a f)) -> gle r z x).
Proof.
move=> r f x or sr ff.
have si: sub (image_of_fun f) (substrate r).
by rewrite sr; apply sub_image_target.
rewrite /is_inf_fun; aw.
rewrite /lower_bound sr /image_of_fun.
have gf: is_graph (graph f) by fprops.
apply iff_eq.
move=> [[xt p1] p2].
split=>//; split.
by move=> a afs; apply p1; aw; ex_tac; graph_tac.
move=> z zt sh; apply p2; ee.
by move=> y; aw; move => [u [usf JG]]; rewrite -(W_pr ff JG); apply sh.
move=> [xt [p1 p2]]; split.
split=>//.
by move=> y; aw; move=> [u [usf JG]]; rewrite -(W_pr ff JG); apply p1.
move=> z [ztg p3].
apply p2=>//; move=> a asf; apply p3; aw; ex_tac; graph_tac.
Qed.
Supremum and infinum of the range of a functional graph
Definition is_sup_graph r f x := least_upper_bound r (range f) x.
Definition is_inf_graph r f x := greatest_lower_bound r (range f) x.
Definition has_sup_graph r f := has_supremum r (range f).
Definition has_inf_graph r f := has_infimum r (range f).
Definition sup_graph r f:= supremum r (range f).
Definition inf_graph r f := infimum r (range f).
Lemma is_sup_graph_pr1: forall r f,
order r -> sub (range f) (substrate r) -> has_sup_graph r f ->
least_upper_bound r (range f) (sup_graph r f).
Proof.
rewrite /has_sup_graph/sup_graph/is_sup_graph=> r f or sr hs. fprops.
Qed.
Lemma is_inf_graph_pr1: forall r f,
order r -> sub (range f) (substrate r) -> has_inf_graph r f ->
greatest_lower_bound r (range f) (inf_graph r f).
Proof. rewrite /has_inf_graph/inf_graph/is_inf_graph; fprops.
Qed.
Lemma is_sup_graph_pr: forall r f x, order r -> sub (range f) (substrate r) ->
fgraph f ->
is_sup_graph r f x = (inc x (substrate r)
& (forall a, inc a (domain f) -> gle r (V a f) x)
& forall z, inc z (substrate r) -> (forall a, inc a (domain f)
-> gle r (V a f) z) -> gle r x z).
Proof.
move=> r f x or sr fg.
rewrite /is_sup_graph; aw; rewrite /upper_bound.
have gf: is_graph f by fprops.
apply iff_eq.
move=> [[xs p1] p2]; split=>//.
split; first by move=> a ad; apply p1; fprops.
move=> z zs p; apply p2.
split=>//.
move=> y; dw; move=> [t Jg]; move: (pr2_V fg Jg); aw; move=> ->;
by apply p; ex_tac.
move=> [xs [p1 p2]]; split.
split=>//; move=> y; dw; move=> [z Jg]; move: (pr2_V fg Jg); aw.
move=> ->; apply p1; aw; ex_tac.
move=> z [zr p3]; apply p2 =>//; move=> a ad; apply p3; fprops.
Qed.
Lemma is_inf_graph_pr: forall r f x, order r -> sub (range f) (substrate r) ->
fgraph f ->
is_inf_graph r f x = (inc x (substrate r)
& (forall a, inc a (domain f) -> gle r x (V a f))
& forall z, inc z (substrate r) -> (forall a, inc a (domain f)
-> gle r z (V a f)) -> gle r z x).
Proof.
move=> r f x or sr fg.
rewrite /is_inf_graph; aw; rewrite /lower_bound.
have gf: is_graph f by fprops.
apply iff_eq.
move=> [[xs p1] p2]; split=>//.
split; first by move=> a ad; apply p1; fprops.
move=> z zs p; apply p2.
split=>//.
move=> y; dw; move=> [t Jg]; move: (pr2_V fg Jg); aw; move=> ->;
by apply p; ex_tac.
move=> [xs [p1 p2]]; split.
split=>//; move=> y; dw; move=> [z Jg]; move: (pr2_V fg Jg); aw.
move=> ->; apply p1; aw; ex_tac.
move=> z [zr p3]; apply p2 =>//; move=> a ad; apply p3; fprops.
Qed.
Theorem compare_inf_sup1: forall r A, order r -> sub A (substrate r) ->
has_supremum r A -> has_infimum r A ->
A = emptyset ->
(greatest_element r (infimum r A) & least_element r (supremum r A)).
Proof.
move=> r A or As hs hi Ae.
move: (supremum_pr1 hs)(infimum_pr1 hi).
rewrite Ae greatest_lower_bound_emptyset // least_upper_bound_emptyset //.
Qed.
Theorem compare_inf_sup2: forall r A, order r -> sub A (substrate r) ->
has_supremum r A -> has_infimum r A ->
nonempty A -> gle r (infimum r A) (supremum r A).
Proof.
move=> r A or As hs hi [x xA].
move: (supremum_pr1 hs)(infimum_pr1 hi).
aw; move=> [[uE p1] _ ] [[vE p2] _].
move: (p1 _ xA)(p2 _ xA)=> q1 q2.
order_tac.
Qed.
Theorem sup_increasing: forall r A B, order r -> sub A (substrate r) ->
sub B (substrate r) -> sub A B ->
has_supremum r A -> has_supremum r B->
gle r (supremum r A) (supremum r B).
Proof.
move=> r A B or As Bs AB sA sB.
move: (supremum_pr1 sA) (supremum_pr1 sB); aw; move=> [uA p1][uB p2].
have aux:(upper_bound r A (supremum r B)).
red; red in uB; ee.
by apply p1.
Qed.
Theorem inf_decreasing: forall r A B, order r -> sub A (substrate r) ->
sub B (substrate r) -> sub A B ->
has_infimum r A -> has_infimum r B ->
gge r (infimum r A) (infimum r B).
Proof.
move=> r A B or As Bs AB sA sB.
move: (infimum_pr1 sA) (infimum_pr1 sB); aw; move=> [uA p1][uB p2].
have aux:(lower_bound r A (infimum r B)).
red; red in uB; ee.
by apply p1.
Qed.
Lemma sup_increasing1: forall r f j,
order r -> fgraph f -> sub (range f) (substrate r) -> sub j (domain f) ->
has_sup_graph r f ->
has_sup_graph r (restr f j) ->
gle r (sup_graph r (restr f j)) (sup_graph r f).
Proof.
rewrite /has_sup_graph/is_sup_graph/sup_graph => r f j or fg sr sj hs1 hs2.
have gr: is_graph (restr f j) by move:(restr_fgraph j fg)=>[h _].
have srr: sub (range (restr f j)) (range f).
move=> t; dw; fprops; move=> [x Jg]; move:(restr_sub Jg)=> h; ex_tac.
apply sup_increasing=>//.
by apply sub_trans with (range f).
Qed.
Lemma inf_decreasing1: forall r f j,
order r -> fgraph f -> sub (range f) (substrate r) -> sub j (domain f) ->
has_inf_graph r f -> has_inf_graph r (restr f j) ->
gge r (inf_graph r (restr f j)) (inf_graph r f).
Proof.
rewrite /has_inf_graph/is_inf_graph/inf_graph => r f j or fg sr sj hs1 hs2.
have gr: is_graph (restr f j) by move:(restr_fgraph j fg)=>[h _].
have srr: sub (range (restr f j)) (range f).
move=> t; dw; fprops; move=> [x Jg]; move:(restr_sub Jg)=> h; ex_tac.
apply inf_decreasing=>//.
by apply sub_trans with (range f).
Qed.
Lemma sup_increasing2: forall r f f',
order r -> fgraph f -> fgraph f' -> domain f = domain f' ->
sub (range f) (substrate r) -> sub (range f') (substrate r) ->
has_sup_graph r f -> has_sup_graph r f'->
(forall x , inc x (domain f) -> gle r (V x f) (V x f')) ->
gle r (sup_graph r f) (sup_graph r f').
Proof.
move=> r f f' or gf gf' df sr sr' hs hs' ale.
move: (is_sup_graph_pr1 or sr hs)(is_sup_graph_pr1 or sr' hs').
move: (is_sup_graph_pr (sup_graph r f) or sr gf).
move:(is_sup_graph_pr (sup_graph r f') or sr' gf').
rewrite /is_sup_graph. move=> -> ->.
move=> [sgr [p1 p2]][sgr' [p1' p2']].
apply p2=>//.
move=> a ad.
apply order_transitivity with (V a f')=>//; [apply ale=>//|apply p1']; ue.
Qed.
Lemma inf_increasing2: forall r f f',
order r -> fgraph f -> fgraph f' -> domain f = domain f' ->
sub (range f) (substrate r) -> sub (range f') (substrate r) ->
has_inf_graph r f ->
has_inf_graph r f'->
(forall x , inc x (domain f) -> gle r (V x f) (V x f')) ->
gle r (inf_graph r f) (inf_graph r f').
Proof.
move=> r f f' or gf gf' df sr sr' hs hs' ale.
move: (is_inf_graph_pr1 or sr hs)(is_inf_graph_pr1 or sr' hs').
move: (is_inf_graph_pr (inf_graph r f) or sr gf).
move:(is_inf_graph_pr (inf_graph r f') or sr' gf').
rewrite /is_inf_graph. move=> -> ->.
move=> [sgr [p1 p2]][sgr' [p1' p2']].
apply p2'=>//.
move=> a ad.
apply order_transitivity with (V a f)=>//;[apply p1 | apply ale=>//]; ue.
Qed.
Associativity of sup and inf
Lemma sup_distributive: forall r f c x,
order r -> fgraph f -> sub (range f) (substrate r) ->
covering c (domain f) ->
(forall l, inc l (domain c) -> has_sup_graph r (restr f (V l c))) ->
is_sup_graph r f x =
is_sup_graph r (L (domain c) (fun l => sup_graph r (restr f (V l c)))) x.
Proof.
move=> r f c x or gf sr [fcc sdu] alsup.
have grf: is_graph f by fprops.
have fgr: forall a, fgraph (restr f (V a c)) by move=> a; fprops.
have grr: forall a, is_graph (restr f (V a c)).
by move=> a; move: (fgr a); fprops.
set g:= L _ _.
have fgg:fgraph g by rewrite /g; gprops.
have ranr: forall a, (sub (range (restr f (V a c))) (substrate r)).
move=> a t; dw;move=> [z zr]; apply sr; move:(restr_sub zr)=> h; ex_tac.
have srh: (sub (range g) (substrate r)).
move=> t. rewrite /g; bw. move=> [b [bd st]].
move: (is_sup_graph_pr1 or (ranr b) (alsup _ bd)).
by rewrite st; aw; move=> [[? _] _].
rewrite is_sup_graph_pr //is_sup_graph_pr // /g; bw.
apply iff_eq; move=> [xsr [p1 p2]]; split=>//.
split.
move=> a adc; bw.
move: (is_sup_graph_pr1 or (ranr a) (alsup _ adc)).
rewrite least_upper_bound_pr //; move=> [_ ]; apply.
split=>//; move=>y; dw; move=> [z];rewrite restr_inc_rw.
aw; move=> [Jf zV]; move: (in_graph_V gf Jf); aw=> aux.
by rewrite (pr2_def aux); apply p1; ex_tac.
move=> z zr hyp.
apply p2 =>//; move=> a ad.
move: (sdu _ ad); srw; move=> [y [yd aV]].
apply order_transitivity with (sup_graph r (restr f (V y c)))=>//.
move: (is_sup_graph_pr1 or (ranr y) (alsup _ yd)).
rewrite least_upper_bound_pr //; move=> [[ _ p] _]; apply p.
srw; rewrite restr_domain //; exists a.
split; [ apply intersection2_inc=>// | rewrite restr_ev1 //].
by move: (hyp _ yd); bw.
split.
move=> a ad; move: (sdu _ ad); srw; move=> [y [yd aV]].
move: (p1 _ yd); bw=> aux.
apply order_transitivity with (sup_graph r (restr f (V y c)))=> //.
move: (is_sup_graph_pr1 or (ranr y) (alsup _ yd)).
rewrite least_upper_bound_pr //.
move=> [[_ p] _]; apply p; srw; exists a.
by rewrite restr_domain //;split;[ apply intersection2_inc| rewrite restr_ev1].
move=> z zr h; apply p2 =>//.
move=> a ad; bw.
move: (is_sup_graph_pr1 or (ranr a) (alsup _ ad)).
rewrite least_upper_bound_pr //; move=> [_ p]; apply p.
split=>// y; dw; move=> [t]; rewrite restr_inc_rw //.
aw;move=> [Jf tV];move: (in_graph_V gf Jf); aw.
move=> h1; rewrite (pr2_def h1).
apply h; ex_tac.
Qed.
Lemma inf_distributive: forall r f c x,
order r -> fgraph f -> sub (range f) (substrate r) ->
covering c (domain f) ->
(forall l, inc l (domain c) -> has_inf_graph r (restr f (V l c))) ->
is_inf_graph r f x =
is_inf_graph r (L (domain c) (fun l => inf_graph r (restr f (V l c)))) x.
Proof.
move=> r f c x or gf sr [fcc sdu] alinf.
have grf: is_graph f by fprops.
have fgr: forall a, fgraph (restr f (V a c)) by move=> a; fprops.
have grr: forall a, is_graph (restr f (V a c)).
by move=> a; move: (fgr a); fprops.
set g:= L _ _.
have fgg:fgraph g by rewrite /g; gprops.
have ranr: forall a, (sub (range (restr f (V a c))) (substrate r)).
move=> a t; dw;move=> [z zr]; apply sr; move:(restr_sub zr)=> h; ex_tac.
have srh: (sub (range g) (substrate r)).
move=> t. rewrite /g; bw. move=> [b [bd st]].
move: (is_inf_graph_pr1 or (ranr b) (alinf _ bd)).
by rewrite st; aw; move=> [[? _] _].
rewrite is_inf_graph_pr //is_inf_graph_pr // /g; bw.
apply iff_eq; move=> [xsr [p1 p2]]; split=>//.
split.
move=> a adc; bw.
move: (is_inf_graph_pr1 or (ranr a) (alinf _ adc)).
rewrite greatest_lower_bound_pr //; move=> [_ ]; apply.
split=>//; move=>y; dw; move=> [z];rewrite restr_inc_rw.
aw; move=> [Jf zV]; move: (in_graph_V gf Jf); aw=> aux.
by rewrite (pr2_def aux); apply p1; ex_tac.
move=> z zr hyp.
apply p2 =>//; move=> a ad.
move: (sdu _ ad); srw; move=> [y [yd aV]].
apply order_transitivity with (inf_graph r (restr f (V y c)))=>//.
by move: (hyp _ yd); bw.
move: (is_inf_graph_pr1 or (ranr y) (alinf _ yd)).
rewrite greatest_lower_bound_pr //; move=> [[ _ p] _]; apply p.
srw; rewrite restr_domain //; exists a.
split; [ apply intersection2_inc=>// | rewrite restr_ev1 //].
split.
move=> a ad; move: (sdu _ ad); srw; move=> [y [yd aV]].
move: (p1 _ yd); bw=> aux.
apply order_transitivity with (inf_graph r (restr f (V y c)))=> //.
move: (is_inf_graph_pr1 or (ranr y) (alinf _ yd)).
rewrite greatest_lower_bound_pr //.
move=> [[_ p] _]; apply p; srw; exists a.
by rewrite restr_domain //;split;[ apply intersection2_inc| rewrite restr_ev1].
move=> z zr h; apply p2 =>//.
move=> a ad; bw.
move: (is_inf_graph_pr1 or (ranr a) (alinf _ ad)).
rewrite greatest_lower_bound_pr //; move=> [_ p]; apply p.
split=>// y; dw; move=> [t]; rewrite restr_inc_rw //.
aw;move=> [Jf tV];move: (in_graph_V gf Jf); aw.
move=> h1; rewrite (pr2_def h1).
apply h; ex_tac.
Qed.
Lemma sup_distributive1: forall r f c,
order r -> fgraph f -> sub (range f) (substrate r) ->
covering c (domain f) ->
(forall l, inc l (domain c) -> has_sup_graph r (restr f (V l c))) ->
has_sup_graph r f =
has_sup_graph r (L (domain c) (fun l => sup_graph r (restr f (V l c)))) .
Proof.
move=> r f c or ff sr co alsup.
apply iff_eq; move=> [x xs];
move: (sup_distributive x or ff sr co alsup);
rewrite /is_sup_graph; exists x; ue.
Qed.
Lemma inf_distributive1: forall r f c,
order r -> fgraph f -> sub (range f) (substrate r) ->
covering c (domain f) ->
(forall l, inc l (domain c) -> has_inf_graph r (restr f (V l c))) ->
has_inf_graph r f =
has_inf_graph r (L (domain c) (fun l => inf_graph r (restr f (V l c)))) .
Proof.
move=> r f c or ff sr co alsup.
apply iff_eq; move=> [x xs];
move: (inf_distributive x or ff sr co alsup);
rewrite /is_inf_graph; exists x; ue.
Qed.
Theorem sup_distributive2: forall r f c,
order r -> fgraph f -> sub (range f) (substrate r) ->
covering c (domain f) ->
(forall l, inc l (domain c) -> has_sup_graph r (restr f (V l c))) ->
((has_sup_graph r f =
has_sup_graph r (L (domain c) (fun l => sup_graph r (restr f (V l c))))) &
(has_sup_graph r f -> sup_graph r f =
sup_graph r (L (domain c) (fun l => sup_graph r (restr f (V l c)))))).
Proof.
move=> r f c or fgf sr co alsup.
split; first by apply sup_distributive1=>//.
move=> hyp; rewrite /sup_graph.
set (g:= L (domain c) (fun l => sup_graph r (restr f (V l c)))).
move: (is_sup_graph_pr1 or sr hyp)=> lu.
have lu': (least_upper_bound r (range f) (supremum r (range f))).
by apply supremum_pr1.
move: (sup_distributive (sup_graph r f) or fgf sr co alsup).
rewrite /is_sup_graph -/g => aux.
have lug: least_upper_bound r (range g) (sup_graph r f).
by rewrite -aux.
clear aux.
set (x:= sup_graph r f) in *.
rewrite -(supremum_unique or lu lu').
have lug': least_upper_bound r (range g) (supremum r (range g)).
by apply supremum_pr1; exists x.
by rewrite -(supremum_unique or lug lug').
Qed.
Theorem inf_distributive2: forall r f c,
order r -> fgraph f -> sub (range f) (substrate r) ->
covering c (domain f) ->
(forall l, inc l (domain c) -> has_inf_graph r (restr f (V l c))) ->
((has_inf_graph r f =
has_inf_graph r (L (domain c) (fun l => inf_graph r (restr f (V l c))))) &
(has_inf_graph r f -> inf_graph r f =
inf_graph r (L (domain c) (fun l => inf_graph r (restr f (V l c)))))).
Proof.
move=> r f c or fgf sr co alsup.
split; first by apply inf_distributive1=>//.
move=> hyp; rewrite /inf_graph.
set (g:= L (domain c) (fun l => inf_graph r (restr f (V l c)))).
move: (is_inf_graph_pr1 or sr hyp)=> lu.
have lu': (greatest_lower_bound r (range f) (infimum r (range f))).
by apply infimum_pr1.
move: (inf_distributive (inf_graph r f) or fgf sr co alsup).
rewrite /is_inf_graph -/g => aux.
have lug: greatest_lower_bound r (range g) (inf_graph r f).
by rewrite -aux.
clear aux.
set (x:= inf_graph r f) in *.
rewrite -(infimum_unique or lu lu').
have lug': greatest_lower_bound r (range g) (infimum r (range g)).
by apply infimum_pr1; exists x.
by rewrite -(infimum_unique or lug lug').
Qed.
Definition partial_fun f x m := restr f (product x (singleton m)).
Lemma sup_distributive3: forall r f x y,
order r -> fgraph f -> sub (range f) (substrate r) ->
domain f = product x y ->
(forall m, inc m y -> has_sup_graph r (partial_fun f x m)) ->
((has_sup_graph r f =
has_sup_graph r (L y (fun m => sup_graph r (partial_fun f x m)))) &
(has_sup_graph r f -> sup_graph r f =
sup_graph r (L y (fun m => sup_graph r (partial_fun f x m))))).
Proof.
move=> r f x y or fgf sr df alsup.
set (c:= L y (fun m => product x (singleton m))).
have co: covering c (domain f).
split; first by rewrite /c; gprops.
rewrite /c df=> t; aw; move=> [pt [Px Qy]].
by apply unionb_inc with (Q t); bw; apply product_inc; fprops.
have dc: y = domain c by rewrite /c; bw.
have pfx: forall m, inc m y -> partial_fun f x m = restr f (V m c).
move=> m my; rewrite /partial_fun /c; bw.
have hsg: forall l, inc l (domain c) -> has_sup_graph r (restr f (V l c)).
by move=> l; rewrite -dc=> ld; rewrite - pfx //;apply alsup.
have aux: ( L (domain c) (fun l => sup_graph r (restr f (V l c))) =
L y (fun m : Set => sup_graph r (partial_fun f x m))).
by rewrite -dc; apply L_exten1=>//; move=> t ty; rewrite pfx.
by rewrite - aux; apply sup_distributive2.
Qed.
Lemma inf_distributive3: forall r f x y,
order r -> fgraph f -> sub (range f) (substrate r) ->
domain f = product x y ->
(forall m, inc m y -> has_inf_graph r (partial_fun f x m)) ->
((has_inf_graph r f =
has_inf_graph r (L y (fun m => inf_graph r (partial_fun f x m)))) &
(has_inf_graph r f -> inf_graph r f =
inf_graph r (L y (fun m => inf_graph r (partial_fun f x m))))).
Proof.
move=> r f x y or fgf sr df alinf.
set (c:= L y (fun m => product x (singleton m))).
have co: covering c (domain f).
split; first by rewrite /c; gprops.
rewrite /c df=> t; aw; move=> [pt [Px Qy]].
by apply unionb_inc with (Q t); bw; apply product_inc; fprops.
have dc: y = domain c by rewrite /c; bw.
have pfx: forall m, inc m y -> partial_fun f x m = restr f (V m c).
move=> m my; rewrite /partial_fun /c; bw.
have hsg: forall l, inc l (domain c) -> has_inf_graph r (restr f (V l c)).
by move=> l; rewrite -dc=> ld; rewrite - pfx //;apply alinf.
have aux: ( L (domain c) (fun l => inf_graph r (restr f (V l c))) =
L y (fun m : Set => inf_graph r (partial_fun f x m))).
by rewrite -dc; apply L_exten1=>//; move=> t ty; rewrite pfx.
by rewrite - aux; apply inf_distributive2.
Qed.
Theorem sup_in_product: forall g A,
let f := fam_of_substrates g in
let Ai:= fun i => (image_by_fun (pr_i f i) A) in
let has_sup :=
forall i, inc i (domain g) -> has_supremum (V i g) (Ai i) in
product_order_axioms g -> sub A (productb f) ->
((has_sup = has_supremum (product_order g) A) &
(has_sup -> supremum (product_order g) A =
L (domain g) (fun i => supremum (V i g) (Ai i)))).
Proof.
move=> g A f Ai hs po Ab.
move: (po)=> [fg allo].
have fgf: fgraph f by rewrite /f/fam_of_substrates; gprops.
have df: domain f = domain g by rewrite /f/fam_of_substrates; bw.
have als: forall i, inc i (domain g) -> substrate (V i g) = V i f.
by move=> i id; rewrite /f/fam_of_substrates; bw.
have Asi: forall i, inc i (domain g) -> sub A (source (pr_i f i)).
by move=> i idg; rewrite /pr_i; aw.
have Ais: forall i, inc i (domain g) -> sub (Ai i) (substrate (V i g)).
move=> i id; rewrite als /Ai //.
have fp: is_function (pr_i f i) by apply pri_function =>//; ue.
move: (Asi _ id) =>As.
move=> t; aw; move=> [u [uA]] <-.
have us:inc u (source (pr_i f i)) by apply As.
have ->: (V i f = target (pr_i f i)) by rewrite /pr_i; aw.
apply inc_W_target=>//.
have p1: (hs -> (forall i, inc i (domain g) ->
least_upper_bound (V i g) (Ai i) (supremum (V i g) (Ai i)))).
move => hts i idg; apply supremum_pr1.
apply hts =>//.
set (mysup:=L (domain g) (fun i : Set => supremum (V i g) (Ai i))).
have opg: order (product_order g) by apply product_order_order.
have hlu: hs -> least_upper_bound (product_order g) A mysup.
move=> hst.
have mp: inc mysup (productb f).
rewrite /mysup;aw; split; first by gprops.
bw; split; first by ue.
move=> i idg; bw.
rewrite -als //; apply inc_supremum_substrate.
by apply allo.
by apply Ais.
by apply hst.
aw;split.
split; first by rewrite product_order_substrate.
move=> y yA; rewrite product_order_related //.
split; first by apply Ab.
split=>//; move=> i idg; rewrite /mysup; bw.
move: (supremum_pr (allo _ idg) (Ais _ idg) (hst _ idg)).
move=> [[_ h]_]; apply h.
rewrite /Ai; aw;try (apply (Asi _ idg)); try (apply pri_function=>//; ue).
by ex_tac; rewrite -df in idg; rewrite (pri_W fgf idg (Ab _ yA)).
move=> z [zs zp]; rewrite product_order_related //.
split=>//.
split; first by rewrite product_order_substrate in zs.
move=> i idg.
have fi: is_function (pr_i f i) by apply pri_function=>//; ue.
move: (supremum_pr (allo _ idg) (Ais _ idg) (hst _ idg)).
rewrite /mysup; bw; move=> [_ h]; apply h.
split; first by move: zs; aw; move=> [_ [_]]; apply.
move: (Asi _ idg) => As.
move=> y; rewrite /Ai; aw; move=> [u [uA]] <-.
rewrite -df in idg; rewrite (pri_W fgf idg (Ab _ uA)).
by move: (zp _ uA); bw; move=> [_[_]]; apply; ue.
have hsu: hs -> has_supremum (product_order g) A.
by move=> hst; exists mysup; apply hlu.
have g2: hs-> supremum (product_order g) A = mysup.
move => hst; move:(hlu hst) => s1; move:( supremum_pr1 (hsu hst)) => s2.
by apply (supremum_unique opg s2 s1).
split=>//.
apply iff_eq =>//.
have sAs: sub A (substrate (product_order g)) by aw.
move=> [x]; rewrite least_upper_bound_pr //; move => [[xs ub] lub].
move=> i idg.
move: (allo _ idg) => p2; move: (Ais _ idg)=> p3; move: (Asi _ idg)=> p4.
have fi: is_function (pr_i f i) by apply pri_function=>//; ue.
exists (V i x); rewrite least_upper_bound_pr//.
move: xs; aw;move=> [fgx [dx iVs]].
split.
split; first by apply iVs.
rewrite /Ai; move=> y; aw ; move=> [u [uA]] <-.
rewrite -df in idg; rewrite (pri_W fgf idg (Ab _ uA)).
by move: (ub _ uA); bw; move=> [_[_]]; apply; ue.
move=> z [zs h4].
set (y:= L (domain g) (fun j=> Yo(j = i) z (V j x))).
have ->: (z = V i y) by rewrite /y; bw; Ytac0.
have yp: inc y (productb f).
aw; rewrite /y; ee; bw; try ue.
move=> k kd; bw; rewrite -als//; Ytac ki; first by rewrite ki; apply zs.
by apply iVs.
have aux: (upper_bound (product_order g) A y).
split; first by rewrite product_order_substrate.
move=> t tA; bw; ee.
move => k kd; rewrite /y; bw.
move: (ub _ tA); bw; move=> [_[_ h5]]; Ytac ki; last by apply h5.
rewrite ki; apply h4.
rewrite / Ai; aw; ex_tac.
by rewrite -df in idg; rewrite (pri_W fgf idg (Ab _ tA)).
by move: (lub _ aux); bw; move=> [_[_]]; apply.
Qed.
Theorem inf_in_product: forall g A,
let f := fam_of_substrates g in
let Ai:= fun i => (image_by_fun (pr_i f i) A) in
let has_inf :=
forall i, inc i (domain g) -> has_infimum (V i g) (Ai i) in
product_order_axioms g -> sub A (productb f) ->
((has_inf = has_infimum (product_order g) A) &
(has_inf -> infimum (product_order g) A =
L (domain g) (fun i => infimum (V i g) (Ai i)))).
Proof.
move=> g A f Ai hs po Ab.
move: (po)=> [fg allo].
have fgf: fgraph f by rewrite /f/fam_of_substrates; gprops.
have df: domain f = domain g by rewrite /f/fam_of_substrates; bw.
have als: forall i, inc i (domain g) -> substrate (V i g) = V i f.
by move=> i id; rewrite /f/fam_of_substrates; bw.
have Asi: forall i, inc i (domain g) -> sub A (source (pr_i f i)).
by move=> i idg; rewrite /pr_i; aw.
have Ais: forall i, inc i (domain g) -> sub (Ai i) (substrate (V i g)).
move=> i id; rewrite als /Ai //.
have fp: is_function (pr_i f i) by apply pri_function =>//; ue.
move: (Asi _ id) =>As.
move=> t; aw; move=> [u [uA]] <-.
have us:inc u (source (pr_i f i)) by apply As.
have ->: (V i f = target (pr_i f i)) by rewrite /pr_i; aw.
apply inc_W_target=>//.
have p1: (hs -> (forall i, inc i (domain g) ->
greatest_lower_bound (V i g) (Ai i) (infimum (V i g) (Ai i)))).
move => hts i idg; apply infimum_pr1.
apply hts =>//.
set (mysup:=L (domain g) (fun i : Set => infimum (V i g) (Ai i))).
have opg: order (product_order g) by apply product_order_order.
have hlu: hs -> greatest_lower_bound (product_order g) A mysup.
move=> hst.
have mp: inc mysup (productb f).
rewrite /mysup;aw; split; first by gprops.
bw; split; first by ue.
move=> i idg; bw.
rewrite -als //; apply inc_infimum_substrate.
by apply allo.
by apply Ais.
by apply hst.
aw;split.
split; first by rewrite product_order_substrate.
move=> y yA; rewrite product_order_related //.
split=>//;split; first by apply Ab.
move=> i idg; rewrite /mysup; bw.
move: (infimum_pr (allo _ idg) (Ais _ idg) (hst _ idg)).
move=> [[_ h]_]; apply h.
rewrite /Ai; aw;try (apply (Asi _ idg)); try (apply pri_function=>//; ue).
by ex_tac; rewrite -df in idg; rewrite (pri_W fgf idg (Ab _ yA)).
move=> z [zs zp]; rewrite product_order_related //.
split; first by rewrite product_order_substrate in zs.
split=>//.
move=> i idg.
have fi: is_function (pr_i f i) by apply pri_function=>//; ue.
move: (infimum_pr (allo _ idg) (Ais _ idg) (hst _ idg)).
rewrite /mysup; bw; move=> [_ h]; apply h.
split; first by move: zs; aw; move=> [_ [_]]; apply.
move: (Asi _ idg) => As.
move=> y; rewrite /Ai; aw; move=> [u [uA]] <-.
rewrite -df in idg; rewrite (pri_W fgf idg (Ab _ uA)).
by move: (zp _ uA); bw; move=> [_[_]]; apply; ue.
have hsu: hs -> has_infimum (product_order g) A.
by move=> hst; exists mysup; apply hlu.
have g2: hs-> infimum (product_order g) A = mysup.
move => hst; move:(hlu hst) => s1; move:(infimum_pr1 (hsu hst)) => s2.
by apply (infimum_unique opg s2 s1).
split=>//.
apply iff_eq =>//.
have sAs: sub A (substrate (product_order g)) by aw.
move=> [x]; rewrite greatest_lower_bound_pr //; move => [[xs ub] lub].
move=> i idg.
move: (allo _ idg) => p2; move: (Ais _ idg)=> p3; move: (Asi _ idg)=> p4.
have fi: is_function (pr_i f i) by apply pri_function=>//; ue.
exists (V i x); rewrite greatest_lower_bound_pr//.
move: xs; aw;move=> [fgx [dx iVs]].
split.
split; first by apply iVs.
rewrite /Ai; move=> y; aw ; move=> [u [uA]] <-.
rewrite -df in idg; rewrite (pri_W fgf idg (Ab _ uA)).
by move: (ub _ uA); bw; move=> [_[_]]; apply; ue.
move=> z [zs h4].
set (y:= L (domain g) (fun j=> Yo(j = i) z (V j x))).
have ->: (z = V i y) by rewrite /y; bw; Ytac0.
have yp: inc y (productb f).
aw; rewrite /y; ee; bw; try ue.
move=> k kd; bw; rewrite -als//; Ytac ki; last by apply iVs.
by rewrite ki;apply zs.
have aux: (lower_bound (product_order g) A y).
split; first by rewrite product_order_substrate.
move=> t tA; bw; ee.
move => k kd; rewrite /y; bw.
move: (ub _ tA); bw; move=> [_[_ h5]]; Ytac ki; last by apply h5.
rewrite ki; apply h4; rewrite / Ai; aw; ex_tac.
by rewrite -df in idg; rewrite (pri_W fgf idg (Ab _ tA)).
by move: (lub _ aux); bw; move=> [_[_]]; apply.
Qed.
Theorem sup_induced1: forall r A F, order r -> sub F (substrate r) -> sub A F ->
has_supremum r A -> has_supremum (induced_order r F) A ->
gle r (supremum r A) (supremum (induced_order r F) A).
Proof.
move=> r A F or Fs AF sA siA.
have oi: order (induced_order r F) by fprops.
have As:sub A (substrate r) by apply sub_trans with F.
have Asi: sub A (substrate (induced_order r F)) by aw.
move: (supremum_pr1 sA) (supremum_pr1 siA).
set (u:= supremum r A).
set (v:=supremum (induced_order r F) A).
aw; move=> [ub lub][[us ubi] lubi]; apply lub.
move: us; aw => vF.
split; first by apply Fs.
by move=> y yA; move: (ubi _ yA); aw; apply AF.
Qed.
Theorem inf_induced1: forall r A F, order r -> sub F (substrate r) -> sub A F ->
has_infimum r A -> has_infimum (induced_order r F) A ->
gge r (infimum r A) (infimum (induced_order r F) A).
Proof.
move=> r A F or Fs AF sA siA.
have oi: order (induced_order r F) by fprops.
have As:sub A (substrate r) by apply sub_trans with F.
have Asi: sub A (substrate (induced_order r F)) by aw.
move: (infimum_pr1 sA) (infimum_pr1 siA).
set (u:= infimum r A).
set (v:=infimum (induced_order r F) A).
aw; move=> [ub lub][[us ubi] lubi]; apply lub.
move: us; aw => vF.
split; first by apply Fs.
by move=> y yA; move: (ubi _ yA); aw; apply AF.
Qed.
Theorem sup_induced2: forall r A F, order r -> sub F (substrate r) -> sub A F ->
has_supremum r A -> inc (supremum r A) F ->
(has_supremum (induced_order r F) A &
supremum r A = supremum (induced_order r F) A).
Proof.
move=> r A F or Fs AF hsA sAF.
have oi: order (induced_order r F) by fprops.
have As: sub A (substrate r) by apply sub_trans with F.
have Asi:sub A (substrate (induced_order r F)) by aw.
move:(supremum_pr1 hsA).
set (u:= supremum r A).
move=> lub.
have lubi: least_upper_bound (induced_order r F) A u.
move: lub; aw; move=> [[us ub] lub].
split.
split; aw; move=> y yA; aw; [ by apply ub |by apply AF].
move=> z [zF];awi zF=>// zub.
aw;apply lub; split; first by apply Fs.
by move=> y yA; move: (zub _ yA); aw; apply AF.
have aux: has_supremum (induced_order r F) A by exists u.
move: (supremum_pr1 aux) =>lubi'.
split=>//;apply (supremum_unique oi lubi lubi').
Qed.
Theorem inf_induced2: forall r A F, order r -> sub F (substrate r) -> sub A F ->
has_infimum r A -> inc (infimum r A) F ->
(has_infimum (induced_order r F) A &
infimum r A = infimum (induced_order r F) A).
Proof.
move=> r A F or Fs AF hsA sAF.
have oi: order (induced_order r F) by fprops.
have As: sub A (substrate r) by apply sub_trans with F.
have Asi:sub A (substrate (induced_order r F)) by aw.
move:(infimum_pr1 hsA).
set (u:= infimum r A).
move=> lub.
have lubi: greatest_lower_bound (induced_order r F) A u.
move: lub; aw; move=> [[us ub] lub].
split.
split; aw; move=> y yA; aw; [ by apply ub |by apply AF].
move=> z [zF];awi zF=>// zub.
aw;apply lub; split; first by apply Fs.
by move=> y yA; move: (zub _ yA); aw; apply AF.
have aux: has_infimum (induced_order r F) A by exists u.
move: (infimum_pr1 aux) =>lubi'.
split=>//;apply (infimum_unique oi lubi lubi').
Qed.
Definition right_directed r :=
order r & forall x, forall y, inc x (substrate r) -> inc y (substrate r) ->
bounded_above r (doubleton x y).
Definition left_directed r :=
order r & forall x, forall y, inc x (substrate r) -> inc y (substrate r) ->
bounded_below r (doubleton x y).
Lemma right_directed_pr: forall r,
right_directed r = (order r &
forall x, forall y, inc x (substrate r) -> inc y (substrate r) -> exists z,
inc z (substrate r) & gle r x z & gle r y z).
Proof.
rewrite /right_directed=>r; apply iff_eq; move=> [or h]; split=>//.
move=> x y xs ys; move: (h _ _ xs ys).
move=> [t [ts tb]]; ex_tac.
move=> x y xs ys; move: (h _ _ xs ys).
move=> [z [zs [xz yz]]].
exists z; split =>//; move=> t td.
by case (doubleton_or td)=>->.
Qed.
Lemma left_directed_pr: forall r,
left_directed r = (order r &
forall x, forall y, inc x (substrate r) -> inc y (substrate r) -> exists z,
inc z (substrate r) & gle r z x & gle r z y).
Proof.
rewrite /left_directed=>r; apply iff_eq; move=> [or h]; split=>//.
move=> x y xs ys; move: (h _ _ xs ys).
move=> [t [ts tb]]; ex_tac.
move=> x y xs ys; move: (h _ _ xs ys).
move=> [z [zs [xz yz]]].
exists z; split =>//; move=> t td.
by case (doubleton_or td)=>->.
Qed.
Lemma greatest_right_directed : forall r, order r ->
(exists a, greatest_element r a ) -> right_directed r.
Proof.
move=> r or [a [asr ga]]; rewrite right_directed_pr.
split =>//; move=> x y xr yr; exists a; ee.
Qed.
Lemma least_left_directed : forall r, order r ->
(exists a, least_element r a ) -> left_directed r.
Proof.
move=> r or [a [asr ga]]; rewrite left_directed_pr.
split =>//; move=> x y xr yr; exists a; ee.
Qed.
Lemma opposite_right_directed : forall r, is_graph r ->
right_directed r = left_directed(opposite_order r).
Proof.
move=> r gr.
rewrite right_directed_pr left_directed_pr.
apply iff_eq; move=> [or hyp].
have ooi: order (opposite_order r) by fprops.
split=>//.
aw; move => x y xs ys.
by move: (hyp _ _ xs ys)=> [z [zs [xz yz]]]; ex_tac; aw; split.
have: order (opposite_order (opposite_order r)) by fprops.
rewrite /opposite_order inverse_graph_involutive// => odr.
split=>//; move => x y xs ys.
awi hyp =>//.
by move: (hyp _ _ xs ys) => [z]; aw; move=>[zs [xz yz]]; ex_tac; split.
Qed.
Lemma opposite_left_directed : forall r, is_graph r ->
left_directed r = right_directed(opposite_order r).
Proof.
move=> r gr; symmetry.
have go: is_graph (opposite_order r) by fprops.
rewrite opposite_right_directed //.
rewrite /opposite_order; rewrite inverse_graph_involutive //.
Qed.
Lemma product_right_directed: forall g,
product_order_axioms g ->
(forall i, inc i (domain g) -> right_directed (V i g))
-> right_directed (product_order g).
Proof.
move=> g pa; rewrite right_directed_pr => alri.
split; first by fprops.
move=> x y xs ys.
set (z:= L (domain g)(fun i => choose (fun w =>
upper_bound (V i g) (doubleton (V i x) (V i y)) w))).
have alu: (forall i, inc i (domain g) ->
upper_bound (V i g) (doubleton (V i x) (V i y)) (V i z)).
move=> i idg; rewrite /z; bw.
move: xs ys;aw; move=>[_[_ p1]] [_[_ p2]]; move:(p1 _ idg)(p2 _ idg)=> p3 p4.
move: (alri _ idg)=> [t h]; move: (h _ _ p3 p4)=> [b bii].
by apply choose_pr; exists b.
have zs:inc z (substrate (product_order g)).
aw; split; first by rewrite/z; gprops.
split; first by rewrite/z; bw.
by move => i idg; move: (alu _ idg); move=> [us ub]; apply us.
ex_tac.
move: xs ys zs; rewrite product_order_substrate // => xs ys zs.
bw;ee.
move=> i idg; move: (alu _ idg); move=> [_ h]; apply h; fprops.
move=> i idg; move: (alu _ idg); move=> [_ h]; apply h; fprops.
Qed.
Lemma product_left_directed: forall g,
product_order_axioms g ->
(forall i, inc i (domain g) -> left_directed (V i g))
-> left_directed (product_order g).
Proof.
move=> g pa; rewrite left_directed_pr => alri.
split; first by fprops.
move=> x y xs ys.
set (z:= L (domain g)(fun i => choose (fun w =>
lower_bound (V i g) (doubleton (V i x) (V i y)) w))).
have alu: (forall i, inc i (domain g) ->
lower_bound (V i g) (doubleton (V i x) (V i y)) (V i z)).
move=> i idg; rewrite /z; bw.
move: xs ys;aw; move=>[_[_ p1]] [_[_ p2]]; move:(p1 _ idg)(p2 _ idg)=> p3 p4.
move: (alri _ idg)=> [t h]; move: (h _ _ p3 p4)=> [b bii].
by apply choose_pr; exists b.
have zs:inc z (substrate (product_order g)).
aw; split; first by rewrite/z; gprops.
split; first by rewrite/z; bw.
by move => i idg; move: (alu _ idg); move=> [us ub]; apply us.
ex_tac.
move: xs ys zs; rewrite product_order_substrate // => xs ys zs.
bw;ee.
move=> i idg; move: (alu _ idg); move=> [_ h]; apply h; fprops.
move=> i idg; move: (alu _ idg); move=> [_ h]; apply h; fprops.
Qed.
Lemma cofinal_right_directed: forall r A,
right_directed r -> cofinal_set r A -> right_directed (induced_order r A).
Proof.
move=> r A; rewrite 2! right_directed_pr; move=> [or rr] [As co].
split; first by fprops.
aw; move=> x y xA yA; move: (rr _ _ (As _ xA)(As _ yA))=> [z [zr [xz yz]]].
move:(co _ zr)=> [t [tA tz]].
by ex_tac; split; aw; apply order_transitivity with z =>//.
Qed.
Lemma coinitial_left_directed: forall r A,
left_directed r -> coinitial_set r A -> left_directed (induced_order r A).
Proof.
move=> r A; rewrite 2! left_directed_pr; move=> [or rr] [As co].
split; first by fprops.
aw; move=> x y xA yA; move: (rr _ _ (As _ xA)(As _ yA))=> [z [zr [xz yz]]].
move:(co _ zr)=> [t [tA tz]].
by ex_tac; split; aw; apply order_transitivity with z =>//.
Qed.
Theorem right_directed_maximal: forall r x,
right_directed r -> maximal_element r x -> greatest_element r x.
Proof.
move=> r x rr [xsr ma]; split=>//.
move=> t ts.
move: rr;rewrite right_directed_pr; move => [or rr].
move:(rr _ _ xsr ts) => [z [zr [xz tz]]].
by rewrite - (ma _ xz).
Qed.
Theorem left_directed_mimimal: forall r x,
left_directed r -> minimal_element r x -> least_element r x.
Proof.
move=> r x rr [xsr ma]; split=>//.
move=> t ts.
move: rr;rewrite left_directed_pr; move => [or rr].
move:(rr _ _ xsr ts) => [z [zr [xz tz]]].
by rewrite - (ma _ xz).
Qed.
Definition lattice r := order r &
forall x, forall y, inc x (substrate r) -> inc y (substrate r) ->
(has_supremum r (doubleton x y) & has_infimum r (doubleton x y)).
Lemma lattice_sup_pr: forall r a b,
lattice r -> inc a (substrate r) -> inc b (substrate r) ->
(gle r a (sup r a b) & gle r b (sup r a b) &
forall z, gle r a z -> gle r b z -> gle r (sup r a b) z).
Proof.
move=> r a b [or lr] asr bsr.
by move: (lr _ _ asr bsr)=> [p1 p2]; apply sup_pr.
Qed.
Lemma lattice_inf_pr: forall r a b,
lattice r -> inc a (substrate r) -> inc b (substrate r) ->
(gle r (inf r a b) a & gle r (inf r a b) b&
forall z, gle r z a -> gle r z b -> gle r z (inf r a b)).
Proof.
move=> r a b [or lr] asr bsr.
by move: (lr _ _ asr bsr)=> [p1 p2]; apply inf_pr.
Qed.
Lemma inf_inclusion: forall A x y, sub x A -> sub y A ->
greatest_lower_bound (inclusion_order A) (doubleton x y) (intersection2 x y).
Proof.
move=> A x y xA yA.
have sd: (sub (doubleton x y) (powerset A)) by apply sub_doubleton; aw.
move: (intersection_is_inf sd).
rewrite Y_if_rw //; apply nonempty_doubleton.
Qed.
Lemma sup_inclusion: forall A x y, sub x A -> sub y A ->
least_upper_bound (inclusion_order A) (doubleton x y) (union2 x y).
Proof.
move=> A x y xA yA.
have sd: (sub (doubleton x y) (powerset A)) by apply sub_doubleton; aw.
apply (union_is_sup sd).
Qed.
Lemma powerset_lattice: forall A, lattice (inclusion_order A).
Proof.
move=> A; split.
apply inclusion_is_order.
rewrite substrate_inclusion_order.
move=> x y; aw=> xp yp; split.
by exists (union2 x y); apply sup_inclusion.
by exists (intersection2 x y); apply inf_inclusion.
Qed.
Lemma product_lattice: forall g,
product_order_axioms g ->
(forall i, inc i (domain g) -> lattice (V i g))
-> lattice (product_order g).
Proof.
move=>g po all; split; first by fprops.
move=> x y xs ys.
rewrite product_order_substrate // in xs ys.
have sd: sub (doubleton x y) (prod_of_substrates g).
by move=> t td; case (doubleton_or td)=> ->.
set (f := fam_of_substrates g).
have fgf: fgraph f by rewrite /f/fam_of_substrates; gprops.
have df: domain f = domain g by rewrite /f/fam_of_substrates; bw.
have pf: productb f = prod_of_substrates g by [].
have aux: (forall i, inc i (domain g) -> exists u, exists v,
inc u (substrate (V i g)) & inc v (substrate (V i g)) &
(image_by_fun (pr_i f i) (doubleton x y) = doubleton u v)).
move=> i idg; exists (V i x); exists (V i y).
move: (xs) (ys); aw; move => [fx [dx iVx]] [fy [dy iVy]].
split; first by apply iVx.
split; first by apply iVy.
have sds: sub (doubleton x y) (source (pr_i f i)).
rewrite /pr_i bl_source.
by move=> t td; case (doubleton_or td) => ->.
have fi: is_function (pr_i f i) by apply pri_function=>//; ue.
have Wx: (W x (pr_i f i) = (V i x)) by apply pri_W=>//; ue.
have Wy: (W y (pr_i f i) = (V i y)) by apply pri_W=>//; ue.
set_extens z; aw.
by move=> [u [ud]] <-; case (doubleton_or ud)=> ->; ue.
move => zd; case zd =>->.
exists x; ee.
by exists y;ee.
move:(sup_in_product po sd) => [h _]; rewrite -h.
move:(inf_in_product po sd) => [h' _]; rewrite -h'.
split.
move=> i idg; move: (aux _ idg) => [u [v [us [vs]]]] -> .
move: (all _ idg)=> [_ lt]; move: (lt _ _ us vs)=> [lt1 lt2].
apply lt1.
move=> i idg; move: (aux _ idg) => [u [v [us [vs]]]] -> .
move: (all _ idg)=> [_ lt]; move: (lt _ _ us vs)=> [lt1 lt2].
apply lt2.
Qed.
Lemma lattice_directed: forall r,
lattice r -> (right_directed r & left_directed r).
Proof.
move=> r [oe lr]; split; split =>// x y xs ys; move: (lr _ _ xs ys)=> [p1 p2].
have sd: sub (doubleton x y) (substrate r) by apply sub_doubleton.
by move: p1=> [s]; aw; move=> [ub _]; exists s.
have sd: sub (doubleton x y) (substrate r) by apply sub_doubleton.
by move: p2=> [s]; aw; move=> [ub _]; exists s.
Qed.
Definition total_order r :=
order r & forall x y, inc x (substrate r) -> inc y (substrate r) ->
(gle r x y \/ gge r x y).
Lemma total_order_pr: forall r,
total_order r =
(compose_graph r r = r &
intersection2 r (opposite_order r) = identity_g(substrate r)&
union2 r (opposite_order r) = coarse (substrate r)).
Proof.
move=> r; rewrite /total_order.
apply iff_eq.
move=> [or to]; move: (or); rewrite order_pr; move => [p1 p2].
ee; set_extens x => xu.
case (union2_or xu).
have gr: (is_graph r) by fprops.
apply (sub_graph_coarse_substrate gr).
have oor: order (opposite_order r) by fprops.
have sor: substrate (opposite_order r) = substrate r.
by apply substrate_opposite_order.
have gr: is_graph (opposite_order r) by fprops.
by rewrite -sor; apply (sub_graph_coarse_substrate gr).
move: xu; rewrite/coarse; aw.
move=> [px [Ps Qs]]; rewrite -px.
by case (to _ _ Ps Qs); [ auto | aw; auto].
move=> [cg [i2 u2]].
have or :order r by rewrite (order_pr r).
split=>//.
move=> x y xs ys.
have Jc: inc (J x y) (coarse (substrate r)).
by rewrite /coarse;apply product_pair_inc.
move: Jc; rewrite -u2; aw.
Qed.
Lemma total_order_pr1 : forall r x y,
total_order r -> inc x (substrate r) -> inc y (substrate r) ->
(glt r x y \/ ggt r x y \/ x = y).
Proof.
move=> r x y tor xs ys.
case (equal_or_not x y).
auto.
move: tor=> [_ p] xy.
rewrite /ggt/glt; case (p _ _ xs ys); auto.
Qed.
Lemma total_order_pr2 : forall r x y,
total_order r -> inc x (substrate r) -> inc y (substrate r) ->
(glt r x y \/ gle r y x).
Proof.
move=> r x y tor xs ys.
move: tor=> [_ p]; rewrite /glt; case (p _ _ xs ys); auto.
case (equal_or_not x y); auto.
move=> ->; auto.
Qed.
Lemma total_order_sub : forall r x,
total_order r -> sub x (substrate r) -> total_order (induced_order r x).
Proof.
move=> r x [or tor] xs; split.
fprops.
aw; move=> a b asr bsr; rewrite /gge; aw.
apply (tor _ _ (xs _ asr) (xs _ bsr)).
Qed.
Lemma total_order_small : forall r,
order r -> small_set(substrate r) -> total_order r.
Proof.
move=> r or ss; split=>//.
move=> x y xs ys; rewrite (ss _ _ xs ys).
left. order_tac.
Qed.
Lemma total_order_conterexample:
~ (total_order (inclusion_order two_points)).
Proof.
move=> [or].
rewrite substrate_inclusion_order => to.
have sa: (inc (singleton TPa) (powerset two_points)).
apply powerset_inc; move=> t; aw. move=> ->; fprops.
have sb: (inc (singleton TPb) (powerset two_points)).
apply powerset_inc; move=> t; aw. move=> ->; fprops.
move: (to _ _ sa sb); rewrite /gge /gle; aw.
case; move=> [_[_ hyp]].
have ta: (inc TPa (singleton TPa)) by fprops.
move: (hyp _ ta); aw; apply two_points_distinct.
have tb: (inc TPb (singleton TPb)) by fprops.
move: (hyp _ tb); aw; apply two_points_distinctb.
Qed.
Lemma total_order_opposite: forall r,
total_order r -> total_order (opposite_order r).
Proof.
move=> t [or tor].
split; first by fprops.
aw; move=> x y xs ys; case (tor _ _ xs ys); aw;auto.
Qed.
order r & forall x y, inc x (substrate r) -> inc y (substrate r) ->
(gle r x y \/ gge r x y).
Lemma total_order_pr: forall r,
total_order r =
(compose_graph r r = r &
intersection2 r (opposite_order r) = identity_g(substrate r)&
union2 r (opposite_order r) = coarse (substrate r)).
Proof.
move=> r; rewrite /total_order.
apply iff_eq.
move=> [or to]; move: (or); rewrite order_pr; move => [p1 p2].
ee; set_extens x => xu.
case (union2_or xu).
have gr: (is_graph r) by fprops.
apply (sub_graph_coarse_substrate gr).
have oor: order (opposite_order r) by fprops.
have sor: substrate (opposite_order r) = substrate r.
by apply substrate_opposite_order.
have gr: is_graph (opposite_order r) by fprops.
by rewrite -sor; apply (sub_graph_coarse_substrate gr).
move: xu; rewrite/coarse; aw.
move=> [px [Ps Qs]]; rewrite -px.
by case (to _ _ Ps Qs); [ auto | aw; auto].
move=> [cg [i2 u2]].
have or :order r by rewrite (order_pr r).
split=>//.
move=> x y xs ys.
have Jc: inc (J x y) (coarse (substrate r)).
by rewrite /coarse;apply product_pair_inc.
move: Jc; rewrite -u2; aw.
Qed.
Lemma total_order_pr1 : forall r x y,
total_order r -> inc x (substrate r) -> inc y (substrate r) ->
(glt r x y \/ ggt r x y \/ x = y).
Proof.
move=> r x y tor xs ys.
case (equal_or_not x y).
auto.
move: tor=> [_ p] xy.
rewrite /ggt/glt; case (p _ _ xs ys); auto.
Qed.
Lemma total_order_pr2 : forall r x y,
total_order r -> inc x (substrate r) -> inc y (substrate r) ->
(glt r x y \/ gle r y x).
Proof.
move=> r x y tor xs ys.
move: tor=> [_ p]; rewrite /glt; case (p _ _ xs ys); auto.
case (equal_or_not x y); auto.
move=> ->; auto.
Qed.
Lemma total_order_sub : forall r x,
total_order r -> sub x (substrate r) -> total_order (induced_order r x).
Proof.
move=> r x [or tor] xs; split.
fprops.
aw; move=> a b asr bsr; rewrite /gge; aw.
apply (tor _ _ (xs _ asr) (xs _ bsr)).
Qed.
Lemma total_order_small : forall r,
order r -> small_set(substrate r) -> total_order r.
Proof.
move=> r or ss; split=>//.
move=> x y xs ys; rewrite (ss _ _ xs ys).
left. order_tac.
Qed.
Lemma total_order_conterexample:
~ (total_order (inclusion_order two_points)).
Proof.
move=> [or].
rewrite substrate_inclusion_order => to.
have sa: (inc (singleton TPa) (powerset two_points)).
apply powerset_inc; move=> t; aw. move=> ->; fprops.
have sb: (inc (singleton TPb) (powerset two_points)).
apply powerset_inc; move=> t; aw. move=> ->; fprops.
move: (to _ _ sa sb); rewrite /gge /gle; aw.
case; move=> [_[_ hyp]].
have ta: (inc TPa (singleton TPa)) by fprops.
move: (hyp _ ta); aw; apply two_points_distinct.
have tb: (inc TPb (singleton TPb)) by fprops.
move: (hyp _ tb); aw; apply two_points_distinctb.
Qed.
Lemma total_order_opposite: forall r,
total_order r -> total_order (opposite_order r).
Proof.
move=> t [or tor].
split; first by fprops.
aw; move=> x y xs ys; case (tor _ _ xs ys); aw;auto.
Qed.
If x is smaller than y, the pair has a supremum and an infimum
Lemma sup_comparable: forall r x y, gle r x y ->
order r -> least_upper_bound r (doubleton x y) y.
Proof.
move=> r x y xy or.
apply least_upper_bound_doubleton =>//.
order_tac; order_tac.
Qed.
Lemma inf_comparable: forall r x y, gle r x y ->
order r -> greatest_lower_bound r (doubleton x y) x.
Proof.
move=> r x y xy or.
apply greatest_lower_bound_doubleton =>//.
order_tac; order_tac.
Qed.
Lemma inf_comparable1: forall r x y, order r -> gle r x y ->
inf r x y = x.
Proof.
by symmetry; apply infimum_pr2 =>//; apply inf_comparable.
Qed.
Lemma sup_comparable1: forall r x y, order r -> gle r x y ->
sup r x y = y.
Proof.
by symmetry; apply supremum_pr2 =>//; apply sup_comparable.
Qed.
Lemma total_order_lattice: forall r,
total_order r -> lattice r.
Proof.
move=> r [or tor]; split=>//.
move=> x y xsr ysr; case (tor _ _ xsr ysr).
move => hyp.
split.
by exists y; apply sup_comparable.
by exists x; apply inf_comparable.
rewrite doubleton_symm.
move => hyp.
split.
by exists x; apply sup_comparable.
by exists y; apply inf_comparable.
Qed.
Lemma total_order_directed: forall r,
total_order r -> (right_directed r & left_directed r).
Proof.
by move=>r to; apply lattice_directed; apply total_order_lattice.
Qed.
Theorem total_order_monotone_injective: forall f r r',
total_order r -> strict_monotone_fun f r r' -> injection f.
Proof.
move=> f r r' tor sm.
case sm; move=>[ff [or [or' [sr [sr' hyp]]]]]; split=>//; move=> x y xs ys sW.
rewrite -sr in xs ys.
case (total_order_pr1 tor xs ys) => h.
move: (hyp _ _ h); rewrite sW /glt;intuition.
case h=> // h'.
have h'': glt r y x by move: h'; rewrite /glt /ggt/gge; intuition.
move: (hyp _ _ h''); rewrite sW /glt;intuition.
rewrite -sr in xs ys.
case (total_order_pr1 tor xs ys) => h.
move: (hyp _ _ h); rewrite sW /ggt/glt;intuition.
case h=> // h'.
have h'': glt r y x by move: h'; rewrite /glt /ggt/gge; intuition.
move: (hyp _ _ h''); rewrite sW /ggt/glt;intuition.
Qed.
Lemma increasing_fun_from_strict: forall f r r',
strict_increasing_fun f r r' -> increasing_fun f r r'.
Proof.
move=> f r r' [ff [or [or' [sr [sr' hyp]]]]].
red; ee.
move=> x y xy; case (equal_or_not x y).
move=> ->; order_tac.
rewrite sr';apply inc_W_target =>//.
rewrite -sr; order_tac.
move=> h.
have aux: (glt r x y) by split.
by case (hyp _ _ aux).
Qed.
Lemma decreasing_fun_from_strict: forall f r r',
strict_decreasing_fun f r r' -> decreasing_fun f r r'.
Proof.
move=> f r r' [ff [or [or' [sr [sr' hyp]]]]].
red; ee.
move=> x y xy; case (equal_or_not x y).
move=> ->; rewrite /gge;order_tac.
rewrite sr';apply inc_W_target =>//.
rewrite -sr; order_tac.
move=> h.
have aux: (glt r x y) by split.
by case (hyp _ _ aux).
Qed.
Theorem total_order_increasing_morphism: forall f r r',
total_order r -> strict_increasing_fun f r r' -> order_morphism f r r'.
Proof.
move=> f r r' tor si.
have ijf: (injection f) .
apply total_order_monotone_injective with r r'=>//.
red; auto.
move: (increasing_fun_from_strict si) => ic.
move: si=> [ff [or [or' [sr [sr' sif]]]]].
move: ic=> [_ [_ [_ [_ [_ nif]]]]].
red; ee.
move=> x y xs ys; apply iff_eq.
apply nif.
rewrite -sr in xs ys.
case (total_order_pr2 tor ys xs).
move=> h; move: (sif _ _ h)=> p1 p2; order_tac.
done.
Qed.
Theorem sup_in_total_order:forall r X x, total_order r -> sub X (substrate r)->
least_upper_bound r X x = (upper_bound r X x &
(forall y, glt r y x -> exists z, inc z X & glt r y z & gle r z x)).
Proof.
move=> r X x tor Xs.
have or: order r by move: tor=> [].
apply iff_eq; aw; move=> [ub lub]; split=>//.
move=> y yx.
have nu: (~ (upper_bound r X y)).
by move=> ys; move: (lub _ ys)=> xy; order_tac.
have ysr: (inc y (substrate r)) by order_tac.
have [z [zX yz]]: (exists z, inc z X & glt r y z).
apply exists_proof; dneg nez; split =>//.
move=> u ux; case (total_order_pr2 tor ysr (Xs _ ux)) =>//.
by move=> aux; elim (nez u).
by exists z; ee; move: ub=> [_]; apply.
move=> z ubz.
have xs:inc x (substrate r) by move: ub=> [].
have zs:inc z (substrate r) by move: ubz=> [].
case (total_order_pr2 tor zs xs) =>//.
move=> h; move: (lub _ h)=> [t [tX [yt tx]]].
move: ubz=> [_ h']; move: (h' _ tX) => h''.
order_tac.
Qed.
Theorem inf_in_total_order:forall r X x, total_order r -> sub X (substrate r)->
greatest_lower_bound r X x = (lower_bound r X x &
(forall y, glt r x y -> exists z, inc z X & glt r z y & gle r x z)).
Proof.
move=> r X x tor Xs.
have or: order r by move: tor=> [].
apply iff_eq; aw; move=> [ub lub]; split=>//.
move=> y yx.
have nu: (~ (lower_bound r X y)).
by move=> ys; move: (lub _ ys)=> xy; order_tac.
have ysr: (inc y (substrate r)) by order_tac.
have [z [zX yz]]: (exists z, inc z X & glt r z y).
apply exists_proof; dneg nez; split =>//.
move=> u ux; case (total_order_pr2 tor (Xs _ ux) ysr) =>//.
by move=> aux; elim (nez u).
by exists z; ee; move: ub=> [_]; apply.
move=> z ubz.
have xs:inc x (substrate r) by move: ub=> [].
have zs:inc z (substrate r) by move: ubz=> [].
case (total_order_pr2 tor xs zs) =>//.
move=> h; move: (lub _ h)=> [t [tX [yt tx]]].
move: ubz=> [_ h']; move: (h' _ tX) => h''.
order_tac.
Qed.
Definition interval_oo r a b :=Zo (substrate r)(fun z => glt r a z & glt r z b).
Definition interval_oc r a b :=Zo (substrate r)(fun z => glt r a z & gle r z b).
Definition interval_ou r a := Zo (substrate r)(fun z => glt r a z).
Definition interval_co r a b := Zo(substrate r)(fun z => gle r a z & glt r z b).
Definition interval_cc r a b := Zo(substrate r)(fun z => gle r a z & gle r z b).
Definition interval_cu r a := Zo (substrate r)(fun z => gle r a z).
Definition interval_uo r b := Zo (substrate r) (fun z => glt r z b).
Definition interval_uc r b := Zo (substrate r) (fun z => gle r z b).
Definition interval_uu r := Zo (substrate r) (fun z => True).
Definition is_closed_interval r x := exists a, exists b,
inc a (substrate r) & inc b (substrate r) & gle r a b & x = interval_cc r a b.
Definition is_open_interval r x := exists a, exists b,
inc a (substrate r) & inc b (substrate r) & gle r a b & x = interval_oo r a b.
Definition is_semi_open_interval r x := exists a, exists b,
inc a (substrate r) & inc b (substrate r) & gle r a b &
(x = interval_oc r a b \/ x = interval_co r a b).
Definition is_bounded_interval r x := is_closed_interval r x \/
is_open_interval r x \/ is_semi_open_interval r x.
Definition is_left_unbounded_interval r x :=
exists b, inc b (substrate r) & (x = interval_uc r b \/ x = interval_uo r b).
Definition is_right_unbounded_interval r x :=
exists a, inc a (substrate r) & (x = interval_cu r a \/ x = interval_ou r a).
Definition is_unbounded_interval r x :=
is_left_unbounded_interval r x \/ is_right_unbounded_interval r x \/
x = interval_uu r.
Definition is_interval r x :=
is_bounded_interval r x \/ is_unbounded_interval r x.
Ltac uf_interval :=
rewrite /interval_cc/interval_oo/interval_co/interval_oc
/interval_uu/interval_uo/interval_ou/interval_uc/interval_cu.
Lemma the_least_interval: forall r a b, order r ->
gle r a b -> the_least_element (induced_order r (interval_cc r a b)) = a.
Proof.
move=> r a b or ab.
have sab: (sub (interval_cc r a b) (substrate r))
by uf_interval; apply Z_sub.
have asr: inc a (substrate r) by apply (inc_arg1_substrate ab).
have aicc: inc a (interval_cc r a b).
uf_interval; apply Z_inc =>//; split=>//; order_tac.
apply the_least_element_pr2.
apply order_induced_order=>//.
red; uf_interval; aw.
split =>//;move=> x xi; aw; move: xi;rewrite Z_rw; intuition.
Qed.
Lemma the_greatest_interval: forall r a b, order r ->
gle r a b -> the_greatest_element (induced_order r (interval_cc r a b)) = b.
Proof.
move=> r a b or ab.
have sab: (sub (interval_cc r a b) (substrate r))
by uf_interval; apply Z_sub.
have asr: inc b (substrate r) by apply (inc_arg2_substrate ab).
have aicc: inc b (interval_cc r a b).
uf_interval; apply Z_inc =>//; split=>//; order_tac.
apply the_greatest_element_pr2.
apply order_induced_order=>//.
red; uf_interval; aw.
split =>//;move=> x xi; aw; move: xi;rewrite Z_rw; intuition.
Qed.
Lemma nonempty_closed_interval: forall r x,
order r -> is_closed_interval r x -> nonempty x.
Proof.
move=> r x or [a [b [asr [bsr [ab xab]]]]].
exists a; rewrite xab; uf_interval; apply Z_inc =>//.
split=>//; order_tac.
Qed.
Lemma singleton_interval: forall r a,
order r -> inc a (substrate r) -> is_singleton (interval_cc r a a).
Proof.
move=> r a or asr; exists a.
uf_interval; apply is_singleton_pr; split.
rewrite Z_rw;ee; order_tac.
move=> z ; rewrite Z_rw;move=> [_ [p1 p2]]; order_tac.
Qed.
Lemma empty_interval: forall r a,
order r -> inc a (substrate r) ->
(empty (interval_co r a a) & empty (interval_oc r a a)&
empty (interval_oo r a a)).
Proof.
move=> r a or asr; uf_interval.
ee; move=> y;rewrite Z_rw; move=> [_ [p1 p2]]; order_tac.
Qed.
Lemma lattice_inverse: forall r, lattice r -> lattice (opposite_order r).
Proof.
move=> r [or lr]; split; first by fprops.
aw. move=> x y xs ys.
move: (lr _ _ xs ys) => [[x1 p1] [x2 p2]].
split.
exists x2; rewrite - inf_sup_opp //; apply sub_doubleton =>//.
exists x1; rewrite - sup_inf_opp //; apply sub_doubleton =>//.
Qed.
Lemma intersection4: forall A B C D,
intersection2 (intersection2 A B) (intersection2 C D)
= intersection2 (intersection2 A C) (intersection2 B D).
Proof.
move=> A B C D.
rewrite - 2! intersection2A.
apply f_equal.
rewrite 2! intersection2A.
by rewrite (intersection2C B C).
Qed.
Lemma intersection_i1: forall r x,
is_interval r x -> intersection2 x (interval_uu r) = x.
Proof.
move=> r x hyp.
have ->: interval_uu r = substrate r.
rewrite /interval_uu; apply extensionality; first by apply Z_sub.
by move=> t tr; rewrite Z_rw.
suff: sub x (substrate r).
move=> h; apply extensionality; first by apply intersection2sub_first.
by move=> t tx; apply intersection2_inc=>//; apply h.
case hyp.
case; first by move=> [a [b [_[_[_]]]]] ->; uf_interval ; apply Z_sub.
case.
move=> [a [b [_[_[_]]]]] ->; uf_interval ; apply Z_sub.
move=> [a [b [_[_[_]]]]].
uf_interval; case; move=> ->; apply Z_sub.
case.
move=> [a [_]]; case; move=> ->; apply Z_sub.
case.
move=> [a [_]]; case; move=> ->; apply Z_sub.
move=> ->; apply Z_sub.
Qed.
Definition is_lu_interval r x :=
x = interval_uu r \/ is_left_unbounded_interval r x.
Definition is_ru_interval r x :=
x= interval_uu r \/ is_right_unbounded_interval r x.
Ltac zztac2 v := uf_interval; set_extens v ; aw; rewrite ? Z_rw; aw.
Lemma intersection_i2: forall r x,
is_interval r x ->
(exists u, exists v, is_lu_interval r u & is_ru_interval r v &
intersection2 u v = x).
Proof.
move=> r x ix; move: (ix).
have p1: forall b, inc b (substrate r) -> is_lu_interval r (interval_uc r b).
move=> b hb; right; exists b;auto.
have p2: forall b, inc b (substrate r) -> is_lu_interval r (interval_uo r b).
move=> b hb; right; exists b; auto.
have p3: forall b, inc b (substrate r) -> is_ru_interval r (interval_cu r b).
move=> b hb; right; exists b; auto.
have p4: forall b, inc b (substrate r) -> is_ru_interval r (interval_ou r b).
move=> b hb; right; exists b; auto.
case.
case.
move=> [a [b [au [bu [ab xab]]]]].
exists (interval_uc r b); exists (interval_cu r a); ee.
rewrite xab; zztac2 y; intuition.
case.
move=> [a [b [au [bu [ab xab]]]]].
exists (interval_uo r b); exists (interval_ou r a); ee.
rewrite xab; zztac2 y; intuition.
move=> [a [b [au [bu [ab xab]]]]].
case xab=> ->.
exists (interval_uc r b); exists (interval_ou r a); ee.
zztac2 y; intuition.
exists (interval_uo r b); exists (interval_cu r a); ee.
zztac2 y; intuition.
case.
move=>[a [au xa]].
exists x; exists (interval_uu r).
split. (case xa); move=> ->; intuition.
by split=>//; [red; auto | apply intersection_i1].
case.
move=>[a [au xa]].
exists (interval_uu r); exists x.
split; first by red; auto.
split.
(case xa); move=> ->; intuition.
by rewrite intersection2C; apply intersection_i1.
move=> h; exists x; exists x; rewrite h.
split; first by red; auto.
split; first by red; auto.
apply intersection_i1. ue.
Qed.
Lemma intersection_i3: forall r x y, lattice r ->
is_left_unbounded_interval r x -> is_left_unbounded_interval r y ->
is_left_unbounded_interval r (intersection2 x y).
Proof.
move=> r x y lar [a [asr xa]][b [bsr yb]].
have or: order r by move: lar=> [].
move: (lattice_inf_pr lar asr bsr).
set (u:=inf r a b); set (v:= sup r a b).
move=> [ua [ub uab]].
exists u; split; first by order_tac.
case xa => ->.
case yb => ->.
left; zztac2 z; first by intuition.
move=> [zs zu]; ee; order_tac.
case (p_or_not_p (glt r u b)).
left; zztac2 z.
move=> [[zs za][_ [zb znb]]]; ee.
move=> [zs zu]; ee; order_tac.
move=> ltuv; right; zztac2 z.
move=> [[zs za][_ [zb nzb]]]; split =>//.
split; first by apply uab.
move=> zu; rewrite zu in zb; elim ltuv; split=>//; ue.
move=> [zs zu]; ee; [ move: zu=> [zu _]; order_tac | order_tac ].
case yb=> ->.
case (p_or_not_p (glt r u a)).
left; zztac2 z.
move=> [[zs [za zna]][_ zb]]; ee.
move=> [zs zu]; ee; order_tac.
move=> ltuv; right; zztac2 z.
move=> [[zs [za nza]][_ zb]]; split =>//.
split; first by apply uab.
move=> zu; rewrite zu in zb; elim ltuv; split=>//; ue.
move=> [zs zu]; ee; [order_tac | move: zu=> [zu _]; order_tac ].
case (p_or_not_p (glt r u a & glt r u b)).
move=> [p1 p2].
left; zztac2 z.
move=> [[zs [za zna]][_ [zb znb]]]; ee.
move=> [zs zu]; ee; order_tac.
move=> p1p2; right; zztac2 z.
move=> [[zs [za zna]][_ [zb znb]]]; rewrite /glt; ee.
move=> zu; rewrite zu in zna znb; elim p1p2; split; split;ee.
move=> [zs zu]; ee; order_tac.
Qed.
Theorem intersection_interval: forall r x y,
lattice r -> is_interval r x -> is_interval r y ->
is_interval r (intersection2 x y).
Proof.
move=> r x y lar ix iy.
have or: order r by move: lar=> [].
move: (intersection_i2 ix) (intersection_i2 iy).
move=> [a [b [lua [rub abx]]]][c [d [luc [rud cdy]]]].
rewrite -abx -cdy intersection4.
have lu1: is_lu_interval r (intersection2 a c).
case lua.
move=>->; rewrite intersection2C intersection_i1 //.
right; red; red in luc; intuition.
case luc.
move=>-> p; rewrite intersection_i1;[ by right| by right; left].
by move=> p1 p2; right; apply intersection_i3.
have ru1: is_ru_interval r (intersection2 b d).
case rub.
move=>->; rewrite intersection2C intersection_i1 //.
right; red; red in rud; intuition.
move=> irub; case rud.
move=>->; rewrite intersection_i1 //; by right; right; left.
move=> irud.
have Ha: forall a, interval_cu r a = interval_uc (opposite_order r) a.
uf_interval; move=> t; aw; set_extens u; rewrite ? Z_rw; aw.
have Hb: forall a, interval_ou r a = interval_uo (opposite_order r) a.
uf_interval; move=> t; aw; set_extens u; rewrite ? Z_rw /glt; aw; ee.
have Hc: is_left_unbounded_interval (opposite_order r) b.
move:irub => [e [es be]]; case be => ->; exists e; split; aw; auto.
have Hd: is_left_unbounded_interval (opposite_order r) d.
move:irud => [e [es be]]; case be => ->; exists e; split; aw; auto.
have He :lattice (opposite_order r) by apply lattice_inverse.
move: (intersection_i3 He Hc Hd) => [e [es]].
rewrite -Ha -Hb; awi es =>//; case => ->; right; exists e; auto.
have i1: is_interval r (intersection2 a c).
right; red; red in lu1; intuition.
have i2: is_interval r (intersection2 b d).
right; red; red in ru1; intuition.
case lu1.
move=>->. rewrite intersection2C intersection_i1 //.
move=> lu2; case ru1; first by move=>->;rewrite intersection_i1 =>//.
move=> ru2.
left.
move: lu2 ru2 => [e [es ace]][f [fs bdf]].
case (p_or_not_p (gle r f e)) => fe.
case ace=> ->.
case bdf=> ->.
left; exists f; exists e; ee; zztac2 t; intuition.
right;right;exists f; exists e; ee; left; zztac2 t; intuition.
case bdf=> ->.
right;right;exists f; exists e; ee; right; zztac2 t; intuition.
right; left ;exists f; exists e; ee; zztac2 t; intuition.
suff: (empty (intersection2 (intersection2 a c) (intersection2 b d))).
move=> h.
move:(empty_interval or fs) => [_[ _ oo]]; right; left.
exists f; exists f; ee; try order_tac.
by set_extens t => te; [ elim (h t) | elim (oo t)].
move=> t; rewrite intersection2_rw; move => [ti1 ti2]; elim fe.
have p1: gle r t e.
by move: ti1; case ace=> ->; uf_interval; rewrite Z_rw /glt; intuition.
have p2: gle r f t.
by move: ti2; case bdf=> ->; uf_interval; rewrite Z_rw /glt; intuition.
order_tac.
Qed.
End Border.
Export Border.