(** * Proofs and definitions obtained from external sources  This file contains proofs and definitions from external sources. Specifically from thr base library used in IC by Prof. Gert Smolka in the version from 15. February 2016. Some other definitions are taken from the preliminary file of then development of Heriditarily finite sets by Prof. Gert Smolka and Kathrin Stark. Mainly these are newer versions of the definitions from the base library from ICL. *)
Global Set Implicit Arguments.
Global Unset Strict Implicit.
Global Unset Printing Records.
Global Unset Printing Implicit Defensive.
Global Set Regular Subst Tactic.
Hint Extern 4 => exact _.  (* make auto use type class inference *)
Require Export Setoid Morphisms.
Require Export Omega List Morphisms.
Set Implicit Arguments.
(* Set Universe Polymorphism. *)
(* exists-style notation for Sigma-types *)
Notation "'Sigma' x .. y , p" :=
(sigT (fun x => .. (sigT (fun y => p)) ..))
(at level 200, x binder, right associativity,
format "'[' 'Sigma'  '/  ' x  ..  y ,  '/  ' p ']'")
: type_scope.
Ltac inv A := inversion A; subst; try clear A.
(** * De Morgan laws *)
(** Decidable propositions *)
Definition dec (P : Prop) := {P} + {~ P}.
Existing Class dec.
Definition decision (P : Prop) (d : dec P) : dec P := d.
Arguments decision P {d}.
Tactic Notation "decide" constr(p) :=
destruct (decision p).
Tactic Notation "decide" constr(p) "as" simple_intropattern(i) :=
destruct (decision p) as i.
Fact dec_trans P Q :
dec P -> P <-> Q -> dec Q.
Instance True_dec :
dec True.
Instance False_dec :
dec False.
Instance impl_dec (P Q : Prop) :
dec P -> dec Q -> dec (P -> Q).
Instance and_dec (P Q : Prop) :
dec P -> dec Q -> dec (P /\ Q).
Instance or_dec (P Q : Prop) :
dec P -> dec Q -> dec (P \/ Q).
Instance not_dec (P : Prop) :
dec P -> dec (~P).
Instance iff_dec (P Q : Prop) :
dec P -> dec Q -> dec (P <-> Q).
Notation "'eq_dec' X" := (forall x y : X, dec (x=y)) (at level 70).
(** Discrete types and decidable predicates *)
Structure eqType := EqType {
eqtype :> Type;
decide_eq : eq_dec eqtype }.
Arguments EqType eqtype {decide_eq}.
(** This is like defined and not like Qed *)
Existing Instance decide_eq.
Structure decPred X := DecPred {
predicate :> X -> Prop;
decide_pred x : dec (predicate x) }.
Arguments DecPred {X} predicate {decide_pred}.
Existing Instance decide_pred.
Instance decp_dec X (p : decPred X) x :
dec (p x).
(** Decidable relations *)
Structure decRel X := DecRel {
relation :> X -> X -> Prop;
decide_rel x y : dec (relation x y) }.
Arguments DecRel {X} relation {decide_rel}.
Instance decRel_dec X (R : decRel X) x y :
dec (R x y).

Lemma dec_DM_impl X Y :
dec X -> dec Y -> ~ (X -> Y) -> X /\ ~ Y.