Require Export HFS.Operations.
Section TransitiveClosure.
Variable X : HF.
Implicit Types x y z a u : X.
Definition TC x u := forall z, z el u <-> forall y, trans y -> x <<= y -> z el y.
Fact TC_trans x u :
TC x u -> trans u.
Proof.
intros A y B a C. apply A. intros b D E.
enough (y el b) by hfs. now apply A.
Qed.
Fact TC_incl x u :
TC x u -> x <<= u.
Proof.
intros A y B. apply A. auto.
Qed.
Fact TC_fun x y y' :
TC x y -> TC x y' -> y = y'.
Proof.
intros A B. extensio as z. split; intros C.
- apply B. intros u D E. now apply A.
- apply A. intros u D E. now apply B.
Qed.
Lemma TC_empty :
TC 0 0.
Proof.
intros z. split. hfs.
intros A. apply A; hfs.
Qed.
Lemma TC_adj a x u v :
TC a u -> TC x v -> TC (a@x) (a @ (bun u v)).
Proof.
intros A B z. split.
- rewrite adj_el, bun_el. intros [-> |[C|C]] y D E.
+ hfs.
+ apply A; hfs.
+ apply B; try hfs.
- intros C. apply C.
+ intros b [-> |[D|D] % bun_el] % adj_el c E; rewrite adj_el, bun_el.
* generalize (TC_incl A). hfs.
* generalize (TC_trans A). hfs.
* generalize (TC_trans B). hfs.
+ intros b; rewrite !adj_el, bun_el. intros [-> |D].
* now auto.
* generalize (TC_trans B), (TC_incl B). hfs.
Qed.
Lemma tc' x :
Sigma u, TC x u.
Proof.
hf_induction x.
- eauto using TC_empty.
- intros a x (u&A) (v&B). eauto using TC_adj.
Qed.
Definition tc x := projT1 (tc' x).
Fact TC_tc x :
TC x (tc x).
Proof.
unfold tc. destruct (tc' x) as (u&A). apply A.
Qed.
Theorem tc_el x z :
z el tc x <-> forall y, trans y -> x <<= y -> z el y.
Proof.
apply TC_tc.
Qed.
Fact tc_trans x:
trans (tc x).
Proof.
eapply TC_trans, TC_tc.
Qed.
Fact tc_incl x:
x <<= tc x.
Proof.
eapply TC_incl, TC_tc.
Qed.
Fact tc_least x y :
trans y -> x <<= y -> tc x <<= y.
Proof.
intros A B z C % tc_el; eauto.
Qed.
Fact tcE_eq :
tc 0 = 0.
Proof.
apply TC_fun with (x:=0). apply TC_tc. apply TC_empty.
Qed.
Fact tcA_eq a x:
tc (a@x) = a @ (bun (tc a) (tc x)).
Proof.
apply TC_fun with (x := a@x). apply TC_tc.
apply TC_adj; apply TC_tc.
Qed.
Inductive tel x y : Prop :=
| telI : x el y -> x < y
| telT z : x < z -> z < y -> x < y
where "x '<' y" := (tel x y).
Fact tel_inv x y :
x < y <-> x el y \/ exists z, x < z /\ z el y.
Proof.
split.
- induction 1 as [x z A|x y z A _ _ IHB].
+ auto.
+ destruct IHB as [C|(u&C&D)]; eauto using tel.
- intros [A|(z&A&B)]; eauto using tel.
Qed.
Fact tel_adjL z a x :
z < a -> z < a @ x.
Proof.
intros A. apply telT with (z:=a). exact A. apply telI. hfs.
Qed.
Fact tel_adjR z a x :
z < x -> z < a @ x.
Proof.
intros [A|(u&A&B)] % tel_inv.
- apply telI. hfs.
- apply telT with (z:=u). exact A. apply telI. hfs.
Qed.
Theorem tel_TC x y :
x < y <-> x el tc y.
Proof.
split; intros A.
- apply tc_el. intros u B C. revert u B C.
induction A as [x z A|x y z _ IHA _ IHB].
+ hfs.
+ intros u C D. specialize (IHB u C D). apply IHA; hfs.
- revert A. hf_induction y.
+ rewrite tcE_eq. hfs.
+ intros a y IHa IHy.
rewrite tcA_eq, adj_el, bun_el. intros [-> |[A|A]].
* apply telI. hfs.
* auto using tel_adjL.
* auto using tel_adjR.
Qed.
Corollary tel_dec x y :
dec (x < y).
Proof.
apply (dec_trans (x el tc y)).
- symmetry. apply tel_TC.
- auto.
Qed.
End TransitiveClosure.