{-# OPTIONS --cubical --allow-unsolved-meta #-}
{-
AGDA IN PADOVA 2024
Exercise sheet 6
┌─ SHORTCUTS ───────────────────────┐ ┌─ BACKSLASH CHARACTERS ─┐
│ C-c C-l = load file │ │ \bN = ℕ │
│ C-c C-c = case split │ │ \alpha = α │
│ C-c C-SPC = check hole │ │ \to = → │
│ C-c C-, = see context │ │ \cdot = · │
│ C-c C-. = see context and goal │ │ \:: = ∷ │
│ C-c C-d = display type │ │ \== = ≡ │
│ C-c C-v = evaluate expression │ └────────────────────────┘
│ C-z = enable Vi keybindings │ Use M-x describe-char to
│ C-x C-+ = increase font size │ lookup input method for
└───────────────────────────────────┘ symbol under cursor.
You can open this file in an Agdapad session by pressing C-x C-f ("find file")
and then entering the path to this file: ~/Padova2024/exercise06.agda.
As this file is read-only, you can then save a copy of this file to your personal
directory and edit that one: File > Save As... For instance, you can save this file
as ~/solutions06.agda.
-}
open import Cubical.Core.Everything
open import Cubical.Foundations.Everything
data ℕ : Set where
zero : ℕ
succ : ℕ → ℕ
_+_ : ℕ → ℕ → ℕ
zero + b = b
succ a + b = succ (a + b)
lemma-+-commutative : (a b : ℕ) → (a + b) ≡ (b + a)
lemma-+-commutative = ?
data UnorderedPair (X : Set) : Set where
pair : (a b : X) → UnorderedPair X
swap : (a b : X) → pair a b ≡ pair b a
data ⊥ : Set where
-- EXERCISE: Implement "cong". Because the name "cong" is already
-- exported from the standard library, we use a different name.
cong' : {X Y : Set} {a b : X} → (f : X → Y) → a ≡ b → f a ≡ f b
cong' = {!!}
-- EXERCISE: Implement the sum operation on unordered pairs.
sum : UnorderedPair ℕ → ℕ
sum = ?
-- EXERCISE: Show that Cubical Agda validates the principle of function
-- extensionality, as follows:
funext : {A B : Set} (f g : A → B) → ((x : A) → f x ≡ g x) → f ≡ g
funext = ?
-- EXERCISE: Implement the successor operation on ℤ.
data ℤ : Set where
_⊝_ : ℕ → ℕ → ℤ -- \o- \ominus
cancel : (a b : ℕ) → a ⊝ b ≡ succ a ⊝ succ b
succℤ : ℤ → ℤ
succℤ (a ⊝ b) = succ a ⊝ b
succℤ (cancel a b i) = {!!}
-- EXERCISE: Show that zero is not succ zero.
--
-- With the inductive definition of _≡_ we used before, this required
-- an empty pattern. Now that _≡_ is no longer inductively defined,
-- but an in-built notion, we cannot case split on equality witnesses.
--
-- Instead, proceed as follows:
-- 1. Define a function "disambig : ℕ → Set" which maps zero to ⊥
-- and everything else to some inhabited type.
-- 2. Assuming that there is a path "zero ≡ succ zero", combine
-- "transport" from the standard library and "disambig":
-- transport : {A B : Set} → A ≡ B → A → B
--
-- Note that "symm" is spelt "sym" in the cubical standard library
-- and "trans" is written as the binary operator "∙" (\.).
lemma-nontrivial : zero ≡ succ zero → ⊥
lemma-nontrivial p = {!!}
-- EXERCISE: Show that the unordered pair abstraction is not leaky, in the
-- sense that there cannot be a function which would extract the first
-- component of an unordered pair.
lemma-not-leaky : (f : UnorderedPair ℕ → ℕ) (p : (a b : ℕ) → f (pair a b) ≡ a) → ⊥
lemma-not-leaky = {!!}
-- A type is called a "proposition" iff all its inhabitants are
-- equal. Hence all there is to know about a proposition is whether it is
-- inhabited.
isProp' : Set → Set
isProp' X = (a b : X) → a ≡ b
-- Show that negations are propositions.
lemma-negations-are-props : (X : Set) → isProp' (X → ⊥)
lemma-negations-are-props = {!!}
-- EXERCISE: Show that 𝟙 and Interval are the same, in the following sense.
data 𝟙 : Set where
* : 𝟙
data Interval : Set where
left : Interval
right : Interval
path : left ≡ right
toInterval : 𝟙 → Interval
toInterval * = left
fromInterval : Interval → 𝟙
fromInterval _ = *
is-iso₁ : (x : 𝟙) → fromInterval (toInterval x) ≡ x
is-iso₁ = {!!}
-- Hint: Use _∧_.
is-iso₂ : (x : Interval) → toInterval (fromInterval x) ≡ x
is-iso₂ = {!!}
-- EXERCISE: Show that ℕ is discrete, in the following sense.
isDiscrete : Set → Set
isDiscrete X = (a b : X) → isProp' (a ≡ b)
Code : ℕ → ℕ → Set
Code zero zero = 𝟙
Code zero (succ y) = ⊥
Code (succ x) zero = ⊥
Code (succ x) (succ y) = Code x y
fromCode : (a b : ℕ) → Code a b → a ≡ b
fromCode a b p = {!!}
ref : (a : ℕ) → Code a a
ref a = {!!}
-- Hint: Use "J" or "transport"!
toCode : (a b : ℕ) → a ≡ b → Code a b
toCode = {!!}
lemma-ℕ-discrete : isDiscrete ℕ
lemma-ℕ-discrete = {!!}