Top source

Module mathcomp.classical.boolp

From HB Require Import structures.
From mathcomp Require Import boot order.
#[warning="-warn-library-file-internal-analysis"]
From mathcomp Require Import unstable.
From mathcomp Require internal_Eqdep_dec.

# Classical Logic This file provides the axioms of classical logic and tools to perform classical reasoning in the Mathematical Component framework. The three axioms are taken from the standard library of Coq, more details can be found in Section 5 of - R. Affeldt, C. Cohen, D. Rouhling. Formalization Techniques for Asymptotic Reasoning in Classical Analysis. JFR 2018 ## Axioms ``` functional_extensionality_dep == functional extensionality (on dependently typed functions), i.e., functions that are pointwise equal are equal propositional_extensionality == propositional extensionality, i.e., iff and equality are the same on Prop constructive_indefinite_description == existential in Prop (ex) implies existential in Type (sig) cid := constructive_indefinite_description (shortcut) ``` A number of properties are derived below from these axioms and are often more pratical to use than directly using the axioms. For instance propext, funext, the excluded middle (EM),... ## Boolean View of Prop ``` `[< P >] == boolean view of P : Prop, see all lemmas about asbool ``` ## Mathematical Components Structures - A decidable equality is defined for any type. It is thus possible to define an eqType structure for any type using the mixin `gen_eqMixin`. - This file adds the possibility to define a choiceType structure for any type thanks to an axiom `gen_choiceMixin` giving a choice mixin. - We chose to have generic mixins and no global instances of the eqType and choiceType structures to let the user choose which definition of equality to use and to avoid conflict with already declared instances. ``` {classic T} == Endow T : Type with a canonical eqType/choiceType. This is intended for local use. E.g., T : Type |- A : {fset {classic T}} Alternatively one may use elim/Pchoice: T => T in H *. to substitute T with T : choiceType once and for all. {eclassic T} == Endow T : eqType with a canonical choiceType. On the model of {classic _}. See also the lemmas Peq and eqPchoice. ``` Functions onto a porderType (resp. latticeType) are equipped with a porderType (resp. latticeType), so that the generic notation (_ <= _)%O (resp. `&`, `|`) from `order.v` can be used. ``` FunOrder.lef f g == pointwise large inequality between two functions FunOrder.ltf f g == pointwise strict inequality between two functions FunLattice.meetf f g == pointwise meet between two functions FunLattice.joinf f g == pointwise join between two functions ```

Unset SsrOldRewriteGoalsOrder.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.

Declare Scope box_scope.
Declare Scope quant_scope.

Axiom
functional_extensionality_dep
Source code
:
       forall ( : Type) ( : A -> Type) ( : forall : A, B x),
       (forall : A, f x = g x) -> f = g.
Axiom
propositional_extensionality
Source code
:
       forall : Prop, P <-> Q -> P = Q.

Axiom
constructive_indefinite_description
Source code
:
  forall ( : Type) ( : A -> Prop),
  (exists : A, P x) -> { : A | P x}.
Notation := constructive_indefinite_description.

Lemma ( : Type) ( : A -> Prop) :
  (exists2 : A, P x & Q x) -> { : A | P x & Q x}.
Proof.
move=> PQA; suff: { | P x /\ Q x} by move=> [a [*]]; exists a.
by apply: cid; case: PQA => x; exists x.
Qed.

Lemma
existT_inj1
Source code
( : Type) ( : T -> Type) ( : T) ( : P x) ( : P y) :
  existT P x Px = existT P y Py -> x = y.
Proof.
by case. Qed.

Lemma
existT_inj2
Source code
( : eqType) ( : T -> Type) ( : T) ( : P x) :
  existT P x Px1 = existT P x Px2 -> Px1 = Px2.
Proof.
apply: internal_Eqdep_dec.inj_pair2_eq_dec => y z.
by have [|/eqP] := eqVneq y z; [left|right].
Qed.

Lemma
surjective_existT
Source code
( : Type) ( : T -> Type) ( : { : T & P x}):
  existT [eta P] (projT1 p) (projT2 p) = p.
Proof.
by case: p. Qed.

Record
mextensionality
Source code
:= {
  _ : forall ( : Prop), (P <-> Q) -> (P = Q);
  _ : forall { : Type} ( : T -> U),
        (forall , f x = g x) -> f = g;
}.

Fact
extensionality
Source code
: mextensionality.
Proof.
split.
- exact: propositional_extensionality.
- by move=> T U f g; apply: functional_extensionality_dep.
Qed.

Lemma ( : Prop) : (P <-> Q) -> (P = Q).
Proof.
by have [propext _] := extensionality; apply: propext. Qed.

Ltac eqProp := apply: propext; split.

Lemma { : Type} ( : T -> U) : (f =1 g) -> f = g.
Proof.
by case: extensionality=> _; apply. Qed.

Lemma ( : Prop) : (P = Q) = (P <-> Q).
Proof.
by apply: propext; split=> [->|/propext]. Qed.

Lemma ( : Prop) : (P = Q) <-> (P <-> Q).
Proof.
by rewrite propeqE. Qed.

Lemma { : Type} ( : T -> U) : (f = g) = (f =1 g).
Proof.
by rewrite propeqE; split=> [->//|/funext]. Qed.

Lemma { : Type} ( : T -> U -> V) : (f = g) = (f =2 g).
Proof.
by rewrite propeqE; split=> [->//|?]; rewrite funeqE=> x; rewrite funeqE.
Qed.

Lemma { : Type} ( : T -> U -> V -> W) :
  (f = g) = (forall , f x y z = g x y z).
Proof.
by rewrite propeqE; split=> [->//|?]; rewrite funeq2E=> x y; rewrite funeqE.
Qed.

Lemma { : Type} ( : T -> U) : (f = g) <-> (f =1 g).
Proof.
by rewrite funeqE. Qed.

Lemma { : Type} ( : T -> U -> V) : (f = g) <-> (f =2 g).
Proof.
by rewrite funeq2E. Qed.

Lemma { : Type} ( : T -> U -> V -> W) :
  (f = g) <-> (forall , f x y z = g x y z).
Proof.
by rewrite funeq3E. Qed.

Lemma {} ( : T -> Prop) : (P = Q) = (forall , P x <-> Q x).
Proof.
by rewrite propeqE; split=> [->//|?]; rewrite funeqE=> x; rewrite propeqE.
Qed.

Lemma
predeq2E
Source code
{ } ( : T -> U -> Prop) :
   (P = Q) = (forall , P x y <-> Q x y).
Proof.
by rewrite propeqE; split=> [->//|?]; rewrite funeq2E=> ??; rewrite propeqE.
Qed.

Lemma
predeq3E
Source code
{ } ( : T -> U -> V -> Prop) :
   (P = Q) = (forall , P x y z <-> Q x y z).
Proof.
by rewrite propeqE; split=> [->//|?]; rewrite funeq3E=> ???; rewrite propeqE.
Qed.

Lemma {} ( : T -> Prop) : (A = B) <-> (forall , A x <-> B x).
Proof.
by rewrite predeqE. Qed.

Lemma
predeq2P
Source code
{ } ( : T -> U -> Prop) :
   (P = Q) <-> (forall , P x y <-> Q x y).
Proof.
by rewrite predeq2E. Qed.

Lemma
predeq3P
Source code
{ } ( : T -> U -> V -> Prop) :
   (P = Q) <-> (forall , P x y z <-> Q x y z).
Proof.
by rewrite predeq3E. Qed.

Lemma { : Prop} : P -> P = True.
Proof.
by move=> p; rewrite propeqE. Qed.

Lemma
Prop_irrelevance
Source code
( : Prop) ( : P) : x = y.
Proof.
by move: x (x) y => /propT-> [] []. Qed.
#[global] Hint Resolve Prop_irrelevance : core.

Record
mclassic
Source code
:= {
  _ : forall ( : Prop), {P} + {~P};
  _ : forall , hasChoice T
}.

Lemma ( : X -> Y -> Prop) :
  (forall , exists , P x y) -> { & forall , P x (f x)}.
Proof.

Theorem : P \/ ~ P.
Proof.
pose U := fun : bool => Q = val \/ P.
have Uex val : exists , U val b by exists val; left.
pose f := projT1 (cid (Uex val)).
pose Uf : U val (f val) := projT2 (cid (Uex val)).
have : f true != f false \/ P.
  have [] := (Uf true, Uf false); rewrite /U.
  by move=> [->|?] [->|?] ; do ?[by right]; left.
move=> [/eqP fTFN|]; [right=> p|by left]; apply: fTFN.
have UTF : U true = U false by rewrite predeqE /U => b; split=> _; right.
rewrite /f; move: (Uex true) (Uex false); rewrite UTF => p1 p2.
by congr (projT1 (cid _)).
Qed.

Lemma ( : Prop): {P} + {~P}.
Proof.
have : exists , if b then P else ~ P.
  by case: (EM P); [exists true|exists false].
by move=> /cid [[]]; [left|right].
Qed.

Lemma
pselectT
Source code
: (T -> False) + T.
Proof.
have [/cid[]//|NT] := pselect (exists : T, True); first by right.
by left=> t; case: NT; exists t.
Qed.

Lemma : mclassic.
Proof.
split=> [|T]; first exact: pselect.
exists (fun ( : pred T) ( : nat) =>
  if pselect (exists , P x) isn't left ex then None
  else Some (projT1 (cid ex)))
  => [P n x|P [x Px]|P Q /funext -> //].
  by case: pselect => // ex [<- ]; case: cid.
by exists 0; case: pselect => // -[]; exists x.
Qed.

Lemma
gen_choiceMixin
Source code
( : Type) : hasChoice T.
Proof.
by case: classic. Qed.

Lemma ( : Prop): P \/ ~P.
Proof.
by case: (pselect P); tauto. Qed.

Lemma : true = True :> Prop.
Proof.
by rewrite propeqE; split. Qed.

Lemma : false = False :> Prop.
Proof.
by rewrite propeqE; split. Qed.

Lemma ( : Prop) : ~ P -> P = False.
Proof.
by move=> p; rewrite propeqE; tauto. Qed.

Lemma ( : T -> rT) :
  (forall : T, U x = V x) -> (fun => U x) = (fun => V x).
Proof.
by move=> /funext->. Qed.

Lemma ( : T1 -> T2 -> rT) :
  (forall , U x y = V x y) -> (fun => U x y) = (fun => V x y).
Proof.
by move=> UV; rewrite funeq2E => x y; rewrite UV. Qed.

Lemma ( : T1 -> T2 -> T3 -> rT) :
  (forall , U x y z = V x y z) ->
  (fun => U x y z) = (fun => V x y z).
Proof.
by move=> UV; rewrite funeq3E => x y z; rewrite UV. Qed.

Lemma
eq_forall
Source code
( : T -> Prop) :
  (forall : T, U x = V x) -> (forall , U x) = (forall , V x).
Proof.
by move=> e; rewrite propeqE; split=> ??; rewrite (e,=^~e). Qed.

Lemma
eq2_forall
Source code
( : forall : T, S x -> Prop) :
  (forall , U x y = V x y) -> (forall , U x y) = (forall , V x y).
Proof.
by move=> UV; apply/eq_forall => x; exact/eq_forall. Qed.

Lemma
eq3_forall
Source code
( : forall ( : T) ( : S x), R x y -> Prop) :
  (forall , U x y z = V x y z) ->
  (forall , U x y z) = (forall , V x y z).
Proof.
by move=> UV; apply/eq2_forall => x y; exact/eq_forall. Qed.

Lemma
eq_exists
Source code
( : T -> Prop) :
  (forall : T, U x = V x) -> (exists , U x) = (exists , V x).
Proof.
by move=> e; rewrite propeqE; split=> - [] x ?; exists x; rewrite (e,=^~e).
Qed.

Lemma
eq2_exists
Source code
( : forall : T, S x -> Prop) :
  (forall , U x y = V x y) -> (exists , U x y) = (exists , V x y).
Proof.
by move=> UV; apply/eq_exists => x; exact/eq_exists. Qed.

Lemma
eq3_exists
Source code
( : forall ( : T) ( : S x), R x y -> Prop) :
  (forall , U x y z = V x y z) ->
  (exists , U x y z) = (exists , V x y z).
Proof.
by move=> UV; apply/eq2_exists => x y; exact/eq_exists. Qed.

Lemma
eq_exist
Source code
( : T -> Prop) ( : T) ( : P s) ( : P t) :
  s = t -> exist P s p = exist P t q.
Proof.
by move=> st; case: _ / st in q *; apply/congr1. Qed.

Lemma
forall_swap
Source code
( : forall ( : T) ( : S), Prop) :
   (forall , U x y) = (forall , U x y).
Proof.
by rewrite propeqE; split. Qed.

Lemma
exists_swap
Source code
( : forall ( : T) ( : S), Prop) :
   (exists , U x y) = (exists , U x y).
Proof.
by rewrite propeqE; split => -[x [y]]; exists y, x. Qed.

Lemma
reflect_eq
Source code
( : Prop) ( : bool) : reflect P b -> P = b.
Proof.
by rewrite propeqE; exact: rwP. Qed.

Definition
asbool

glue1 : forall {T T' : Type} {X Y : set T} {A B : set T'} {XY : [disjoint X & Y]%classic} {AB : [disjoint A & B]%classic} (f g : T -> T'), {in X, glue XY AB f g =1 f} glue1 is not universe polymorphic Expanded type for implicit arguments glue1 : forall {T T' : Type} {X Y : set T} {A B : set T'} {XY : [disjoint X & Y]%classic} {AB : [disjoint A & B]%classic} (f g : T -> T') [x : T], x \in X -> glue XY AB f g x = f x Arguments glue1 {T T'}%_type_scope {X Y A B}%_classical_set_scope {XY AB} (f g)%_function_scope [x] _ glue1 is opaque Expands to: Constant mathcomp.classical.functions.glue1 Declared in library mathcomp.classical.functions, line 1500, characters 11-16


Source code
( : Prop) := if pselect P then true else false.

Notation
"`[< P >]"
Source code
:= (asbool P) : bool_scope.

Lemma ( : Prop) : `[<P>] = P :> Prop.
Proof.
by rewrite propeqE /asbool; case: pselect; split. Qed.

Lemma ( : Prop) : reflect P `[<P>].
Proof.
by apply: (equivP idP); rewrite asboolE. Qed.

Lemma ( : bool) : `[< b >] = b.
Proof.
by apply/asboolP/idP. Qed.

Lemma
asboolPn
Source code
( : Prop) : reflect (~ P) (~~ `[<P>]).
Proof.
by rewrite /asbool; case: pselect=> h; constructor. Qed.

Lemma ( : Prop) : `[<P>] -> P.
Proof.
by case: asboolP. Qed.

Lemma : A \/ B -> A + B.
Proof.
have [|NA] := asboolP A; first by left.
have [|NB] := asboolP B; first by right.
by move=> AB; exfalso; case: AB.
Qed.

Lemma : [\/ A, B | C] -> A + B + C.
Proof.
have [|NA] := asboolP A; first by left; left.
have [|NB] := asboolP B; first by left; right.
have [|NC] := asboolP C; first by right.
by move=> ABC; exfalso; case: ABC.
Qed.

Lemma : [\/ A, B, C | D] -> A + B + C + D.
Proof.
have [|NA] := asboolP A; first by left; left; left.
have [|NB] := asboolP B; first by left; left; right.
have [|NC] := asboolP C; first by left; right.
have [|ND] := asboolP D; first by right.
by move=> ABCD; exfalso; case: ABCD.
Qed.

Lemma ( : Prop) : P -> `[<P>].
Proof.
by case: asboolP. Qed.

Lemma ( : Prop) : ~ P -> `[<P>] = false.
Proof.
by apply/introF/asboolP. Qed.

Lemma ( : eqType) ( : T) : (x == y : Prop) = (x = y).
Proof.
by apply/propext; split=> /eqP. Qed.

Lemma
is_true_inj
Source code
: injective is_true.
Proof.
by move=> [] []; rewrite ?(trueE, falseE) ?propeqE; tauto. Qed.

Definition
gen_eq

glue2 : forall {T T' : Type} {X Y : set T} {A B : set T'} {XY : [disjoint X & Y]%classic} {AB : [disjoint A & B]%classic} (f g : T -> T'), {in Y, glue XY AB f g =1 g} glue2 is not universe polymorphic Expanded type for implicit arguments glue2 : forall {T T' : Type} {X Y : set T} {A B : set T'} {XY : [disjoint X & Y]%classic} {AB : [disjoint A & B]%classic} (f g : T -> T') [x : T], x \in Y -> glue XY AB f g x = g x Arguments glue2 {T T'}%_type_scope {X Y A B}%_classical_set_scope {XY AB} (f g)%_function_scope [x] _ glue2 is opaque Expands to: Constant mathcomp.classical.functions.glue2 Declared in library mathcomp.classical.functions, line 1503, characters 11-16


Source code
( : Type) ( : T) := `[<u = v>].
Lemma ( : Type) : Equality.axiom (@gen_eq T).
Proof.
by move=> x y; apply: (iffP (asboolP _)). Qed.
Definition
gen_eqMixin

fun_set_bij : forall {aT rT : Type} {A : set aT} {B : set rT} {f : aT -> rT}, set_bij A B f -> aT -> rT fun_set_bij is not universe polymorphic Arguments fun_set_bij {aT rT}%_type_scope {A B}%_classical_set_scope {f}%_function_scope _ _ fun_set_bij is a coercion fun_set_bij is transparent Expands to: Constant mathcomp.classical.functions.fun_set_bij Declared in library mathcomp.classical.functions, line 1789, characters 11-22


Source code
( : Type) : hasDecEq T :=
  hasDecEq.Build T (@gen_eqP T).

.
instance
Source code
Definition
Source code
() ( -> eqType) :=
  gen_eqMixin (forall : T, T' t).

.
instance
Source code
Definition
Source code
() ( -> choiceType) :=
  gen_choiceMixin (forall : T, T' t).

.
instance
Source code
Definition
Source code
gen_eqMixin
Source code
Prop.
.
instance
Source code
Definition
Source code
gen_choiceMixin
Source code
Prop.

Section classicType.
Variable : Type.
Definition
classicType

set_bij_bijfun : forall [aT rT : Type] [A : set aT] [B : set rT] [f : aT -> rT] (fS : set_bij A B f), Bij.axioms_ A B fS set_bij_bijfun is not universe polymorphic Arguments set_bij_bijfun [aT rT]%_type_scope [A B]%_classical_set_scope [f]%_function_scope fS set_bij_bijfun is a coercion set_bij_bijfun is transparent Expands to: Constant mathcomp.classical.functions.set_bij_bijfun Declared in library mathcomp.classical.functions, line 1808, characters 9-23


Source code
:= T.
.
instance
Source code
Definition
Source code
gen_eqMixin
Source code
classicType.
.
instance
Source code
Definition
Source code
gen_choiceMixin
Source code
classicType.
End classicType.
Notation
"'{classic' T }"
Source code
:= (classicType T)
 (format "'{classic' T }") : type_scope.

Section eclassicType.
Variable : eqType.
Definition
eclassicType

bij_of_set_bijection : forall {aT rT : Type} {A : set aT} {B : set rT} {f : aT -> rT}, set_bij A B f -> {bij A >-> B} bij_of_set_bijection is not universe polymorphic Arguments bij_of_set_bijection {aT rT}%_type_scope {A B}%_classical_set_scope {f}%_function_scope fbij bij_of_set_bijection is a coercion bij_of_set_bijection is transparent Expands to: Constant mathcomp.classical.functions.bij_of_set_bijection Declared in library mathcomp.classical.functions, line 1814, characters 11-31


Source code
: Type := T.
.
instance
Source code
Definition
Source code
Equality
Source code
.copy eclassicType T.
.
instance
Source code
Definition
Source code
gen_choiceMixin
Source code
eclassicType.
End eclassicType.
Notation
"'{eclassic' T }"
Source code
:= (eclassicType T)
 (format "'{eclassic' T }") : type_scope.

Definition
canonical_of

phant_bij : forall [aT rT : Type] [A : set aT] [B : set rT] [f : {bij A >-> B}], phantom (aT -> rT) f -> set_bij A B f phant_bij is not universe polymorphic Arguments phant_bij [aT rT]%_type_scope [A B]%_classical_set_scope [f] _ phant_bij is transparent Expands to: Constant mathcomp.classical.functions.phant_bij Declared in library mathcomp.classical.functions, line 1821, characters 11-20


Source code
( : U -> T) := forall ( : T -> Type),
  (forall , G (sort x')) -> forall , G x.
Notation
canonical_
Source code
sort := (@canonical_of _ _ sort).
Notation
canonical
Source code
T E := (@canonical_of T E id).

Lemma ( : U -> T) :
  (forall , exists , sort y = x) -> canonical_ sort.
Proof.
by move=> + G Gs x => /(_ x)/cid[x' <-]. Qed.
Arguments canon {T U sort} x.

Lemma : canonical Type eqType.
Proof.
by apply: canon => T; exists {classic T}. Qed.
Lemma : canonical Type choiceType.
Proof.
by apply: canon => T; exists {classic T}. Qed.
Lemma
eqPchoice
Source code
: canonical eqType choiceType.
Proof.
by apply: canon => T; exists {eclassic T}; case: T => //= T [?]//. Qed.

Lemma
not_True
Source code
: (~ True) = False
Proof.
exact/propext. Qed.
Lemma
not_False
Source code
: (~ False) = True
Proof.
by apply/propext; split=> _. Qed.

Lemma
asbool_equiv_eq
Source code
{ : Prop} : (P <-> Q) -> `[<P>] = `[<Q>].
Proof.
by rewrite -propeqE => ->. Qed.

Lemma
asbool_equiv_eqP
Source code
{ : Prop} : reflect Q b -> (P <-> Q) -> `[<P>] = b.
Proof.
by move=> Q_b [PQ QP]; apply/asboolP/Q_b. Qed.

Lemma
asbool_equiv
Source code
{ : Prop} : (P <-> Q) -> (`[<P>] <-> `[<Q>]).
Proof.
by move/asbool_equiv_eq->. Qed.

Lemma
asbool_eq_equiv
Source code
{ : Prop} : `[<P>] = `[<Q>] -> (P <-> Q).
Proof.
by move=> eq; split=> /asboolP; rewrite (eq, =^~ eq) => /asboolP. Qed.

Lemma
and_asboolP
Source code
( : Prop) : reflect (P /\ Q) (`[< P >] && `[< Q >]).
Proof.
apply: (iffP idP); first by case/andP => /asboolP p /asboolP q.
by case=> /asboolP-> /asboolP->.
Qed.

Lemma
and3_asboolP
Source code
( : Prop) :
  reflect [/\ P, Q & R] [&& `[< P >], `[< Q >] & `[< R >]].
Proof.
apply: (iffP idP); first by case/and3P => /asboolP p /asboolP q /asboolP r.
by case => /asboolP -> /asboolP -> /asboolP ->.
Qed.

Lemma
or_asboolP
Source code
( : Prop) : reflect (P \/ Q) (`[< P >] || `[< Q >]).
Proof.
apply: (iffP idP); first by case/orP=> /asboolP; [left | right].
by case=> /asboolP-> //=; rewrite orbT.
Qed.

Lemma
or3_asboolP
Source code
( : Prop) :
  reflect [\/ P, Q | R] [|| `[< P >], `[< Q >] | `[< R >]].
Proof.
apply: (iffP idP); last by case=> [| |] /asboolP -> //=; rewrite !orbT.
by case/orP=> [/asboolP p|/orP[]/asboolP]; [exact:Or31|exact:Or32|exact:Or33].
Qed.

Lemma
asbool_neg
Source code
{ : Prop} : `[<~ P>] = ~~ `[<P>].
Proof.
by apply/idP/asboolPn=> [/asboolP|/asboolT]. Qed.

Lemma
asbool_or
Source code
{ : Prop} : `[<P \/ Q>] = `[<P>] || `[<Q>].
Proof.
exact: (asbool_equiv_eqP (or_asboolP _ _)). Qed.

Lemma
asbool_and
Source code
{ : Prop} : `[<P /\ Q>] = `[<P>] && `[<Q>].
Proof.
exact: (asbool_equiv_eqP (and_asboolP _ _)). Qed.

Lemma
imply_asboolP
Source code
{ : Prop} : reflect (P -> Q) (`[<P>] ==> `[<Q>]).
Proof.
apply: (iffP implyP)=> [PQb /asboolP/PQb/asboolW //|].
by move=> PQ /asboolP/PQ/asboolT.
Qed.

Lemma
asbool_imply
Source code
{ : Prop} : `[<P -> Q>] = `[<P>] ==> `[<Q>].
Proof.

Lemma
imply_asboolPn
Source code
( : Prop) : reflect (P /\ ~ Q) (~~ `[<P -> Q>]).
Proof.

Lemma
forall_asboolP
Source code
{ : Type} ( : T -> Prop) :
  reflect (forall , `[<P x>]) (`[<forall , P x>]).
Proof.
apply: (iffP idP); first by move/asboolP=> Px x; apply/asboolP.
by move=> Px; apply/asboolP=> x; apply/asboolP.
Qed.

Lemma
exists_asboolP
Source code
{ : Type} ( : T -> Prop) :
  reflect (exists , `[<P x>]) (`[<exists , P x>]).
Proof.
apply: (iffP idP); first by case/asboolP=> x Px; exists x; apply/asboolP.
by case=> x bPx; apply/asboolP; exists x; apply/asboolP.
Qed.


Variant
BoolProp
Source code
: Prop -> Type :=
 |
TrueProp
Source code
: BoolProp True
 |
FalseProp
Source code
: BoolProp False.

Lemma : BoolProp P.
Proof.
by case: (asboolP P) => [/propT-> | /propF->]; [left | right]. Qed.

Lemma : ((~ True) = False) * ((~ False) = True).
Proof.
by rewrite /not; split; eqProp. Qed.

Lemma : left_id True and * right_id True and
          * (left_zero False and * right_zero False and * idempotent_op and).
Proof.
by do ![split] => /PropB[]; eqProp=> // -[]. Qed.

Lemma : left_id False or * right_id False or
          * (left_zero True or * right_zero True or * idempotent_op or).
Proof.
do ![split] => /PropB[]; eqProp=> -[] //; by [left | right]. Qed.

Lemma : let ( : Prop) := P -> Q in
    (imply False =1 fun=> True) * (imply^~ False =1 not)
  * (left_id True imply * right_zero True imply * self_inverse True imply).
Proof.
by do ![split] => /PropB[]; eqProp=> //; apply. Qed.

Lemma
decide_or
Source code
: P \/ Q -> {P} + {Q}.
Proof.
by case/PropB: P; [left | rewrite orB; right]. Qed.


Lemma ( : Prop) : P = False -> ~ P.
Proof.
by move->. Qed.

Lemma
contrapT
Source code
: ~ ~ P -> P.
Proof.
by case: (PropB P) => //; rewrite not_False. Qed.

Lemma ( : Prop) : (~ P) -> P = False
Proof.
by case: (PropB P). Qed.

Lemma ( : Prop) : (~ P) = False -> P.
Proof.
by move/notT; exact: contrapT. Qed.

Lemma : involutive not.
Proof.
by case/PropB; rewrite !(not_False,not_True). Qed.

Lemma
contra_notP
Source code
( : Prop) : (~ Q -> P) -> ~ P -> Q.
Proof.
by move: Q P => /PropB[] /PropB[]. Qed.

Lemma
contraPP
Source code
( : Prop) : (~ Q -> ~ P) -> P -> Q.
Proof.
by move: Q P => /PropB[] /PropB[]//; rewrite not_False not_True. Qed.

Lemma
contra_notT
Source code
( : Prop) : (~~ b -> P) -> ~ P -> b.
Proof.
by move=> bP; apply: contra_notP => /negP. Qed.

Lemma
contraPT
Source code
( : Prop) : (~~ b -> ~ P) -> P -> b.
Proof.
by move=> /contra_notT; rewrite notK. Qed.

Lemma
contraTP
Source code
( : Prop) : (~ Q -> ~~ b) -> b -> Q.
Proof.
by move=> QB; apply: contraPP => /QB/negP. Qed.

Lemma
contraNP
Source code
( : Prop) ( : bool) : (~ P -> b) -> ~~ b -> P.
Proof.
by move=> /contra_notP + /negP => /[apply]. Qed.

Lemma
contra_neqP
Source code
( : eqType) ( : T) : (~ P -> x = y) -> x != y -> P.
Proof.
by move=> Pxy; apply: contraNP => /Pxy/eqP. Qed.

Lemma
contra_eqP
Source code
( : eqType) ( : T) : (~ Q -> x != y) -> x = y -> Q.
Proof.
by move=> Qxy /eqP; apply: contraTP. Qed.

Lemma
contra_leP
Source code
{} { : porderType disp1} [ : Prop] [ : T1] :
  (~ P -> (x < y)%O) -> (y <= x)%O -> P.
Proof.
move=> Pxy yx; apply/asboolP.
by apply: Order.POrderTheory.contra_leT yx => /asboolPn.
Qed.

Lemma
contra_ltP
Source code
{} { : porderType disp1} [ : Prop] [ : T1] :
  (~ P -> (x <= y)%O) -> (y < x)%O -> P.
Proof.
move=> Pxy yx; apply/asboolP.
by apply: Order.POrderTheory.contra_ltT yx => /asboolPn.
Qed.

Lemma
wlog_neg
Source code
: (~ P -> P) -> P.
Proof.
by case: (PropB P); exact. Qed.

Lemma : injective not
Proof.
exact: can_inj notK. Qed.

Lemma : (P = (~ Q)) -> (~ P) = Q
Proof.
exact: canLR notK. Qed.

Lemma : (~ P) = Q -> P = (~ Q)
Proof.
exact: canRL notK. Qed.

Lemma
iff_notr
Source code
( : Prop) : (P <-> ~ Q) <-> (~ P <-> Q).
Proof.
by split=> [/propext ->|/propext <-]; rewrite notK. Qed.

Lemma
iff_not2
Source code
( : Prop) : (~ P <-> ~ Q) <-> (P <-> Q).
Proof.
by split=> [/iff_notr|PQ]; [|apply/iff_notr]; rewrite notK. Qed.


Definition
predp

bijection_of_bijective : forall {aT rT : Type} {f : aT -> rT}, bijective f -> {splitbij [set: aT] >-> [set: rT]} bijection_of_bijective is not universe polymorphic Arguments bijection_of_bijective {aT rT}%_type_scope {f}%_function_scope fbijTT bijection_of_bijective is transparent Expands to: Constant mathcomp.classical.functions.bijection_of_bijective Declared in library mathcomp.classical.functions, line 1829, characters 11-33


Source code
:= T -> Prop.

Identity Coercion fun_of_pred : predp >-> Funclass.

Definition
relp

phant_bijTT : forall [aT rT : Type] [f : {bij [set: aT] >-> [set: rT]}], phantom (aT -> rT) f -> bijective f phant_bijTT is not universe polymorphic Arguments phant_bijTT [aT rT]%_type_scope [f] _ phant_bijTT is transparent Expands to: Constant mathcomp.classical.functions.phant_bijTT Declared in library mathcomp.classical.functions, line 1845, characters 11-22


Source code
:= T -> predp T.

Identity Coercion fun_of_rel : rel >-> Funclass.

Notation := (fun _ => False).
Notation := (fun _ => True).
Notation := (fun ( : predp _) => p1 x /\ p2 x).
Notation := (fun ( : predp _) => p1 x \/ p2 x).
Notation := (fun ( : predp _) => ~ p x).
Notation := (fun ( : predp _) => ~ p2 x /\ p1 x).
Notation := (fun ( : predp _) => p (f x)).
Notation := (fun ( : relp _) => r1 x y \/ r2 x y).

Definition
pred0p

patch : forall {aT rT : Type}, (aT -> rT) -> set aT -> (aT -> rT) -> aT -> rT patch is not universe polymorphic Arguments patch {aT rT}%_type_scope d%_function_scope A%_classical_set_scope f%_function_scope u patch is transparent Expands to: Constant mathcomp.classical.functions.patch Declared in library mathcomp.classical.functions, line 1856, characters 11-16


Source code
( : Type) ( : predp T) : bool := `[<P =1 xpredp0>].
Prenex Implicits pred0p.

Lemma ( : Type) ( : predp T) : reflect (P =1 xpredp0) (pred0p P).
Proof.
by apply: (iffP (asboolP _)). Qed.

Lemma
forallp_asboolPn
Source code
{} { : T -> Prop} :
  reflect (forall : T, ~ P x) (~~ `[<exists : T, P x>]).
Proof.
apply: (iffP idP)=> [/asboolPn NP x Px|NP].
by apply/NP; exists x. by apply/asboolP=> -[x]; apply/NP.
Qed.

Lemma
existsp_asboolPn
Source code
{} { : T -> Prop} :
  reflect (exists : T, ~ P x) (~~ `[<forall : T, P x>]).
Proof.
apply: (iffP idP); last by case=> x NPx; apply/asboolPn=> /(_ x).
move/asboolPn=> NP; apply/asboolP/negbNE/asboolPn=> h.
by apply/NP=> x; apply/asboolP/negbNE/asboolPn=> NPx; apply/h; exists x.
Qed.

Lemma
asbool_forallNb
Source code
{ : Type} ( : pred T) :
  `[< forall : T, ~~ (P x) >] = ~~ `[< exists : T, P x >].
Proof.
apply: (asbool_equiv_eqP forallp_asboolPn);
  by split=> h x; apply/negP/h.
Qed.

Lemma
asbool_existsNb
Source code
{ : Type} ( : pred T) :
  `[< exists : T, ~~ (P x) >] = ~~ `[< forall : T, P x >].
Proof.
apply: (asbool_equiv_eqP existsp_asboolPn);
  by split=> -[x h]; exists x; apply/negP.
Qed.

Lemma
not_implyP
Source code
( : Prop) : ~ (P -> Q) <-> P /\ ~ Q.
Proof.
split=> [/asboolP|[p nq pq]]; [|exact/nq/pq].
by rewrite asbool_neg => /imply_asboolPn.
Qed.

Lemma
not_andE
Source code
( : Prop) : (~ (P /\ Q)) = (~ P \/ ~ Q).
Proof.
eqProp=> [/asboolPn|[|]]; try by apply: contra_not => -[].
by rewrite asbool_and negb_and => /orP[]/asboolPn; [left|right].
Qed.

Lemma
not_andP
Source code
( : Prop) : ~ (P /\ Q) <-> ~ P \/ ~ Q.
Proof.
by rewrite not_andE. Qed.

Lemma
not_and3P
Source code
( : Prop) : ~ [/\ P, Q & R] <-> [\/ ~ P, ~ Q | ~ R].
Proof.
split=> [/and3_asboolP|/or3_asboolP].
by rewrite 2!negb_and -3!asbool_neg => /or3_asboolP.
by rewrite 3!asbool_neg -2!negb_and => /and3_asboolP.
Qed.

Lemma
not_notP
Source code
( : Prop) : ~ ~ P <-> P.
Proof.
by split => [|p]; [exact: contrapT|exact]. Qed.
#[deprecated(since="mathcomp-analysis 1.15.0", note="Renamed to `not_notP`. Warning: a different `notP` is provided by `contra.v`.")]
Notation := not_notP (only parsing).

Lemma
not_notE
Source code
( : Prop) : (~ ~ P) = P.
Proof.
by rewrite propeqE not_notP. Qed.
#[deprecated(since="mathcomp-analysis 1.15.0", note="Renamed to `not_notE`. Warning: a different `notE` is provided by `contra.v`.")]
Notation := not_notE (only parsing).

Lemma ( : Prop) : (~ (P \/ Q)) = (~ P /\ ~ Q).
Proof.
by rewrite -[_ /\ _]not_notE not_andE 2!not_notE. Qed.

Lemma ( : Prop) : ~ (P \/ Q) <-> ~ P /\ ~ Q.
Proof.
by rewrite not_orE. Qed.

Lemma
not_implyE
Source code
( : Prop) : (~ (P -> Q)) = (P /\ ~ Q).
Proof.
by rewrite propeqE not_implyP. Qed.

Lemma ( : Prop) : (P -> Q) = (~ P \/ Q).
Proof.

Lemma : commutative or.
Proof.
by move=> /PropB[] /PropB[] => //; rewrite !orB. Qed.

Lemma : associative or.
Proof.
by move=> P Q R; rewrite propeqE; split=> [|]; tauto. Qed.

Lemma : left_commutative or.
Proof.
by move=> P Q R; rewrite !orA (orC P). Qed.

Lemma : right_commutative or.
Proof.
by move=> P Q R; rewrite -!orA (orC Q). Qed.

Lemma : interchange or or.
Proof.
by move=> P Q R S; rewrite !orA (orAC P). Qed.

Lemma : (~ P \/ Q) = (P -> Q).
Proof.
by case/PropB: P; rewrite notB orB implyB. Qed.

Lemma : (P \/ ~ Q) = (Q -> P)
Proof.
by rewrite orC orNp. Qed.

Lemma : [\/ P, Q | R] = (P \/ Q \/ R).
Proof.
rewrite -(asboolE P) -(asboolE Q) -(asboolE R) (reflect_eq or3P).
by rewrite -2!(reflect_eq orP).
Qed.

Lemma : [\/ P, Q, R | S] = (P \/ Q \/ R \/ S).
Proof.
rewrite -(asboolE P) -(asboolE Q) -(asboolE R) -(asboolE S) (reflect_eq or4P).
by rewrite -3!(reflect_eq orP).
Qed.

Lemma : commutative and.
Proof.
by move=> /PropB[] /PropB[]; rewrite !andB. Qed.

Lemma : associative and.
Proof.
by move=> P Q R; rewrite propeqE; split=> [|]; tauto. Qed.

Lemma : left_commutative and.
Proof.
by move=> P Q R; rewrite !andA (andC P). Qed.

Lemma : right_commutative and.
Proof.
by move=> P Q R; rewrite -!andA (andC Q). Qed.

Lemma : interchange and and.
Proof.
by move=> P Q R S; rewrite !andA (andAC P). Qed.

Lemma : [/\ P, Q & R] = (P /\ Q /\ R).
Proof.
by eqProp=> [[] | [? []]]. Qed.

Lemma : [/\ P, Q, R & S] = (P /\ Q /\ R /\ S).
Proof.
by eqProp=> [[] | [? [? []]]]. Qed.

Lemma : [/\ P, Q, R, S & T] = (P /\ Q /\ R /\ S /\ T).
Proof.
by eqProp=> [[] | [? [? [? []]]]]. Qed.

Lemma : (~ P -> Q : Prop) = (P \/ Q).
Proof.
by rewrite -orNp notK. Qed.

Lemma ( : Prop) : (P -> ~ Q) = (~ (P /\ Q)).
Proof.
by case/PropB: P; rewrite implyB andB ?notB. Qed.

Lemma : (~ P -> ~ Q) = (Q -> P).
Proof.
by rewrite implyNp orpN. Qed.

Lemma : right_distributive or and.
Proof.
by case/PropB=> Q R; rewrite !orB ?andB. Qed.

Lemma : left_distributive or and.
Proof.
by move=> P Q R; rewrite -!(orC R) or_andr. Qed.

Lemma : right_distributive and or.
Proof.
by move=> P Q R; apply/not_inj; rewrite !(not_andE, not_orE) or_andr. Qed.

Lemma : left_distributive and or.
Proof.
by move=> P Q R; apply/not_inj; rewrite !(not_andE, not_orE) or_andl. Qed.

Lemma
forallNE
Source code
{} ( : T -> Prop) : (forall , ~ P x) = (~ exists , P x).
Proof.
by rewrite propeqE; split => [fP [x /fP]//|nexP x Px]; apply: nexP; exists x.
Qed.

Lemma
existsNE
Source code
{} ( : T -> Prop) : (exists , ~ P x) = (~ forall , P x).
Proof.
rewrite propeqE; split=> [[x Px] aP //|NaP].
by apply: contrapT; rewrite -forallNE => aP; apply: NaP => x; apply: contrapT.
Qed.

Lemma
existsNP
Source code
( : T -> Prop) : (exists , ~ P x) <-> ~ forall , P x.
Proof.
by rewrite existsNE. Qed.

Lemma
not_existsP
Source code
( : T -> Prop) : (exists , P x) <-> ~ forall , ~ P x.
Proof.
by rewrite forallNE notK. Qed.

Lemma
forallNP
Source code
( : T -> Prop) : (forall , ~ P x) <-> ~ exists , P x.
Proof.
by rewrite forallNE. Qed.

Lemma
not_forallP
Source code
( : T -> Prop) : (forall , P x) <-> ~ exists , ~ P x.
Proof.
by rewrite existsNE notK. Qed.

Lemma
exists2E
Source code
: (exists2 : A, P x & Q x) = (exists , P x /\ Q x).
Proof.
by eqProp=> -[x]; last case; exists x. Qed.

Lemma
exists2P
Source code
( : T -> Prop) :
  (exists2 , P x & Q x) <-> exists , P x /\ Q x.
Proof.
by rewrite exists2E. Qed.

Lemma
not_exists2P
Source code
( : T -> Prop) :
  (exists2 , P x & Q x) <-> ~ forall , ~ P x \/ ~ Q x.
Proof.
rewrite exists2P not_existsP.
by split; apply: contra_not => PQx x; apply/not_andP; apply: PQx.
Qed.

Lemma
forall2NP
Source code
( : T -> Prop) :
  (forall , ~ P x \/ ~ Q x) <-> ~ (exists2 , P x & Q x).
Proof.
split=> [PQ [t Pt Qt]|PQ t]; first by have [] := PQ t.
by rewrite -not_andP => -[Pt Qt]; apply PQ; exists t.
Qed.

Lemma
forallPNP
Source code
( : T -> Prop) :
  (forall , P x -> ~ Q x) <-> ~ (exists2 , P x & Q x).
Proof.
split=> [PQ [t Pt Qt]|PQ t]; first by have [] := PQ t.
by move=> Pt Qt; apply: PQ; exists t.
Qed.

Lemma
existsPNP
Source code
( : T -> Prop) :
  (exists2 , P x & ~ Q x) <-> ~ (forall , P x -> Q x).
Proof.
split=> [[x Px NQx] /(_ x Px)//|]; apply: contra_notP => + x Px.
by apply: contra_notP => NQx; exists x.
Qed.

Lemma
forallp_asboolPn2
Source code
{} { : T -> Prop} :
  reflect (forall : T, ~ P x \/ ~ Q x) (~~ `[<exists2 : T, P x & Q x>]).
Proof.
apply: (iffP idP)=> [/asboolPn NP x|NP].
  by move/forallPNP : NP => /(_ x)/and_rec/not_andP.
by apply/asboolP=> -[x Px Qx]; have /not_andP := NP x; exact.
Qed.

Section bigmaxmin.
Local Notation := Order.max.
Local Notation := Order.min.
Local Open Scope order_scope.
Context {} { : orderType d} ( : T)
  { : finType} ( : pred I) ( : T) ( : I -> T).

Import Order.TTheory.

Lemma
bigmax_geP
Source code
: reflect (m <= x \/ exists2 , P i & m <= F i)
                           (m <= \big[max/x]_( | P i) F i).
Proof.
apply: (iffP idP) => [|[mx|[i Pi mFi]]].
- rewrite leNgt => /bigmax_ltP /not_andP[/negP|]; first by rewrite -leNgt; left.
  by move=> /existsNP[i /not_implyP[Pi /negP]]; rewrite -leNgt; right; exists i.
- by rewrite bigmax_idl le_max mx.
- by rewrite (bigmaxD1 i)// le_max mFi.
Qed.

Lemma
bigmax_gtP
Source code
: reflect (m < x \/ exists2 , P i & m < F i)
                           (m < \big[max/x]_( | P i) F i).
Proof.
apply: (iffP idP) => [|[mx|[i Pi mFi]]].
- rewrite ltNge => /bigmax_leP /not_andP[/negP|]; first by rewrite -ltNge; left.
  by move=> /existsNP[i /not_implyP[Pi /negP]]; rewrite -ltNge; right; exists i.
- by rewrite bigmax_idl lt_max mx.
- by rewrite (bigmaxD1 i)// lt_max mFi.
Qed.

Lemma
bigmin_leP
Source code
: reflect (x <= m \/ exists2 , P i & F i <= m)
                           (\big[min/x]_( | P i) F i <= m).
Proof.
apply: (iffP idP) => [|[xm|[i Pi Fim]]].
- rewrite leNgt => /bigmin_gtP /not_andP[/negP|]; first by rewrite -leNgt; left.
  by move=> /existsNP[i /not_implyP[Pi /negP]]; rewrite -leNgt; right; exists i.
- by rewrite bigmin_idl ge_min xm.
- by rewrite (bigminD1 i)// ge_min Fim.
Qed.

Lemma
bigmin_ltP
Source code
: reflect (x < m \/ exists2 , P i & F i < m)
                           (\big[min/x]_( | P i) F i < m).
Proof.
apply: (iffP idP) => [|[xm|[i Pi Fim]]].
- rewrite ltNge => /bigmin_geP /not_andP[/negP|]; first by rewrite -ltNge; left.
  by move=> /existsNP[i /not_implyP[Pi /negP]]; rewrite -ltNge; right; exists i.
- by rewrite bigmin_idl gt_min xm.
- by rewrite (bigminD1 _ _ _ Pi) gt_min Fim.
Qed.

End bigmaxmin.

Module
FunOrder
Source code
.
Section FunOrder.
Import Order.TTheory.
Context { : Type} {} { : porderType d}.
Implicit Types f g h : aT -> T.

Lemma
fun_display
Source code
: Order.disp_t
Proof.
exact: Order.default_display. Qed.

Definition
lef

valL_ : forall {U V : Type}, V -> forall {A : set U}, (A -> V) -> U -> V valL_ is not universe polymorphic Arguments valL_ {U V}%_type_scope v {A}%_classical_set_scope f%_function_scope u / (where some original arguments have been renamed) The reduction tactics unfold valL_ when applied to 6 arguments valL_ is transparent Expands to: Constant mathcomp.classical.functions.valL_ Declared in library mathcomp.classical.functions, line 1950, characters 11-16


Source code
:= `[< forall , (f x <= g x)%O >].
Local Notation
"f <= g"
Source code
:= (lef f g).

Definition
ltf

valLfun_ : forall {U V : Type}, V -> forall {A : set U} {B : set V}, {fun [set: A] >-> B} -> {fun A >-> B} valLfun_ is not universe polymorphic Arguments valLfun_ {U V}%_type_scope v {A B}%_classical_set_scope f valLfun_ is transparent Expands to: Constant mathcomp.classical.functions.valLfun_ Declared in library mathcomp.classical.functions, line 1956, characters 11-19


Source code
:= `[< (forall , (f x <= g x)%O) /\ exists , f x != g x >].
Local Notation := (ltf f g).

Lemma : (f < g) = (g != f) && (f <= g).
Proof.
apply/idP/andP => [fg|[gf fg]]; [split|apply/asboolP; split; [exact/asboolP|]].
- by apply/eqP => gf; move: fg => /asboolP[fg] [x /eqP]; apply; rewrite gf.
- apply/asboolP => x; rewrite le_eqVlt; move/asboolP : fg => [fg [y gfy]].
  by have [//|gfx /=] := boolP (f x == g x); rewrite lt_neqAle gfx /= fg.
- apply/not_existsP => h.
  have : f =1 g by move=> x; have /negP/negPn/eqP := h x.
  by rewrite -funeqE; apply/nesym/eqP.
Qed.

Fact
lef_refl
Source code
: reflexive lef
Proof.
by move=> f; apply/asboolP => x. Qed.

Fact
lef_anti
Source code
: antisymmetric lef.
Proof.
move=> f g => /andP[/asboolP fg /asboolP gf]; rewrite funeqE => x.
by apply/eqP; rewrite eq_le fg gf.
Qed.

Fact
lef_trans
Source code
: transitive lef.
Proof.
move=> g f h /asboolP fg /asboolP gh; apply/asboolP => x.
by rewrite (le_trans (fg x)).
Qed.

#[export]
Source code

.
instance
Source code
Definition
Source code
.isPOrder.Build
  fun_display (aT -> T) lef ltf ltf_def lef_refl lef_anti lef_trans.

End FunOrder.

Section FunLattice.
Import Order.TTheory.
Context { : Type} {} { : latticeType d}.
Implicit Types f g h : aT -> T.

Definition
meetf

valR : forall {U V : Type} {A : set V}, (U -> A) -> U -> V valR is not universe polymorphic Arguments valR {U V}%_type_scope {A}%_classical_set_scope f%_function_scope x valR is transparent Expands to: Constant mathcomp.classical.functions.valR Declared in library mathcomp.classical.functions, line 2025, characters 11-15


Source code
:= fun => Order.meet (f x) (g x).
Definition
joinf

valR_fun : forall {U V : Type} {A : set V}, (U -> A) -> {fun [set: U] >-> A} valR_fun is not universe polymorphic Arguments valR_fun {U V}%_type_scope {A}%_classical_set_scope f%_function_scope valR_fun is transparent Expands to: Constant mathcomp.classical.functions.valR_fun Declared in library mathcomp.classical.functions, line 2028, characters 11-19


Source code
:= fun => Order.join (f x) (g x).

Lemma : commutative meetf.
Proof.
move=> f g; apply/funext => x; exact: meetC. Qed.

Lemma : commutative joinf.
Proof.
move=> f g; apply/funext => x; exact: joinC. Qed.

Lemma : associative meetf.
Proof.
move=> f g h; apply/funext => x; exact: meetA. Qed.

Lemma : associative joinf.
Proof.
move=> f g h; apply/funext => x; exact: joinA. Qed.

Lemma : meetf f (joinf f g) = f.
Proof.
apply/funext => x; exact: joinKI. Qed.

Lemma : joinf f (meetf f g) = f.
Proof.
apply/funext => x; exact: meetKU. Qed.

Lemma
lef_meet
Source code
: (f <= g)%O = (meetf f g == f).
Proof.
apply/idP/idP => [/asboolP f_le_g|/eqP <-].
- apply/eqP/funext => x; exact/meet_l/f_le_g.
- apply/asboolP => x; exact: leIr.
Qed.

#[export]
Source code

.
instance
Source code
Definition
Source code
.POrder_isLattice.Build _ (aT -> T)
  meetfC joinfC meetfA joinfA joinfKI meetfKU lef_meet.

End FunLattice.
Module .
HB.reexport.
End Exports.
End FunOrder.
Export FunOrder.Exports.

Lemma ( : Type) ( : porderType d) ( : aT -> T) :
  reflect (forall , (f x <= g x)%O) (f <= g)%O.
Proof.
by apply: (iffP idP) => [fg|fg]; [exact/asboolP | exact/asboolP]. Qed.

Lemma ( : Type) ( : latticeType d) ( : aT -> T) :
  ((f `&` g) x = f x `&` g x)%O.
Proof.
by []. Qed.

Lemma ( : Type) ( : latticeType d) ( : aT -> T) :
  ((f `|` g) x = f x `|` g x)%O.
Proof.
by []. Qed.

Lemma {} ( : T -> T) : iter n.+1 f = f \o iter n f.
Proof.
by []. Qed.

Lemma {} ( : T -> T) : iter n.+1 f = iter n f \o f.
Proof.
by apply/funeqP => ?; rewrite iterSr. Qed.

Lemma {} ( : T -> T) : iter 0 f = id.
Proof.
by []. Qed.

Section Inhabited.
Context ( : Type).

Lemma
inhabitedE
Source code
: inhabited T = exists : T, True.
Proof.
by eqProp; case. Qed.

Lemma
inhabited_witness
Source code
: inhabited T -> T.
Proof.
by rewrite inhabitedE => /cid[]. Qed.

End Inhabited.

Lemma
uncurryK
Source code
{ : Type} : cancel (@uncurry X Y Z) curry.
Proof.
by move=> f; rewrite funeq2E. Qed.

Lemma { : Type} : cancel curry (@uncurry X Y Z).
Proof.
by move=> f; rewrite funeqE=> -[]. Qed.