(* Contribution to the Coq Library   V6.3 (July 1999)                    *)

(****************************************************************************)
(* This contribution was updated for Coq V5.10 by the COQ workgroup.        *)
(* January 1995                                                             *)
(****************************************************************************)
(*                                   ps.v                                   *)
(****************************************************************************)

Require Import Classical.

Require Import Ensembles.
Require Import Relations_1.
Require Import Relations_1_facts.
Require Import podefs.
Require Import podefs_1.

Section The_power_set_partial_order.
   Variable U : Type.
   
   Inductive Power_set (A : Ensemble U) : Ensemble (Ensemble U) :=
       Definition_of_Power_set :
         forall X : Ensemble U,
         Included U X A -> In (Ensemble U) (Power_set A) X.
   Hint Resolve Definition_of_Power_set.
   
   (* Consider a set A, and its powerset P  *)
   Variable A : Ensemble U.
   
   Theorem Empty_set_minimal :
    forall X : Ensemble U, Included U (Empty_set U) X.
   Proof.
(* Goal: forall X : Ensemble U, Included U (Empty_set U) X *)
   red in |- *; intros X x H'; elim H'.
   Qed.
   Hint Resolve Empty_set_minimal.
   
   Theorem Power_set_non_empty :
    forall A : Ensemble U, Non_empty (Ensemble U) (Power_set A).
   Proof.
(* Goal: forall A : Ensemble U, Non_empty (Ensemble U) (Power_set A) *)
   intro A'; apply Non_empty_intro with (Empty_set U); auto.
   Qed.
   Hint Resolve Power_set_non_empty.
   
   Theorem Inclusion_is_an_order : Order (Ensemble U) (Included U).
   Proof.
(* Goal: Order (Ensemble U) (Included U) *)
   auto 8.
   Qed.
   Hint Resolve Inclusion_is_an_order.
   
   Theorem Inclusion_is_transitive : Transitive (Ensemble U) (Included U).
(* Goal: Transitive (Ensemble U) (Included U) *)
   elim Inclusion_is_an_order; auto.
   Qed.
   Hint Resolve Inclusion_is_transitive.
   
   Theorem Same_set_equivalence : Equivalence (Ensemble U) (Same_set U).
   Proof.
   generalize (Equiv_from_order (Ensemble U) (Included U)); intro H'; elim H';
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
    auto.
   Qed.

   Theorem Same_set_reflexive : Reflexive (Ensemble U) (Same_set U).
   Proof.
(* Goal: Reflexive (Ensemble U) (Same_set U) *)
   elim Same_set_equivalence; auto.
   Qed.
   Hint Resolve Same_set_reflexive.
   
   Theorem Power_set_PO : PO (Ensemble U).
   Proof.
(* Goal: PO (Ensemble U) *)
   apply Definition_of_PO with (Power_set A) (Included U); auto.
   Defined.
   
   Theorem Union_minimal :
    forall a b X : Ensemble U,
    Included U a X -> Included U b X -> Included U (Union U a b) X.
   Proof.
(* Goal: forall (a b X : Ensemble U) (_ : Included U a X) (_ : Included U b X), Included U (Union U a b) X *)
   intros a b X H' H'0; red in |- *; (intros x H'1; elim H'1); auto.
   Qed.
   Hint Resolve Union_minimal.
   
   Theorem Intersection_maximal :
    forall a b X : Ensemble U,
    Included U X a -> Included U X b -> Included U X (Intersection U a b).
   Proof.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   auto.
   Qed.
   
   Theorem Union_increases_l :
    forall a b : Ensemble U, Included U a (Union U a b).
   Proof.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   auto.
   Qed.
   
   Theorem Union_increases_r :
    forall a b : Ensemble U, Included U b (Union U a b).
   Proof.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   auto.
   Qed.
   
   Theorem Intersection_decreases_l :
    forall a b : Ensemble U, Included U (Intersection U a b) a.
   Proof.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   intros a b; red in |- *; auto.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   intros x H'; elim H'; auto.
   Qed.
   
   Theorem Intersection_decreases_r :
    forall a b : Ensemble U, Included U (Intersection U a b) b.
   Proof.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   intros a b; red in |- *; auto.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   intros x H'; elim H'; auto.
   Qed.
   Hint Resolve Union_increases_l Union_increases_r Intersection_decreases_l
     Intersection_decreases_r.
   
   Theorem Empty_set_is_Bottom :
    Bottom (Ensemble U) Power_set_PO (Empty_set U).
   Proof.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   apply Bottom_definition; simpl in |- *; auto.
   Qed.
   Hint Resolve Empty_set_is_Bottom.
  
   Theorem Union_is_Lub :
    forall a b : Ensemble U,
    Included U a A ->
    Included U b A ->
    Lub (Ensemble U) Power_set_PO (Couple (Ensemble U) a b) (Union U a b).
   Proof.
(* Goal: forall (a b : Ensemble U) (_ : Included U a A) (_ : Included U b A), Glb (Ensemble U) Power_set_PO (Couple (Ensemble U) a b) (Intersection U a b) *)
   intros a b H' H'0.
(* Goal: Lub (Ensemble U) Power_set_PO (Couple (Ensemble U) a b) (Union U a b) *)
   apply Lub_definition; simpl in |- *.
(* Goal: Upper_Bound (Ensemble U) Power_set_PO (Couple (Ensemble U) a b) (Union U a b) *)
(* Goal: forall (y : Ensemble U) (_ : Upper_Bound (Ensemble U) Power_set_PO (Couple (Ensemble U) a b) y), Included U (Union U a b) y *)
   apply Upper_Bound_definition; simpl in |- *.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   auto.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   intros y H'1; elim H'1; auto.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   intros y H'1; elim H'1; simpl in |- *; auto.
   Qed.


   Theorem Intersection_is_Glb :
    forall a b : Ensemble U,
    Included U a A ->
    Included U b A ->
    Glb (Ensemble U) Power_set_PO (Couple (Ensemble U) a b)
      (Intersection U a b).
   Proof.
(* Goal: forall (a b : Ensemble U) (_ : Included U a A) (_ : Included U b A), Glb (Ensemble U) Power_set_PO (Couple (Ensemble U) a b) (Intersection U a b) *)
   intros a b H' H'0.
(* Goal: Glb (Ensemble U) Power_set_PO (Couple (Ensemble U) a b) (Intersection U a b) *)
   apply Glb_definition.
(* Goal: Lower_Bound (Ensemble U) Power_set_PO (Couple (Ensemble U) a b) (Intersection U a b) *)
(* Goal: forall (y : Ensemble U) (_ : Lower_Bound (Ensemble U) Power_set_PO (Couple (Ensemble U) a b) y), Rel_of (Ensemble U) Power_set_PO y (Intersection U a b) *)
   apply Lower_Bound_definition; simpl in |- *.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   apply Definition_of_Power_set; auto.
   generalize Inclusion_is_transitive; intro IT; red in IT; apply IT with a;
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
    auto.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   intros y H'1; elim H'1; auto.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   intros y H'1; elim H'1; simpl in |- *; auto.
   Qed.
   
   Theorem Empty_set_zero :
    forall X : Ensemble U, Union U (Empty_set U) X = X.
   Proof.
(* Goal: forall X : Ensemble U, @eq (Ensemble U) (Union U (Empty_set U) X) X *)
   auto 10.
   Qed.
   
   Theorem Union_commutative :
    forall A B : Ensemble U, Union U A B = Union U B A.
   Proof.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   auto.
   Qed.
   
   Theorem Union_associative :
    forall A B C : Ensemble U,
    Union U (Union U A B) C = Union U A (Union U B C).
   Proof.
(* Goal: forall A B C : Ensemble U, @eq (Ensemble U) (Union U (Union U A B) C) (Union U A (Union U B C)) *)
   auto 20.
   Qed.
   
   Theorem Non_disjoint_union :
    forall (X : Ensemble U) (x : U),
    In U X x -> Union U (Singleton U x) X = X.
   Proof.
(* Goal: forall X : Ensemble U, @eq (Ensemble U) (Union U (Empty_set U) X) X *)
   intros X x H'; try assumption; auto 10.
   apply Extensionality_Ensembles; unfold Same_set in |- *; split;
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
    auto.
(* Goal: forall X : Ensemble U, @eq (Ensemble U) (Union U (Empty_set U) X) X *)
   red in |- *; auto 10.
(* Goal: forall X : Ensemble U, @eq (Ensemble U) (Union U (Empty_set U) X) X *)
   intros x0 H'0; elim H'0; auto 10.
(* Goal: forall X : Ensemble U, @eq (Ensemble U) (Union U (Empty_set U) X) X *)
   intros x1 H'1; elim H'1; auto 10.
   Qed.
   
   Theorem Finite_plus_one_is_finite :
    forall (X : Ensemble U) (x : U),
    Finite U X -> Finite U (Union U (Singleton U x) X).
   Proof.
(* Goal: forall (X : Ensemble U) (x : U) (_ : Finite U X), Finite U (Union U (Singleton U x) X) *)
   intros X x H'.
   generalize (classic (In U X x)); intro h; elim h;
    [ intro H'0; clear h; try exact H'0 | clear h; intro H'0 ];
(* Goal: forall X : Ensemble U, @eq (Ensemble U) (Union U (Empty_set U) X) X *)
    auto 10.
   generalize (Non_disjoint_union X x); intro h; lapply h;
    [ intro H'1; rewrite H'1; clear h | clear h ]; 
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
    auto.
   Qed.
   Hint Resolve Finite_plus_one_is_finite.
  
   Theorem Singleton_is_finite : forall x : U, Finite U (Singleton U x).
   Proof.
   intro x; generalize (Empty_set_zero (Singleton U x)); intro h;
    rewrite <- h; clear h.
   generalize (Union_commutative (Empty_set U) (Singleton U x)); intro h;
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
    rewrite h; clear h; auto.
   Qed.
   Hint Resolve Singleton_is_finite.
   
   Theorem Union_of_finite_is_finite :
    forall X Y : Ensemble U,
    Finite U X -> Finite U Y -> Finite U (Union U X Y).
   Proof.
(* Goal: forall (X Y : Ensemble U) (_ : Finite U X) (_ : Finite U Y), Finite U (Union U X Y) *)
   intros X Y H'; elim H'.
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
   generalize (Empty_set_zero Y); intro h; rewrite h; clear h; auto.
(* Goal: forall (A : Ensemble U) (_ : Finite U A) (_ : forall _ : Finite U Y, Finite U (Union U A Y)) (x : U) (_ : not (In U A x)) (_ : Finite U Y), Finite U (Union U (Union U (Singleton U x) A) Y) *)
   clear A.
(* Goal: forall (A : Ensemble U) (_ : Finite U A) (_ : forall _ : Finite U Y, Finite U (Union U A Y)) (x : U) (_ : not (In U A x)) (_ : Finite U Y), Finite U (Union U (Union U (Singleton U x) A) Y) *)
   intros AA H'0 H'1 x H'2 H'3.
   generalize (Union_associative (Singleton U x) AA Y); intro h; rewrite h;
(* Goal: forall A B : Ensemble U, @eq (Ensemble U) (Union U A B) (Union U B A) *)
    clear h; auto.
   Qed.
   
End The_power_set_partial_order.
Hint Resolve Empty_set_minimal.
Hint Resolve Power_set_non_empty.
Hint Resolve Inclusion_is_an_order.
Hint Resolve Inclusion_is_transitive.
Hint Resolve Same_set_reflexive.
Hint Resolve Union_minimal.
Hint Resolve Same_set_reflexive.
Hint Resolve Union_increases_l.
Hint Resolve Union_increases_r.
Hint Resolve Intersection_decreases_l.
Hint Resolve Intersection_decreases_r.
Hint Resolve Empty_set_is_Bottom.
Hint Resolve Empty_set_zero.
Hint Resolve Finite_plus_one_is_finite.
Hint Resolve Singleton_is_finite.

