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.
(** * Propositional truncation implies function extensionality *)
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Metatheory.Core Metatheory.FunextVarieties Metatheory.ImpredicativeTruncation.(** Assuming that we have a propositional truncation operation with a definitional computation rule, we can prove function extensionality. Since we can't assume we have a definitional computation rule, we work with the propositional truncation defined as a HIT, which does have a definitional computation rule. *)(** We can construct an interval type as [Trunc -1 Bool]. *)Local Definitioninterval := Trunc (-1) Bool.
P: Type a, b: P p: a = b
interval -> P
P: Type a, b: P p: a = b
interval -> P
(* We define this map by factoring it through the type [{ x : P & x = b}], which is a proposition since it is contractible. *)
P: Type a, b: P p: a = b
interval -> {x : P & x = b}
P: Type a, b: P p: a = b
Bool -> {x : P & x = b}
P: Type a, b: P p: a = b
{x : P & x = b}
P: Type a, b: P p: a = b
{x : P & x = b}
P: Type a, b: P p: a = b
{x : P & x = b}
exact (a; p).
P: Type a, b: P p: a = b
{x : P & x = b}
exact (b; idpath).Defined.Local Definitionseg : tr true = tr false :> interval
:= path_ishprop _ _.(** From an interval type, and thus from truncations, we can prove function extensionality. See IntervalImpliesFunext.v for an approach that works with an interval defined as a HIT. *)Definitionfunext_type_from_trunc : Funext_type
:= WeakFunext_implies_Funext (NaiveFunext_implies_WeakFunext
(funAPfgp =>
leth := fun (x:interval) (a:A) =>
interval_rec _ (f a) (g a) (p a) x
in ap h seg)).(** ** Function extensionality implies an interval type *)(** Assuming [Funext] (and not propositional resizing), the construction [Trm] in ImpredicativeTruncation.v applied to [Bool] gives an interval type with definitional computation on the end points. So we see that function extensionality is equivalent to the existence of an interval type. *)SectionAssumeFunext.Context `{Funext}.Definitionfinterval := Trm Bool.
H: Funext P: Type a, b: P p: a = b
finterval -> P
H: Funext P: Type a, b: P p: a = b
finterval -> P
H: Funext P: Type a, b: P p: a = b
finterval -> {x : P & x = b}
H: Funext P: Type a, b: P p: a = b
Bool -> {x : P & x = b}
H: Funext P: Type a, b: P p: a = b
{x : P & x = b}
H: Funext P: Type a, b: P p: a = b
{x : P & x = b}
H: Funext P: Type a, b: P p: a = b
{x : P & x = b}
exact (a; p).
H: Funext P: Type a, b: P p: a = b
{x : P & x = b}
exact (b; idpath).Defined.(** As an example, we check that it computes on [true]. *)Definitionfinterval_rec_beta (P : Type) (ab : P) (p : a = b)
: finterval_rec P a b p (trm true) = a
:= idpath.Definitionfseg : trm true = trm false :> finterval
:= path_ishprop _ _.(** To verify that our interval type is good enough, we use it to prove function extensionality. *)Definitionfunext_type_from_finterval : Funext_type
:= WeakFunext_implies_Funext (NaiveFunext_implies_WeakFunext
(funAPfgp =>
leth := fun (x:finterval) (a:A) =>
finterval_rec _ (f a) (g a) (p a) x
in ap h fseg)).EndAssumeFunext.