Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. 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.
(** * Truncatedness *)
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Local Set Universe Minimization ToSet.LocalOpen Scope trunc_scope.LocalOpen Scope path_scope.Generalizable VariablesA B m n f.(** ** Notation for truncation-levels *)Open Scope trunc_scope.(** Increase a truncation index by a natural number. *)Fixpointtrunc_index_inc@{} (k : trunc_index) (n : nat)
: trunc_index
:= match n with
| O => k
| S m => (trunc_index_inc k m).+1end.(** This is a variation that inserts the successor operations in the other order. This is sometimes convenient. *)Fixpointtrunc_index_inc'@{} (k : trunc_index) (n : nat)
: trunc_index
:= match n with
| O => k
| S m => (trunc_index_inc' k.+1 m)
end.
n: nat k: trunc_index
trunc_index_inc' k.+1 n = (trunc_index_inc' k n).+1
n: nat k: trunc_index
trunc_index_inc' k.+1 n = (trunc_index_inc' k n).+1
k: trunc_index
trunc_index_inc' k.+10 = (trunc_index_inc' k 0).+1
n: nat IHn: forallk : trunc_index, trunc_index_inc' k.+1 n = (trunc_index_inc' k n).+1 k: trunc_index
trunc_index_inc' k.+1 n.+1 =
(trunc_index_inc' k n.+1).+1
k: trunc_index
trunc_index_inc' k.+10 = (trunc_index_inc' k 0).+1
reflexivity.
n: nat IHn: forallk : trunc_index, trunc_index_inc' k.+1 n = (trunc_index_inc' k n).+1 k: trunc_index
trunc_index_inc' k.+1 n.+1 =
(trunc_index_inc' k n.+1).+1
exact (IHn k.+1).Defined.
k: trunc_index n: nat
trunc_index_inc k n = trunc_index_inc' k n
k: trunc_index n: nat
trunc_index_inc k n = trunc_index_inc' k n
k: trunc_index
trunc_index_inc k 0 = trunc_index_inc' k 0
k: trunc_index n: nat IHn: trunc_index_inc k n = trunc_index_inc' k n
trunc_index_inc k n.+1 = trunc_index_inc' k n.+1
k: trunc_index
trunc_index_inc k 0 = trunc_index_inc' k 0
reflexivity.
k: trunc_index n: nat IHn: trunc_index_inc k n = trunc_index_inc' k n
trunc_index_inc k n.+1 = trunc_index_inc' k n.+1
k: trunc_index n: nat IHn: trunc_index_inc k n = trunc_index_inc' k n
(trunc_index_inc k n).+1 = trunc_index_inc' k.+1 n
k: trunc_index n: nat IHn: trunc_index_inc k n = trunc_index_inc' k n
(trunc_index_inc' k n).+1 = trunc_index_inc' k.+1 n
exact (ap _ p).Defined.Definitionint_to_trunc_index@{} (v : Decimal.int) : option trunc_index
:= match v with
| Decimal.Pos d => Some (nat_to_trunc_index (Nat.of_uint d))
| Decimal.Neg d => match Nat.of_uint d with
| 2%nat => Some minus_two
| 1%nat => Some (minus_two.+1)
| 0%nat => Some (minus_two.+2)
| _ => None
endend.Definitionnum_int_to_trunc_index@{} (v : Numeral.int) : option trunc_index :=
match v with
| Numeral.IntDec v => int_to_trunc_index v
| Numeral.IntHex _ => None
end.Fixpointtrunc_index_to_little_uint@{} n acc :=
match n with
| minus_two => acc
| minus_two.+1 => acc
| minus_two.+2 => acc
| trunc_S n => trunc_index_to_little_uint n (Decimal.Little.succ acc)
end.Definitiontrunc_index_to_int@{} n :=
match n with
| minus_two => Decimal.Neg (Nat.to_uint 2)
| minus_two.+1 => Decimal.Neg (Nat.to_uint 1)
| n => Decimal.Pos (Decimal.rev (trunc_index_to_little_uint n Decimal.zero))
end.Definitiontrunc_index_to_num_int@{} n :=
Numeral.IntDec (trunc_index_to_int n).(** This allows us to use notation like (-2) and 42 for a [trunc_index]. *)Number Notationtrunc_index num_int_to_trunc_index trunc_index_to_num_int
: trunc_scope.(** Sends a [trunc_index] [n] to the natural number [n+2]. *)Fixpointtrunc_index_to_nat (n : trunc_index) : nat
:= match n with
| minus_two => 0%nat
| n'.+1 => (trunc_index_to_nat n').+1end.(** ** Arithmetic on truncation-levels. *)Fixpointtrunc_index_add@{} (m n : trunc_index) : trunc_index
:= match m with
| -2 => n
| m'.+1 => (trunc_index_add m' n).+1end.Notation"m +2+ n" := (trunc_index_add m n) : trunc_scope.
m: trunc_index
m +2+ -2 = m
m: trunc_index
m +2+ -2 = m
-2 +2+ -2 = -2
m: trunc_index IHm: m +2+ -2 = m
m.+1 +2+ -2 = m.+1
m: trunc_index IHm: m +2+ -2 = m
m.+1 +2+ -2 = m.+1
m: trunc_index IHm: m +2+ -2 = m
m +2+ -2 = m
assumption.Defined.
m, n: trunc_index
m +2+ n.+1 = (m +2+ n).+1
m, n: trunc_index
m +2+ n.+1 = (m +2+ n).+1
n: trunc_index
-2 +2+ n.+1 = (-2 +2+ n).+1
n, m: trunc_index IHm: m +2+ n.+1 = (m +2+ n).+1
m.+1 +2+ n.+1 = (m.+1 +2+ n).+1
n, m: trunc_index IHm: m +2+ n.+1 = (m +2+ n).+1
m.+1 +2+ n.+1 = (m.+1 +2+ n).+1
cbn; apply ap; assumption.Defined.
m, n: trunc_index
m +2+ n = n +2+ m
m, n: trunc_index
m +2+ n = n +2+ m
m: trunc_index
m +2+ -2 = -2 +2+ m
m, n: trunc_index IHn: m +2+ n = n +2+ m
m +2+ n.+1 = n.+1 +2+ m
m: trunc_index
m +2+ -2 = -2 +2+ m
apply trunc_index_add_minus_two.
m, n: trunc_index IHn: m +2+ n = n +2+ m
m +2+ n.+1 = n.+1 +2+ m
exact (trunc_index_add_succ _ _ @ ap trunc_S IHn).Defined.Fixpointtrunc_index_leq@{} (m n : trunc_index) : Type0
:= match m, n with
| -2, _ => Unit
| m'.+1, -2 => Empty
| m'.+1, n'.+1 => trunc_index_leq m' n'
end.Existing Classtrunc_index_leq.Notation"m <= n" := (trunc_index_leq m n) : trunc_scope.Instancetrunc_index_leq_minus_two_n@{} n : -2 <= n := tt.
n: trunc_index
n <= n.+1
n: trunc_index
n <= n.+1
byinduction n as [|n IHn] using trunc_index_ind.Defined.
(* The RHS is definitionally [m +2+ n], which is definitionally [m +2+ n.-1.+1], so this finishes it off: *)symmetry; napply trunc_index_add_succ.Defined.
(* The RHS is definitionally [m +2+ n], which is definitionally [m +2+ n.-1.+1], so this finishes it off: *)symmetry; napply trunc_index_add_succ.Defined.
n: trunc_index
n <= -2 -> n = -2
n: trunc_index
n <= -2 -> n = -2
-2 <= -2 -> -2 = -2
n: trunc_index
n.+1 <= -2 -> n.+1 = -2
n: trunc_index
n.+1 <= -2 -> n.+1 = -2
contradiction.Defined.
n, m: trunc_index
n <= m -> n <= m.+1
n, m: trunc_index
n <= m -> n <= m.+1
n: trunc_index
forallm : trunc_index, n <= m -> n <= m.+1
forallm : trunc_index, -2 <= m -> -2 <= m.+1
n: trunc_index IHn: forallm : trunc_index, n <= m -> n <= m.+1
forallm : trunc_index, n.+1 <= m -> n.+1 <= m.+1
n: trunc_index IHn: forallm : trunc_index, n <= m -> n <= m.+1
forallm : trunc_index, n.+1 <= m -> n.+1 <= m.+1
n: trunc_index IHn: forallm : trunc_index, n <= m -> n <= m.+1 m: trunc_index p: n.+1 <= m
n <= m
n: trunc_index IHn: forallm : trunc_index, n <= m -> n <= m.+1 p: n.+1 <= -2
n <= -2
n: trunc_index IHn: forallm : trunc_index, n <= m -> n <= m.+1 m: trunc_index p: n.+1 <= m.+1 IHm: n.+1 <= m -> n <= m
n <= m.+1
n: trunc_index IHn: forallm : trunc_index, n <= m -> n <= m.+1 m: trunc_index p: n.+1 <= m.+1 IHm: n.+1 <= m -> n <= m
n <= m.+1
apply IHn, p.Defined.
Reflexive trunc_index_leq
Reflexive trunc_index_leq
n: trunc_index
n <= n
byinduction n as [|n IHn] using trunc_index_ind.Defined.
Transitive trunc_index_leq
Transitive trunc_index_leq
a, b, c: trunc_index p: a <= b q: b <= c
a <= c
forallbac : trunc_index, a <= b -> b <= c -> a <= c
forallac : trunc_index, a <= -2 -> -2 <= c -> a <= c
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c
forallac : trunc_index,
a <= b.+1 -> b.+1 <= c -> a <= c
forallac : trunc_index, a <= -2 -> -2 <= c -> a <= c
a, c: trunc_index p: a <= -2
-2 <= c -> a <= c
bydestruct (trunc_index_leq_minus_two p).
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c
forallac : trunc_index,
a <= b.+1 -> b.+1 <= c -> a <= c
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c
-2 <= b.+1 -> b.+1 <= -2 -> -2 <= -2
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c c: trunc_index IHc: -2 <= b.+1 -> b.+1 <= c -> -2 <= c
-2 <= b.+1 -> b.+1 <= c.+1 -> -2 <= c.+1
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c a: trunc_index IHa: forallc : trunc_index, a <= b.+1 -> b.+1 <= c -> a <= c
a.+1 <= b.+1 -> b.+1 <= -2 -> a.+1 <= -2
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c a: trunc_index IHa: forallc : trunc_index, a <= b.+1 -> b.+1 <= c -> a <= c c: trunc_index IHc: a.+1 <= b.+1 -> b.+1 <= c -> a.+1 <= c
a.+1 <= b.+1 -> b.+1 <= c.+1 -> a.+1 <= c.+1
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c p: -2 <= b.+1 q: b.+1 <= -2
-2 <= -2
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c c: trunc_index IHc: -2 <= b.+1 -> b.+1 <= c -> -2 <= c p: -2 <= b.+1 q: b.+1 <= c.+1
-2 <= c.+1
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c a: trunc_index IHa: forallc : trunc_index, a <= b.+1 -> b.+1 <= c -> a <= c p: a.+1 <= b.+1 q: b.+1 <= -2
a.+1 <= -2
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c a: trunc_index IHa: forallc : trunc_index, a <= b.+1 -> b.+1 <= c -> a <= c c: trunc_index IHc: a.+1 <= b.+1 -> b.+1 <= c -> a.+1 <= c p: a.+1 <= b.+1 q: b.+1 <= c.+1
a.+1 <= c.+1
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c a: trunc_index IHa: forallc : trunc_index, a <= b.+1 -> b.+1 <= c -> a <= c p: a.+1 <= b.+1 q: b.+1 <= -2
a.+1 <= -2
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c a: trunc_index IHa: forallc : trunc_index, a <= b.+1 -> b.+1 <= c -> a <= c c: trunc_index IHc: a.+1 <= b.+1 -> b.+1 <= c -> a.+1 <= c p: a.+1 <= b.+1 q: b.+1 <= c.+1
a.+1 <= c.+1
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c a: trunc_index IHa: forallc : trunc_index, a <= b.+1 -> b.+1 <= c -> a <= c c: trunc_index IHc: a.+1 <= b.+1 -> b.+1 <= c -> a.+1 <= c p: a.+1 <= b.+1 q: b.+1 <= c.+1
a.+1 <= c.+1
b: trunc_index IHb: forallac : trunc_index, a <= b -> b <= c -> a <= c a: trunc_index IHa: forallc : trunc_index, a <= b.+1 -> b.+1 <= c -> a <= c c: trunc_index IHc: a.+1 <= b.+1 -> b.+1 <= c -> a.+1 <= c p: a <= b q: b <= c
a <= c
byapply IHb.Defined.
n, m: trunc_index
n <= m +2+ n
n, m: trunc_index
n <= m +2+ n
n: trunc_index
n <= -2 +2+ n
n, m: trunc_index IHm: n <= m +2+ n
n <= m.+1 +2+ n
n: trunc_index
n <= -2 +2+ n
reflexivity.
n, m: trunc_index IHm: n <= m +2+ n
n <= m.+1 +2+ n
rapply trunc_index_leq_transitive.Defined.
n, m: trunc_index
n <= n +2+ m
n, m: trunc_index
n <= n +2+ m
n, m: trunc_index
n <= m +2+ n
apply trunc_index_leq_add.Defined.
trunc_index_min: trunc_index ->
trunc_index -> trunc_index n, m: trunc_index
trunc_index
trunc_index_min: trunc_index ->
trunc_index -> trunc_index n, m: trunc_index
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m = trunc_index_min m n m: trunc_index IHm: trunc_index_min n.+1 m = trunc_index_min m n.+1
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m = trunc_index_min m n m: trunc_index IHm: trunc_index_min n.+1 m = trunc_index_min m n.+1
n: trunc_index IHn: forallm : trunc_index, (trunc_index_min n m = n) + (trunc_index_min n m = m) m: trunc_index IHm: (trunc_index_min n.+1 m = n.+1) + (trunc_index_min n.+1 m = m)
n: trunc_index IHn: forallm : trunc_index, (trunc_index_min n m = n) + (trunc_index_min n m = m) m: trunc_index IHm: (trunc_index_min n.+1 m = n.+1) + (trunc_index_min n.+1 m = m)
n: trunc_index IHn: forallm : trunc_index, (trunc_index_min n m = n) + (trunc_index_min n m = m) m: trunc_index IHm: (trunc_index_min n.+1 m = n.+1) + (trunc_index_min n.+1 m = m) p: trunc_index_min n m = n
n: trunc_index IHn: forallm : trunc_index, (trunc_index_min n m = n) + (trunc_index_min n m = m) m: trunc_index IHm: (trunc_index_min n.+1 m = n.+1) + (trunc_index_min n.+1 m = m) p: trunc_index_min n m = m
n: trunc_index IHn: forallm : trunc_index, (trunc_index_min n m = n) + (trunc_index_min n m = m) m: trunc_index IHm: (trunc_index_min n.+1 m = n.+1) + (trunc_index_min n.+1 m = m) p: trunc_index_min n m = n
trunc_index_min n.+1 m.+1 = n.+1
n: trunc_index IHn: forallm : trunc_index, (trunc_index_min n m = n) + (trunc_index_min n m = m) m: trunc_index IHm: (trunc_index_min n.+1 m = n.+1) + (trunc_index_min n.+1 m = m) p: trunc_index_min n m = m
n: trunc_index IHn: forallm : trunc_index, (trunc_index_min n m = n) + (trunc_index_min n m = m) m: trunc_index IHm: (trunc_index_min n.+1 m = n.+1) + (trunc_index_min n.+1 m = m) p: trunc_index_min n m = n
trunc_index_min n.+1 m.+1 = n.+1
n: trunc_index IHn: forallm : trunc_index, (trunc_index_min n m = n) + (trunc_index_min n m = m) m: trunc_index IHm: (trunc_index_min n.+1 m = n.+1) + (trunc_index_min n.+1 m = m) p: trunc_index_min n m = m
trunc_index_min n.+1 m.+1 = m.+1
1,2: cbn; byapply ap.Defined.
n, m: trunc_index
trunc_index_min n m <= n
n, m: trunc_index
trunc_index_min n m <= n
forallnm : trunc_index, trunc_index_min n m <= n
forallm : trunc_index, trunc_index_min (-2) m <= -2
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m <= n
forallm : trunc_index, trunc_index_min n.+1 m <= n.+1
trunc_index_min (-2) (-2) <= -2
m: trunc_index IHm: trunc_index_min (-2) m <= -2
trunc_index_min (-2) m.+1 <= -2
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m <= n
trunc_index_min n.+1 (-2) <= n.+1
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m <= n m: trunc_index IHm: trunc_index_min n.+1 m <= n.+1
trunc_index_min n.+1 m.+1 <= n.+1
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m <= n m: trunc_index IHm: trunc_index_min n.+1 m <= n.+1
trunc_index_min n.+1 m.+1 <= n.+1
exact (IHn m).Defined.
n, m: trunc_index
trunc_index_min n m <= m
n, m: trunc_index
trunc_index_min n m <= m
forallnm : trunc_index, trunc_index_min n m <= m
forallm : trunc_index, trunc_index_min (-2) m <= m
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m <= m
forallm : trunc_index, trunc_index_min n.+1 m <= m
trunc_index_min (-2) (-2) <= -2
m: trunc_index IHm: trunc_index_min (-2) m <= m
trunc_index_min (-2) m.+1 <= m.+1
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m <= m
trunc_index_min n.+1 (-2) <= -2
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m <= m m: trunc_index IHm: trunc_index_min n.+1 m <= m
trunc_index_min n.+1 m.+1 <= m.+1
n: trunc_index IHn: forallm : trunc_index, trunc_index_min n m <= m m: trunc_index IHm: trunc_index_min n.+1 m <= m
trunc_index_min n.+1 m.+1 <= m.+1
exact (IHn m).Defined.(** ** Truncatedness proper. *)(** A contractible space is (-2)-truncated, by definition. This function is the identity, so there is never any need to actually use it, but it exists to be found in searches. *)Definitioncontr_istrunc_minus_two `{H : IsTrunc (-2) A} : Contr A
:= H.(** Truncation levels are cumulative. *)
n: trunc_index A: Type IsTrunc0: IsTrunc n A
forallxy : A, IsTrunc n (x = y)
n: trunc_index A: Type IsTrunc0: IsTrunc n A
forallxy : A, IsTrunc n (x = y)
n: trunc_index
forallA : Type,
IsTrunc n A -> forallxy : A, IsTrunc n (x = y)
A: Type H: Contr A x, y: A
Contr (x = y)
n: trunc_index IH: forallA : Type,
IsTrunc n A -> forallxy : A, IsTrunc n (x = y) A: Type H: IsTrunc n.+1 A x, y: A
IsTrunc n.+1 (x = y)
A: Type H: Contr A x, y: A
Contr (x = y)
apply contr_paths_contr.
n: trunc_index IH: forallA : Type,
IsTrunc n A -> forallxy : A, IsTrunc n (x = y) A: Type H: IsTrunc n.+1 A x, y: A
IsTrunc n.+1 (x = y)
n: trunc_index IH: forallA : Type,
IsTrunc n A -> forallxy : A, IsTrunc n (x = y) A: Type H: IsTrunc n.+1 A x, y: A
forallx0y0 : x = y, IsTrunc n (x0 = y0)
rapply IH.Defined.
n: trunc_index A: Type IsTrunc0: IsTrunc n A
IsTrunc n.+1 A
n: trunc_index A: Type IsTrunc0: IsTrunc n A
IsTrunc n.+1 A
n: trunc_index A: Type IsTrunc0: IsTrunc n A
forallxy : A, IsTrunc n (x = y)
exact istrunc_paths'.Defined.(** This could be an [Instance] (with very high priority, so it doesn't get applied trivially). However, we haven't given typeclass search any hints allowing it to solve goals like [m <= n], so it would only ever be used trivially. *)
m, n: trunc_index Hmn: m <= n A: Type IsTrunc0: IsTrunc m A
IsTrunc n A
m, n: trunc_index Hmn: m <= n A: Type IsTrunc0: IsTrunc m A
IsTrunc n A
n: trunc_index
forallm : trunc_index,
m <= n -> forallA : Type, IsTrunc m A -> IsTrunc n A
Hmn: -2 <= -2 A: Type IsTrunc0: Contr A
Contr A
m': trunc_index Hmn: m'.+1 <= -2 A: Type IsTrunc0: IsTrunc m'.+1 A
Contr A
n': trunc_index IH: forallm : trunc_index,
m <= n' ->
forallA : Type, IsTrunc m A -> IsTrunc n' A Hmn: -2 <= n'.+1 A: Type IsTrunc0: Contr A
IsTrunc n'.+1 A
n': trunc_index IH: forallm : trunc_index,
m <= n' ->
forallA : Type, IsTrunc m A -> IsTrunc n' A m': trunc_index Hmn: m'.+1 <= n'.+1 A: Type IsTrunc0: IsTrunc m'.+1 A
IsTrunc n'.+1 A
Hmn: -2 <= -2 A: Type IsTrunc0: Contr A
Contr A
assumption.
m': trunc_index Hmn: m'.+1 <= -2 A: Type IsTrunc0: IsTrunc m'.+1 A
Contr A
destruct Hmn.
n': trunc_index IH: forallm : trunc_index,
m <= n' ->
forallA : Type, IsTrunc m A -> IsTrunc n' A Hmn: -2 <= n'.+1 A: Type IsTrunc0: Contr A
IsTrunc n'.+1 A
apply @istrunc_succ, (IH (-2)); auto.
n': trunc_index IH: forallm : trunc_index,
m <= n' ->
forallA : Type, IsTrunc m A -> IsTrunc n' A m': trunc_index Hmn: m'.+1 <= n'.+1 A: Type IsTrunc0: IsTrunc m'.+1 A
IsTrunc n'.+1 A
n': trunc_index IH: forallm : trunc_index,
m <= n' ->
forallA : Type, IsTrunc m A -> IsTrunc n' A m': trunc_index Hmn: m'.+1 <= n'.+1 A: Type IsTrunc0: IsTrunc m'.+1 A
forallxy : A, IsTrunc n' (x = y)
intros x y; apply (IH m'); auto with typeclass_instances.Defined.(** In particular, a contractible type, hprop, or hset is truncated at all higher levels. We don't allow these to be used as idmaps, since there would be no point to it. *)Definitionistrunc_contr {n} {A} `{Contr A} : IsTrunc n.+1 A
:= (@istrunc_leq (-2) n.+1 tt _ _).Definitionistrunc_hprop {n} {A} `{IsHProp A} : IsTrunc n.+2 A
:= (@istrunc_leq (-1) n.+2 tt _ _).Definitionistrunc_hset {n} {A} `{IsHSet A}
: IsTrunc n.+3 A
:= (@istrunc_leq 0 n.+3 tt _ _).(** Consider the preceding definitions as instances for typeclass search, but only if the requisite hypothesis is already a known assumption; otherwise they result in long or interminable searches. *)#[export] Hint Immediate istrunc_contr : typeclass_instances.#[export] Hint Immediate istrunc_hprop : typeclass_instances.#[export] Hint Immediate istrunc_hset : typeclass_instances.(** Equivalence preserves truncation (this is, of course, trivial with univalence). This is not an [Instance] because it causes infinite loops. *)
A, B: Type f: A -> B n: trunc_index IsTrunc0: IsTrunc n A H: IsEquiv f
IsTrunc n B
A, B: Type f: A -> B n: trunc_index IsTrunc0: IsTrunc n A H: IsEquiv f
IsTrunc n B
n: trunc_index
forallA : Type,
IsTrunc n A ->
forall (B : Type) (f : A -> B),
IsEquiv f -> IsTrunc n B
A: Type IsTrunc0: Contr A B: Type f: A -> B H: IsEquiv f
Contr B
n: trunc_index IH: forallA : Type,
IsTrunc n A ->
forall (B : Type) (f : A -> B),
IsEquiv f -> IsTrunc n B A: Type IsTrunc0: IsTrunc n.+1 A B: Type f: A -> B H: IsEquiv f
IsTrunc n.+1 B
A: Type IsTrunc0: Contr A B: Type f: A -> B H: IsEquiv f
Contr B
exact (contr_equiv _ f).
n: trunc_index IH: forallA : Type,
IsTrunc n A ->
forall (B : Type) (f : A -> B),
IsEquiv f -> IsTrunc n B A: Type IsTrunc0: IsTrunc n.+1 A B: Type f: A -> B H: IsEquiv f
IsTrunc n.+1 B
n: trunc_index IH: forallA : Type,
IsTrunc n A ->
forall (B : Type) (f : A -> B),
IsEquiv f -> IsTrunc n B A: Type IsTrunc0: IsTrunc n.+1 A B: Type f: A -> B H: IsEquiv f
forallxy : B, IsTrunc n (x = y)
n: trunc_index IH: forallA : Type,
IsTrunc n A ->
forall (B : Type) (f : A -> B),
IsEquiv f -> IsTrunc n B A: Type IsTrunc0: IsTrunc n.+1 A B: Type f: A -> B H: IsEquiv f x, y: B
IsTrunc n (x = y)
exact (IH _ _ _ (ap (f^-1))^-1 _).Defined.Definitionistrunc_equiv_istruncA {B} (f : A <~> B) `{IsTrunc n A}
: IsTrunc n B
:= istrunc_isequiv_istrunc A f.(** ** Truncated morphisms *)ClassIsTruncMap (n : trunc_index) {XY : Type} (f : X -> Y)
:= istruncmap_fiber :: forally:Y, IsTrunc n (hfiber f y).NotationIsEmbedding := (IsTruncMap (-1)).(** ** Universes of truncated types *)(** It is convenient for some purposes to consider the universe of all n-truncated types (within a given universe of types). In particular, this allows us to state the important fact that each such universe is itself (n+1)-truncated. *)RecordTruncType (n : trunc_index) := {
trunctype_type : Type ;
trunctype_istrunc :: IsTrunc n trunctype_type
}.Arguments Build_TruncType _ _ {_}.Arguments trunctype_type {_} _.Arguments trunctype_istrunc [_] _.Coerciontrunctype_type : TruncType >-> Sortclass.Notation"n -Type" := (TruncType n) : type_scope.NotationHProp := (-1)-Type.NotationHSet := 0-Type.NotationBuild_HProp := (Build_TruncType (-1)).NotationBuild_HSet := (Build_TruncType 0).(** This is (as of October 2014) the only [Canonical Structure] in the library. It would be nice to do without it, in the interests of minimizing the number of fancy Coq features that the reader needs to know about. *)Canonical Structuredefault_TruncType := funnTP => (@Build_TruncType n T P).(** Version of [smalltype] for n-Types. *)
n: trunc_index P: n -Type smallP: IsSmall P
n -Type
n: trunc_index P: n -Type smallP: IsSmall P
n -Type
n: trunc_index P: n -Type smallP: IsSmall P
IsTrunc n (smalltype P)
apply (@istrunc_equiv_istrunc _ _ (equiv_smalltype P)^-1 n _).Defined.Notationsmallhprop := (smallntype (-1)).(** ** Facts about hprops *)(** An inhabited proposition is contractible. This is not an [Instance] because it causes infinite loops. *)
A: Type H: IsHProp A x: A
Contr A
A: Type H: IsHProp A x: A
Contr A
A: Type H: IsHProp A x: A
forally : A, x = y
A: Type H: IsHProp A x, y: A
x = y
rapply center.Defined.(** If inhabitation implies contractibility, then we have an h-proposition. We probably won't often have a hypothesis of the form [A -> Contr A], so we make sure we give priority to other instances. *)
A: Type
(A -> Contr A) -> IsHProp A
A: Type
(A -> Contr A) -> IsHProp A
A: Type H: A -> Contr A x, y: A
Contr (x = y)
A: Type H: A -> Contr A x, y: A C:= H x: Contr A
Contr (x = y)
apply contr_paths_contr.Defined.(** Any two points in an hprop are connected by a path. *)
A: Type H: IsHProp A
forallxy : A, x = y
A: Type H: IsHProp A
forallxy : A, x = y
A: Type H: IsHProp A x, y: A
x = y
rapply center.Defined.(** Conversely, this property characterizes hprops. *)
A: Type
(forallxy : A, x = y) -> IsHProp A
A: Type
(forallxy : A, x = y) -> IsHProp A
A: Type H: forallxy : A, x = y x, y: A
Contr (x = y)
A: Type H: forallxy : A, x = y x, y: A
Contr A
exact (Build_Contr _ x (H x)).Defined.(** Two propositions are equivalent as soon as there are maps in both directions. *)
A: Type IsHProp0: IsHProp A B: Type IsHProp1: IsHProp B f: A -> B g: B -> A
IsEquiv f
A: Type IsHProp0: IsHProp A B: Type IsHProp1: IsHProp B f: A -> B g: B -> A
IsEquiv f
apply (isequiv_adjointify f g);
intros ?; apply path_ishprop.Defined.
A: Type IsHProp0: IsHProp A B: Type IsHProp1: IsHProp B
A <-> B -> A <~> B
A: Type IsHProp0: IsHProp A B: Type IsHProp1: IsHProp B
A <-> B -> A <~> B
A: Type IsHProp0: IsHProp A B: Type IsHProp1: IsHProp B fg: A <-> B
A <~> B
apply (equiv_adjointify (fst fg) (snd fg));
intros ?; apply path_ishprop.Defined.Definitionequiv_iff_hprop `{IsHProp A} `{IsHProp B}
: (A -> B) -> (B -> A) -> (A <~> B)
:= funfg => equiv_iff_hprop_uncurried (f, g).
A: Type IsHProp0: IsHProp A
Contr A <-> A
A: Type IsHProp0: IsHProp A
Contr A <-> A
A: Type IsHProp0: IsHProp A
Contr A -> A
A: Type IsHProp0: IsHProp A
A -> Contr A
A: Type IsHProp0: IsHProp A
Contr A -> A
apply center.
A: Type IsHProp0: IsHProp A
A -> Contr A
rapply contr_inhabited_hprop.Defined.(** ** Truncatedness: any dependent product of n-types is an n-type *)
H: Funext A: Type P: A -> Type H0: foralla : A, Contr (P a)
Contr (foralla : A, P a)
H: Funext A: Type P: A -> Type H0: foralla : A, Contr (P a)
Contr (foralla : A, P a)
H: Funext A: Type P: A -> Type H0: foralla : A, Contr (P a)
forally : foralla : A, P a,
(funa : A => center (P a)) = y
H: Funext A: Type P: A -> Type H0: foralla : A, Contr (P a) f: foralla : A, P a
(funa : A => center (P a)) = f
H: Funext A: Type P: A -> Type H0: foralla : A, Contr (P a) f: foralla : A, P a
(funa : A => center (P a)) == f
H: Funext A: Type P: A -> Type H0: foralla : A, Contr (P a) f: foralla : A, P a a: A
center (P a) = f a
apply contr.Defined.
H: Funext A: Type P: A -> Type n: trunc_index H0: foralla : A, IsTrunc n (P a)
IsTrunc n (foralla : A, P a)
H: Funext A: Type P: A -> Type n: trunc_index H0: foralla : A, IsTrunc n (P a)
IsTrunc n (foralla : A, P a)
H: Funext A: Type n: trunc_index
forallP : A -> Type,
(foralla : A, IsTrunc n (P a)) ->
IsTrunc n (foralla : A, P a)
H: Funext A: Type P: A -> Type H0: foralla : A, Contr (P a)
Contr (foralla : A, P a)
H: Funext A: Type n: trunc_index IH: forallP : A -> Type,
(foralla : A, IsTrunc n (P a)) ->
IsTrunc n (foralla : A, P a) P: A -> Type H0: foralla : A, IsTrunc n.+1 (P a)
IsTrunc n.+1 (foralla : A, P a)
(* case [n = -2], i.e. contractibility *)
H: Funext A: Type P: A -> Type H0: foralla : A, Contr (P a)
Contr (foralla : A, P a)
exact contr_forall.(* case n = n'.+1 *)
H: Funext A: Type n: trunc_index IH: forallP : A -> Type,
(foralla : A, IsTrunc n (P a)) ->
IsTrunc n (foralla : A, P a) P: A -> Type H0: foralla : A, IsTrunc n.+1 (P a)
IsTrunc n.+1 (foralla : A, P a)
H: Funext A: Type n: trunc_index IH: forallP : A -> Type,
(foralla : A, IsTrunc n (P a)) ->
IsTrunc n (foralla : A, P a) P: A -> Type H0: foralla : A, IsTrunc n.+1 (P a)
forallxy : foralla : A, P a, IsTrunc n (x = y)
intros f g; exact (istrunc_isequiv_istrunc@{u1 u1} _ (apD10@{_ _ u1} ^-1)).Defined.(** Truncatedness is an hprop. *)
H: Funext n: trunc_index A: Type
IsHProp (IsTrunc n A)
H: Funext n: trunc_index A: Type
IsHProp (IsTrunc n A)
H: Funext A: Type
IsHProp (Contr A)
H: Funext n: trunc_index IH: forallA : Type, IsHProp (IsTrunc n A) A: Type
IsHProp (IsTrunc n.+1 A)
H: Funext A: Type
IsHProp (Contr A)
H: Funext A: Type
IsHProp (IsTrunc_unfolded (-2) A)
H: Funext A: Type
forallxy : IsTrunc_unfolded (-2) A, x = y
H: Funext A: Type a1: A c1: forally : A, a1 = y a2: A c2: forally : A, a2 = y
(a1; c1) = (a2; c2)
H: Funext A: Type a1: A c1, c2: forally : A, a1 = y
(a1; c1) = (a1; c2)
H: Funext A: Type a1: A c1, c2: forally : A, a1 = y
c1 = c2
H: Funext A: Type a1: A c1, c2: forally : A, a1 = y x: A
c1 x = c2 x
pose (Build_Contr _ a1 c1); apply path2_contr.
H: Funext n: trunc_index IH: forallA : Type, IsHProp (IsTrunc n A) A: Type
IsHProp (IsTrunc n.+1 A)
exact (istrunc_equiv_istrunc _ (equiv_istrunc_unfold n.+1 A)^-1%equiv).(* This case follows from [istrunc_forall]. *)Defined.(** By [trunc_hprop], it follows that [IsTrunc n A] is also [m]-truncated for any [m >= -1]. *)(** Similarly, a map being truncated is also a proposition. *)
H: Funext n: trunc_index X, Y: Type f: X -> Y
IsHProp (IsTruncMap n f)
H: Funext n: trunc_index X, Y: Type f: X -> Y
IsHProp (IsTruncMap n f)
H: Funext n: trunc_index X, Y: Type f: X -> Y s, t: IsTruncMap n f
s = t
H: Funext n: trunc_index X, Y: Type f: X -> Y s, t: IsTruncMap n f x: Y
s x = t x
apply path_ishprop.Defined.(** If a type [A] is [n]-truncated, then [IsTrunc n A] is contractible. *)Instancecontr_istrunc `{Funext} (n : trunc_index) (A : Type) `{istruncA : IsTrunc n A}
: Contr (IsTrunc n A) | 100
:= contr_inhabited_hprop _ _.
A: Type H: Funext IsHProp0: IsHProp A
Contr A <~> A
A: Type H: Funext IsHProp0: IsHProp A
Contr A <~> A
exact (equiv_iff_hprop_uncurried (iff_contr_hprop A)).Defined.(** If a type [A] implies that it is [n.+1]-truncated, then it is [n.+1]-truncated. **)Definitionistrunc_inhabited_istrunc {n : trunc_index}
{A : Type} (H : A -> IsTrunc n.+1 A)
: IsTrunc n.+1 A
:= istrunc_S _ (funab => H a a b).(** If you are looking for a theorem about truncation, you may want to read the note "Finding Theorems" in "STYLE.md". *)