universe quantification in agda - agda

I could spot the problem and added universe quantification.
But if anyone can spell what is really going on, that would be interesting.
module Level0Equality (A : Set) where
data _Tauto'_ : A → A → Set where
refl2 : (a : A) → a Tauto' a
-- universe quantified
data _Tauto_ {l} {A : Set l} : A → A → Set l where
refl2 : (a : A) → a Tauto a
-- PEq x = the type of proof that y ≡ x
data PEq {A : Set} ( x : A ) : Set where
it : (y : A ) -> (y Tauto x ) -> PEq x
-- does not work because of lack of universe quantification in Tauto'
-- A !=< A of type Set
-- (because one has deBruijn index 2 and the other 3)
-- when checking that the expression y has type A
data PEq' {A : Set} ( x : A ) : Set where
it : (y : A ) -> (y Tauto' x ) -> PEq' x

The problem is that your definition of PEq' tells us that it works for any A from Set. However, _Tauto'_ only works for the one particular A that the user provides as the module parameter to Level0Equality.
Let me demonstrate it with an example:
open Level0Equality Bool
_Tauto'_ : Bool → Bool → Set
PEq' : {A : Set} → A → Set
Say we choose A = String, then we have:
PEq' {A = String} : String → Set
This will obviously cause problems in the PEq'.it constructor. The type of both x and y is now String, but the equality _Tauto'_ only works for Bools!
The fix is rather simple: use the A from the module telescope.
data PEq' ( x : A ) : Set where
it : (y : A ) -> (y Tauto' x ) -> PEq' x

Related

Agda Error message : Cannot eliminate type with variable pattern

I was asked to finish one of the recommended question from plfa:
Exercise ⇔≃× (recommended)
Show that A ⇔ B as defined earlier is isomorphic to (A → B) × (B → A).
I know I need to prove some property of equivalence first, and here is my proof:
record _⇔_ (A B : Set) : Set where
field
to : A → B
from : B → A
⇔-refl : ∀ {A : Set} → A ⇔ A
⇔-refl =
record
{ to = λ{x → x}
; from = λ{y → y}
}
⇔-sym : ∀ {A B : Set}
→ A ⇔ B
→ B ⇔ A
⇔-sym A⇔B =
record
{ to = _⇔_.from A⇔B
; from = _⇔_.to A⇔B
}
⇔-trans : ∀ {A B C : Set}
→ A ⇔ B
→ B ⇔ C
→ A ⇔ C
⇔-trans A⇔B B⇔C =
record
{ to = (_⇔_.to B⇔C) ∘ (_⇔_.to A⇔B )
; from = (_⇔_.from A⇔B) ∘ (_⇔_.from B⇔C )
}
And now, from my understanding, I need to prove
⇔≃× : ∀ {A B : Set} → A ⇔ B ≃ (A → B) × (B → A)
So to prove this, we need to prove four sections: "to" "from" "from∘to" "to∘from"
⇔≃× : ∀ {A B : Set} → (A ⇔ B) ≃ ((A → B) × (B → A))
⇔≃× =
record
{ to = λ{ x ⇔ y → ⟨ ( x → y ) , ( y → x ) ⟩ }
; from = ?
; from∘to = ?
; to∘from = ?
}
But when I finish the "to" section, I want to see if it can pass. So I compile and I got this error message:
Cannot eliminate type (A → B) × (B → A) with variable pattern ⇔(did you supply too many arguments?)when checking the clause left hand side.extendedlambda2 x ⇔ y
Can anyone give some explanation on this type of error message?
Thanks in advance
λ{ x ⇔ y → binds three arguments: x, ⇔, and y but the function you're supposed to define only takes one.

About the image of the succ function

I defined the natural numbers as usually:
data Nat : Set where
zero : Nat
succ : Nat → Nat
and i.e the number one should be
one : Nat
one = succ zero
Later on, we can define the image datatype,
data Image_∋_ {A B : Set} (f : A → B) : B -> Set where
im : (x : A) → Image f ∋ (f x)
And to prove something like "the one is in the Image of the successor function" I wrote:
one-succ : Image succ ∋ one
one-succ = im zero
I would like to have the following.
Define the predecessor function that not allowed zero as an input just its successors. So the next is not valid.
pred : Nat → Nat
pred zero = zero
pred (succ n) = n
I would like to have a variable called Z⁺ representing the positive numbers but using in its definition the image of successor function (Image_∋_ data type defined above).
Image f ∋ y reads as "there is some x such that y ≡ f x". Pattern matching on Image f ∋ y by im x reveals the x.
So an element of type Image succ ∋ n is a proof that n is of the form succ m where m is carried inside that element. Hence the definition is simply
ipred : ∀ {n} → Image succ ∋ n → Nat
ipred (im m) = m
because n ≡ succ m and the predecessor of succ m is m.
It reads nicer if we rename im to isucc:
open Image_∋_ renaming (im to isucc)
ipred : ∀ {n} → Image succ ∋ n → Nat
ipred (isucc m) = m
Another way of writing the same thing is
data Image_∋_ {A B : Set} : (A → B) → B → Set where
_·_ : (f : A → B) → (x : A) → Image f ∋ f x
pred : ∀ {n} → Image succ ∋ n → Nat
pred (.succ · m) = m
Here f in Image f ∋ y is an index rather than a parameter, so _·_ (previously im) now receives two arguments: a function and its argument. It's not possible to pattern match on functions, but .succ is an "irrefutable pattern", i.e. it says "f can be nothing, but succ".
Nat⁺ can be defined as
data Nat⁺ : Set where
nat⁺ : ∀ {n} → Image succ ∋ n → Nat⁺
succ⁺ receives a natural number (implicitly) and a proof that this number is of the form succ m for some m.
You can always take the predecessor of a positive natural number:
pred⁺ : Nat⁺ → Nat
pred⁺ (nat⁺ (im m)) = m
But since Nat⁺ is a non-indexed one-constructor data type, it can be defined as a record:
record Nat⁺ : Set where
constructor nat⁺
field
{pred⁺} : Nat
image : Image succ ∋ pred⁺
open Nat⁺
open Nat⁺ introduces pred⁺ : Nat⁺ → Nat in scope.

Modeling System F's parametric polymorphism at Set₀

In System F, the kind of a polymorphic type is * (as that's the only kind in System F anyway...), so e.g. for the following closed type:
[] ⊢ (forall α : *. α → α) : *
I would like to represent System F in Agda, and because everything is in *, I thought I'd interpret types (like the above) as Agda Sets; so something like
evalTy : RepresentationOfAWellKindedClosedType → Set
However, Agda doesn't have polymorphic types, so the above type, in Agda, would need to be a (large!) Π type:
idType = (α : Set) → α → α
which means it is not in Set₀:
idType : Set
idType = (α : Set) → α → α
poly-level.agda:4,12-29
Set₁ != Set
when checking that the expression (α : Set) → α → α has type Set
Is there a way out of this, or is System F not embeddable in this sense into Agda?
Instead of
evalTy : Type → Set
you can write
evalTy : (σ : Type) -> Set (levelOf σ)
(András Kovács, care to add an answer with references to your embedding of predicative System F?)
This is enough for embedding, but I've seen a lot of Setω errors and they have traumatised me, so now I'm trying to avoid dependent universes as much as possible.
You can embed polymorphic types into Set₁ and monomorphic types into Set, so you can embed any type into Set₁ using the ugly lifting mechanism. I tried this several times and it always was awful.
The thing I would try is to define evalTy as
evalTy : Type -> Set ⊎ Set₁
and then eliminate it at the type level like this:
data [_,_]ᵀ {α β γ δ} {A : Set α} {B : Set β} (C : A -> Set γ) (D : B -> Set δ)
: A ⊎ B -> Set (γ ⊔ δ) where
inj¹ : ∀ {x} -> C x -> [ C , D ]ᵀ (inj₁ x)
inj² : ∀ {y} -> D y -> [ C , D ]ᵀ (inj₂ y)
You can run this elimination:
Runᴸ : ∀ {α β γ δ} {A : Set α} {B : Set β} {C : A -> Set γ} {D : B -> Set δ} {s}
-> [ C , D ]ᵀ s -> Level
Runᴸ {γ = γ} (inj¹ _) = γ
Runᴸ {δ = δ} (inj² _) = δ
Runᵀ : ∀ {α β γ δ} {A : Set α} {B : Set β} {C : A -> Set γ} {D : B -> Set δ} {s}
-> (sᵀ : [ C , D ]ᵀ s) -> Set (Runᴸ sᵀ)
Runᵀ {C = C} (inj¹ {x} _) = C x
Runᵀ {D = D} (inj² {y} _) = D y
runᵀ : ∀ {α β γ δ} {A : Set α} {B : Set β} {C : A -> Set γ} {D : B -> Set δ} {s}
-> (sᵀ : [ C , D ]ᵀ s) -> Runᵀ sᵀ
runᵀ (inj¹ z) = z
runᵀ (inj² w) = w
Thus you introduce a universe dependency only at the end, when you actually need to compute something.
E.g.
SomeSet : ℕ -> Set ⊎ Set₁
SomeSet 0 = inj₁ ℕ
SomeSet n = inj₂ Set
ofSomeSet : ∀ n -> [ (λ A -> A × A) , id ]ᵀ (SomeSet n)
ofSomeSet zero = inj¹ (0 , 5)
ofSomeSet (suc n) = inj² ℕ
-- 0 , 5
test₁ : ℕ × ℕ
test₁ = runᵀ (ofSomeSet 0)
-- ℕ
test₂ : Set
test₂ = runᵀ (ofSomeSet 1)
ofSomeSet is a dependent function, but not a "universally dependent", you can write e.g. f = ofSomeSet ∘ suc and it's a perfectly typeable expression. This doesn't work with universes dependencies:
fun : ∀ α -> Set (Level.suc α)
fun α = Set α
oops = fun ∘ Level.suc
-- ((α : Level) → Set (Level.suc α)) !=< ((y : _B_160 .x) → _C_161 y)
-- because this would result in an invalid use of Setω
You can also enhance [_,_]ᵀ to make it mappable like I did here, but this all is probably overkill and you should just use
evalTy : (σ : Type) -> Set (levelOf σ)
Note that I'm talking only about the predicative fragment of System F. Full System F is not embeddable as Dominique Devriese explains in his comments to the question.
However I feel like we can embed more than the predicative fragment, if we first normalize a System F term. E.g. id [∀ α : *. α → α] id is not directly embeddable, but after normalization it becomes just id, which is embeddable.
However it should be possible to embed id [∀ α : *. α → α] id even without normalization by transforming it into Λ α. id [α → α] (id [α]), which is what Agda does with implicit arguments (right?). So it's not clear to me what exactly we can't embed.

How to make Agda pretty-print products nicely

Consider the following self-contained program:
module Test where
record Σ {A : Set} (B : A -> Set) : Set where
constructor _,_
field
fst : A
snd : B fst
open Σ public
infixr 0 _,_
_×_ : Set -> Set -> Set
A × B = Σ (\ (_ : A) -> B)
infixr 10 _×_
f : {A B : Set} → A × B → A
f x = {!!}
If you C-c C-l in the goal, you get:
Goal: .A
————————————————————————————————————————————————————————————
x : Σ (λ _ → .B)
.B : Set
.A : Set
i.e. you see the underlying sigma, and the type of the binder of the lambda is hidden. This is pretty annoying. Is there a way to make Agda show the type of binders that don't bind names by default?
This is Agda 2.3.2.2.
Agda 2.4.3 displays x : .A × .B.
You can use the abstract keyword:
abstract
_×_ : Set -> Set -> Set
A × B = Σ (\ (_ : A) -> B)
fst' : ∀ {A B} -> A × B -> A
fst' (x , y) = x
snd' : ∀ {A B} -> A × B -> B
snd' (x , y) = y
But that's definitely overkill (and it looks like pattern synonyms do not work in abstract blocks).
It's much more annoying to me, that Agda doesn't want to reduce functions like flip and especially _∘_, but unfolds some functions with really long definitions. Agda needs a mechanism for fixing these problems.
It appears that this problem has been fixed in the latest version of Agda, so you should upgrade.

How to define a singleton set?

Assume I have a value x : A and I want to define a set containing only x.
This is what I tried:
open import Data.Product
open import Relation.Binary.PropositionalEquality
-- Singleton x is the set that only contains x. Its values are tuples containing
-- a value of type A and a proof that this value is equal to x.
Singleton : ∀ {ℓ} {A : Set ℓ} → (x : A) → Set ℓ
Singleton {A = A} x = Σ[ y ∈ A ] (y ≡ x)
-- injection
singleton : ∀ {ℓ} {A : Set ℓ} → (x : A) → Singleton x
singleton x = x , refl
-- projection
fromSingleton : ∀ {ℓ} {A : Set ℓ} {x : A} → Singleton x → A
fromSingleton s = proj₁ s
Is there a better way to do it?
An example for why I want this: If you have a monoid over some set A, then you can form a category with A as the only object. To express that in Agda you need a way to write "the set containing only A".
I think this is a very good way to do it. Usually, when you want to create a "subset" of a type, it looks like:
postulate
A : Set
P : A → Set
record Subset : Set where
field
value : A
prop : P value
However, this might not be a subset in the sense that it can actually contain more elements than the original type. That is because prop might have more propositionally different values. For example:
open import Data.Nat
data ℕ-prop : ℕ → Set where
c1 : ∀ n → ℕ-prop n
c2 : ∀ n → ℕ-prop n
record ℕ-Subset : Set where
field
value : ℕ
prop : ℕ-prop value
And suddenly, the subset has twice as many elements as the original type. This example is a bit contrived, I agree, but imagine you had a subset relation on sets (sets from set theory). Something like this is actually fairly possible:
sub₁ : {1, 2} ⊆ {1, 2, 3, 4}
sub₁ = drop 3 (drop 4 same)
sub₂ : {1, 2} ⊆ {1, 2, 3, 4}
sub₂ = drop 4 (drop 3 same)
The usual approach to this problem is to use irrelevant arguments:
record Subset : Set where
field
value : A
.prop : P value
This means that two values of type Subset are equal if they have the same value, the prop field is irrelevant to the equality. And indeed:
record Subset : Set where
constructor sub
field
value : A
.prop : P value
prop-irr : ∀ {a b} {p : P a} {q : P b} →
a ≡ b → sub a p ≡ sub b q
prop-irr refl = refl
However, this is more of a guideline, because your representation doesn't suffer from this problem. This is because the implementation of pattern matching in Agda implies axiom K:
K : ∀ {a p} {A : Set a} (x : A) (P : x ≡ x → Set p) (h : x ≡ x) →
P refl → P h
K x P refl p = p
Well, this doesn't tell you much. Luckily, there's another property that is equivalent to axiom K:
uip : ∀ {a} {A : Set a} {x y : A} (p q : x ≡ y) → p ≡ q
uip refl refl = refl
This tells us that there's only one way in which two elements can be equal, namely refl (uip means uniqueness of identity proofs).
This means that when you use propositional equality to make a subset, you're getting a true subset.
Let's make this explicit:
isSingleton : ∀ {ℓ} → Set ℓ → Set _
isSingleton A = Σ[ x ∈ A ] (∀ y → x ≡ y)
isSingleton A expresses the fact that A contains only one element, up to propositonal equality. And indeed, Singleton x is a singleton:
Singleton-isSingleton : ∀ {ℓ} {A : Set ℓ} (x : A) →
isSingleton (Singleton x)
Singleton-isSingleton x = (x , refl) , λ {(.x , refl) → refl}
Interestingly, this also works without axiom K. If you put {-# OPTIONS --without-K #-} pragma at the top of your file, it will still compile.
You can define a record without projections:
record Singleton {α} {A : Set α} (x : A) : Set α where
fromSingleton : ∀ {α} {A : Set α} {x : A} -> Singleton x -> A
fromSingleton {x = x} _ = x
singleton : ∀ {α} {A : Set α} -> (x : A) -> Singleton x
singleton _ = _
Or equalently
record Singleton {α} {A : Set α} (x : A) : Set α where
fromSingleton = x
open Singleton public
singleton : ∀ {α} {A : Set α} -> (x : A) -> Singleton x
singleton _ = _
Now you can use it like this:
open import Relation.Binary.PropositionalEquality
open import Data.Nat
f : Singleton 5 -> ℕ
f x = fromSingleton x
test : f (singleton 5) ≡ 5
test = refl
test' : f _ ≡ 5
test' = refl
And this is rejected:
fail : f (singleton 4) ≡ 4
fail = ?
The error:
4 != 5 of type ℕ
when checking that the expression singleton 4 has type Singleton 5
It can be defined as an indexed datatype:
data Singleton {ℓ : _} {A : Set ℓ} : A -> Set where
singleton : (a : A) -> Singleton a
This is analogous to how propositional equality a ≡ b is indexed by two particular elements a and b, or how Vector X n is indexed by a particular n ∈ ℕ.

Resources