Built with Alectryon, running Coq+SerAPI v8.15.0+0.15.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.
(* mathcomp analysis (c) 2017 Inria and AIST. License: CeCILL-C.              *)
(* -------------------------------------------------------------------- *)
(* Copyright (c) - 2015--2016 - IMDEA Software Institute                *)
(* Copyright (c) - 2015--2018 - Inria                                   *)
(* Copyright (c) - 2016--2018 - Polytechnique                           *)
(* -------------------------------------------------------------------- *)

Notation "[ predI _ & _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ predU _ & _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ predD _ & _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ predC _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ preim _ of _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "_ + _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ - _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ >= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ > _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ * _" was already used in scope nat_scope. [notation-overridden,parsing]
(******************************************************************************) (* Classical Logic *) (* *) (* This file provides the axioms of classical logic and tools to perform *) (* classical reasoning in the Mathematical Compnent framework. The three *) (* axioms are taken from the standard library of Coq, more details can be *) (* found in Section 5 of *) (* Reynald Affeldt, Cyril Cohen, Damien Rouhling: *) (* Formalization Techniques for Asymptotic Reasoning in Classical Analysis. *) (* Journal of Formalized Reasoning, 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 *) (* {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 into a porderType (resp. latticeType) are equipped with *) (* a porderType (resp. latticeType), (f <= g)%O when f x <= g x for all x, *) (* see lemma lefP. *) (******************************************************************************) Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. Declare Scope box_scope. Declare Scope quant_scope. (* -------------------------------------------------------------------- *) Axiom functional_extensionality_dep : forall (A : Type) (B : A -> Type) (f g : forall x : A, B x), (forall x : A, f x = g x) -> f = g. Axiom propositional_extensionality : forall P Q : Prop, P <-> Q -> P = Q. Axiom constructive_indefinite_description : forall (A : Type) (P : A -> Prop), (exists x : A, P x) -> {x : A | P x}. Notation cid := constructive_indefinite_description.
A: Type
P, Q: A -> Prop

(exists2 x : A, P x & Q x) -> {x : A | P x & Q x}
2
5
6
PQA: exists2 x : A, P x & Q x

{x : A | P x /\ Q x}
by apply: cid; case: PQA => x; exists x. Qed. (* -------------------------------------------------------------------- *) Record mextentionality := { _ : forall (P Q : Prop), (P <-> Q) -> (P = Q); _ : forall {T U : Type} (f g : T -> U), (forall x, f x = g x) -> f = g; }.

mextentionality
10

forall P Q : Prop, P <-> Q -> P = Q

forall (T U : Type) (f g : T -> U), (forall x : T, f x = g x) -> f = g
15

1a
1d
by move=> T U f g; apply: functional_extensionality_dep. Qed.
P, Q: Prop

P <-> Q -> P = Q
21
by have [propext _] := extentionality; apply: propext. Qed.
T, U: Type
f, g: T -> U

f =1 g -> f = g
28
by case: extentionality=> _; apply. Qed.
23
(P = Q) = (P <-> Q)
30
by apply: propext; split=> [->|/propext]. Qed.
23
P = Q <-> (P <-> Q)
35
by rewrite propeqE. Qed.
2a
(f = g) = (f =1 g)
3a
by rewrite propeqE; split=> [->//|/funext]. Qed.
T, U, V: Type
f, g: T -> U -> V

(f = g) = (f =2 g)
3f
by rewrite propeqE; split=> [->//|?]; rewrite funeqE=> x; rewrite funeqE. Qed.
T, U, V, W: Type
f, g: T -> U -> V -> W

(f = g) = (forall (x : T) (y : U) (z : V), f x y z = g x y z)
47
by rewrite propeqE; split=> [->//|?]; rewrite funeq2E=> x y; rewrite funeqE. Qed.
2a
f = g <-> f =1 g
4f
by rewrite funeqE. Qed.
41
f = g <-> f =2 g
54
by rewrite funeq2E. Qed.
49
f = g <-> (forall (x : T) (y : U) (z : V), f x y z = g x y z)
59
by rewrite funeq3E. Qed.
T: Type
P, Q: T -> Prop

(P = Q) = (forall x : T, P x <-> Q x)
5e
by rewrite propeqE; split=> [->//|?]; rewrite funeqE=> x; rewrite propeqE. Qed.
2b
P, Q: T -> U -> Prop

(P = Q) = (forall (x : T) (y : U), P x y <-> Q x y)
66
by rewrite propeqE; split=> [->//|?]; rewrite funeq2E=> ??; rewrite propeqE. Qed.
42
P, Q: T -> U -> V -> Prop

(P = Q) = (forall (x : T) (y : U) (z : V), P x y z <-> Q x y z)
6d
by rewrite propeqE; split=> [->//|?]; rewrite funeq3E=> ???; rewrite propeqE. Qed.
61
A, B: T -> Prop

A = B <-> (forall x : T, A x <-> B x)
74
by rewrite predeqE. Qed.
68
P = Q <-> (forall (x : T) (y : U), P x y <-> Q x y)
7b
by rewrite predeq2E. Qed.
6f
P = Q <-> (forall (x : T) (y : U) (z : V), P x y z <-> Q x y z)
80
by rewrite predeq3E. Qed.
P: Prop

P -> P = True
85
by move=> p; rewrite propeqE. Qed.
88
x, y: P

x = y
8c
by move: x (x) y => /propT-> [] []. Qed. #[global] Hint Resolve Prop_irrelevance : core. (* -------------------------------------------------------------------- *) Record mclassic := { _ : forall (P : Prop), {P} + {~P}; _ : forall T, Choice.mixin_of T }.
X, Y: Type
P: X -> Y -> Prop

(forall x : X, exists y : Y, P x y) -> {f : X -> Y & forall x : X, P x (f x)}
93
by move=> /(_ _)/constructive_indefinite_description -/all_tag. Qed. (* Diaconescu Theorem *)
87
P \/ ~ P
9b
88
U:= fun val Q : bool => Q = val \/ P: bool -> bool -> Prop

9d
88
a3
Uex: forall val : bool, exists b : bool, U val b

9d
88
a3
a8
f:= fun val : bool => projT1 (cid (Uex val)): bool -> bool

9d
88
a3
a8
ad
Uf:= (fun val : bool => projT2 (cid (Uex val))) : (forall val : bool, U val (f val)): forall val : bool, U val (f val)

9d
b1
f true != f false \/ P
b1
f true != f false \/ P -> P \/ ~ P
b1
f true = true \/ P -> f false = false \/ P -> f true != f false \/ P
b7
b1
b9
88
a3
a8
ad
b2
p: P

f true = f false
88
a3
a8
ad
b2
c5
UTF: U true = U false

c6
88
a3
a8
ad
b2
c5
cb
p1, p2: exists b : bool, U false b

projT1 (cid p1) = projT1 (cid p2)
by congr (projT1 (cid _)). Qed.
87
{P} + {~ P}
d3
87
exists b : bool, if b then P else ~ P
87
(exists b : bool, if b then P else ~ P) -> {P} + {~ P}
87
dd
by move=> /cid [[]]; [left|right]. Qed.
61

((T -> False) + T)%type
e2
61
NT: ~ (exists _ : T, True)

e5
by left=> t; case: NT; exists t. Qed.

mclassic
ed
e4
choiceMixin T
61
P: pred T
n: nat
x: T

match pselect (exists x : T, P x) with | left ex => Some (projT1 (cid ex)) | right _ => None end = Some x -> P x
61
f9
fb
Px: P x
exists _ : nat, match pselect (exists x : T, P x) with | left ex => Some (projT1 (cid ex)) | right _ => None end
ff
101
by exists 0; case: pselect => // -[]; exists x. Qed.
f2
f2
by case: classic. Qed.
87
P = True \/ P = False
108
by have [p|Np] := pselect P; [left|right]; rewrite propeqE. Qed.
9b
9b
by case: (pselect P); tauto. Qed. (* -------------------------------------------------------------------- *)

true = True
10f
by rewrite propeqE; split. Qed.

false = False
114
by rewrite propeqE; split. Qed.
87
~ P -> P = False
119
by move=> p; rewrite propeqE; tauto. Qed.
T, rT: Type
U, V: T -> rT

(forall x : T, U x = V x) -> [eta U] = [eta V]
11e
by move=> /funext->. Qed.
T1, T2, rT: Type
U, V: T1 -> T2 -> rT

(forall (x : T1) (y : T2), U x y = V x y) -> (fun x : T1 => [eta U x]) = (fun x : T1 => [eta V x])
126
by move=> UV; rewrite funeq2E => x y; rewrite UV. Qed.
T1, T2, T3, rT: Type
U, V: T1 -> T2 -> T3 -> rT

(forall (x : T1) (y : T2) (z : T3), U x y z = V x y z) -> (fun (x : T1) (y : T2) => [eta U x y]) = (fun (x : T1) (y : T2) => [eta V x y])
12e
by move=> UV; rewrite funeq3E => x y z; rewrite UV. Qed.
61
U, V: T -> Prop

(forall x : T, U x = V x) -> (forall x : T, U x) = (forall x : T, V x)
136
by move=> e; rewrite propeqE; split=> ??; rewrite (e,=^~e). Qed.
61
S: T -> Type
U, V: forall x : T, S x -> Prop

(forall (x : T) (y : S x), U x y = V x y) -> (forall (x : T) (y : S x), U x y) = (forall (x : T) (y : S x), V x y)
13d
by move=> UV; apply/eq_forall => x; apply/eq_forall. Qed.
61
140
R: forall x : T, S x -> Type
U, V: forall (x : T) (y : S x), R x y -> Prop

(forall (x : T) (y : S x) (z : R x y), U x y z = V x y z) -> (forall (x : T) (y : S x) (z : R x y), U x y z) = (forall (x : T) (y : S x) (z : R x y), V x y z)
145
by move=> UV; apply/eq_forall2 => x y; apply/eq_forall. Qed.
138
(forall x : T, U x = V x) -> (exists x : T, U x) = (exists x : T, V x)
14d
by move=> e; rewrite propeqE; split=> - [] x ?; exists x; rewrite (e,=^~e). Qed.
13f
(forall (x : T) (y : S x), U x y = V x y) -> (exists (x : T) (y : S x), U x y) = (exists (x : T) (y : S x), V x y)
152
by move=> UV; apply/eq_exists => x; apply/eq_exists. Qed.
147
(forall (x : T) (y : S x) (z : R x y), U x y z = V x y z) -> (exists (x : T) (y : S x) (z : R x y), U x y z) = (exists (x : T) (y : S x) (z : R x y), V x y z)
157
by move=> UV; apply/eq_exists2 => x y; apply/eq_exists. Qed.
61
P: T -> Prop
s, t: T
p: P s
q: P t

s = t -> exist P s p = exist P t q
15c
by move=> st; case: _ / st in q *; apply/congr1. Qed.
T, S: Type
U: T -> S -> Prop

(forall (x : T) (y : S), U x y) = (forall (y : S) (x : T), U x y)
166
by rewrite propeqE; split. Qed.
168
(exists (x : T) (y : S), U x y) = (exists (y : S) (x : T), U x y)
16e
by rewrite propeqE; split => -[x [y]]; exists y, x. Qed.
88
b: bool

reflect P b -> P = b
173
by rewrite propeqE; exact: rwP. Qed. Definition asbool (P : Prop) := if pselect P then true else false. Notation "`[< P >]" := (asbool P) : bool_scope.
87
`[< P >] = P
17a
by rewrite propeqE /asbool; case: pselect; split. Qed.
87
reflect P `[< P >]
17f
by apply: (equivP idP); rewrite asboolE. Qed.
176

`[< b >] = b
184
by apply/asboolP/idP. Qed.
87
reflect (~ P) (~~ `[< P >])
18a
by rewrite /asbool; case: pselect=> h; constructor. Qed.
87
`[< P >] -> P
18f
by case: asboolP. Qed. (* Shall this be a coercion ?*)
87
P -> `[< P >]
194
by case: asboolP. Qed.
87
~ P -> `[< P >] = false
199
by apply/introF/asboolP. Qed.
T: eqType
x, y: T

(x == y : Prop) = (x = y)
19e
by apply/propext; split=> /eqP. Qed.

injective is_true
1a6
by move=> [] []; rewrite ?(trueE, falseE) ?propeqE; tauto. Qed. Definition gen_eq (T : Type) (u v : T) := `[<u = v>].
e4
Equality.axiom (gen_eq (T:=T))
1ab
by move=> x y; apply: (iffP (asboolP _)). Qed. Definition gen_eqMixin {T : Type} := EqMixin (@gen_eqP T). Canonical arrow_eqType (T : Type) (T' : eqType) := EqType (T -> T') gen_eqMixin. Canonical arrow_choiceType (T : Type) (T' : choiceType) := ChoiceType (T -> T') gen_choiceMixin. Definition dep_arrow_eqType (T : Type) (T' : T -> eqType) := EqType (forall x : T, T' x) gen_eqMixin. Definition dep_arrow_choiceClass (T : Type) (T' : T -> choiceType) := Choice.Class (Equality.class (dep_arrow_eqType T')) gen_choiceMixin. Definition dep_arrow_choiceType (T : Type) (T' : T -> choiceType) := Choice.Pack (dep_arrow_choiceClass T'). Canonical Prop_eqType := EqType Prop gen_eqMixin. Canonical Prop_choiceType := ChoiceType Prop gen_choiceMixin. Section classicType. Variable T : Type. Definition classicType := T. Canonical classicType_eqType := EqType classicType gen_eqMixin. Canonical classicType_choiceType := ChoiceType classicType gen_choiceMixin. End classicType. Notation "'{classic' T }" := (classicType T) (format "'{classic' T }") : type_scope. Section eclassicType. Variable T : eqType. Definition eclassicType : Type := T. Canonical eclassicType_eqType := EqType eclassicType (Equality.class T). Canonical eclassicType_choiceType := ChoiceType eclassicType gen_choiceMixin. End eclassicType. Notation "'{eclassic' T }" := (eclassicType T) (format "'{eclassic' T }") : type_scope. Definition canonical_of T U (sort : U -> T) := forall (G : T -> Type), (forall x', G (sort x')) -> forall x, G x. Notation canonical_ sort := (@canonical_of _ _ sort). Notation canonical T E := (@canonical_of T E id).
2b
sort: U -> T

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

canonical_ [eta Equality.sort]
1b7
by apply: canon => T; exists [eqType of {classic T}]. Qed.

canonical_ [eta Choice.sort]
1bc
by apply: canon => T; exists [choiceType of {classic T}]. Qed.

canonical_ [eta Choice.eqType]
1c1
by apply: canon=> T; exists [choiceType of {eclassic T}]; case: T. Qed.

(~ True) = False
1c6
exact/propext. Qed.

(~ False) = True
1cb
by apply/propext; split=> _. Qed. (* -------------------------------------------------------------------- *)
23
P <-> Q -> `[< P >] = `[< Q >]
1d0
by rewrite -propeqE => ->. Qed.
24
176

reflect Q b -> P <-> Q -> `[< P >] = b
1d5
by move=> Q_b [PQ QP]; apply/asboolP/Q_b. Qed.
23
P <-> Q -> `[< P >] <-> `[< Q >]
1db
by move/asbool_equiv_eq->. Qed.
23
`[< P >] = `[< Q >] -> P <-> Q
1e0
by move=> eq; split=> /asboolP; rewrite (eq, =^~ eq) => /asboolP. Qed. (* -------------------------------------------------------------------- *)
23
reflect (P /\ Q) (`[< P >] && `[< Q >])
1e5
23
P /\ Q -> `[< P >] && `[< Q >]
by case=> /asboolP-> /asboolP->. Qed.
P, Q, R: Prop

reflect [/\ P, Q & R] [&& `[< P >], `[< Q >] & `[< R >]]
1ee
1f0
[/\ P, Q & R] -> [&& `[< P >], `[< Q >] & `[< R >]]
by case => /asboolP -> /asboolP -> /asboolP ->. Qed.
23
reflect (P \/ Q) (`[< P >] || `[< Q >])
1f9
23
P \/ Q -> `[< P >] || `[< Q >]
by case=> /asboolP-> //=; rewrite orbT. Qed.
1f0
reflect [\/ P, Q | R] [|| `[< P >], `[< Q >] | `[< R >]]
202
1f0
[|| `[< P >], `[< Q >] | `[< R >]] -> [\/ P, Q | R]
by case/orP=> [/asboolP p|/orP[]/asboolP]; [exact:Or31|exact:Or32|exact:Or33]. Qed.
87
`[< ~ P >] = ~~ `[< P >]
20b
by apply/idP/asboolPn=> [/asboolP|/asboolT]. Qed.
23
`[< P \/ Q >] = `[< P >] || `[< Q >]
210
exact: (asbool_equiv_eqP (or_asboolP _ _)). Qed.
23
`[< P /\ Q >] = `[< P >] && `[< Q >]
215
exact: (asbool_equiv_eqP (and_asboolP _ _)). Qed. (* -------------------------------------------------------------------- *)
23
reflect (P -> Q) (`[< P >] ==> `[< Q >])
21a
23
(P -> Q) -> `[< P >] -> `[< Q >]
by move=> PQ /asboolP/PQ/asboolT. Qed.
23
`[< P -> Q >] = `[< P >] ==> `[< Q >]
223
exact: (asbool_equiv_eqP imply_asboolP). Qed.
23
reflect (P /\ ~ Q) (~~ `[< P -> Q >])
228
23
~~ `[< P -> Q >] -> P /\ ~ Q
23
P /\ ~ Q -> ~~ `[< P -> Q >]
23
232
by move/and_asboolP; rewrite asbool_neg -negb_imply asbool_imply. Qed. (* -------------------------------------------------------------------- *)
61
15f

reflect (forall x : T, `[< P x >]) `[< forall x : T, P x >]
237
239
(forall x : T, `[< P x >]) -> `[< forall x : T, P x >]
by move=> Px; apply/asboolP=> x; apply/asboolP. Qed.
239
reflect (exists x : T, `[< P x >]) `[< exists x : T, P x >]
241
239
(exists x : T, `[< P x >]) -> `[< exists x : T, P x >]
by case=> x bPx; apply/asboolP; exists x; apply/asboolP. Qed. (* -------------------------------------------------------------------- *)
87
P = False -> ~ P
24a
by move->. Qed.
87
~ ~ P -> P
24f
by move/asboolPn=> nnb; apply/asboolP; apply: contraR nnb => /asboolPn /asboolP. Qed.
119
11c by case: (pdegen P)=> ->. Qed.
87
(~ P) = False -> P
255
move/notT; exact: contrapT. Qed.

involutive not
25a
87
(~ ~ True) = True
by rewrite [~ True]notTE //; case: (pdegen (~ False)) => // /notFE. Qed.
Q, P: Prop

(~ Q -> P) -> ~ P -> Q
263
266
cb: ~ Q -> P
nb: ~~ `[< P >]

`[< Q >]
by apply: contraR nb => /asboolP /cb /asboolP. Qed.
265
(~ Q -> ~ P) -> P -> Q
271
266
cb: ~ Q -> ~ P
hb: `[< P >]

26f
by apply: contraLR hb => /asboolP /cb /asboolPn. Qed.
176
88

(~~ b -> P) -> ~ P -> b
27c
by move=> bP; apply: contra_notP => /negP. Qed.
175
(~~ b -> ~ P) -> P -> b
282
by move=> /contra_notT; rewrite notK. Qed.
176
Q: Prop

(~ Q -> ~~ b) -> b -> Q
287
by move=> QB; apply: contraPP => /QB/negP. Qed.
175
(~ P -> b) -> ~~ b -> P
28e
by move=> /contra_notP + /negP => /[apply]. Qed.
1a1
1a2
88

(~ P -> x = y) -> x != y -> P
293
by move=> Pxy; apply: contraNP => /Pxy/eqP. Qed.
1a1
1a2
28a

(~ Q -> x != y) -> x = y -> Q
299
by move=> Qxy /eqP; apply: contraTP. Qed.
87
(~ P -> P) -> P
29f
by move=> ?; case: (pselect P). Qed.

injective not
2a4
exact: can_inj notK. Qed.
23
P = (~ Q) -> (~ P) = Q
2a9
exact: canLR notK. Qed.
23
(~ P) = Q -> P = (~ Q)
2ae
exact: canRL notK. Qed.
23
(P <-> ~ Q) <-> (~ P <-> Q)
2b3
by split=> [/propext ->|/propext <-]; rewrite notK. Qed.
23
(~ P <-> ~ Q) <-> (P <-> Q)
2b8
by split=> [/iff_notr|PQ]; [|apply/iff_notr]; rewrite notK. Qed. (* -------------------------------------------------------------------- *) (* assia : let's see if we need the simplpred machinery. In any case, we sould first try definitions + appropriate Arguments setting to see whether these can replace the canonical structures machinery. *) Definition predp T := T -> Prop. Identity Coercion fun_of_pred : predp >-> Funclass. Definition relp T := T -> predp T. Identity Coercion fun_of_rel : rel >-> Funclass. Notation xpredp0 := (fun _ => False). Notation xpredpT := (fun _ => True). Notation xpredpI := (fun (p1 p2 : predp _) x => p1 x /\ p2 x). Notation xpredpU := (fun (p1 p2 : predp _) x => p1 x \/ p2 x). Notation xpredpC := (fun (p : predp _) x => ~ p x). Notation xpredpD := (fun (p1 p2 : predp _) x => ~ p2 x /\ p1 x). Notation xpreimp := (fun f (p : predp _) x => p (f x)). Notation xrelpU := (fun (r1 r2 : relp _) x y => r1 x y \/ r2 x y). (* -------------------------------------------------------------------- *) Definition pred0p (T : Type) (P : predp T) : bool := `[<P =1 xpredp0>]. Prenex Implicits pred0p.
61
P: predp T

reflect (P =1 xpredp0) (pred0p P)
2bd
by apply: (iffP (asboolP _)). Qed. (* -------------------------------------------------------------------- *)
239
reflect (forall x : T, ~ P x) (~~ `[< exists x : T, P x >])
2c4
61
15f
NP: ~ (exists x : T, P x)
fb
100

False
61
15f
NP: forall x : T, ~ P x
~~ `[< exists x : T, P x >]
2d0
2d2
by apply/asboolP=> -[x]; apply/NP. Qed.
239
reflect (exists x : T, ~ P x) (~~ `[< forall x : T, P x >])
2d7
239
~~ `[< forall x : T, P x >] -> exists x : T, ~ P x
61
15f
NP: ~ (forall x : T, P x)
h: ~ (exists x : T, ~ P x)

2cd
by apply/NP=> x; apply/asboolP/negbNE/asboolPn=> NPx; apply/h; exists x. Qed.
61
f9

`[< forall x : T, ~~ P x >] = ~~ `[< exists x : T, P x >]
2e6
apply: (asbool_equiv_eqP forallp_asboolPn); by split=> h x; apply/negP/h. Qed.
2e8
`[< exists x : T, ~~ P x >] = ~~ `[< forall x : T, P x >]
2ec
apply: (asbool_equiv_eqP existsp_asboolPn); by split=> -[x h]; exists x; apply/negP. Qed.
23
~ (P -> Q) <-> P /\ ~ Q
2f1
23
`[< ~ (P -> Q) >] -> P /\ ~ Q
by rewrite asbool_neg => /imply_asboolPn. Qed.
23
~ (P /\ Q) <-> ~ P \/ ~ Q
2fa
23
~~ `[< P /\ Q >] -> ~ P \/ ~ Q
by rewrite asbool_and negb_and => /orP[]/asboolPn; [left|right]. Qed.
1f0
~ [/\ P, Q & R] <-> [\/ ~ P, ~ Q | ~ R]
303
1f0
~~ [&& `[< P >], `[< Q >] & `[< R >]] -> [\/ ~ P, ~ Q | ~ R]
1f0
[|| `[< ~ P >], `[< ~ Q >] | `[< ~ R >]] -> ~ [/\ P, Q & R]
1f0
30d
by rewrite 3!asbool_neg -2!negb_and => /and3_asboolP. Qed.
23
~ (P \/ Q) <-> ~ P /\ ~ Q
312
split; [apply: contra_notP => /not_andP|apply: contraPnot => AB; apply/not_andP]; by rewrite 2!notK. Qed.
23
(~ (P -> Q)) = (P /\ ~ Q)
317
by rewrite propeqE not_implyP. Qed.
23
(P \/ Q) = (Q \/ P)
31c
by rewrite propeqE; split=> [[]|[]]; [right|left|right|left]. Qed.

associative or
321
by move=> P Q R; rewrite propeqE; split=> [|]; tauto. Qed.
23
(P /\ Q) = (Q /\ P)
326
by rewrite propeqE; split=> [[]|[]]. Qed.

associative and
32b
by move=> P Q R; rewrite propeqE; split=> [|]; tauto. Qed.
239
(forall x : T, ~ P x) = (~ (exists x : T, P x))
330
by rewrite propeqE; split => [fP [x /fP]//|nexP x Px]; apply: nexP; exists x. Qed.
239
(exists x : T, ~ P x) = (~ (forall x : T, P x))
335
61
15f
NaP: ~ (forall x : T, P x)

exists x : T, ~ P x
by apply: contrapT; rewrite -forallNE => aP; apply: NaP => x; apply: contrapT. Qed.
239
(exists x : T, ~ P x) <-> ~ (forall x : T, P x)
340
by rewrite existsNE. Qed.
239
(exists x : T, P x) <-> ~ (forall x : T, ~ P x)
345
by rewrite forallNE notK. Qed.
239
(forall x : T, ~ P x) <-> ~ (exists x : T, P x)
34a
by rewrite forallNE. Qed.
239
(forall x : T, P x) <-> ~ (exists x : T, ~ P x)
34f
by rewrite existsNE notK. Qed.
60
(exists2 x : T, P x & Q x) <-> (exists x : T, P x /\ Q x)
354
by split=> [[x ? ?] | [x []]]; exists x. Qed.
60
(exists2 x : T, P x & Q x) <-> ~ (forall x : T, ~ P x \/ ~ Q x)
359
60
~ (forall x : T, ~ (P x /\ Q x)) <-> ~ (forall x : T, ~ P x \/ ~ Q x)
by split; apply: contra_not => PQx x; apply/not_andP; apply: PQx. Qed.
60
(forall x : T, ~ P x \/ ~ Q x) <-> ~ (exists2 x : T, P x & Q x)
362
61
62
PQ: ~ (exists2 x : T, P x & Q x)
t: T

~ P t \/ ~ Q t
by rewrite -not_andP => -[Pt Qt]; apply PQ; exists t. Qed.
60
(forall x : T, P x -> ~ Q x) <-> ~ (exists2 x : T, P x & Q x)
36e
369
P t -> ~ Q t
by move=> Pt Qt; apply: PQ; exists t. Qed.
60
(exists2 x : T, P x & ~ Q x) <-> ~ (forall x : T, P x -> Q x)
377
61
62
fb
100

~ (exists2 x : T, P x & ~ Q x) -> Q x
by apply: contra_notP => NQx; exists x. Qed.
60
reflect (forall x : T, ~ P x \/ ~ Q x) (~~ `[< exists2 x : T, P x & Q x >])
381
61
62
NP: ~ (exists2 x : T, P x & Q x)
fb

~ P x \/ ~ Q x
61
62
NP: forall x : T, ~ P x \/ ~ Q x
~~ `[< exists2 x : T, P x & Q x >]
38d
38f
by apply/asboolP=> -[x Px Qx]; have /not_andP := NP x; exact. Qed. Module FunOrder. Section FunOrder. Import Order.TTheory. Variables (aT : Type) (d : unit) (T : porderType d). Implicit Types f g h : aT -> T.
aT: Type
d: unit
T: porderType d

unit
394
exact: tt. Qed. Definition lef f g := `[< forall x, (f x <= g x)%O >]. Local Notation "f <= g" := (lef f g). Definition ltf f g := `[< (forall x, (f x <= g x)%O) /\ exists x, f x != g x >]. Local Notation "f < g" := (ltf f g).
397
398
399
f, g: aT -> T

(f < g) = (g != f) && (f <= g)
39d
397
398
399
3a0
fg: f < g

g != f
3a6
f <= g
397
398
399
3a0
gf: g != f
fg: f <= g
exists x : aT, f x != g x
3a4
3a6
3ab
3ac
3b3
397
398
399
3a0
x: aT
fg: forall x : aT, (f x <= g x)%O
y: aT
gfy: f y != g y

(f x == g x) || (f x < g x)%O
3b5
3ad
3b0
3c1
397
398
399
3a0
3ae
3af
h: forall x : aT, ~ f x != g x

2cd
3c7
f =1 g -> False
by rewrite -funeqE; apply/nesym/eqP. Qed.
396
reflexive lef
3ce
by move=> f; apply/asboolP => x. Qed.
396
antisymmetric lef
3d3
397
398
399
3a0
3bc
gf: forall x : aT, (g x <= f x)%O
3bb

f x = g x
by apply/eqP; rewrite eq_le fg gf. Qed.
396
transitive lef
3de
397
398
399
g, f, h: aT -> T
3bc
gh: forall x : aT, (g x <= h x)%O
3bb

(f x <= h x)%O
by rewrite (le_trans (fg x)). Qed. Definition porderMixin := @LePOrderMixin _ lef ltf ltf_def lef_refl lef_anti lef_trans. Canonical porderType := POrderType fun_display (aT -> T) porderMixin. End FunOrder. Section FunLattice. Import Order.TTheory. Variables (aT : Type) (d : unit) (T : latticeType d). Implicit Types f g h : aT -> T. Definition meetf f g := fun x => Order.meet (f x) (g x). Definition joinf f g := fun x => Order.join (f x) (g x).
397
398
T: latticeType d

commutative meetf
3ea
move=> f g; apply/funext => x; exact: meetC. Qed.
3ec
commutative joinf
3f1
move=> f g; apply/funext => x; exact: joinC. Qed.
3ec
associative meetf
3f6
move=> f g h; apply/funext => x; exact: meetA. Qed.
3ec
associative joinf
3fb
move=> f g h; apply/funext => x; exact: joinA. Qed.
397
398
3ed
g, f: aT -> T

meetf f (joinf f g) = f
400
apply/funext => x; exact: joinKI. Qed.
402
joinf f (meetf f g) = f
407
apply/funext => x; exact: meetKU. Qed.
397
398
3ed
3a0

(f <= g)%O = (meetf f g == f)
40c
397
398
3ed
3a0
f_le_g: forall x : aT, (f x <= g x)%O

meetf f g == f
40e
(meetf f g <= g)%O
412
40e
419
41c
apply/asboolP => x; exact: leIr. Qed. Definition latticeMixin := LatticeMixin meetfC joinfC meetfA joinfA joinfKI meetfKU lef_meet. Canonical latticeType := LatticeType (aT -> T) latticeMixin. End FunLattice. Module Exports.
Ignoring canonical projection to forall _, _ by Order.POrder.sort in porderType: redundant with porderType [redundant-canonical-projection,typechecker]
Ignoring canonical projection to forall _, _ by Order.Lattice.sort in latticeType: redundant with latticeType [redundant-canonical-projection,typechecker]
End Exports. End FunOrder. Export FunOrder.Exports.
39f
reflect (forall x : aT, (f x <= g x)%O) (f <= g)%O
422
by apply: (iffP idP) => [fg|fg]; [exact/asboolP | apply/asboolP]. Qed.
397
398
3ed
3a0
3bb

(f `&` g)%O x = (f x `&` g x)%O
427
by []. Qed.
429
(f `|` g)%O x = (f x `|` g x)%O
42d
by []. Qed.
61
f: T -> T
fa

iter n.+1 f = f \o iter n f
432
by []. Qed.
434
iter n.+1 f = iter n f \o f
439
by apply/funeqP => ?; rewrite iterSr. Qed.
61
435

iter 0 f = id
43e
by []. Qed.