Week 02 - Agda Exercises
Please read before starting the exercises
The exercises are designed to increase in difficulty so that we can cater to our large and diverse audience. This also means that it is perfectly fine if you don’t manage to do all exercises: some of them are definitely a bit hard for beginners and there are likely too many exercises! You may wish to come back to them later when you have learned more.
Having said that, here we go!
This is a markdown file with Agda code, which means that it displays nicely on GitHub, but at the same time you can load this file in Agda and fill the holes to solve exercises.
Please make a copy of this file to work in, so that it
doesn’t get overwritten (in case we update the exercises through
git
)!
{-# OPTIONS --without-K --allow-unsolved-metas #-} module 02-Exercises where open import prelude open import decidability open import sums
Part I: Propositions as types
Exercise 1 (★)
Proveuncurry : {A B X : Type} → (A → B → X) → (A × B → X) uncurry = {!!} curry : {A B X : Type} → (A × B → X) → (A → B → X) curry = {!!}
You might know these functions from programming e.g. in Haskell. But what do they say under the propositions-as-types interpretation?
Exercise 2 (★)
Consider the following goals:[i] : {A B C : Type} → (A × B) ∔ C → (A ∔ C) × (B ∔ C) [i] = {!!} [ii] : {A B C : Type} → (A ∔ B) × C → (A × C) ∔ (B × C) [ii] = {!!} [iii] : {A B : Type} → ¬ (A ∔ B) → ¬ A × ¬ B [iii] = {!!} [iv] : {A B : Type} → ¬ (A × B) → ¬ A ∔ ¬ B [iv] = {!!} [v] : {A B : Type} → (A → B) → ¬ B → ¬ A [v] = {!!} [vi] : {A B : Type} → (¬ A → ¬ B) → B → A [vi] = {!!} [vii] : {A B : Type} → ((A → B) → A) → A [vii] = {!!} [viii] : {A : Type} {B : A → Type} → ¬ (Σ a ꞉ A , B a) → (a : A) → ¬ B a [viii] = {!!} [ix] : {A : Type} {B : A → Type} → ¬ ((a : A) → B a) → (Σ a ꞉ A , ¬ B a) [ix] = {!!} [x] : {A B : Type} {C : A → B → Type} → ((a : A) → (Σ b ꞉ B , C a b)) → Σ f ꞉ (A → B) , ((a : A) → C a (f a)) [x] = {!!}
For each goal determine whether it is provable or not. If it is, fill it. If not, explain why it shouldn’t be possible. Propositions-as-types might help.
Exercise 3 (★★)
¬¬_ : Type → Type ¬¬ A = ¬ (¬ A) ¬¬¬ : Type → Type ¬¬¬ A = ¬ (¬¬ A)In the lecture we have discussed that we can’t prove
∀ {A : Type} → ¬¬ A → A
. What you can prove however, is
tne : ∀ {A : Type} → ¬¬¬ A → ¬ A tne = {!!}
Exercise 4 (★★★)
Prove¬¬-functor : {A B : Type} → (A → B) → ¬¬ A → ¬¬ B ¬¬-functor = {!!} ¬¬-kleisli : {A B : Type} → (A → ¬¬ B) → ¬¬ A → ¬¬ B ¬¬-kleisli = {!!}
Hint: For the second goal use tne
from the previous
exercise
Part II: _≡_
for
Bool
In this exercise we want to investigate what equality of
booleans looks like. In particular we want to show that for
true false : Bool
we have
true ≢ false
.
Exercise 1 (★)
Under the propositions-as-types paradigm, an inhabited type corresponds to a true proposition while an uninhabited type corresponds to a false proposition. With this in mind construct a familybool-as-type : Bool → Type bool-as-type = {!!}
such that bool-as-type true
corresponds to “true” and
bool-as-type false
corresponds to “false”. (Hint: we have
seen canonical types corresponding true and false in the lectures)
Exercise 2 (★★)
Provebool-≡-char₁ : ∀ (b b' : Bool) → b ≡ b' → (bool-as-type b ⇔ bool-as-type b') bool-≡-char₁ = {!!}
Exercise 3 (★★)
Using ex. 2, conclude thattrue≢false : ¬ (true ≡ false) true≢false ()
You can actually prove this much easier! How?
Exercise 4 (★★★)
Finish our characterisation of_≡_
by proving
bool-≡-char₂ : ∀ (b b' : Bool) → (bool-as-type b ⇔ bool-as-type b') → b ≡ b' bool-≡-char₂ = {!!}
Part III (🌶)
A typeA
is called discrete if it has decidable
equality. Consider the following predicate on types:
has-bool-dec-fct : Type → Type has-bool-dec-fct A = Σ f ꞉ (A → A → Bool) , (∀ x y → x ≡ y ⇔ (f x y) ≡ true)
Prove that
decidable-equality-char : (A : Type) → has-decidable-equality A ⇔ has-bool-dec-fct A decidable-equality-char = ?