Skip to content

Instantly share code, notes, and snippets.

@Trebor-Huang
Last active October 10, 2023 16:03
Show Gist options
  • Save Trebor-Huang/bfd533defbc1fdb328a9cde22fe1440c to your computer and use it in GitHub Desktop.
Save Trebor-Huang/bfd533defbc1fdb328a9cde22fe1440c to your computer and use it in GitHub Desktop.
Quotient types in MLTT imply excluded middle
open import Agda.Builtin.Equality
-- Some familiar results about equality
UIP : {A : Set} (x y : A) (p q : x ≡ y) → p ≡ q
UIP x y refl refl = refl
coerce : {A : Set} (B : A → Set)
→ {x y : A} → x ≡ y
→ B x → B y
coerce B refl b = b
infixl 5 _∙_
_∙_ : {A : Set} {a b c : A}
→ a ≡ b → b ≡ c → a ≡ c
refl ∙ refl = refl
sym : {A : Set} {a b : A}
→ a ≡ b → b ≡ a
sym refl = refl
ap : {A B : Set} (f : A → B) {x y : A}
→ x ≡ y → f x ≡ f y
ap f refl = refl
-- Postulate a quotient type
record EquivRel (A : Set) : Set₁ where
field
_~_ : A → A → Set
Refl : ∀ {a} → a ~ a
Sym : ∀ {a b} → a ~ b → b ~ a
Trans : ∀ {a b c} → a ~ b → b ~ c → a ~ c
postulate
_/_ : (A : Set) → EquivRel A → Set
module Quotient {A} (R : EquivRel A) where
open EquivRel R
postulate
[_] : A → A / R
path : {x y : A} → x ~ y → [ x ] ≡ [ y ]
sound : {x y : A} → [ x ] ≡ [ y ] → x ~ y
elim : {M : A / R → Set} -- Dependent elimination for quotients
→ (f : (a : A) → M [ a ])
→ (∀ x y → (p : x ~ y) → coerce M (path p) (f x) ≡ f y)
→ (x : A / R) → M x
-- We prove the excluded middle
data Bool : Set where true false : Bool
record True : Set where
data False : Set where
true≠false : true ≡ false → False
true≠false ()
record Σ (A : Set) (B : A → Set) : Set where
constructor _,_
field
fst : A
snd : B fst
open Σ
infixl 1 _,_
module Truncate (P : Set) where
R : EquivRel Bool
R = record {
_~_ = λ { true true → True
; true false → P
; false true → P
; false false → True } ;
Refl = λ { {true} → _
; {false} → _ } ;
Sym = λ { {true} {true} → _
; {true} {false} → λ z → z
; {false} {true} → λ z → z
; {false} {false} → _ } ;
Trans = λ { {true} {true} {true} → _
; {true} {true} {false} → λ _ z → z
; {true} {false} {true} → _
; {true} {false} {false} → λ z _ → z
; {false} {true} {true} → λ z _ → z
; {false} {true} {false} → _
; {false} {false} {true} → λ _ z → z
; {false} {false} {false} → _ } }
open EquivRel R
open Quotient R
|P| : Set
|P| = [ true ] ≡ [ false ]
P→|P| : P → |P|
P→|P| = path
|P|→P : |P| → P
|P|→P = sound
isProp|P| : (x y : |P|) → x ≡ y
isProp|P| = UIP _ _
module LEM (P : Set) where
data Decidable : Set where -- Datatype recording whether P is true
yes : P → Decidable
no : (P → False) → Decidable
open Truncate P using (R)
open Quotient R
open Truncate hiding (R) renaming (|P| to Trunc)
surj : (x : Bool / R) → Trunc (Σ Bool λ b → x ≡ [ b ])
surj = elim
(λ { true → P→|P| _ (true , refl)
; false → P→|P| _ (false , refl) })
λ _ _ _ → isProp|P| _ _ _
section : (x : Bool / R) → Σ Bool λ b → x ≡ [ b ]
section x = |P|→P _ (surj x)
decide : Decidable
decide with section [ true ] in T | section [ false ] in F
... | false , p | y = yes (sound p)
... | true , _ | true , p = yes (sound p)
... | true , _ | false , _ = no λ p →
true≠false (sym (ap fst T) ∙ ap (λ b → section b .fst) (path p) ∙ ap fst F)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment