Assignment1: TSPL Assignment 1
module Assignment1 where -
YOUR NAME AND EMAIL GOES HERE
Introduction
You must do all the exercises labelled “(recommended)”.
Exercises labelled “(stretch)” are there to provide an extra challenge. You don’t need to do all of these, but should attempt at least a few.
Exercises labelled “(practice)” are included for those who want extra practice.
Submit your homework using Gradescope. Go to the course page under Learn. Select Assessment
, then select Assignment Submission
. Please ensure your files execute correctly under Agda!
Good Scholarly Practice.
Please remember the University requirement as regards all assessed work. Details about this can be found at:
https://web.inf.ed.ac.uk/infweb/admin/policies/academic-misconduct
You are required to take reasonable measures to protect your assessed work from unauthorised access. For example, if you put any such work on a public repository then you must set access permissions appropriately (generally permitting access only to yourself). Do not publish solutions to the coursework.
Naturals
module Naturals where - import Relation.Binary.PropositionalEquality as Eq - open Eq using (_≡_; refl) - open Eq.≡-Reasoning using (begin_; step-≡-∣; _∎) - open import Data.Nat using (ℕ; zero; suc; _+_; _*_; _∸_) -
Exercise seven
(practice)
Write out 7
in longhand.
-- Your code goes here -
You will need to give both a type signature and definition for the variable seven
. Type C-c C-l
in Emacs to instruct Agda to re-load.
Exercise +-example
(practice)
Compute 3 + 4
, writing out your reasoning as a chain of equations, using the equations for +
.
-- Your code goes here -
Exercise *-example
(practice)
Compute 3 * 4
, writing out your reasoning as a chain of equations, using the equations for *
. (You do not need to step through the evaluation of +
.)
-- Your code goes here +
YOUR NAME AND EMAIL GOES HERE
Introduction
You must do all the exercises labelled “(recommended)”.
Exercises labelled “(stretch)” are there to provide an extra challenge. You don’t need to do all of these, but should attempt at least a few.
Exercises labelled “(practice)” are included for those who want extra practice.
Submit your homework using Gradescope. Go to the course page under Learn. Select Assessment
, then select Assignment Submission
. Please ensure your files execute correctly under Agda!
Good Scholarly Practice.
Please remember the University requirement as regards all assessed work. Details about this can be found at:
https://web.inf.ed.ac.uk/infweb/admin/policies/academic-misconduct
You are required to take reasonable measures to protect your assessed work from unauthorised access. For example, if you put any such work on a public repository then you must set access permissions appropriately (generally permitting access only to yourself). Do not publish solutions to the coursework.
Deadline and late policy
The deadline and late policy for this assignment are specified on Learn in the “Coursework Planner”. There are no extensions and no ETAs. Coursework is marked best three out of four. Guidance on late submissions is at
Naturals
module Naturals where + import Relation.Binary.PropositionalEquality as Eq + open Eq using (_≡_; refl) + open Eq.≡-Reasoning using (begin_; step-≡-∣; _∎) + open import Data.Nat using (ℕ; zero; suc; _+_; _*_; _∸_) +
Exercise seven
(practice)
Write out 7
in longhand.
-- Your code goes here +
You will need to give both a type signature and definition for the variable seven
. Type C-c C-l
in Emacs to instruct Agda to re-load.
Exercise +-example
(practice)
Compute 3 + 4
, writing out your reasoning as a chain of equations, using the equations for +
.
-- Your code goes here +
Exercise *-example
(practice)
Compute 3 * 4
, writing out your reasoning as a chain of equations, using the equations for *
. (You do not need to step through the evaluation of +
.)
-- Your code goes here
Exercise _^_
(recommended)
Define exponentiation, which is given by the following equations:
m ^ 0 = 1
-m ^ (1 + n) = m * (m ^ n)
Check that 3 ^ 4
is 81
.
-- Your code goes here -
Exercise ∸-example₁
and ∸-example₂
(recommended)
Compute 5 ∸ 3
and 3 ∸ 5
, writing out your reasoning as a chain of equations.
-- Your code goes here -
Exercise Bin
(stretch)
A more efficient representation of natural numbers uses a binary rather than a unary system. We represent a number as a bitstring:data Bin : Set where - ⟨⟩ : Bin - _O : Bin → Bin - _I : Bin → Bin +m ^ (1 + n) = m * (m ^ n)
Check that 3 ^ 4
is 81
.
-- Your code goes here +
Exercise ∸-example₁
and ∸-example₂
(recommended)
Compute 5 ∸ 3
and 3 ∸ 5
, writing out your reasoning as a chain of equations.
-- Your code goes here +
Exercise Bin
(stretch)
A more efficient representation of natural numbers uses a binary rather than a unary system. We represent a number as a bitstring:data Bin : Set where + ⟨⟩ : Bin + _O : Bin → Bin + _I : Bin → Bin
For instance, the bitstring
1011
standing for the number eleven is encoded as
⟨⟩ I O I I
Representations are not unique due to leading zeros. Hence, eleven is also represented by 001011
, encoded as:
⟨⟩ O O I O I I
Define a function
inc : Bin → Bin
that converts a bitstring to the bitstring for the next higher number. For example, since 1100
encodes twelve, we should have:
inc (⟨⟩ I O I I) ≡ ⟨⟩ I I O O
Confirm that this gives the correct answer for the bitstrings encoding zero through four.
Using the above, define a pair of functions to convert between the two representations.
to : ℕ → Bin
-from : Bin → ℕ
For the former, choose the bitstring to have no leading zeros if it represents a positive natural, and represent zero by ⟨⟩ O
. Confirm that these both give the correct answer for zero through four.
-- Your code goes here -
Induction
module Induction where -
Imports
We require equality as in the previous chapter, plus the naturals and some operations upon them. We also require a couple of new operations,cong
, sym
, and _≡⟨_⟩_
, which are explained below:import Relation.Binary.PropositionalEquality as Eq - open Eq using (_≡_; refl; cong; sym) - open Eq.≡-Reasoning using (begin_; step-≡-∣; step-≡-⟩; _∎) - open import Data.Nat using (ℕ; zero; suc; _+_; _*_; _∸_; _^_) - open import Data.Nat.Properties using (+-assoc; +-identityʳ; +-suc; +-comm) -
(Importing step-≡
defines _≡⟨_⟩_
.)
open import plfa.part1.Induction - hiding () -
Exercise operators
(practice)
Give another example of a pair of operators that have an identity and are associative, commutative, and distribute over one another. (You do not have to prove these properties.)
Give an example of an operator that has an identity and is associative but is not commutative. (You do not have to prove these properties.)
Exercise finite-+-assoc
(stretch)
Write out what is known about associativity of addition on each of the first four days using a finite story of creation, as earlier.
-- Your code goes here -
Exercise +-swap
(recommended)
Show
m + (n + p) ≡ n + (m + p)
for all naturals m
, n
, and p
. No induction is needed, just apply the previous results which show addition is associative and commutative.
-- Your code goes here -
Exercise *-distrib-+
(recommended)
Show multiplication distributes over addition, that is,
(m + n) * p ≡ m * p + n * p
for all naturals m
, n
, and p
.
-- Your code goes here -
Exercise *-assoc
(recommended)
Show multiplication is associative, that is,
(m * n) * p ≡ m * (n * p)
for all naturals m
, n
, and p
.
-- Your code goes here -
Exercise *-comm
(practice)
Show multiplication is commutative, that is,
m * n ≡ n * m
for all naturals m
and n
. As with commutativity of addition, you will need to formulate and prove suitable lemmas.
-- Your code goes here -
Exercise 0∸n≡0
(practice)
Show
zero ∸ n ≡ zero
for all naturals n
. Did your proof require induction?
-- Your code goes here -
Exercise ∸-+-assoc
(practice)
Show that monus associates with addition, that is,
m ∸ n ∸ p ≡ m ∸ (n + p)
for all naturals m
, n
, and p
.
-- Your code goes here +from : Bin → ℕ
For the former, choose the bitstring to have no leading zeros if it represents a positive natural, and represent zero by ⟨⟩ O
. Confirm that these both give the correct answer for zero through four.
-- Your code goes here +
Induction
module Induction where +
Imports
We require equality as in the previous chapter, plus the naturals and some operations upon them. We also require a couple of new operations,cong
, sym
, and _≡⟨_⟩_
, which are explained below:import Relation.Binary.PropositionalEquality as Eq + open Eq using (_≡_; refl; cong; sym) + open Eq.≡-Reasoning using (begin_; step-≡-∣; step-≡-⟩; _∎) + open import Data.Nat using (ℕ; zero; suc; _+_; _*_; _∸_; _^_) + open import Data.Nat.Properties using (+-assoc; +-identityʳ; +-suc; +-comm) +
(Importing step-≡
defines _≡⟨_⟩_
.)
open import plfa.part1.Induction + hiding () +
Exercise operators
(practice)
Give another example of a pair of operators that have an identity and are associative, commutative, and distribute over one another. (You do not have to prove these properties.)
Give an example of an operator that has an identity and is associative but is not commutative. (You do not have to prove these properties.)
Exercise finite-+-assoc
(stretch)
Write out what is known about associativity of addition on each of the first four days using a finite story of creation, as earlier.
-- Your code goes here +
Exercise +-swap
(recommended)
Show
m + (n + p) ≡ n + (m + p)
for all naturals m
, n
, and p
. No induction is needed, just apply the previous results which show addition is associative and commutative.
-- Your code goes here +
Exercise *-distrib-+
(recommended)
Show multiplication distributes over addition, that is,
(m + n) * p ≡ m * p + n * p
for all naturals m
, n
, and p
.
-- Your code goes here +
Exercise *-assoc
(recommended)
Show multiplication is associative, that is,
(m * n) * p ≡ m * (n * p)
for all naturals m
, n
, and p
.
-- Your code goes here +
Exercise *-comm
(practice)
Show multiplication is commutative, that is,
m * n ≡ n * m
for all naturals m
and n
. As with commutativity of addition, you will need to formulate and prove suitable lemmas.
-- Your code goes here +
Exercise 0∸n≡0
(practice)
Show
zero ∸ n ≡ zero
for all naturals n
. Did your proof require induction?
-- Your code goes here +
Exercise ∸-+-assoc
(practice)
Show that monus associates with addition, that is,
m ∸ n ∸ p ≡ m ∸ (n + p)
for all naturals m
, n
, and p
.
-- Your code goes here
Exercise +*^
(stretch)
Show the following three laws
m ^ (n + p) ≡ (m ^ n) * (m ^ p) (^-distribˡ-+-*)
(m * n) ^ p ≡ (m ^ p) * (n ^ p) (^-distribʳ-*)
- (m ^ n) ^ p ≡ m ^ (n * p) (^-*-assoc)
for all m
, n
, and p
.
-- Your code goes here + (m ^ n) ^ p ≡ m ^ (n * p) (^-*-assoc)
for all m
, n
, and p
.
-- Your code goes here
Exercise Bin-laws
(stretch)
Recall that Exercise Bin defines a datatype Bin
of bitstrings representing natural numbers, and asks you to define functions
inc : Bin → Bin
to : ℕ → Bin
from : Bin → ℕ
Consider the following laws, where n
ranges over naturals and b
over bitstrings:
from (inc b) ≡ suc (from b)
to (from b) ≡ b
-from (to n) ≡ n
For each law: if it holds, prove; if not, give a counterexample.
-- Your code goes here -
Relations
module Relations where -
Imports
import Relation.Binary.PropositionalEquality as Eq - open Eq using (_≡_; refl; cong) - open import Data.Nat using (ℕ; zero; suc; _+_) - open import Data.Nat.Properties using (+-comm; +-identityʳ) - open import Data.Nat using (_≤_; z≤n; s≤s) - open import Data.Nat.Properties - using (≤-refl; ≤-trans; ≤-antisym; ≤-total; - +-monoʳ-≤; +-monoˡ-≤; +-mono-≤) -
Exercise orderings
(practice)
Give an example of a preorder that is not a partial order.
-- Your code goes here -
Give an example of a partial order that is not a total order.
-- Your code goes here -
Exercise ≤-antisym-cases
(practice)
The above proof omits cases where one argument is z≤n
and one argument is s≤s
. Why is it ok to omit them?
-- Your code goes here -
Exercise *-mono-≤
(stretch)
Show that multiplication is monotonic with regard to inequality.
-- Your code goes here -
Exercise <-trans
(recommended)
Show that strict inequality is transitive. Use a direct proof. (A later exercise exploits the relation between < and ≤.)
-- Your code goes here -
Exercise trichotomy
(practice)
Show that strict inequality satisfies a weak version of trichotomy, in the sense that for any m
and n
that one of the following holds: * m < n
, * m ≡ n
, or * m > n
.
Define m > n
to be the same as n < m
. You will need a suitable data declaration, similar to that used for totality. (We will show that the three cases are exclusive after we introduce negation.)
-- Your code goes here -
Exercise +-mono-<
(practice)
Show that addition is monotonic with respect to strict inequality. As with inequality, some additional definitions may be required.
-- Your code goes here -
Exercise ≤→<, <→≤
(recommended)
Show that suc m ≤ n
implies m < n
, and conversely.
-- Your code goes here -
Exercise <-trans-revisited
(practice)
Give an alternative proof that strict inequality is transitive, using the relation between strict inequality and inequality and the fact that inequality is transitive.
-- Your code goes here -
Exercise o+o≡e
(stretch)
Show that the sum of two odd numbers is even.
-- Your code goes here +from (to n) ≡ n
For each law: if it holds, prove; if not, give a counterexample.
-- Your code goes here +
Relations
module Relations where +
Imports
import Relation.Binary.PropositionalEquality as Eq + open Eq using (_≡_; refl; cong) + open import Data.Nat using (ℕ; zero; suc; _+_) + open import Data.Nat.Properties using (+-comm; +-identityʳ) + open import Data.Nat using (_≤_; z≤n; s≤s) + open import Data.Nat.Properties + using (≤-refl; ≤-trans; ≤-antisym; ≤-total; + +-monoʳ-≤; +-monoˡ-≤; +-mono-≤) +
Exercise orderings
(practice)
Give an example of a preorder that is not a partial order.
-- Your code goes here +
Give an example of a partial order that is not a total order.
-- Your code goes here +
Exercise ≤-antisym-cases
(practice)
The above proof omits cases where one argument is z≤n
and one argument is s≤s
. Why is it ok to omit them?
-- Your code goes here +
Exercise *-mono-≤
(stretch)
Show that multiplication is monotonic with regard to inequality.
-- Your code goes here +
Exercise <-trans
(recommended)
Show that strict inequality is transitive. Use a direct proof. (A later exercise exploits the relation between < and ≤.)
-- Your code goes here +
Exercise trichotomy
(practice)
Show that strict inequality satisfies a weak version of trichotomy, in the sense that for any m
and n
that one of the following holds: * m < n
, * m ≡ n
, or * m > n
.
Define m > n
to be the same as n < m
. You will need a suitable data declaration, similar to that used for totality. (We will show that the three cases are exclusive after we introduce negation.)
-- Your code goes here +
Exercise +-mono-<
(practice)
Show that addition is monotonic with respect to strict inequality. As with inequality, some additional definitions may be required.
-- Your code goes here +
Exercise ≤→<, <→≤
(recommended)
Show that suc m ≤ n
implies m < n
, and conversely.
-- Your code goes here +
Exercise <-trans-revisited
(practice)
Give an alternative proof that strict inequality is transitive, using the relation between strict inequality and inequality and the fact that inequality is transitive.
-- Your code goes here +
Exercise o+o≡e
(stretch)
Show that the sum of two odd numbers is even.
-- Your code goes here
Exercise Bin-predicates
(stretch)
Recall that Exercise Bin defines a datatype Bin
of bitstrings representing natural numbers. Representations are not unique due to leading zeros. Hence, eleven may be represented by both of the following:
⟨⟩ I O I I
⟨⟩ O O I O I I
Define a predicate
Can : Bin → Set
over all bitstrings that holds if the bitstring is canonical, meaning it has no leading zeros; the first representation of eleven above is canonical, and the second is not. To define it, you will need an auxiliary predicate
One : Bin → Set
that holds only if the bitstring has a leading one. A bitstring is canonical if it has a leading one (representing a positive number) or if it consists of a single zero (representing zero).
Show that increment preserves canonical bitstrings:
Can b
------------
@@ -70,5 +70,5 @@
1 ≤ n
---------------------
-to (2 * n) ≡ (to n) O
The hypothesis 1 ≤ n
is required for the latter, because to (2 * 0) ≡ ⟨⟩ O
but (to 0) O ≡ ⟨⟩ O O
.
-- Your code goes here +to (2 * n) ≡ (to n) O
The hypothesis 1 ≤ n
is required for the latter, because to (2 * 0) ≡ ⟨⟩ O
but (to 0) O ≡ ⟨⟩ O O
.
-- Your code goes here