added universe polymorphism to Equality

This commit is contained in:
wadler 2018-03-27 16:03:24 -03:00
parent 858e191639
commit f7ec2acef5
3 changed files with 75 additions and 10 deletions

View file

@ -63,7 +63,7 @@ It is instructive to develop `sym` interactively. To start, we supply
a variable for the argument on the left, and a hole for the body on
the right:
sym : ∀ {} {A : Set } {x y : A} → x ≡ y → y ≡ x
sym : ∀ {A : Set} {x y : A} → x ≡ y → y ≡ x
sym e = {! !}
If we go into the hole and type `C-C C-,` then Agda reports:
@ -73,14 +73,13 @@ If we go into the hole and type `C-C C-,` then Agda reports:
e : .x ≡ .y
.y : .A
.x : .A
.A : Set .
. : .Agda.Primitive.Level
.A : Set
If in the hole we type `C-C C-C e` then Agda will instantiate `e` to
all possible constructors, with one equation for each. There is only
one possible constructor:
sym : ∀ {} {A : Set } {x y : A} → x ≡ y → y ≡ x
sym : ∀ {A : Set} {x y : A} → x ≡ y → y ≡ x
sym refl = {! !}
If we go into the hole again and type `C-C C-,` then Agda now reports:
@ -88,8 +87,7 @@ If we go into the hole again and type `C-C C-,` then Agda now reports:
Goal: .x ≡ .x
————————————————————————————————————————————————————————————
.x : .A
.A : Set .
. : .Agda.Primitive.Level
.A : Set
This is the key step---Agda has worked out that `x` and `y` must be
the same to match the pattern `refl`!
@ -98,7 +96,7 @@ Finally, if we go back into the hole and type `C-C C-R` it will
instantiate the hole with the one constructor that yields a value of
the expected type.
sym : ∀ {} {A : Set } {x y : A} → x ≡ y → y ≡ x
sym : ∀ {A : Set} {x y : A} → x ≡ y → y ≡ x
sym refl = refl
This completes the definition as given above.
@ -112,7 +110,7 @@ Again, a useful exercise is to carry out an interactive development, checking
how Agda's knowledge changes as each of the two arguments is
instantiated.
## Congruence and Substitution
## Congruence and substitution
Equality satisfies *congruence*. If two terms are equal,
they remain so after the same function is applied to both.
@ -549,6 +547,62 @@ Jesper Cockx, Dominique Devries, Andreas Nuyts, and Philip Wadler,
draft paper, 2017.)
## Universe polymorphism {#unipoly}
As we have seen, not every type belongs to `Set`, but instead every
type belongs somewhere in the hierarchy `Set₀`, `Set₁`, `Set₂`, and so on,
where `Set` abbreviates `Set₀`, and `Set₀ : Set₁`, `Set₁ : Set₂`, and so on.
The definition of equality given above is fine if we want to compare two
values of a type that belongs to `Set`, but what if we want to compare
two values of a type that belongs to `Set ` for some arbitrary level ``?
The answer is *universe polymorphism*, where a definition is made
with respect to an arbitrary level ``. To make use of levels, we
first import the following.
\begin{code}
open import Level using (Level; suc; zero; _⊔_)
\end{code}
Levels are isomorphic to natural numbers, and have the same constructors:
zero : Level
suc : Level → Level
The names `Set₀`, `Set₁`, `Set₂` and so on are abbreviations for
Set zero
Set (suc zero)
Set (suc (suc zero))
and so on. There is also an operator
_⊔_ : Level → Level → Level
that given two levels returns the larger of the two.
Here is the definition of equality, generalised to an arbitrary level.
\begin{code}
data _≡_ { : Level} {A : Set } : A → A → Set where
refl : ∀ {x : A} → x ≡′ x
\end{code}
Similarly, here is the generalised definition of symmetry.
\begin{code}
sym : ∀ { : Level} {A : Set } {x y : A} → x ≡′ y → y ≡′ x
sym refl = refl
\end{code}
For simplicity, we avoid universe polymorphism in the definitions given in
the text, but most definitions in the standard library, including those for
equality, are generalised to arbitrary levels as above.
Here is the generalised definition of Leibniz equality.
\begin{code}
_≐_ : ∀ { : Level} {A : Set } (x y : A) → Set (suc )
_≐_ {A} x y = ∀ (P : A → Set ) → P x → P y
\end{code}
Before the signature used `Set₁` as the type of a term that includes
`Set`, whereas here the signature uses `Set (suc )` as the type of a
term that includes `Set `.
## Standard library
Definitions similar to those in this chapter can be found in the standard library.

View file

@ -299,6 +299,7 @@ module ≲-Reasoning where
≲-begin_ : ∀ {A B : Set} → A ≲ B → A ≲ B
≲-begin A≲B = A≲B
_≲⟨_⟩_ : ∀ (A : Set) {B C : Set} → A ≲ B → B ≲ C → A ≲ C
A ≲⟨ A≲B ⟩ B≲C = ≲-trans A≲B B≲C

View file

@ -21,6 +21,7 @@ open import Relation.Nullary using (¬_)
open import Data.Product using (_×_) renaming (_,_ to ⟨_,_⟩)
open import Isomorphism using (_≃_)
open import Function using (_∘_)
open import Level using (Level)
\end{code}
We assume [extensionality][extensionality].
@ -850,15 +851,24 @@ replacement for `_×_`. As a consequence, demonstrate an isomorphism relating
### Exercise (`¬Any≃All¬`)
We first generalise composition to arbitrary levels, using
[universe polymorphism][unipoly].
\begin{code}
_∘_ : ∀ {ℓ₁ ℓ₂ ℓ₃ : Level} {A : Set ℓ₁} {B : Set ℓ₂} {C : Set ℓ₃} → (B → C) → (A → B) → A → C
(g ∘′ f) x = g (f x)
\end{code}
[unipoly]: Equality/index.html#unipoly
Show that `Any` and `All` satisfy a version of De Morgan's Law.
\begin{code}
postulate
¬Any≃All¬ : ∀ {A : Set} (P : A → Set) (xs : List A) → (¬_ ∘ Any P) xs ≃ All (¬_ ∘ P) xs
¬Any≃All¬ : ∀ {A : Set} (P : A → Set) (xs : List A) → (¬_ ∘ Any P) xs ≃ All (¬_ ∘ P) xs
\end{code}
Do we also have the following?
(¬_ ∘ All P) xs ≃ Any (¬_ ∘ P) xs
(¬_ ∘ All P) xs ≃ Any (¬_ ∘ P) xs
If so, prove; if not, explain why.