(* This program 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 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program 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      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)


(**********************************************************

               Functions in classical ZFC 

		Carlos Simpson
		carlos@math.unice.fr
		CNRS, Laboratoire J.A. Dieudonne
		Universite de Nice-Sophia Antipolis

***********************************************************

We start from an axiomatization of set theory which is close
to what Benjamin Werner constructed. I suppose that if  you
replace our parameter Ens by the Ens which he constructed, then
one should be able to prove the things which we suppose as axioms, 
relatively easily from his paper. However, we don't treat that here,
rather we just start with some reasonable-sounding axioms.

Then we proceed with the standard development of ZFC set theory.
Our definition of pair is slightly different from the standard
one, designed to make the proofs of the main lemmas about pairs
a little easier and more transparent. 

Our goal is to introduce functions and prove some basic properties.
We also introduce the set Naturals and prove some basic properties. 
See below for a summary of parameters, axioms, definitions and theorems
(only after this summary does the actual Coq file start).

Most of what we do was already done by Guillaume Alexandre in his Coq
contribution ``An axiomatisation of intuitionistic Zermelo-Fraenkel 
set theory'' (zf, 1995), indeed we start with the same parameters and similar 
axioms. We use classical logic (which is easier) though: our parameter 
Ens is in Type. It is also worth noting that everything we do here is
also already known in the context of the MIZAR system.

The main difference between the present work and Alexandre's file
is in the writing style: we don't use the Coq proof engine but rather 
construct explicitly the proof terms, depending often on the Section 
mechanism. The file compiles in about 6 seconds using 
the native code version 6.2.3 on our Linux server.

This style of proof development can be thought of as an attempt to
implement some of the ideas discussed in the TPHOLs '99 volume (for example
the article by Markus Wenzel about Isar).

Our functions CHOICE and REPLACEMENT are defined on all properties 
P: Ens ->Prop; however they satisfy the required properties CHOICE_pr and 
REPLACEMENT_pr1, REPLACEMENT_pr2, only when P holds for one element
(in the case of CHOICE) or when P is bounded (in the case of 
REPLACEMENT).  Since all other constructions are based on these
(plus a few everywhere-defined constructions in the parameters)
we gain the beneficial situation that all of our constructions are
defined as Ens->Ens; no constructions depend on proofs. 
This can be contrasted with the ``setoid'' approach. Our
constructions have the required properties only when the arguments
have the required properties. Thus for example we have a construction
(EV f x) defined for all sets f and x: however, it represents what one
might call the evaluation of the function f on the element x, only when
(IN x (Domain f)). 

The system of axioms which we assume was just invented on the spur of the
moment; it is basically ZFC but there are probably several redundancies.
Also there is a certain interaction between this ZFC and the ambient
type-theoretic language of Coq, which seems to mean that we are probably
implicitly assuming the existence of one or maybe two inaccessible cardinals.
See Werner's paper ``Sets in Types, Types in Sets'' for the discussion that
underlies our justification for doing what we are doing.
A possible perspective of the present work is that one could envision 
coding this first half of Werner's paper, giving a construction Type -> Ens 
with the properties he describes. This might be useful.  






*************************************************************************

                                SUMMARY 
here is a listing of all the parameters, axioms, definitions and theorems
(generated by a c program)

*************************************************************************


Parameter Ens : Type . 

Parameter IN : Ens -> Ens -> Prop . 

Definition SUB := 
   [A, B : Ens]
   (C : Ens)
   ((IN C A) -> (IN C B)).

Record EQ [A : Ens ; B : Ens] : Prop := {
   EQ_forwards : (SUB A B);
   EQ_backwards : (SUB B A)
}.

Axiom excluded_middle : 
   (P : Prop) 
   (not (not P)) 
   -> 
   P . 

Theorem false_implies_everything : 
   (P : Prop) 
   (False -> P) . 

Definition DOESNT_EXIST := 
   [P : Ens -> Prop]
   ((A : Ens) (not (P A))).

Definition EXISTS := 
   [P : Ens -> Prop]
   (not (DOESNT_EXIST P)).

Parameter CHOICE : (P : Ens -> Prop) Ens . 

Axiom CHOICE_pr : 
   (P : Ens -> Prop) 
   (h : (EXISTS P)) 
   (P (CHOICE P)) . 

Parameter EmptySet : Ens . 

Axiom EmptySet_pr : 
   (DOESNT_EXIST ([X : Ens] (IN X EmptySet))) . 

Definition Bounded_By := 
   [A : Ens]
   [P : Ens -> Prop]
   (X : Ens)
   ((P X) -> (IN X A)).

Definition Bounded := 
   [P : Ens -> Prop]
   (EXISTS ([A : Ens] (Bounded_By A P))).

Parameter union : (A, B : Ens) Ens . 

Axiom union_pr1 : 
   (A, B : Ens) 
   (SUB A (union A B)) . 

Axiom union_pr2 : 
   (A, B : Ens) 
   (SUB B (union A B)) . 

Axiom union_pr3 : 
   (A, B, C : Ens) 
   (h : (SUB A C)) 
   (k : (SUB B C)) 
   (SUB (union A B) C) . 

Record nested_IN [A, B, C : Ens] : Prop := {
   nested_IN_ab : (IN A B);
   nested_IN_bc : (IN B C)
}.

Definition b_in_Union_a := 
   [A, B : Ens]
   (EXISTS ([C : Ens] (nested_IN B C A))).

Axiom Union_bounded : 
   (F : Ens) 
   (Bounded (b_in_Union_a F)) . 

Parameter Singleton : Ens -> Ens . 

Axiom Singleton_pr1 : 
   (X : Ens) 
   (IN X (Singleton X)) . 

Axiom Singleton_pr2 : 
   (X : Ens) 
   (Y : Ens) 
   (h : (IN Y (Singleton X))) 
   (EQ X Y) . 

Axiom Extensionality : 
   (X, Y, Z : Ens) 
   (h : (EQ X Y)) 
   (k : (IN Y Z)) 
   (IN X Z) . 

Axiom Powerset_bounded : 
   (X : Ens) 
   (Bounded ([Y : Ens] (SUB Y X))) . 

Parameter REPLACEMENT : (P : Ens -> Prop) Ens . 

Axiom REPLACEMENT_pr1 : 
   (P : Ens -> Prop) 
   (b : (Bounded P)) 
   (X : Ens) 
   ((P X) -> (IN X (REPLACEMENT P))) . 

Axiom REPLACEMENT_pr2 : 
   (P : Ens -> Prop) 
   (b : (Bounded P)) 
   (X : Ens) 
   ((IN X (REPLACEMENT P)) -> (P X)) . 

Definition Zero := 
   EmptySet.

Definition Next : Ens -> Ens := 
   [X : Ens]
   (union X (Singleton X)).

Record Contains_NN [X : Ens] : Prop := {
   Contains_NN_zero : (IN Zero X);
   Contains_NN_nexts : (A : Ens)(h : (IN A X))(IN (Next A) X)
}.

Axiom Infinity_exists : 
   (EXISTS Contains_NN) . 

Theorem EXISTS_th1 : 
   (P : Ens -> Prop) 
   (X : Ens) 
   (p : (P X)) 
   (EXISTS P) . 

Theorem SUB_refl : 
   (A : Ens) 
   (SUB A A) . 

Theorem EQ_refl : 
   (A : Ens) 
   (EQ A A) . 

Theorem EQ_symm : 
   (A, B : Ens) 
   (EQ A B) 
   -> 
   (EQ B A) . 

Definition NEQ := 
   [A, B : Ens]
   (not (EQ A B)).

Theorem NEQ_symm : 
   (A, B : Ens) 
   (k : (NEQ A B)) 
   (NEQ B A) . 

Theorem SUB_trans : 
   (A, B, C : Ens) 
   (h : (SUB A B)) 
   (k : (SUB B C)) 
   (SUB A C) . 

Theorem EQ_trans : 
   (A, B, C : Ens) 
   (h : (EQ A B)) 
   (k : (EQ B C)) 
   (EQ A C) . 

Record StrictSUB [A, B : Ens] : Prop := {
   StrictSUB_sub : (SUB A B);
   StrictSUB_neq : (not (EQ A B))
}.

Theorem StrictSUB_trans1 : 
   (A, B, C : Ens) 
   (h : (StrictSUB A B)) 
   (k : (SUB B C)) 
   (StrictSUB A C) . 

Theorem EmptySet_th1 : 
   (X : Ens) 
   (h : (IN X EmptySet)) 
   False . 

Theorem EmptySet_th2 : 
   (A : Ens) 
   (SUB EmptySet A) . 

Definition Its_empty := 
   [A : Ens]
   (X : Ens)
   (not (IN X A)).

Theorem its_empty_implies_equals_emptyset : 
   (A : Ens) 
   (k : (Its_empty A)) 
   (EQ A EmptySet) . 

Theorem Its_empty_emptyset : 
   (Its_empty EmptySet) . 

Definition Its_nonempty := 
   [A : Ens]
   (not (Its_empty A)).

Theorem Its_nonempty_th1 : 
   (X, A : Ens) 
   (h : (IN X A)) 
   (Its_nonempty A) . 

Theorem Nothing_strictsub_Zero : 
   (X : Ens) 
   (not (StrictSUB X Zero)) . 

Theorem Bounded_th1 : 
   (P : Ens -> Prop) 
   (A : Ens) 
   (h : (X : Ens) ((P X) -> (IN X A))) 
   (Bounded P) . 

Theorem Bounded_th2 : 
   (P : Ens -> Prop) 
   (A : Ens) 
   (h : (Bounded_By A P)) 
   (Bounded P) . 

Definition Bounded_CHOICE := 
   [P : Ens -> Prop]
   (REPLACEMENT P).

Theorem Bounded_CHOICE_pr : 
   (P : Ens -> Prop) 
   (b : (Bounded P)) 
   (Bounded_By (Bounded_CHOICE P) P) . 

Definition SUBPROP := 
   [P : Ens -> Prop]
   [Q : Ens -> Prop]
   (X : Ens)
   (P X)
   ->
   (Q X).

Theorem Bounded_subprops_th1 : 
   (P, Q : Ens -> Prop) 
   (s : (SUBPROP P Q)) 
   (A : Ens) 
   (h : (Bounded_By A Q)) 
   (Bounded_By A P) . 

Theorem Bounded_subprops_th2 : 
   (P, Q : Ens -> Prop) 
   (s : (SUBPROP P Q)) 
   (b : (Bounded Q)) 
   (Bounded P) . 

Record Restriction [P : Ens -> Prop ; A : Ens ; X : Ens] : Prop := {
   remaining_property : (P X);
   the_restriction : (IN X A)
}.

Theorem Restriction_bounded : 
   (P : Ens -> Prop) 
   (A : Ens) 
   (Bounded (Restriction P A)) . 

Definition Set_Of := 
   [A : Ens]
   [P : Ens -> Prop]
   (REPLACEMENT (Restriction P A)).

Theorem Set_Of_pr1 : 
   (A : Ens) 
   (P : Ens -> Prop) 
   (X : Ens) 
   (Restriction P A X) 
   -> 
   (IN X (Set_Of A P)) . 

Theorem Set_Of_pr2 : 
   (A : Ens) 
   (P : Ens -> Prop) 
   (X : Ens) 
   (IN X (Set_Of A P)) 
   -> 
   (Restriction P A X) . 

Theorem Set_Of_th1 : 
   (A : Ens) 
   (P : Ens -> Prop) 
   (X : Ens) 
   (h : (IN X A)) 
   (k : (P X)) 
   (IN X (Set_Of A P)) . 

Theorem Set_Of_th2 : 
   (A : Ens) 
   (P : Ens -> Prop) 
   (X : Ens) 
   (h : (IN X (Set_Of A P))) 
   (P X) . 

Theorem Set_Of_th3 : 
   (A : Ens) 
   (P : Ens -> Prop) 
   (X : Ens) 
   (h : (IN X (Set_Of A P))) 
   (IN X A) . 

Theorem Set_Of_th4 : 
   (A : Ens) 
   (P : Ens -> Prop) 
   (SUB (Set_Of A P) A) . 

Definition intersection := 
   [A, B : Ens]
   (Set_Of A ([X : Ens] (IN X B))).

Theorem intersection_th1 : 
   (A, B : Ens) 
   (SUB (intersection A B) A) . 

Theorem intersection_th2 : 
   (A, B : Ens) 
   (SUB (intersection A B) B) . 

Theorem intersection_th3 : 
   (A, B, X : Ens) 
   (i : (IN X A)) 
   (j : (IN X B)) 
   (IN X (intersection A B)) . 

Theorem intersection_th4 : 
   (A, B, C : Ens) 
   (s : (SUB C A)) 
   (t : (SUB C B)) 
   (SUB C (intersection A B)) . 

Definition IntersectionProp := 
   [F : Ens -> Ens]
   [X : Ens]
   (Y : Ens)
   (IN X (F Y)).

Definition Intersection : (F : Ens -> Ens) Ens := 
   [F : Ens -> Ens]
   (REPLACEMENT (IntersectionProp F)).

Theorem Intersection_pr1 : 
   (F : Ens -> Ens) 
   (X : Ens) 
   (IntersectionProp F X) 
   -> 
   (IN X (Intersection F)) . 

Theorem Intersection_pr2 : 
   (F : Ens -> Ens) 
   (X : Ens) 
   (IN X (Intersection F)) 
   -> 
   (IntersectionProp F X) . 

Theorem Intersection_th1 : 
   (F : Ens -> Ens) 
   (X : Ens) 
   (h : ((Y : Ens) (IN X (F Y)))) 
   (IN X (Intersection F)) . 

Theorem Intersection_th2 : 
   (F : Ens -> Ens) 
   (X : Ens) 
   (Y : Ens) 
   (i : (IN X (Intersection F))) 
   (IN X (F Y)) . 

Theorem Singleton_th1 : 
   (X, A : Ens) 
   (h : (IN X A)) 
   (SUB (Singleton X) A) . 

Theorem Singleton_th2 : 
   (X : Ens) 
   (Its_nonempty (Singleton X)) . 

Theorem union_th1 : 
   (A, B : Ens) 
   (X : Ens) 
   (h : (IN X A)) 
   (IN X (union A B)) . 

Theorem union_th2 : 
   (A, B : Ens) 
   (X : Ens) 
   (h : (IN X B)) 
   (IN X (union A B)) . 

Theorem union_th3 : 
   (A, B : Ens) 
   (X : Ens) 
   (h : (not (IN X A))) 
   (k : (not (IN X B))) 
   (not (IN X (union A B))) . 

Theorem union_th4 : 
   (P : Prop) 
   (A, B, X : Ens) 
   (i : (IN X (union A B))) 
   (a : ((IN X A) -> P)) 
   (b : ((IN X B) -> P)) 
   P . 

Theorem union_refl : 
   (A : Ens) 
   (EQ A (union A A)) . 

Theorem union_symm : 
   (A, B : Ens) 
   (EQ (union A B) (union B A)) . 

Definition Union : (F : Ens) Ens := 
   [F : Ens]
   (REPLACEMENT (b_in_Union_a F)).

Theorem Union_pr1 : 
   (F, X : Ens) 
   (h : (EXISTS ([U : Ens] (nested_IN X U F)))) 
   (IN X (Union F)) . 

Theorem Union_pr2 : 
   (F, X : Ens) 
   (i : (IN X (Union F))) 
   (EXISTS ([U : Ens] (nested_IN X U F))) . 

Definition Union_intermediate : (F, X : Ens) (i : (IN X (Union F))) Ens := 
   [F, X : Ens]
   [i : (IN X (Union F))]
   (CHOICE ([U : Ens] (nested_IN X U F))).

Theorem Union_intermediate_pr : 
   (F, X : Ens) 
   (i : (IN X (Union F))) 
   (nested_IN X (Union_intermediate F X i) F) . 

Theorem Union_intermediate_th1 : 
   (F, X : Ens) 
   (i : (IN X (Union F))) 
   (IN X (Union_intermediate F X i)) . 

Theorem Union_intermediate_th2 : 
   (F, X : Ens) 
   (i : (IN X (Union F))) 
   (IN (Union_intermediate F X i) F) . 

Theorem Union_th1 : 
   (F, X, U : Ens) 
   (h : (IN X U)) 
   (k : (IN U F)) 
   (IN X (Union F)) . 

Definition has_leq_0_elements := 
   Its_empty.

Theorem zero_has_leq_0_elements : 
   (has_leq_0_elements Zero) . 

Definition has_geq_1_elements := 
   [A : Ens]
   (not (has_leq_0_elements A)).

Definition Choose_an_element : (A : Ens) (k : (has_geq_1_elements A)) Ens := 
   [A : Ens]
   [k : (has_geq_1_elements A)]
   (CHOICE ([X : Ens] (IN X A))).

Theorem Choose_an_element_pr : 
   (A : Ens) 
   (k : (has_geq_1_elements A)) 
   (IN (Choose_an_element A k) A) . 

Theorem has_geq_1_elements_th1 : 
   (A : Ens) 
   (X : Ens) 
   (k : (IN X A)) 
   (has_geq_1_elements A) . 

Theorem Singletons_have_geq_1_elements : 
   (X : Ens) 
   (has_geq_1_elements (Singleton X)) . 

Definition has_leq_1_elements := 
   [A : Ens]
   (X, Y : Ens)
   (k : (IN X A))
   (l : (IN Y A))
   (EQ X Y).

Theorem has_leq_0_elements_implies_leq_1 : 
   (A : Ens) 
   (q : (has_leq_0_elements A)) 
   (has_leq_1_elements A) . 

Theorem Singletons_have_leq_1_elements : 
   (A : Ens) 
   (has_leq_1_elements (Singleton A)) . 

Definition has_geq_2_elements := 
   [A : Ens]
   (not (has_leq_1_elements A)).

Theorem has_geq_2_elements_th1 : 
   (A : Ens) 
   (X, Y : Ens) 
   (k : (IN X A)) 
   (l : (IN Y A)) 
   (m : (not (EQ X Y))) 
   (has_geq_2_elements A) . 

Definition Doubleton := 
   [X : Ens]
   [Y : Ens]
   (union (Singleton X) (Singleton Y)).

Theorem Doubleton_th1 : 
   (X, Y : Ens) 
   (IN X (Doubleton X Y)) . 

Theorem Doubleton_th2 : 
   (X, Y : Ens) 
   (IN Y (Doubleton X Y)) . 

Theorem Doubleton_th3 : 
   (X, Y : Ens) 
   (A : Ens) 
   (iXA : (IN X A)) 
   (iYA : (IN Y A)) 
   (SUB (Doubleton X Y) A) . 

Theorem Doubleton_th4 : 
   (X, Y : Ens) 
   (Z : Ens) 
   (k : (IN Z (Doubleton X Y))) 
   (m : (not (EQ Z X))) 
   (n : (not (EQ Z Y))) 
   False . 

Theorem Doubleton_th4_a : 
   (X, Y : Ens) 
   (Z : Ens) 
   (k : (IN Z (Doubleton X Y))) 
   (m : (not (EQ Z X))) 
   (EQ Z Y) . 

Theorem Doubleton_th4_b : 
   (X, Y : Ens) 
   (Z : Ens) 
   (k : (IN Z (Doubleton X Y))) 
   (n : (not (EQ Z Y))) 
   (EQ Z X) . 

Theorem distinct_Doubletons_have_geq_2_elements : 
   (X, Y : Ens) 
   (n : (not (EQ X Y))) 
   (has_geq_2_elements (Doubleton X Y)) . 

Theorem Big_Extensionality : 
   (P : Ens -> Prop) 
   (X, Y : Ens) 
   (p : (P X)) 
   (e : (EQ X Y)) 
   (P Y) . 

Theorem Substitute : 
   (X, Y : Ens) 
   (P : Ens -> Prop) 
   (e : (EQ X Y)) 
   (p : (P Y)) 
   (P X) . 

Theorem counting_lem1 : 
   (X, Y : Ens) 
   (m : (has_leq_0_elements X)) 
   (n : (has_geq_1_elements Y)) 
   (not (EQ X Y)) . 

Theorem counting_lem2 : 
   (X, Y : Ens) 
   (m : (has_leq_1_elements X)) 
   (n : (has_geq_2_elements Y)) 
   (not (EQ X Y)) . 

Definition First : Ens -> Ens := 
   [X : Ens]
   (Singleton X).

Definition Second : Ens -> Ens := 
   [X : Ens]
   (Doubleton Zero (Singleton X)).

Definition PAIR : Ens -> Ens -> Ens := 
   [X, Y : Ens]
   (Doubleton (First X) (Second Y)).

Theorem First_uniqueness : 
   (A, B : Ens) 
   (m : (EQ (First A) (First B))) 
   (EQ A B) . 

Theorem Singleton_uniqueness : 
   (A, B : Ens) 
   (m : (EQ (Singleton A) (Singleton B))) 
   (EQ A B) . 

Record pairwise_EQ [A, B, C, D : Ens] : Prop := {
   pairwise_EQ_ac : (EQ A C);
   pairwise_EQ_bd : (EQ B D)
}.

Theorem Doubleton_uniqueness : 
   (P : Ens -> Prop) 
   (A, B, C, D : Ens) 
   (pA : (P A)) 
   (nB : (not (P B))) 
   (pC : (P C)) 
   (nD : (not (P D))) 
   (e : (EQ (Doubleton A B) (Doubleton C D))) 
   (pairwise_EQ A B C D) . 

Theorem Second_has_geq_2_elements : 
   (A : Ens) 
   (has_geq_2_elements (Second A)) . 

Theorem Second_uniqueness : 
   (A, B : Ens) 
   (k : (EQ (Second A) (Second B))) 
   (EQ A B) . 

Theorem PAIR_uniqueness : 
   (A, B, C, D : Ens) 
   (e : (EQ (PAIR A B) (PAIR C D))) 
   (pairwise_EQ A B C D) . 

Theorem PAIR_uni_ac : 
   (A, B, C, D : Ens) 
   (e : (EQ (PAIR A B) (PAIR C D))) 
   (EQ A C) . 

Theorem PAIR_uni_bd : 
   (A, B, C, D : Ens) 
   (e : (EQ (PAIR A B) (PAIR C D))) 
   (EQ B D) . 

Definition is_a_pair := 
   [M : Ens]
   (EXISTS ([A : Ens] (EXISTS ([B : Ens] (EQ M (PAIR A B)))))).

Theorem a_pair_is_a_pair : 
   (A, B : Ens) 
   (is_a_pair (PAIR A B)) . 

Theorem a_pair_is_a_pair_th2 : 
   (A, B, U : Ens) 
   (i : (EQ (PAIR A B) U)) 
   (is_a_pair U) . 

Definition PR1 := 
   [M : Ens]
   (CHOICE ([A : Ens] (EXISTS ([B : Ens] (EQ M (PAIR A B)))))).

Theorem PAIR_proj1_pr1 : 
   (M : Ens) 
   (p : (is_a_pair M)) 
   (EXISTS ([B : Ens] (EQ M (PAIR (PR1 M) B)))) . 

Definition PR2 := 
   [M : Ens]
   (CHOICE ([B : Ens] (EQ M (PAIR (PR1 M) B)))).

Theorem PAIR_proj_th1 : 
   (M : Ens) 
   (p : (is_a_pair M)) 
   (EQ M (PAIR (PR1 M) (PR2 M))) . 

Theorem PAIR_proj_th2 : 
   (X, Y : Ens) 
   (pairwise_EQ X Y (PR1 (PAIR X Y)) (PR2 (PAIR X Y))) . 

Theorem PAIR_proj_th3 : 
   (X, Y : Ens) 
   (EQ X (PR1 (PAIR X Y))) . 

Theorem PAIR_proj_th4 : 
   (X, Y : Ens) 
   (EQ Y (PR2 (PAIR X Y))) . 

Theorem PAIR_proj_uni : 
   (M : Ens) 
   (m : (is_a_pair M)) 
   (N : Ens) 
   (n : (is_a_pair N)) 
   (e : (EQ (PR1 M) (PR1 N))) 
   (f : (EQ (PR2 M) (PR2 N))) 
   (EQ M N) . 

Definition Powerset := 
   [X : Ens]
   (REPLACEMENT ([Y : Ens] (SUB Y X))).

Theorem Powerset_pr1 : 
   (X, Y : Ens) 
   (h : (SUB Y X)) 
   (IN Y (Powerset X)) . 

Theorem Powerset_pr2 : 
   (X, Y : Ens) 
   (i : (IN Y (Powerset X))) 
   (SUB Y X) . 

Theorem Powerset_th1 : 
   (A : Ens) 
   (IN Zero (Powerset A)) . 

Theorem Powerset_th2 : 
   (A, X, Y : Ens) 
   (x : (IN X (Powerset A))) 
   (y : (IN Y (Powerset A))) 
   (IN (union X Y) (Powerset A)) . 

Theorem Powerset_th3 : 
   (A, X, Y : Ens) 
   (x : (IN X (Powerset A))) 
   (y : (IN Y (Powerset A))) 
   (IN (intersection X Y) (Powerset A)) . 

Theorem Powerset_th4 : 
   (A, X : Ens) 
   (x : (IN X A)) 
   (IN (Singleton X) (Powerset A)) . 

Theorem Powerset_th5 : 
   (A, X, Y : Ens) 
   (x : (IN X A)) 
   (y : (IN Y A)) 
   (IN (Doubleton X Y) (Powerset A)) . 

Theorem Powerset_th6 : 
   (A, X : Ens) 
   (x : (IN X A)) 
   (IN (Second X) (Powerset (Powerset A))) . 

Theorem Powerset_th7 : 
   (A, B : Ens) 
   (a : (SUB A B)) 
   (SUB (Powerset A) (Powerset B)) . 

Definition Element_of_NN := 
   [Y : Ens]
   (X : Ens)
   (k : (Contains_NN X))
   (IN Y X).

Theorem Zero_element_of_NN : 
   (Element_of_NN Zero) . 

Theorem Nexts_element_of_NN : 
   (A : Ens) 
   (h : (Element_of_NN A)) 
   (Element_of_NN (Next A)) . 

Definition Set_containing_NN := 
   (CHOICE Contains_NN).

Theorem Set_containing_NN_pr : 
   (Contains_NN Set_containing_NN) . 

Theorem Bounded_NN_pre : 
   (EXISTS ([A : Ens] (Bounded_By A Element_of_NN))) . 

Theorem Bounded_NN : 
   (Bounded Element_of_NN) . 

Definition Naturals := 
   (REPLACEMENT Element_of_NN).

Theorem Naturals_pr1 : 
   (X : Ens) 
   (Element_of_NN X) 
   -> 
   (IN X Naturals) . 

Theorem Naturals_pr2 : 
   (X : Ens) 
   (IN X Naturals) 
   -> 
   (Element_of_NN X) . 

Theorem Zero_in_Naturals : 
   (IN Zero Naturals) . 

Theorem Nexts_in_Naturals : 
   (A : Ens) 
   (h : (IN A Naturals)) 
   (IN (Next A) Naturals) . 

Theorem Contains_NN_Naturals : 
   (Contains_NN Naturals) . 

Theorem Naturals_th1 : 
   (X : Ens) 
   (h : (Contains_NN X)) 
   (SUB Naturals X) . 

Theorem anything_sub_next_of_itself : 
   (A : Ens) 
   (SUB A (Next A)) . 

Theorem anything_in_next_of_itself : 
   (A : Ens) 
   (IN A (Next A)) . 

Definition naturals_induction_nexts := 
   [P : Ens -> Prop]
   (A : Ens)
   (h : (IN A Naturals))
   (k : (P A))
   (P (Next A)).

Theorem naturals_inductionA : 
   (P : Ens -> Prop) 
   (IH_zero : (P Zero)) 
   (IH_nexts : (naturals_induction_nexts P)) 
   (B : Ens) 
   (p : (IN B Naturals)) 
   (P B) . 

Definition in_then_strictsub := 
   [N : Ens]
   (X : Ens)
   (IN X N)
   ->
   (StrictSUB X N).

Definition not_in_itself := 
   [X : Ens]
   (not (IN X X)).

Record naturals_main_ind_hyp [N : Ens] : Prop := {
   naturals_main_ind1 : (in_then_strictsub N);
   naturals_main_ind2 : (not_in_itself N)
}.

Theorem some_things_strictsub_their_nexts : 
   (A : Ens) 
   (h : (not_in_itself A)) 
   (StrictSUB A (Next A)) . 

Theorem in_then_strictsub_Zero : 
   (X : Ens) 
   (IN X Zero) 
   -> 
   (StrictSUB X Zero) . 

Theorem zero_not_in_itself : 
   (not_in_itself Zero) . 

Theorem naturals_main_ind_for_Zero : 
   (naturals_main_ind_hyp Zero) . 

Theorem naturals_main_induction_next : 
   (A : Ens) 
   (h : (naturals_main_ind_hyp A)) 
   (naturals_main_ind_hyp (Next A)) . 

Theorem naturals_main_induction_next_1 : 
   (naturals_induction_nexts naturals_main_ind_hyp) . 

Theorem naturals_main_th1 : 
   (B : Ens) 
   (i : (IN B Naturals)) 
   (naturals_main_ind_hyp B) . 

Theorem naturals_main_th2 : 
   (B : Ens) 
   (i : (IN B Naturals)) 
   (in_then_strictsub B) . 

Theorem naturals_main_th2_rewrite : 
   (B : Ens) 
   (i : (IN B Naturals)) 
   (A : Ens) 
   (j : (IN A B)) 
   (StrictSUB A B) . 

Theorem naturals_main_th3 : 
   (B : Ens) 
   (i : (IN B Naturals)) 
   (not_in_itself B) . 

Theorem naturals_main_th3_rewrite : 
   (B : Ens) 
   (i : (IN B Naturals)) 
   (not (IN B B)) . 

Definition UnionPlus := 
   [F : Ens]
   (union F (Union F)).

Definition Total := 
   [R : Ens]
   (UnionPlus (UnionPlus (UnionPlus R))).

Theorem UnionPlus_th1 : 
   (X, F : Ens) 
   (i : (IN X F)) 
   (IN X (UnionPlus F)) . 

Theorem UnionPlus_th2 : 
   (X, U, F : Ens) 
   (i : (IN X U)) 
   (j : (IN U F)) 
   (IN X (UnionPlus F)) . 

Theorem Total_th1 : 
   (X, F : Ens) 
   (i : (IN X F)) 
   (IN X (Total F)) . 

Theorem Total_th2 : 
   (X, Y, F : Ens) 
   (i : (IN X Y)) 
   (j : (IN Y F)) 
   (IN X (Total F)) . 

Theorem Total_th3 : 
   (X, Y, Z, F : Ens) 
   (i : (IN X Y)) 
   (j : (IN Y Z)) 
   (k : (IN Z F)) 
   (IN X (Total F)) . 

Theorem Total_th4 : 
   (X, Y, Z, W, F : Ens) 
   (i : (IN X Y)) 
   (j : (IN Y Z)) 
   (k : (IN Z W)) 
   (l : (IN W F)) 
   (IN X (Total F)) . 

Theorem Relation_Total_th1 : 
   (R : Ens) 
   (A, B : Ens) 
   (i : (IN (PAIR A B) R)) 
   (IN A (Total R)) . 

Theorem Relation_Total_th2 : 
   (R : Ens) 
   (A, B : Ens) 
   (i : (IN (PAIR A B) R)) 
   (IN B (Total R)) . 

Definition Domain_prop := 
   [R : Ens]
   [X : Ens]
   (EXISTS ([Y : Ens] (IN (PAIR X Y) R))).

Definition Range_prop := 
   [R : Ens]
   [Y : Ens]
   (EXISTS ([X : Ens] (IN (PAIR X Y) R))).

Definition EV := 
   [R : Ens]
   [X : Ens]
   (CHOICE ([Y : Ens] (IN (PAIR X Y) R))).

Theorem EV_pr : 
   (R : Ens) 
   (X : Ens) 
   (p : (Domain_prop R X)) 
   (IN (PAIR X (EV R X)) R) . 

Definition inverse_EV := 
   [R : Ens]
   [Y : Ens]
   (CHOICE ([X : Ens] (IN (PAIR X Y) R))).

Theorem inverse_EV_pr : 
   (R : Ens) 
   (Y : Ens) 
   (p : (Range_prop R Y)) 
   (IN (PAIR (inverse_EV R Y) Y) R) . 

Theorem Domain_prop_bounded : 
   (R : Ens) 
   (Bounded (Domain_prop R)) . 

Theorem Range_prop_bounded : 
   (R : Ens) 
   (Bounded (Range_prop R)) . 

Definition Domain := 
   [R : Ens]
   (REPLACEMENT (Domain_prop R)).

Theorem Domain_pr1 : 
   (R : Ens) 
   (X : Ens) 
   (p : (Domain_prop R X)) 
   (IN X (Domain R)) . 

Theorem Domain_pr2 : 
   (R : Ens) 
   (X : Ens) 
   (i : (IN X (Domain R))) 
   (Domain_prop R X) . 

Theorem EV_th1 : 
   (R : Ens) 
   (X : Ens) 
   (i : (IN X (Domain R))) 
   (IN (PAIR X (EV R X)) R) . 

Theorem Domain_th1 : 
   (R : Ens) 
   (X, Y : Ens) 
   (i : (IN (PAIR X Y) R)) 
   (IN X (Domain R)) . 

Definition Range := 
   [R : Ens]
   (REPLACEMENT (Range_prop R)).

Theorem Range_pr1 : 
   (R : Ens) 
   (X : Ens) 
   (p : (Range_prop R X)) 
   (IN X (Range R)) . 

Theorem Range_pr2 : 
   (R : Ens) 
   (X : Ens) 
   (i : (IN X (Range R))) 
   (Range_prop R X) . 

Theorem inverse_EV_th1 : 
   (R : Ens) 
   (Y : Ens) 
   (i : (IN Y (Range R))) 
   (IN (PAIR (inverse_EV R Y) Y) R) . 

Theorem Range_th1 : 
   (R : Ens) 
   (X, Y : Ens) 
   (i : (IN (PAIR X Y) R)) 
   (IN Y (Range R)) . 

Theorem EV_in_range : 
   (R, X : Ens) 
   (i : (IN X (Domain R))) 
   (IN (EV R X) (Range R)) . 

Theorem inverse_EV_in_domain : 
   (R, Y : Ens) 
   (i : (IN Y (Range R))) 
   (IN (inverse_EV R Y) (Domain R)) . 

Definition is_a_relation := 
   [R : Ens]
   (X : Ens)
   (i : (IN X R))
   (is_a_pair X).

Theorem relation_sub : 
   (R : Ens) 
   (r : (is_a_relation R)) 
   (S : Ens) 
   (SUB S R) 
   -> 
   (is_a_relation S) . 

Definition well_definedness := 
   [F : Ens]
   (X, Y, Z : Ens)
   (i : (IN (PAIR X Y) F))
   (j : (IN (PAIR X Z) F))
   (EQ Y Z).

Theorem well_definedness_sub : 
   (F : Ens) 
   (w : (well_definedness F)) 
   (R : Ens) 
   (h : (SUB R F)) 
   (well_definedness R) . 

Record is_a_function [F : Ens] : Prop := {
   function_is_a_relation : (is_a_relation F);
   function_well_definedness : (well_definedness F)
}.

Theorem function_sub : 
   (F : Ens) 
   (f : (is_a_function F)) 
   (G : Ens) 
   (s : (SUB G F)) 
   (is_a_function G) . 

Record is_a_function_on [D, F : Ens] : Prop := {
   function_on_fn : (is_a_function F);
   function_on_dom : (EQ D (Domain F))
}.

Theorem function_is_a_function_on : 
   (F : Ens) 
   (f : (is_a_function F)) 
   (is_a_function_on (Domain F) F) . 

Theorem function_th1 : 
   (F : Ens) 
   (f : (is_a_function F)) 
   (X, Y : Ens) 
   (i : (IN (PAIR X Y) F)) 
   (EQ Y (EV F X)) . 

Definition Extensionally_equivalent := 
   [F, G : Ens]
   (X : Ens)
   (i : (IN X (Domain F)))
   (j : (IN X (Domain G)))
   (EQ (EV F X) (EV G X)).

Theorem ex_eq_symm : 
   (F, G : Ens) 
   (Extensionally_equivalent F G) 
   -> 
   (Extensionally_equivalent G F) . 

Theorem ex_eq_sub : 
   (F, G : Ens) 
   (f : (is_a_function F)) 
   (s : (SUB (Domain F) (Domain G))) 
   (e : (Extensionally_equivalent F G)) 
   (SUB F G) . 

Theorem Extensionality_for_functions : 
   (F, G : Ens) 
   (f : (is_a_function F)) 
   (g : (is_a_function G)) 
   (d : (EQ (Domain F) (Domain G))) 
   (e : (Extensionally_equivalent F G)) 
   (EQ F G) . 

Theorem function_evaluation : 
   (F, X, Y : Ens) 
   (f : (is_a_function F)) 
   (i : (IN (PAIR X Y) F)) 
   (EQ Y (EV F X)) . 

Definition restricted_to := 
   [A, F : Ens]
   (Set_Of F ([M : Ens] (IN (PR1 M) A))).

Theorem restricted_to_th1 : 
   (A, F : Ens) 
   (U : Ens) 
   (i : (IN U F)) 
   (j : (IN (PR1 U) A)) 
   (IN U (restricted_to A F)) . 

Theorem restricted_to_th2 : 
   (A, F : Ens) 
   (U : Ens) 
   (i : (IN U (restricted_to A F))) 
   (IN (PR1 U) A) . 

Theorem restricted_to_th3 : 
   (A, F : Ens) 
   (U : Ens) 
   (i : (IN U (restricted_to A F))) 
   (IN U F) . 

Theorem restricted_to_th4 : 
   (A, F : Ens) 
   (SUB (restricted_to A F) F) . 

Theorem restricted_to_th5 : 
   (A, F : Ens) 
   (EQ (intersection A (Domain F)) (Domain (restricted_to A F))) . 

Theorem restricted_to_th6 : 
   (A, F : Ens) 
   (f : (is_a_function F)) 
   (s : (SUB (Domain F) A)) 
   (SUB F (restricted_to A F)) . 

Theorem restricted_to_th7 : 
   (A, F : Ens) 
   (f : (is_a_function F)) 
   (s : (SUB (Domain F) A)) 
   (EQ F (restricted_to A F)) . 

Theorem restricted_to_th8 : 
   (A, F : Ens) 
   (f : (is_a_function F)) 
   (X : Ens) 
   (i : (IN X (intersection A (Domain F)))) 
   (EQ (EV F X) (EV (restricted_to A F) X)) . 

Theorem restricted_to_th9 : 
   (A, F : Ens) 
   (f : (is_a_function F)) 
   (X : Ens) 
   (i : (IN X A)) 
   (j : (IN X (Domain F))) 
   (EQ (EV F X) (EV (restricted_to A F) X)) . 

Theorem empty_function_relation : 
   (is_a_relation Zero) . 

Theorem empty_function_well_definedness : 
   (well_definedness Zero) . 

Theorem empty_function_function : 
   (is_a_function Zero) . 

Theorem empty_function_domain_empty : 
   (Its_empty (Domain Zero)) . 

Theorem empty_function_domain : 
   (EQ Zero (Domain Zero)) . 

Definition PowerPlus := 
   [A : Ens]
   (union A (Powerset A)).

Theorem PowerPlus_th1 : 
   (A : Ens) 
   (SUB A (PowerPlus A)) . 

Theorem PowerPlus_th2 : 
   (A : Ens) 
   (SUB (Powerset A) (PowerPlus A)) . 

Definition PowerTotal := 
   [A : Ens]
   (Powerset (PowerPlus (PowerPlus A))).

Theorem PowerTotal_th1 : 
   (A, X, Y : Ens) 
   (x : (IN X A)) 
   (y : (IN Y A)) 
   (IN (PAIR X Y) (PowerTotal A)) . 

Theorem PowerTotal_th2 : 
   (A, B, X, Y : Ens) 
   (x : (IN X A)) 
   (y : (IN Y B)) 
   (IN (PAIR X Y) (PowerTotal (union A B))) . 

Record in_cartesian [A, B, P : Ens] : Prop := {
   in_cartesian_pair : (is_a_pair P);
   in_cartesian_pr1 : (IN (PR1 P) A);
   in_cartesian_pr2 : (IN (PR2 P) B)
}.

Theorem in_cartesian_bounded : 
   (A, B : Ens) 
   (Bounded (in_cartesian A B)) . 

Definition Cartesian := 
   [A, B : Ens]
   (REPLACEMENT (in_cartesian A B)).

Theorem Cartesian_pr1 : 
   (A, B : Ens) 
   (M : Ens) 
   (h : (in_cartesian A B M)) 
   (IN M (Cartesian A B)) . 

Theorem Cartesian_pr2 : 
   (A, B : Ens) 
   (M : Ens) 
   (i : (IN M (Cartesian A B))) 
   (in_cartesian A B M) . 

Theorem Cartesian_construction : 
   (A, B : Ens) 
   (X, Y : Ens) 
   (i : (IN X A)) 
   (j : (IN Y B)) 
   (IN (PAIR X Y) (Cartesian A B)) . 

Theorem Cartesian_th1 : 
   (A, B : Ens) 
   (U : Ens) 
   (i : (IN U (Cartesian A B))) 
   (is_a_pair U) . 

Theorem Cartesian_proj1_th : 
   (A, B, U : Ens) 
   (i : (IN U (Cartesian A B))) 
   (IN (PR1 U) A) . 

Theorem Cartesian_proj2_th : 
   (A, B, U : Ens) 
   (i : (IN U (Cartesian A B))) 
   (IN (PR2 U) B) . 

Theorem Cartesian_pair_th1 : 
   (A, B, X, Y : Ens) 
   (i : (IN (PAIR X Y) (Cartesian A B))) 
   (IN X A) . 

Theorem Cartesian_pair_th2 : 
   (A, B, X, Y : Ens) 
   (i : (IN (PAIR X Y) (Cartesian A B))) 
   (IN Y B) . 

Theorem relations_in_cartesian : 
   (R : Ens) 
   (r : (is_a_relation R)) 
   (SUB R (Cartesian (Domain R) (Range R))) . 

Theorem cartesian_is_relation : 
   (A, B : Ens) 
   (is_a_relation (Cartesian A B)) . 

Theorem cartesian_subs_are_relations : 
   (A, B : Ens) 
   (R : Ens) 
   (s : (SUB R (Cartesian A B))) 
   (is_a_relation R) . 

Theorem covering_th1 : 
   (A, B, F, G : Ens) 
   (f : (is_a_function F)) 
   (g : (is_a_function G)) 
   (u : (EQ (Domain F) (union A B))) 
   (i : (EQ (restricted_to A F) (restricted_to A G))) 
   (j : (EQ (restricted_to B F) (restricted_to B G))) 
   (Extensionally_equivalent F G) . 

Theorem covering_th2 : 
   (A, B, F, G : Ens) 
   (f : (is_a_function F)) 
   (g : (is_a_function G)) 
   (u : (EQ (Domain F) (union A B))) 
   (v : (EQ (Domain G) (union A B))) 
   (i : (EQ (restricted_to A F) (restricted_to A G))) 
   (j : (EQ (restricted_to B F) (restricted_to B G))) 
   (EQ F G) . 

Theorem glueing_th1 : 
   (F, G : Ens) 
   (f : (is_a_relation F)) 
   (g : (is_a_relation G)) 
   (is_a_relation (union F G)) . 

Theorem glueing_th2 : 
   (F, G : Ens) 
   (SUB (Domain (union F G)) (union (Domain F) (Domain G))) . 

Theorem glueing_th3 : 
   (F, G : Ens) 
   (SUB (union (Domain F) (Domain G)) (Domain (union F G))) . 

Theorem glueing_th4 : 
   (F, G : Ens) 
   (EQ (Domain (union F G)) (union (Domain F) (Domain G))) . 

Theorem glueing_th5 : 
   (F, G : Ens) 
   (f : (is_a_function F)) 
   (g : (is_a_function G)) 
   (e : (Extensionally_equivalent F G)) 
   (is_a_function (union F G)) . 

Record Comp_inter [F, G, X, Y, Z : Ens] : Prop := {
   Comp_inter_xy : (IN (PAIR X Y) F);
   Comp_inter_yz : (IN (PAIR Y Z) G)
}.

Record Comp_prop [F, G, X : Ens] : Prop := {
   Comp_pair : (is_a_pair X);
   Comp_intern : (EXISTS ([Y : Ens] (Comp_inter F G (PR1 X) Y (PR2 X))))
}.

Definition Comp_INTER := 
   [F, G, X : Ens]
   (CHOICE ([Y : Ens] (Comp_inter F G (PR1 X) Y (PR2 X)))).

Theorem Comp_INTER_pr1 : 
   (F, G, X : Ens) 
   (c : (Comp_prop F G X)) 
   (Comp_inter F G (PR1 X) (Comp_INTER F G X) (PR2 X)) . 

Theorem Comp_INTER_th1 : 
   (F, G, X : Ens) 
   (c : (Comp_prop F G X)) 
   (IN (PAIR (PR1 X) (Comp_INTER F G X)) F) . 

Theorem Comp_INTER_th2 : 
   (F, G, X : Ens) 
   (c : (Comp_prop F G X)) 
   (IN (PAIR (Comp_INTER F G X) (PR2 X)) G) . 

Theorem Comp_prop_th1 : 
   (F, G, X : Ens) 
   (c : (Comp_prop F G X)) 
   (IN (PR1 X) (Domain F)) . 

Theorem Comp_prop_th2 : 
   (F, G, X : Ens) 
   (c : (Comp_prop F G X)) 
   (IN (PR2 X) (Range G)) . 

Theorem Comp_prop_th3 : 
   (F, G, X : Ens) 
   (c : (Comp_prop F G X)) 
   (IN X (Cartesian (Domain F) (Range G))) . 

Theorem composition_bounded_by : 
   (F, G : Ens) 
   (Bounded_By (Cartesian (Domain F) (Range G)) (Comp_prop F G)) . 

Theorem composition_bounded : 
   (F, G : Ens) 
   (Bounded (Comp_prop F G)) . 

Definition COMP := 
   [F, G : Ens]
   (REPLACEMENT (Comp_prop F G)).

Theorem COMP_pr1 : 
   (F, G, X : Ens) 
   (Comp_prop F G X) 
   -> 
   (IN X (COMP F G)) . 

Theorem COMP_pr2 : 
   (F, G, X : Ens) 
   (IN X (COMP F G)) 
   -> 
   (Comp_prop F G X) . 

Theorem COMP_th1 : 
   (F, G : Ens) 
   (is_a_relation (COMP F G)) . 

Theorem COMP_th2 : 
   (F, G : Ens) 
   (SUB (COMP F G) (Cartesian (Domain F) (Range G))) . 

Theorem COMP_th3 : 
   (F, G, X : Ens) 
   (i : (IN X (COMP F G))) 
   (IN (PAIR (PR1 X) (Comp_INTER F G X)) F) . 

Theorem COMP_th4 : 
   (F, G, X : Ens) 
   (i : (IN X (COMP F G))) 
   (IN (PAIR (Comp_INTER F G X) (PR2 X)) G) . 

Definition Comp_INTERp := 
   [F, G, X, Y : Ens]
   (Comp_INTER F G (PAIR X Y)).

Theorem COMP_th3p : 
   (F, G, X, Y : Ens) 
   (i : (IN (PAIR X Y) (COMP F G))) 
   (IN (PAIR X (Comp_INTERp F G X Y)) F) . 

Theorem COMP_th4p : 
   (F, G, X, Y : Ens) 
   (i : (IN (PAIR X Y) (COMP F G))) 
   (IN (PAIR (Comp_INTERp F G X Y) Y) G) . 

Theorem composition_well_definedness : 
   (F, G : Ens) 
   (f : (well_definedness F)) 
   (g : (well_definedness G)) 
   (well_definedness (COMP F G)) . 

Theorem composition_th1 : 
   (F, G : Ens) 
   (f : (well_definedness F)) 
   (g : (well_definedness G)) 
   (is_a_function (COMP F G)) . 

Theorem composition_th2 : 
   (F, G : Ens) 
   (f : (is_a_function F)) 
   (g : (is_a_function G)) 
   (is_a_function (COMP F G)) . 

Theorem COMP_th5 : 
   (F, G, X, Y, Z : Ens) 
   (i : (IN (PAIR X Y) F)) 
   (j : (IN (PAIR Y Z) G)) 
   (IN (PAIR X Z) (COMP F G)) . 

Theorem composition_th3 : 
   (F, G, X : Ens) 
   (i : (IN X (Domain F))) 
   (j : (IN (EV F X) (Domain G))) 
   (IN (PAIR X (EV G (EV F X))) (COMP F G)) . 

Theorem composition_th4 : 
   (F, G, X : Ens) 
   (f : (is_a_function F)) 
   (g : (is_a_function G)) 
   (i : (IN X (Domain F))) 
   (j : (IN (EV F X) (Domain G))) 
   (EQ (EV (COMP F G) X) (EV G (EV F X))) . 

Theorem COMP_assoc_th1 : 
   (F, G, H : Ens) 
   (SUB (COMP F (COMP G H)) (COMP (COMP F G) H)) . 

Theorem COMP_assoc_th2 : 
   (F, G, H : Ens) 
   (SUB (COMP (COMP F G) H) (COMP F (COMP G H))) . 

Theorem COMP_assoc : 
   (F, G, H : Ens) 
   (EQ (COMP F (COMP G H)) (COMP (COMP F G) H)) . 



************************************************)




(********* the actual Coq file starts here ******)

(************************************************)
(********** parameters and axioms ***************)
(************************************************)




Parameter Ens : Type.(*** that was the only time we refer to Type, thus we avoid ``typical ambiguity'' ***)

Parameter IN : Ens -> Ens -> Prop.Definition SUB (A B : Ens) := forall C : Ens, IN C A -> IN C B.Record EQ (A B : Ens) : Prop := 
  {EQ_forwards : SUB A B; EQ_backwards : SUB B A}.Record EQ (A B : Ens) : Prop := 
  {EQ_forwards : SUB A B; EQ_backwards : SUB B A}.Record EQ (A B : Ens) : Prop := 
  {EQ_forwards : SUB A B; EQ_backwards : SUB B A}.Axiom excluded_middle : forall P : Prop, ~ ~ P -> P.

(* Specifications: *)
Theorem false_implies_everything : forall P : Prop, False -> P.