Files
org_roam/Uni/20250121110241-afp_lec_1.org
Zaine 5e983f43d4
All checks were successful
Build Roam Site / build (push) Successful in 28s
gitea runners 2
2026-05-06 15:42:32 +01:00

4.0 KiB
Raw Blame History

afp_lec_1

<2025-01-21 Tue> Week 1 Handout

Week 1 lec 1

if you want to put a hole in the file (ie the { }1 ) then put a ? and load the file

types are default called 'sets' in agda but we will call them types.

data Bool : Type where true false : Bool

Here we create a type called Bool

data Maybe (A : Type) : Type where nothing : Maybe A just : A → Maybe A

Given the type A we produce another type Then we have two constructors, we can actually call them whatever we want, the only rule is that it shouldnt have spaces in the middle. For example, instead of nothing we can call 'nothing' as 'Nothingljfsdsdj'.

The below is known as coercion or the disjoint union Considering Blah = Either Bool left 0: Blah right false: Blah

data : Type where zero : suc :

4 = suc (suc (suc (suc zero)))

data List (A : Type) : Type where [] : List A :: : A → List A → List A

Below is a function that maps a type to a type: myList : Type -> Type myList = List

N -> Type … this is called 'Dependant Type' which depends on elements of another type. When it comes to types, its often the case where the language we use doesnt exactly define the type we want it to. For example in haskell, the binary tree, when we want to use the binary search tree its a little difficult. In agda we can define a precise type; including the binary search tree. In summary agda can write precise types.

if_then_else_ : {A : Type} → Bool → A → A → A if true then x else y = x if false then x else y = y

this above is known as mixfix operation, we use the _ to denote where the arguments of the function are going to be places

+ : zero + y = y suc x + y = suc (x + y)

here we can pattern match on any of x or y in haskell, recursion can be done and there arent restrictions on it. in Agda we have structural recursion as there is a termination on recursion. Structural recursion is when you follow the structure of the definition, for example in suc x + y, we get suc (x + y), we keep removing the x from suc until we are left with 0. scrcpy

* : zero * y = zero suc x * y = x * y + y

for suc x * y: (1 + x) * y y + x * y

in infixr, the r means the brackets are explicitly on the right, if we use infixl then its on the left: x + y + z x + (y + z) : r (x + y) + z : l

research implicit arguements.

reverse : {A : Type} → List A → List A reverse [] = [] reverse (x :: xs) = reverse xs ++ [ x ]

although this program works, its inefficient.

rev-append : {A : Type} → List A → List A → List A rev-append [] ys = ys rev-append (x :: xs) ys = rev-append xs (x :: ys)

rev : {A : Type} → List A → List A rev xs = rev-append xs []

the revappend is a helper function. you can see theres no ++ (concatenation) involved.

Week 1 lec 2

N-Induction : (P: N -> Type) -> P 0 -> ((k:N) -> Pk (P (suc k)) choose k = 0

P0 : P0 f0 p1 : P1 f1 p2 : p2

-> (n:N) -> Pn

This is proof by induction,

-induction P p0 f 0 = P0 -induction P p0 f(suc n) = goal where : Pn = -induction P p0 f n

-induction P p0 f 3 = f3(f2(f1 p0)) essentially this is a for loop.

indstep : (k:N) -> k≣k -> suc k ≣ suc k indstep k e = e

-refl n = -induction (λx -> x≣x) * (λke -> e)

introduction and elimination rules

List-induction : { x : Type } -> (P : List X -> Type) -> P [] -> ((x:X)(xs:List X) -> Pxs -> P(x::xs))

-> (xs : List X ) -> P xs

List-induction

Keybindings:

  • C-c C-l : to load the agda file
  • SPC-w for the windows
  • C-c C-c : case split (agda mode) (put x, or b or whatever the first one is, then use this - very useful).
  • C-c C-SPC: give: tries to fill the hole
  • C-shift - : undo
  • C-c C-r : refine
  • C-c C-, : show the context