diff --git a/Lebesgue/Subset-new.v b/Lebesgue/Subset-new.v
new file mode 100644
index 0000000000000000000000000000000000000000..1abd2755511893773f2d463850127071290e5046
--- /dev/null
+++ b/Lebesgue/Subset-new.v
@@ -0,0 +1,2051 @@
+(**
+This file is part of the Elfic library
+
+Copyright (C) Boldo, Clément, Martin, Mayero, Mouhcine
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+COPYING file for more details.
+*)
+
+(** Operations on subsets (definitions and properties).
+
+  Subsets of the type U are represented by their belonging function,
+  of type U -> Prop.
+
+  Most of the properties are tautologies, and can be found on Wikipedia:
+  https://en.wikipedia.org/wiki/List_of_set_identities_and_relations *)
+
+From Coq Require Import Classical.
+From Coq Require Import PropExtensionality FunctionalExtensionality.
+
+
+Section Base_Def1.
+
+Context {U : Type}. (* Universe. *)
+
+(** Nullary constructors of subsets. *)
+
+Definition emptyset : U -> Prop := fun _ => False.
+Definition fullset : U -> Prop := fun _ => True.
+
+(** Unary constructors of subsets. *)
+
+(** Either the emptyset when p := False, or the fullset U when p := True. *)
+Definition Prop_cst : Prop -> U -> Prop := fun p _ => p.
+
+Definition singleton : U -> U -> Prop := fun a x => x = a.
+
+(** Unary predicates on subsets. *)
+
+Variable A : U -> Prop. (* Subset. *)
+
+Definition empty : Prop := forall x, A x -> False.
+Definition nonempty : Prop := exists x, A x.
+Definition full : Prop := forall x, A x.
+
+(** Unary operation on subsets. *)
+
+Definition compl : U -> Prop := fun x => ~ A x.
+
+(** Binary predicates on subsets. *)
+
+Variable B : U -> Prop. (* Subset. *)
+
+Definition incl : Prop := forall x, A x -> B x.
+Definition same : Prop := forall x, A x <-> B x.
+
+Definition disj : Prop := forall x, A x -> B x -> False.
+
+(** Binary operations on subsets. *)
+
+Definition union : U -> Prop := fun x => A x \/ B x.
+Definition inter : U -> Prop := fun x => A x /\ B x.
+
+End Base_Def1.
+
+
+Section Base_Def2.
+
+Context {U : Type}. (* Universe. *)
+
+(** Sesquary operation on subsets. *)
+
+Variable A : U -> Prop. (* Subset. *)
+Variable a : U. (* Element. *)
+
+Definition add : U -> Prop := union A (singleton a).
+
+(** More binary operation on subsets. *)
+
+Variable B : U -> Prop. (* Subset. *)
+
+Definition diff : U -> Prop := inter A (compl B).
+
+(** Ternary predicate on subsets. *)
+
+Variable C : U -> Prop. (* Subset. *)
+
+Definition partition : Prop := A = union B C /\ disj B C.
+
+End Base_Def2.
+
+
+Section Base_Def3.
+
+Context {U : Type}. (* Universe. *)
+
+(** Binary constructor of subsets. *)
+
+Variable a b : U. (* Elements. *)
+
+Definition pair : U -> Prop := add (singleton a) b.
+
+(** More binary operation on subsets. *)
+
+Variable A B : U -> Prop. (* Subsets. *)
+
+Definition sym_diff : U -> Prop := union (diff A B) (diff B A).
+
+End Base_Def3.
+
+
+Section Base_Def4.
+
+Context {U1 U2 : Type}. (* Universes. *)
+
+Variable A1 : U1 -> Prop. (* Subset. *)
+Variable A2 : U2 -> Prop. (* Subset. *)
+
+Definition prod : U1 * U2 -> Prop :=
+  inter (fun x => A1 (fst x)) (fun x => A2 (snd x)).
+
+Definition swap : forall {U : Type}, (U1 * U2 -> U) -> U2 * U1 -> U :=
+  fun U f x => f (snd x, fst x).
+
+End Base_Def4.
+
+
+Section Base_Def5.
+
+Context {U1 U2 : Type}. (* Universes. *)
+
+Variable f g : U1 -> U2. (* Function. *)
+
+Definition same_fun : Prop := forall x, f x = g x.
+
+Variable A1 : U1 -> Prop. (* Subset. *)
+Variable A2 : U2 -> Prop. (* Subset. *)
+
+Inductive image : U2 -> Prop := Im : forall x1, A1 x1 -> image (f x1).
+
+Definition preimage : U1 -> Prop := fun x1 => A2 (f x1).
+
+End Base_Def5.
+
+
+Section Prop_Facts0.
+
+Context {U : Type}. (* Universe. *)
+
+(** Extensionality of subsets. *)
+
+Lemma subset_ext :
+  forall (A B : U -> Prop),
+    same A B -> A = B.
+Proof.
+intros.
+apply functional_extensionality;
+    intros x; now apply propositional_extensionality.
+Qed.
+
+Lemma subset_ext_equiv :
+  forall (A B : U -> Prop),
+    A = B <-> incl A B /\ incl B A.
+Proof.
+intros; split.
+intros H; split; now rewrite H.
+intros [H1 H2]; apply subset_ext; split; [apply H1 | apply H2].
+Qed.
+
+End Prop_Facts0.
+
+
+Ltac subset_unfold :=
+  repeat unfold
+    same_fun, partition, disj, same, incl, full, nonempty, empty, (* Predicates. *)
+    preimage, pair, (* Constructors. *)
+    swap, prod, sym_diff, diff, add, inter, union, compl, (* Operators. *)
+    singleton, Prop_cst, fullset, emptyset. (* Constructors. *)
+
+Ltac subset_auto :=
+  subset_unfold; try easy; try tauto; auto.
+
+Ltac subset_ext_auto0 :=
+  apply subset_ext; subset_auto.
+
+Ltac subset_ext_auto1 x :=
+  subset_ext_auto0; intros x; subset_auto.
+
+Ltac subset_ext_auto2 x Hx :=
+  subset_ext_auto1 x; split; intros Hx; subset_auto.
+
+Tactic Notation "subset_ext_auto" := subset_ext_auto0.
+Tactic Notation "subset_ext_auto" ident(x) := subset_ext_auto1 x.
+Tactic Notation "subset_ext_auto" ident(x) ident(Hx) := subset_ext_auto2 x Hx.
+
+
+Section Prop_Facts.
+
+Context {U : Type}. (* Universe. *)
+
+(** Facts about emptyset and fullset. *)
+
+Lemma nonempty_is_not_empty :
+  forall (A : U -> Prop), nonempty A <-> ~ empty A.
+Proof.
+intros A; split.
+intros [x Hx] H; apply (H x); easy.
+apply not_all_not_ex.
+Qed.
+
+Lemma empty_emptyset :
+  forall (A : U -> Prop),
+    empty A <-> A = emptyset.
+Proof.
+intros; split; intros H.
+subset_ext_auto x Hx; now apply (H x).
+now rewrite H.
+Qed.
+
+Lemma full_fullset :
+  forall (A : U -> Prop),
+    full A <-> A = fullset.
+Proof.
+intros; split; intros H.
+now apply subset_ext.
+now rewrite H.
+Qed.
+
+(** Facts about singleton. *)
+
+Lemma singleton_in :
+  forall a : U, singleton a a.
+Proof.
+subset_auto.
+Qed.
+
+Lemma singleton_out :
+  forall a x : U, x <> a -> compl (singleton a) x.
+Proof.
+subset_auto.
+Qed.
+
+(** Facts about incl. *)
+
+(** It is an order binary relation. *)
+
+Lemma incl_refl :
+  forall (A B : U -> Prop),
+    same A B -> incl A B.
+Proof.
+intros A B H x; now rewrite (H x).
+Qed.
+
+Lemma incl_antisym :
+  forall (A B : U -> Prop),
+    incl A B -> incl B A -> A = B.
+Proof.
+intros; now rewrite subset_ext_equiv.
+Qed.
+
+Lemma incl_trans :
+  forall (A B C : U -> Prop),
+    incl A B -> incl B C -> incl A C.
+Proof.
+intros; intros x Hx; auto.
+Qed.
+
+Lemma full_not_empty :
+  inhabited U <-> ~ incl (@fullset U) emptyset.
+Proof.
+subset_unfold; split.
+intros [x]; auto.
+intros H; apply exists_inhabited with (fun x => ~ (True -> False)).
+now apply not_all_ex_not in H.
+Qed.
+
+Lemma incl_empty :
+  forall (A : U -> Prop),
+    incl A emptyset -> A = emptyset.
+Proof.
+intros A H; subset_ext_auto x Hx; apply (H x Hx).
+Qed.
+
+Lemma full_incl :
+  forall (A : U -> Prop),
+    incl fullset A -> A = fullset.
+Proof.
+intros A H; subset_ext_auto x Hx; apply (H x Hx).
+Qed.
+
+(** Facts about same. *)
+
+(** It is an equivalence binary relation. *)
+
+(* Useless?
+Lemma same_refl :
+  forall (A : U -> Prop),
+    same A A.
+Proof.
+easy.
+Qed.*)
+
+(* This one is used! *)
+Lemma same_sym :
+  forall (A B : U -> Prop),
+    same A B -> same B A.
+Proof.
+easy.
+Qed.
+
+Lemma same_trans :
+  forall (A B C : U -> Prop),
+    same A B -> same B C -> same A C.
+Proof.
+intros A B C H1 H2 x; now rewrite (H1 x).
+Qed.
+
+(** Facts about disj. *)
+
+Lemma disj_equiv_def :
+  forall (A B : U -> Prop),
+    disj A B <-> inter A B = emptyset.
+Proof.
+intros; rewrite <- empty_emptyset; subset_unfold; split;
+    intros H x; intros; now apply (H x).
+Qed.
+
+Lemma disj_irrefl :
+  forall (A : U -> Prop),
+    disj A A <-> A = emptyset.
+Proof.
+intros; rewrite <- empty_emptyset; split; intros H x Hx; now apply (H x).
+Qed.
+
+Lemma disj_sym :
+  forall (A B : U -> Prop),
+    disj A B <-> disj B A.
+Proof.
+intros; split; intros H x Hx1 Hx2; now apply (H x).
+Qed.
+
+Lemma disj_full_l :
+  forall (A : U -> Prop),
+    disj fullset A -> A = emptyset.
+Proof.
+intros A H; apply empty_emptyset; intros x Hx; now apply (H x).
+Qed.
+
+Lemma disj_full_r :
+  forall (A : U -> Prop),
+    disj A fullset -> A = emptyset.
+Proof.
+intros A; rewrite disj_sym; apply disj_full_l.
+Qed.
+
+Lemma disj_monot_l :
+  forall (A B C : U -> Prop),
+    incl A B ->
+    disj B C -> disj A C.
+Proof.
+intros A B C H1 H2 x Hx1 Hx2; apply (H2 x); auto.
+Qed.
+
+Lemma disj_monot_r :
+  forall (A B C : U -> Prop),
+    incl A B ->
+    disj C B -> disj C A.
+Proof.
+intros A B C H1 H2 x Hx1 Hx2; apply (H2 x); auto.
+Qed.
+
+Lemma incl_disj :
+  forall (A B : U -> Prop),
+    incl A B ->
+    disj A B <-> A = emptyset.
+Proof.
+intros; split; intros H2.
+apply empty_emptyset; intros x Hx; apply (H2 x); auto.
+now rewrite H2.
+Qed.
+
+(** Facts about same_fun. *)
+
+(** It is an equivalence binary relation. *)
+
+Context {V : Type}. (* Universe. *)
+
+(* Useless?
+Lemma same_fun_refl :
+  forall (f : U -> V),
+    same_fun f f.
+Proof.
+easy.
+Qed.*)
+
+(* Useful? *)
+Lemma same_fun_sym :
+  forall (f g : U -> V),
+    same_fun f g -> same_fun g f.
+Proof.
+easy.
+Qed.
+
+Lemma same_fun_trans :
+  forall (f g h : U -> V),
+    same_fun f g -> same_fun g h -> same_fun f h.
+Proof.
+intros f g h H1 H2 x; now rewrite (H1 x).
+Qed.
+
+End Prop_Facts.
+
+
+Section Compl_Facts.
+
+(** Facts about complement. *)
+
+Context {U : Type}. (* Universe. *)
+
+Lemma compl_empty :
+  compl (@emptyset U) = fullset.
+Proof.
+now apply subset_ext.
+Qed.
+
+Lemma compl_full :
+  compl (@fullset U) = emptyset.
+Proof.
+subset_ext_auto.
+Qed.
+
+Lemma compl_invol :
+  forall (A : U -> Prop),
+    compl (compl A) = A.
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma compl_monot :
+  forall (A B : U -> Prop),
+    incl A B -> incl (compl B) (compl A).
+Proof.
+subset_auto; intros; intuition.
+Qed.
+
+Lemma incl_compl_equiv :
+  forall (A B : U -> Prop),
+    incl (compl B) (compl A) <-> incl A B.
+Proof.
+intros; split.
+rewrite <- (compl_invol A) at 2; rewrite <- (compl_invol B) at 2.
+apply compl_monot.
+apply compl_monot.
+Qed.
+
+Lemma same_compl :
+  forall (A B : U -> Prop),
+    same A B -> same (compl A) (compl B).
+Proof.
+subset_unfold; intros; now apply not_iff_compat.
+Qed.
+
+Lemma same_compl_equiv :
+  forall (A B : U -> Prop),
+    same (compl A) (compl B) <-> same A B.
+Proof.
+intros; split.
+rewrite <- (compl_invol A) at 2; rewrite <- (compl_invol B) at 2.
+apply same_compl.
+apply same_compl.
+Qed.
+
+Lemma compl_reg :
+  forall (A B : U -> Prop),
+    same (compl A) (compl B) -> A = B.
+Proof.
+intros; now apply subset_ext, same_compl_equiv.
+Qed.
+
+Lemma compl_ext :
+  forall (A B : U -> Prop),
+    compl A = compl B -> A = B.
+Proof.
+intros A B H; apply compl_reg; now rewrite H.
+Qed.
+
+Lemma disj_incl_compl_l :
+  forall (A B : U -> Prop),
+    disj A B <-> incl A (compl B).
+Proof.
+subset_auto.
+Qed.
+
+Lemma disj_incl_compl_r :
+  forall (A B : U -> Prop),
+    disj A B <-> incl B (compl A).
+Proof.
+intros A B; rewrite disj_sym; apply disj_incl_compl_l.
+Qed.
+
+End Compl_Facts.
+
+
+Section Union_Facts.
+
+(** Facts about union. *)
+
+Context {U : Type}. (* Universe. *)
+
+Lemma union_assoc :
+  forall (A B C : U -> Prop),
+    union (union A B) C = union A (union B C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma union_comm :
+  forall (A B : U -> Prop),
+    union A B = union B A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma union_idem :
+  forall (A : U -> Prop),
+    union A A = A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma union_empty_l :
+  forall (A : U -> Prop),
+    union emptyset A = A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma union_empty_r :
+  forall (A : U -> Prop),
+    union A emptyset = A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma empty_union :
+  forall (A B : U -> Prop),
+    union A B = emptyset <-> A = emptyset /\ B = emptyset.
+Proof.
+intros; do 3 rewrite <- empty_emptyset; split.
+intros H; split; intros x Hx; apply (H x); [now left | now right].
+intros [H1 H2] x [Hx | Hx]; [now apply (H1 x) | now apply (H2 x)].
+Qed.
+
+Lemma union_full_l :
+  forall (A : U -> Prop),
+    union fullset A = fullset.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma union_full_r :
+  forall (A : U -> Prop),
+    union A fullset = fullset.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma union_ub_l :
+  forall (A B : U -> Prop),
+    incl A (union A B).
+Proof.
+subset_auto.
+Qed.
+
+Lemma union_ub_r :
+  forall (A B : U -> Prop),
+    incl B (union A B).
+Proof.
+subset_auto.
+Qed.
+
+Lemma union_lub :
+  forall (A B C : U -> Prop),
+    incl A C -> incl B C ->
+    incl (union A B) C.
+Proof.
+intros; intros x [H3 | H3]; auto.
+Qed.
+
+Lemma incl_union :
+  forall (A B C : U -> Prop),
+    incl (union A B) C -> incl A C /\ incl B C.
+Proof.
+intros A B C H; split; intros x Hx; apply (H x); [now left | now right].
+Qed.
+
+Lemma union_left :
+  forall (A B : U -> Prop),
+    incl A B <-> union B A = B.
+Proof.
+intros; split.
+(* *)
+intros; rewrite subset_ext_equiv; split; intros x.
+intros [Hx | Hx]; auto.
+intros Hx; now left.
+(* *)
+intros H x Hx; rewrite <- H; now right.
+Qed.
+
+Lemma union_right :
+  forall (A B : U -> Prop),
+    incl A B <-> union A B = B.
+Proof.
+intros A B; rewrite union_comm; apply union_left.
+Qed.
+
+Lemma union_monot :
+  forall (A B C D : U -> Prop),
+    incl A B -> incl C D -> incl (union A C) (union B D).
+Proof.
+intros A B C D HAB HCD x [Hx | Hx]; [left | right]; auto.
+Qed.
+
+Lemma union_monot_l :
+  forall (A B C : U -> Prop),
+    incl A B -> incl (union A C) (union B C).
+Proof.
+intros; apply union_monot; easy.
+Qed.
+
+Lemma union_monot_r :
+  forall (A B C : U -> Prop),
+    incl A B -> incl (union C A) (union C B).
+Proof.
+intros; apply union_monot; easy.
+Qed.
+
+Lemma disj_union_l :
+  forall (A B C : U -> Prop),
+    disj (union A B) C <-> disj A C /\ disj B C.
+Proof.
+intros; split.
+intros H; split; intros x Hx1 Hx2; apply (H x); try easy; [now left | now right].
+intros [H1 H2] x [Hx1 | Hx1] Hx2; [now apply (H1 x) | now apply (H2 x)].
+Qed.
+
+Lemma disj_union_r :
+  forall (A B C : U -> Prop),
+    disj A (union B C) <-> disj A B /\ disj A C.
+Proof.
+intros A B C; now rewrite disj_sym, disj_union_l, (disj_sym B), (disj_sym C).
+Qed.
+
+Lemma union_compl_l :
+  forall (A : U -> Prop),
+    union (compl A) A = fullset.
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma union_compl_r :
+  forall (A : U -> Prop),
+    union A (compl A) = fullset.
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+End Union_Facts.
+
+
+Section Inter_Facts.
+
+(** Facts about intersection. *)
+
+Context {U : Type}. (* Universe. *)
+
+Lemma inter_assoc :
+  forall (A B C : U -> Prop),
+    inter (inter A B) C = inter A (inter B C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_comm :
+  forall (A B : U -> Prop),
+    inter A B = inter B A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_idem :
+  forall (A : U -> Prop),
+    inter A A = A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_full_l :
+  forall (A : U -> Prop),
+    inter fullset A = A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_full_r :
+  forall (A : U -> Prop),
+    inter A fullset = A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma full_inter :
+  forall (A B : U -> Prop),
+    inter A B = fullset <-> A = fullset /\ B = fullset.
+Proof.
+intros; do 3 rewrite <- full_fullset; split.
+intros H; split; intros x; now destruct (H x).
+intros [H1 H2] x; split; [apply (H1 x) | apply (H2 x)].
+Qed.
+
+Lemma inter_empty_l :
+  forall (A : U -> Prop),
+    inter emptyset A = emptyset.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_empty_r :
+  forall (A : U -> Prop),
+    inter A emptyset = emptyset.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_lb_l :
+  forall (A B : U -> Prop),
+    incl (inter A B) A.
+Proof.
+subset_auto.
+Qed.
+
+Lemma inter_lb_r :
+  forall (A B : U -> Prop),
+    incl (inter A B) B.
+Proof.
+subset_auto.
+Qed.
+
+Lemma inter_glb :
+  forall (A B C : U -> Prop),
+    incl C A -> incl C B ->
+    incl C (inter A B).
+Proof.
+intros; intros x Hx; split; auto.
+Qed.
+
+Lemma incl_inter :
+  forall (A B C : U -> Prop),
+    incl A (inter B C) -> incl A B /\ incl A C.
+Proof.
+intros A B C H; split; intros x Hx; now apply (H x).
+Qed.
+
+Lemma inter_left :
+  forall (A B : U -> Prop),
+    incl A B <-> inter A B = A.
+Proof.
+intros; split.
+(* *)
+rewrite subset_ext_equiv; split; intros x.
+intros [Hx1 Hx2]; auto.
+intros Hx; split; auto.
+(* *)
+intros H x Hx; rewrite <- H in Hx; now destruct Hx as [_ Hx].
+Qed.
+
+Lemma inter_right :
+  forall (A B : U -> Prop),
+    incl B A <-> inter A B = B.
+Proof.
+intros; rewrite inter_comm; apply inter_left.
+Qed.
+
+Lemma inter_monot :
+  forall (A B C D : U -> Prop),
+    incl A B -> incl C D -> incl (inter A C) (inter B D).
+Proof.
+intros A B C D HAB HCD x [Hx1 Hx2]; split; auto.
+Qed.
+
+Lemma inter_monot_l :
+  forall (A B C : U -> Prop),
+    incl A B -> incl (inter A C) (inter B C).
+Proof.
+intros; apply inter_monot; easy.
+Qed.
+
+Lemma inter_monot_r :
+  forall (A B C : U -> Prop),
+    incl A B -> incl (inter C A) (inter C B).
+Proof.
+intros; apply inter_monot; easy.
+Qed.
+
+Lemma inter_disj_compat_l :
+  forall (A B C : U -> Prop),
+    disj A B -> disj (inter C A) (inter C B).
+Proof.
+intros A B C H; rewrite disj_equiv_def in H; rewrite disj_equiv_def.
+rewrite <- empty_emptyset in H; rewrite <- empty_emptyset.
+intros x [[_ Hx1] [_ Hx2]]; now apply (H x).
+Qed.
+
+Lemma inter_disj_compat_r :
+  forall (A B C : U -> Prop),
+    disj A B -> disj (inter A C) (inter B C).
+Proof.
+intros A B C; rewrite (inter_comm A), (inter_comm B); apply inter_disj_compat_l.
+Qed.
+
+Lemma inter_compl_l :
+  forall (A : U -> Prop),
+    inter (compl A) A = emptyset.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_compl_r :
+  forall (A : U -> Prop),
+    inter A (compl A) = emptyset.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+End Inter_Facts.
+
+
+Section Union_Inter_Facts.
+
+(** Facts about union and intersection. *)
+
+Context {U : Type}. (* Universe. *)
+
+Lemma incl_inter_union :
+  forall (A B : U -> Prop),
+    incl (inter A B) (union A B).
+Proof.
+intros; intros x [Hx _]; now left.
+Qed.
+
+Lemma disj_inter_union :
+  forall (A B : U -> Prop),
+    disj (inter A B) (union A B) <-> disj A B.
+Proof.
+intros; split; intros H x.
+intros Hx1 Hx2; apply (H x); [easy | now left].
+intros [Hx1 Hx2] _; now apply (H x).
+Qed.
+
+(** De Morgan's laws. *)
+
+Lemma compl_union :
+  forall (A B : U -> Prop),
+    compl (union A B) = inter (compl A) (compl B).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma compl_inter :
+  forall (A B : U -> Prop),
+    compl (inter A B) = union (compl A) (compl B).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+(** Distributivity. *)
+
+Lemma union_union_distr_l :
+  forall (A B C : U -> Prop),
+    union A (union B C) = union (union A B) (union A C).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma union_union_distr_r :
+  forall (A B C : U -> Prop),
+    union (union A B) C = union (union A C) (union B C).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma union_inter_distr_l :
+  forall (A B C : U -> Prop),
+    union A (inter B C) = inter (union A B) (union A C).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma union_inter_distr_r :
+  forall (A B C : U -> Prop),
+    union (inter A B) C = inter (union A C) (union B C).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma union_inter :
+  forall (A B C D : U -> Prop),
+    union (inter A B) (inter C D) =
+    inter (inter (union A C) (union B C)) (inter (union A D) (union B D)).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma inter_union_distr_l :
+  forall (A B C : U -> Prop),
+    inter A (union B C) = union (inter A B) (inter A C).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma inter_union_distr_r :
+  forall (A B C : U -> Prop),
+    inter (union A B) C = union (inter A C) (inter B C).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma inter_union :
+  forall (A B C D : U -> Prop),
+    inter (union A B) (union C D) =
+    union (union (inter A C) (inter B C)) (union (inter A D) (inter B D)).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma inter_inter_distr_l :
+  forall (A B C : U -> Prop),
+    inter A (inter B C) = inter (inter A B) (inter A C).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma inter_inter_distr_r :
+  forall (A B C : U -> Prop),
+    inter (inter A B) C = inter (inter A C) (inter B C).
+Proof.
+intros; rewrite subset_ext_equiv; split; subset_auto.
+Qed.
+
+Lemma disj_compl_l :
+  forall (A B : U -> Prop),
+    disj (compl A) B -> ~ empty B -> ~ disj A B.
+Proof.
+intros A B H1 H2 H3; rewrite disj_equiv_def in H1, H3.
+contradict H2; apply empty_emptyset.
+rewrite <- (inter_full_l B).
+rewrite <- (union_compl_l A), inter_union_distr_r, H1, H3.
+now apply empty_union.
+Qed.
+
+Lemma disj_compl_r :
+  forall (A B : U -> Prop),
+    disj A (compl B) -> ~ empty A -> ~ disj A B.
+Proof.
+intros A B H1 H2.
+rewrite disj_sym in H1; rewrite disj_sym.
+now apply disj_compl_l.
+Qed.
+
+End Union_Inter_Facts.
+
+
+Section Add_Facts.
+
+(** Facts about addition of one element. *)
+
+Context {U : Type}. (* Universe. *)
+
+Lemma incl_add_l :
+  forall A B (a : U), incl (add A a) B <-> incl A B /\ B a.
+Proof.
+intros A B a; split; intros H.
+apply incl_union in H; split; try apply H; apply singleton_in.
+apply union_lub; try easy; intros x Hx; now rewrite Hx.
+Qed.
+
+Lemma incl_add_r :
+  forall A (a : U), incl A (add A a).
+Proof.
+intros; apply union_ub_l.
+Qed.
+
+Lemma add_in :
+  forall A (a : U), add A a a.
+Proof.
+intros; apply union_ub_r, singleton_in.
+Qed.
+
+End Add_Facts.
+
+
+Section Diff_Facts.
+
+(** Facts about set difference. *)
+
+Context {U : Type}. (* Universe. *)
+
+Lemma diff_equiv_def_inter :
+  forall (A B : U -> Prop),
+    diff A B = inter A (compl B).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_equiv_def_union :
+  forall (A B : U -> Prop),
+    diff A B = compl (union (compl A) B).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma compl_equiv_def_diff :
+  forall (A : U -> Prop),
+    compl A = diff fullset A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_equiv_def_diff :
+  forall (A B : U -> Prop),
+    inter A B = diff A (diff A B).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma union_equiv_def_diff :
+  forall (A B : U -> Prop),
+    union A B = compl (diff (compl A) B).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma diff_lb_l :
+  forall (A B : U -> Prop),
+    incl (diff A B) A.
+Proof.
+intros; apply inter_lb_l.
+Qed.
+
+Lemma diff_lb_r :
+  forall (A B : U -> Prop),
+    incl (diff A B) (compl B).
+Proof.
+intros; apply inter_lb_r.
+Qed.
+
+Lemma partition_union_diff_l :
+  forall (A B : U -> Prop),
+    partition (union A B) (diff A B) B.
+Proof.
+intros; split.
+subset_ext_auto x.
+subset_auto.
+Qed.
+
+Lemma partition_union_diff_r :
+  forall (A B : U -> Prop),
+    partition (union A B) A (diff B A).
+Proof.
+intros; split.
+subset_ext_auto x.
+subset_auto.
+Qed.
+
+Lemma diff_monot_l :
+  forall (A B C : U -> Prop),
+    incl A B -> incl (diff A C) (diff B C).
+Proof.
+intros A B C H x [Hx1 Hx2]; split; [now apply H | easy].
+Qed.
+
+Lemma diff_monot_r :
+  forall (A B C : U -> Prop),
+    incl B C -> incl (diff A C) (diff A B).
+Proof.
+intros A B C H x [Hx1 Hx2]; split; [easy | intros Hx3; now apply Hx2, H].
+Qed.
+
+Lemma diff_disj :
+  forall (A B : U -> Prop),
+    disj A B <-> diff A B = A.
+Proof.
+intros; rewrite subset_ext_equiv; split.
+intros H; split; subset_unfold; intros x Hx1; specialize (H x); intuition.
+intros [_ H] x Hx1 Hx2; specialize (H x Hx1); now destruct H as [_ H].
+Qed.
+
+Lemma diff_disj_compat_r :
+  forall (A B C : U -> Prop),
+    disj A B -> disj (diff A C) (diff B C).
+Proof.
+intros A B C H x HAx HBx; apply (H x); now apply (diff_lb_l _ C).
+Qed.
+
+Lemma diff_empty :
+  forall (A B : U -> Prop),
+    diff A B = emptyset <-> incl A B.
+Proof.
+intros; rewrite <- empty_emptyset; split; intros H.
+intros x Hx1; apply NNPP; intros Hx2; now apply (H x).
+intros x [Hx1 Hx2]; auto.
+Qed.
+
+Lemma diff_empty_diag :
+  forall (A : U -> Prop),
+    diff A A = emptyset.
+Proof.
+intros; now rewrite diff_empty.
+Qed.
+
+Lemma full_diff :
+  forall (A B : U -> Prop),
+    diff A B = fullset <-> A = fullset /\ B = emptyset.
+Proof.
+intros; do 2 rewrite <- full_fullset; rewrite <- empty_emptyset.
+split; intros H.
+split; intros x; now destruct (H x) as [H1 H2].
+intros x; destruct H as [H1 H2]; split; [apply H1 | exact (H2 x)].
+Qed.
+
+Lemma compl_diff :
+  forall (A B : U -> Prop),
+    compl (diff A B) = union (compl A) B.
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma diff_empty_l :
+  forall (A : U -> Prop),
+    diff emptyset A = emptyset.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_empty_r :
+  forall (A : U -> Prop),
+    diff A emptyset = A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_full_l :
+  forall (A : U -> Prop),
+    diff fullset A = compl A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_full_r :
+  forall (A : U -> Prop),
+    diff A fullset = emptyset.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_compl_l :
+  forall (A B : U -> Prop),
+    diff (compl A) B = diff (compl B) A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_compl_r :
+  forall (A B : U -> Prop),
+    diff A (compl B) = diff B (compl A).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma diff_compl :
+  forall (A B : U -> Prop),
+    diff (compl A) (compl B) = diff B A.
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma diff_union_distr_l :
+  forall (A B C : U -> Prop),
+    diff (union A B) C = union (diff A C) (diff B C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_union_distr_r :
+  forall (A B C : U -> Prop),
+    diff A (union B C) = inter (diff A B) (diff A C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_inter_distr_l :
+  forall (A B C : U -> Prop),
+    diff (inter A B) C = inter (diff A C) (diff B C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_inter_distr_r :
+  forall (A B C : U -> Prop),
+    diff A (inter B C) = union (diff A B) (diff A C).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma diff_union_l_diag :
+  forall (A B : U -> Prop),
+    diff (union A B) A = diff B A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_union_r_diag :
+  forall (A B : U -> Prop),
+    diff (union A B) B = diff A B.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_inter_l_diag :
+  forall (A B : U -> Prop),
+    diff A (inter A B) = diff A B.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_inter_r_diag :
+  forall (A B : U -> Prop),
+    diff B (inter A B) = diff B A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma union_diff_l :
+  forall (A B C : U -> Prop),
+    union (diff A B) C = diff (union A C) (diff B C).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma union_diff_r :
+  forall (A B C : U -> Prop),
+    union A (diff B C) = diff (union A B) (diff C A).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma inter_diff_distr_l :
+  forall (A B C : U -> Prop),
+    inter A (diff B C) = diff (inter A B) (inter A C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_diff_distr_r :
+  forall (A B C : U -> Prop),
+    inter (diff A B) C = diff (inter A C) (inter B C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff2_l :
+  forall (A B C : U -> Prop),
+    diff (diff A B) C = diff A (union B C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff2_r :
+  forall (A B C : U -> Prop),
+    diff A (diff B C) = union (inter A C) (diff A B).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma diff2_r_inter :
+  forall (A B C : U -> Prop),
+    incl A B ->
+    diff A (diff B C) = inter A C.
+Proof.
+intros A B C H; apply diff_empty in H.
+rewrite diff2_r, H; apply union_empty_r.
+Qed.
+
+Lemma diff2 :
+  forall (A B C D : U -> Prop),
+    diff (diff A B) (diff C D) =
+      union (diff (inter A (compl C)) B)
+            (diff (inter A D) B).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma diff2_diag_l :
+  forall (A B C : U -> Prop),
+    diff (diff A B) (diff A C) = diff (inter A C) B.
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma diff2_cancel_left :
+  forall (A B C : U -> Prop),
+    incl A B ->
+    diff (diff B C) (diff B A) = diff A C.
+Proof.
+intros; now rewrite diff2_diag_l, inter_comm, (proj1 (inter_left _ _)).
+Qed.
+
+Lemma diff2_diag_r :
+  forall (A B C : U -> Prop),
+    diff (diff A C) (diff B C) = diff (inter A (compl B)) C.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+End Diff_Facts.
+
+
+Section Sym_diff_Facts.
+
+(** Facts about symmetric difference. *)
+
+Context {U : Type}. (* Universe. *)
+
+Lemma sym_diff_equiv_def_union :
+  forall (A B : U -> Prop),
+    sym_diff A B = union (diff A B) (diff B A).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma sym_diff_equiv_def_diff :
+  forall (A B : U -> Prop),
+    sym_diff A B = diff (union A B) (inter A B).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma union_equiv_def_sym_diff :
+  forall (A B : U -> Prop),
+    union A B = sym_diff (sym_diff A B) (inter A B).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma inter_equiv_def_sym_diff :
+  forall (A B : U -> Prop),
+    inter A B = diff (union A B) (sym_diff A B).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma diff_equiv_def_sym_diff_inter :
+  forall (A B : U -> Prop),
+    diff A B = sym_diff A (inter A B).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma diff_equiv_def_sym_diff_union :
+  forall (A B : U -> Prop),
+    diff A B = sym_diff (union A B) B.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+(* ((U -> Prop) -> Prop, sym_diff) is a Boolean group,
+  ie an abelian group with the emptyset as neutral, and inv = id. *)
+
+Lemma sym_diff_assoc :
+  forall (A B C : U -> Prop),
+    sym_diff (sym_diff A B) C = sym_diff A (sym_diff B C).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma sym_diff_comm :
+  forall (A B : U -> Prop),
+    sym_diff A B = sym_diff B A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma sym_diff_inv :
+  forall (A : U -> Prop),
+    sym_diff A A = emptyset.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma sym_diff_empty_l :
+  forall (A : U -> Prop),
+    sym_diff emptyset A = A.
+Proof.
+intros; rewrite sym_diff_equiv_def_union, diff_empty_l, diff_empty_r.
+apply union_empty_l.
+Qed.
+
+Lemma sym_diff_empty_r :
+  forall (A : U -> Prop),
+    sym_diff A emptyset = A.
+Proof.
+intros; rewrite sym_diff_comm; apply sym_diff_empty_l.
+Qed.
+
+Lemma sym_diff_full_l :
+  forall (A : U -> Prop),
+    sym_diff fullset A = compl A.
+Proof.
+intros; rewrite sym_diff_equiv_def_diff, union_full_l, inter_full_l.
+symmetry; apply compl_equiv_def_diff.
+Qed.
+
+Lemma sym_diff_full_r :
+  forall (A : U -> Prop),
+    sym_diff A fullset = compl A.
+Proof.
+intros; rewrite sym_diff_comm; apply sym_diff_full_l.
+Qed.
+
+Lemma sym_diff_eq_reg_l :
+  forall (A B C : U -> Prop),
+    sym_diff A B = sym_diff A C -> B = C.
+Proof.
+intros A B C H.
+rewrite <- (sym_diff_empty_l B), <- (sym_diff_empty_l C), <- (sym_diff_inv A).
+do 2 rewrite sym_diff_assoc.
+now f_equal.
+Qed.
+
+Lemma sym_diff_eq_reg_r :
+  forall (A B C : U -> Prop),
+    sym_diff A B = sym_diff C B -> A = C.
+Proof.
+intros A B C H; apply sym_diff_eq_reg_l with B.
+now rewrite (sym_diff_comm _ A), (sym_diff_comm _ C).
+Qed.
+
+Lemma sym_diff_compl_l :
+  forall (A : U -> Prop),
+    sym_diff (compl A) A = fullset.
+Proof.
+intros; rewrite <- sym_diff_full_l, sym_diff_assoc, sym_diff_inv.
+apply sym_diff_empty_r.
+Qed.
+
+Lemma sym_diff_compl_r :
+  forall (A : U -> Prop),
+    sym_diff A (compl A) = fullset.
+Proof.
+intros; rewrite sym_diff_comm; apply sym_diff_compl_l.
+Qed.
+
+Lemma sym_diff_compl :
+  forall (A B : U -> Prop),
+    sym_diff (compl A) (compl B) = sym_diff A B.
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma union_sym_diff_super_distr_l :
+  forall (A B C : U -> Prop),
+    incl (sym_diff (union A C) (union B C))
+         (union (sym_diff A B) C).
+Proof.
+intros; subset_auto.
+Qed.
+
+Lemma union_sym_diff_super_distr_r :
+  forall (A B C : U -> Prop),
+    incl (sym_diff (union A B) (union A C))
+         (union A (sym_diff B C)).
+Proof.
+intros; subset_auto.
+Qed.
+
+Lemma union_sym_diff_super_distr :
+  forall (A B C D : U -> Prop),
+    incl (sym_diff (union A C) (union B D))
+         (union (sym_diff A B) (sym_diff C D)).
+Proof.
+intros; subset_auto.
+Qed.
+
+Lemma sym_diff_union_sub_distr_l :
+  forall (A B C : U -> Prop),
+    incl (sym_diff (union A B) C)
+         (union (sym_diff A C) (sym_diff B C)).
+Proof.
+intros; subset_auto.
+Qed.
+
+Lemma sym_diff_union_sub_distr_r :
+  forall (A B C : U -> Prop),
+    incl (sym_diff A (union B C))
+         (union (sym_diff A B) (sym_diff A C)).
+Proof.
+intros; subset_auto.
+Qed.
+
+Lemma sym_diff_union_sub_distr :
+  forall (A B C D : U -> Prop),
+    incl (sym_diff (union A B) (union C D))
+         (union (sym_diff A C) (sym_diff B D)).
+Proof.
+intros; subset_auto.
+Qed.
+
+(* ((U -> Prop) -> Prop, sym_diff, inter) is a Boolean ring,
+  ie an abelian ring with fullset as neutral for intersection. *)
+
+Lemma inter_sym_diff_distr_l :
+  forall (A B C : U -> Prop),
+    inter (sym_diff A B) C = sym_diff (inter A C) (inter B C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_sym_diff_distr_r :
+  forall (A B C : U -> Prop),
+    inter A (sym_diff B C) = sym_diff (inter A B) (inter A C).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma inter_sym_diff_distr :
+  forall (A B C D : U -> Prop),
+    inter (sym_diff A B) (sym_diff C D) =
+    sym_diff (sym_diff (inter A C) (inter A D))
+             (sym_diff (inter B C) (inter B D)).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma sym_diff_inter_super_distr_l :
+  forall (A B C : U -> Prop),
+    incl (inter (sym_diff A C) (sym_diff B C))
+         (sym_diff (inter A B) C).
+Proof.
+intros; subset_auto.
+Qed.
+
+Lemma sym_diff_inter_super_distr_r :
+  forall (A B C : U -> Prop),
+    incl (inter (sym_diff A B) (sym_diff A C))
+         (sym_diff A (inter B C)).
+Proof.
+intros; subset_auto.
+Qed.
+
+Lemma sym_diff_inter_super_distr :
+  forall (A B C D : U -> Prop),
+    incl (inter (inter (sym_diff A C) (sym_diff A D))
+                (inter (sym_diff B C) (sym_diff B D)))
+         (sym_diff (inter A B) (inter C D)).
+Proof.
+intros; subset_auto.
+Qed.
+
+(* ((U -> Prop) -> Prop, sym_diff, inter) is a Boolean algebra. *)
+
+Lemma sym_diff_union :
+  forall (A B : U -> Prop),
+    sym_diff A B = union A B <-> disj A B.
+Proof.
+intros; rewrite sym_diff_equiv_def_diff, <- diff_disj, (disj_sym (union _ _)).
+apply disj_inter_union.
+Qed.
+
+Lemma disj_sym_diff_inter :
+  forall (A B : U -> Prop),
+    disj (sym_diff A B) (inter A B).
+Proof.
+intros; subset_auto.
+Qed.
+
+Lemma union_sym_diff_inter :
+  forall (A B : U -> Prop),
+    union (sym_diff A B) (inter A B) = union A B.
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma partition_union_sym_diff_inter :
+  forall (A B : U -> Prop),
+    partition (union A B) (sym_diff A B) (inter A B).
+Proof.
+intros; split.
+symmetry; apply union_sym_diff_inter.
+apply disj_sym_diff_inter.
+Qed.
+
+Lemma sym_diff_cancel_middle :
+  forall (A B C : U -> Prop),
+    sym_diff (sym_diff A B) (sym_diff B C) = sym_diff A C.
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma sym_diff2 :
+  forall (A B C D : U -> Prop),
+    sym_diff (sym_diff A B) (sym_diff C D) =
+      sym_diff A (sym_diff B (sym_diff C D)).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma sym_diff_triangle_ineq :
+  forall (A B C : U -> Prop),
+    incl (sym_diff A C) (union (sym_diff A B) (sym_diff B C)).
+Proof.
+intros; intros x; subset_auto.
+Qed.
+
+Lemma sym_diff_diff_diag_l :
+  forall (A B C : U -> Prop),
+    incl (union B C) A ->
+    sym_diff (diff A B) (diff A C) = sym_diff B C.
+Proof.
+intros A B C H; apply incl_union in H.
+rewrite sym_diff_equiv_def_union.
+repeat rewrite diff2_cancel_left; try easy.
+now rewrite <- sym_diff_equiv_def_union, sym_diff_comm.
+Qed.
+
+End Sym_diff_Facts.
+
+
+Section Partition_Facts.
+
+(** Facts about partition. *)
+
+Context {U : Type}. (* Universe. *)
+
+Lemma partition_sym :
+  forall (A B C : U -> Prop),
+    partition A B C -> partition A C B.
+Proof.
+intros A B C; unfold partition.
+now rewrite union_comm, disj_sym.
+Qed.
+
+Lemma inter_partition_compat_l :
+  forall (A B C D : U -> Prop),
+    partition A B C -> partition (inter D A) (inter D B) (inter D C).
+Proof.
+intros A B C D [H1 H2]; split.
+rewrite H1; apply inter_union_distr_l.
+now apply inter_disj_compat_l.
+Qed.
+
+Lemma inter_partition_compat_r :
+  forall (A B C D : U -> Prop),
+    partition A B C -> partition (inter A D) (inter B D) (inter C D).
+Proof.
+intros A B C D.
+rewrite (inter_comm A), (inter_comm B), (inter_comm C).
+apply inter_partition_compat_l.
+Qed.
+
+Lemma diff_partition_compat_r :
+  forall (A B C D : U -> Prop),
+    partition A B C -> partition (diff A D) (diff B D) (diff C D).
+Proof.
+intros; now apply inter_partition_compat_r.
+Qed.
+
+End Partition_Facts.
+
+
+Section Prod_Facts.
+
+(** Facts about Cartesian product. *)
+
+Context {U1 U2 : Type}. (* Universes. *)
+
+Lemma inhabited_prod :
+  inhabited U1 -> inhabited U2 -> inhabited (U1 * U2).
+Proof.
+intros [x1] [x2]; apply (inhabits (x1, x2)).
+Qed.
+
+Lemma prod_empty_l :
+  forall A2, prod emptyset A2 = @emptyset (U1 * U2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_empty_r :
+  forall A1, prod A1 emptyset = @emptyset (U1 * U2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_full :
+  prod fullset fullset = @fullset (U1 * U2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_full_l :
+  forall A2, prod fullset A2 = fun x : U1 * U2 => A2 (snd x).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_full_r :
+  forall A1, prod A1 fullset = fun x : U1 * U2 => A1 (fst x).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_equiv :
+  forall (A1 : U1 -> Prop) (A2 : U2 -> Prop),
+    prod A1 A2 = inter (prod A1 fullset) (prod fullset A2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_compl_full :
+  forall A1 : U1 -> Prop,
+    prod (compl A1) (@fullset U2) = compl (prod A1 fullset).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_full_compl :
+  forall A2 : U2 -> Prop,
+    prod (@fullset U1) (compl A2) = compl (prod fullset A2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_union_full :
+  forall A1 B1 : U1 -> Prop,
+    prod (union A1 B1) (@fullset U2) = union (prod A1 fullset) (prod B1 fullset).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_full_union :
+  forall A2 B2 : U2 -> Prop,
+    prod (@fullset U1) (union A2 B2) = union (prod fullset A2) (prod fullset B2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_inter_full :
+  forall A1 B1 : U1 -> Prop,
+    prod (inter A1 B1) (@fullset U2) = inter (prod A1 fullset) (prod B1 fullset).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_full_inter :
+  forall A2 B2 : U2 -> Prop,
+    prod (@fullset U1) (inter A2 B2) = inter (prod fullset A2) (prod fullset B2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_inter :
+  forall (A1 B1 : U1 -> Prop) (A2 B2 : U2 -> Prop),
+    inter (prod A1 A2) (prod B1 B2) = prod (inter A1 B1) (inter A2 B2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_compl_union :
+  forall (A1 : U1 -> Prop) (A2 : U2 -> Prop),
+    compl (prod A1 A2) = union (prod (compl A1) A2) (prod fullset (compl A2)).
+Proof.
+intros; subset_ext_auto x.
+Qed.
+
+Lemma prod_compl_disj :
+  forall (A1 : U1 -> Prop) (A2 : U2 -> Prop),
+    disj (prod (compl A1) A2) (prod fullset (compl A2)).
+Proof.
+subset_auto.
+Qed.
+
+Lemma prod_compl_partition :
+  forall (A1 : U1 -> Prop) (A2 : U2 -> Prop),
+    partition (compl (prod A1 A2))
+      (prod (compl A1) A2) (prod fullset (compl A2)).
+Proof.
+intros; split.
+apply prod_compl_union.
+apply prod_compl_disj.
+Qed.
+
+Lemma swap_prod:
+  forall (A1 : U1 -> Prop) (A2 : U2 -> Prop), swap (prod A1 A2) = prod A2 A1.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma prod_swap :
+  forall (A1 : U1 -> Prop) (A2 : U2 -> Prop),
+    (fun x21 : U2 * U1 => prod A1 A2 (swap (fun x : U1 * U2 => x) x21)) = prod A2 A1.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma swap_invol : forall A : U1 * U2 -> Prop, swap (swap A) = A.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+End Prod_Facts.
+
+
+Section Image_Facts.
+
+(** Facts about images. *)
+
+Context {U1 U2 : Type}. (* Universes. *)
+
+Variable f g : U1 -> U2. (* Functions. *)
+
+Lemma image_ext_fun : forall A1, same_fun f g -> image f A1 = image g A1.
+Proof.
+intros; subset_ext_auto x2 Hx2; induction Hx2 as [x1 Hx1];
+    [rewrite H | rewrite <- H]; easy.
+Qed.
+
+Lemma image_ext : forall A1 B1, same A1 B1 -> image f A1 = image f B1.
+Proof.
+intros A1 B1 H.
+subset_ext_auto x2 Hx2; induction Hx2 as [x1 Hx1]; apply Im; apply H; easy.
+Qed.
+
+Lemma image_empty_equiv :
+  forall A1, empty (image f A1) <-> empty A1.
+Proof.
+intros A1; split; intros HA1.
+intros x1 Hx1; apply (HA1 (f x1)); easy.
+intros x2 [x1 Hx1]; apply (HA1 x1); easy.
+Qed.
+
+Lemma image_emptyset : image f emptyset = emptyset.
+Proof.
+apply empty_emptyset, image_empty_equiv; easy.
+Qed.
+
+Lemma image_monot :
+  forall A1 B1, incl A1 B1 -> incl (image f A1) (image f B1).
+Proof.
+intros A1 B1 H1 x2 [x1 Hx1]; apply Im, H1; easy.
+Qed.
+
+Lemma image_union :
+  forall A1 B1, image f (union A1 B1) = union (image f A1) (image f B1).
+Proof.
+intros A1 B1; apply subset_ext_equiv; split; intros x2.
+intros [x1 [Hx1 | Hx1]]; [left | right]; easy.
+intros [[x1 Hx1] | [x1 Hx1]]; apply Im; [left | right]; easy.
+Qed.
+
+Lemma image_inter :
+  forall A1 B1, incl (image f (inter A1 B1)) (inter (image f A1) (image f B1)).
+Proof.
+intros A1 B1 x2 [x1 Hx1]; split; apply Im, Hx1.
+Qed.
+
+Lemma image_diff :
+  forall A1 B1, incl (diff (image f A1) (image f B1)) (image f (diff A1 B1)).
+Proof.
+intros A1 B1 x2 [[x1 Hx1] Hx2']; apply Im; split; try easy.
+intros Hx1'; apply Hx2'; easy.
+Qed.
+
+Lemma image_compl : forall A1, incl (diff (image f fullset) (image f A1)) (image f (compl A1)).
+Proof.
+intros; rewrite compl_equiv_def_diff; apply image_diff.
+Qed.
+
+Lemma image_sym_diff :
+  forall A1 B1,
+    incl (sym_diff (image f A1) (image f B1)) (image f (sym_diff A1 B1)).
+Proof.
+intros; unfold sym_diff; rewrite image_union.
+apply union_monot; apply image_diff.
+Qed.
+
+End Image_Facts.
+
+
+Section Preimage_Facts.
+
+(** Facts about preimages. *)
+
+Context {U1 U2 : Type}. (* Universes. *)
+
+Variable f g : U1 -> U2. (* Functions. *)
+
+Lemma preimage_ext_fun : forall A2, same_fun f g -> preimage f A2 = preimage g A2.
+Proof.
+intros A2 H; subset_ext_auto x1; rewrite (H x1); easy.
+Qed.
+
+Lemma preimage_ext : forall A2 B2, same A2 B2 -> preimage f A2 = preimage f B2.
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma preimage_empty_equiv :
+  forall A2, empty (preimage f A2) <-> disj A2 (image f fullset).
+Proof.
+intros A2; split.
+intros HA2 x2 Hx2 [x1 Hx1].
+
+unfold empty, preimage in HA2.
+apply (HA2 x1).
+
+intros HA2 x2 Hx2 [x1 [_ Hx1]]; apply (HA2 x1); rewrite Hx1 in Hx2; easy.
+intros HA2 x1 Hx1; apply (HA2(f x1)); try easy; exists x1; easy.
+Qed.
+
+Lemma preimage_emptyset : preimage f emptyset = emptyset.
+Proof.
+apply empty_emptyset, preimage_empty_equiv; easy.
+Qed.
+
+Lemma preimage_full_equiv :
+  forall A2, full (preimage f A2) <-> incl (image f fullset) A2.
+Proof.
+intros A2; split; intros HA2.
+intros x2 [x1 [_ Hx1]]; rewrite Hx1; specialize (HA2 x1); easy.
+intros x1; apply HA2; exists x1; easy.
+Qed.
+
+Lemma preimage_monot :
+  forall A2 B2, incl A2 B2 -> incl (preimage f A2) (preimage f B2).
+Proof.
+intros; subset_auto.
+Qed.
+
+Lemma preimage_compl :
+  forall A2, preimage f (compl A2) = compl (preimage f A2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma preimage_union :
+  forall A2 B2,
+    preimage f (union A2 B2) = union (preimage f A2) (preimage f B2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma preimage_inter :
+  forall A2 B2,
+    preimage f (inter A2 B2) = inter (preimage f A2) (preimage f B2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma preimage_diff :
+  forall A2 B2,
+    preimage f (diff A2 B2) = diff (preimage f A2) (preimage f B2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+Lemma preimage_sym_diff :
+  forall A2 B2,
+    preimage f (sym_diff A2 B2) = sym_diff (preimage f A2) (preimage f B2).
+Proof.
+intros; subset_ext_auto.
+Qed.
+
+End Preimage_Facts.
+
+
+Section Image_Preimage_Facts.
+
+(** Facts about images and preimages. *)
+
+Context {U1 U2 : Type}. (* Universes. *)
+
+Variable f : U1 -> U2. (* Function. *)
+
+Lemma image_of_preimage :
+  forall A2, image f (preimage f A2) = inter A2 (image f fullset).
+Proof.
+intros A2; apply subset_ext; intros x2; split.
+(* *)
+intros [x1 [Hx1a Hx1b]]; split.
+rewrite Hx1b; easy.
+exists x1; easy.
+(* *)
+intros [Hx2 [x1 [_ Hx1]]]; rewrite Hx1 in Hx2.
+exists x1; easy.
+Qed.
+
+Lemma image_of_preimage_of_image :
+  forall A1, image f (preimage f (image f A1)) = image f A1.
+Proof.
+intros; rewrite image_of_preimage.
+apply subset_ext; intros x2; split.
+intros [Hx2 _]; easy.
+intros [x1 Hx1]; split; exists x1; easy.
+Qed.
+
+Lemma preimage_of_image : forall A1, incl A1 (preimage f (image f A1)).
+Proof.
+intros A1 x1 Hx1; exists x1; easy.
+Qed.
+
+Lemma preimage_of_image_full : preimage f (image f fullset) = fullset.
+Proof.
+apply subset_ext_equiv; split; try easy.
+apply preimage_of_image.
+Qed.
+
+Lemma preimage_of_image_of_preimage :
+  forall A2, preimage f (image f (preimage f A2)) = preimage f A2.
+Proof.
+intros; rewrite image_of_preimage.
+rewrite preimage_inter, preimage_of_image_full.
+apply inter_full_r.
+Qed.
+
+Lemma preimage_of_image_equiv :
+  forall A1, (preimage f (image f A1)) = A1 <-> exists A2, preimage f A2 = A1.
+Proof.
+intros A1; split.
+intros HA1; exists (image f A1); easy.
+intros [A2 HA2]; rewrite <- HA2.
+apply preimage_of_image_of_preimage.
+Qed.
+
+End Image_Preimage_Facts.