Skip to content

Commit

Permalink
Use inverted-image class in whole lecture (#24)
Browse files Browse the repository at this point in the history
Co-authored-by: Tomas Votroubek <tomas.votroubek@outlook.com>
  • Loading branch information
nmheim and votroto authored May 3, 2024
1 parent 292687c commit 106a388
Show file tree
Hide file tree
Showing 12 changed files with 275 additions and 275 deletions.
26 changes: 13 additions & 13 deletions labs/lab04.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ using the recursion on the length of `lst`.
(define (interleave el lst)
(if (null? lst)
; there is only a single way one can insert el into '()
(list (list el))
(list (list el))
; otherwise one possibility is to prepend el to lst
(cons (cons el lst)
; for the rest take all possible insertions of el into (cdr lst)
; for the rest take all possible insertions of el into (cdr lst)
(map (curry cons (car lst))
; and prepend (car lst) to each of them
(interleave el (cdr lst))))))
(define (permutations lst)
(if (null? lst)
'(())
(apply append
; into each permutation of (cdr lst) interleave (car last)
(apply append
; into each permutation of (cdr lst) interleave (car last)
(map (curry interleave (car lst)) (permutations (cdr lst))))))
```
:::
Expand All @@ -63,15 +63,15 @@ permutations with the (builtin) `in-permutations` function.
Binary decision trees represent Boolean functions, i.e., functions from $\{0,1\}^n$ to $\{0,1\}$.
Let $f(x_1,\ldots,x_n)$ be a Boolean function. The corresponding binary decision tree is created as
follows:
- Each input variable $x_i$ induces the $i$th-level in the tree whose nodes are labelled by $x_i$.
- Each input variable $x_i$ induces the $i$th-level in the tree whose nodes are labelled by $x_i$.
- Leaves are elements from $\{0,1\}$.

Each path from the root to a leaf encodes an evaluation of input variables. If the path in an
internal node $x_i$ goes to the left, the variable $x_i$ is evaluated by $0$. If to the right, it is
evaluated by $1$. The leaf in the path represents the value $f(x_1,\ldots,x_n)$ for the evaluation
defined by the path. Example of a Boolean function and its binary decision tree:

![](/img/bdd.png){ style="width: 70%; margin: auto;" }
![](/img/bdd.png){ style="width: 70%; margin: auto;" class="inverting-image"}

We will represent the inner variable nodes as Racket structures:
```scheme
Expand All @@ -98,7 +98,7 @@ values of variables $x_1,\ldots,x_n$ and returns $f(x_1,\ldots,x_n)$. E.g.
(evaluate bool-tree '(1 0 1)) => 0
(evaluate bool-tree '(0 1 1)) => 1
```
The second function `(satisficing-evaluations tree)` takes a binary decision
The second function `(satisficing-evaluations tree)` takes a binary decision
tree `tree`
representing a Boolean function $f(x_1,\ldots,x_n)$ and returns all its satisficing evaluations,
i.e., those for which $f(x_1,\ldots,x_n)=1$. To represent a variable assignment, we introduce the
Expand Down Expand Up @@ -143,25 +143,25 @@ Finally, it applies their composition to `tree`.
```
:::

The function `satisficing-evaluations` is a recursive
The function `satisficing-evaluations` is a recursive
function using an accumulator `ev`,
keeping partial evaluation as we traverse the tree.
It recursively finds all satisficing evaluations of the left and right subtree, extends them by $0$ (resp. $1$) if they come from left (resp. right), and append them together.
It recursively finds all satisficing evaluations of the left and right subtree, extends them by $0$ (resp. $1$) if they come from left (resp. right), and append them together.

::: details Solution `satisficing-evaluations`
```scheme
(define (satisficing-evaluations tree [ev '()])
(match tree
[1 (list (reverse ev))] ; we reverse the evaluation so that the root variable comes first
[0 '()]
[0 '()]
[(node v l r)
(append (satisficing-evaluations l (cons (assignment v 0) ev))
(satisficing-evaluations r (cons (assignment v 1) ev)))]))
(append (satisficing-evaluations l (cons (assignment v 0) ev))
(satisficing-evaluations r (cons (assignment v 1) ev)))]))
```
:::

## Task 1
Write a function `(sub-seq lst)`
Write a function `(sub-seq lst)`
taking a list `lst` and returning a list of all its sublists/subsequences. E.g.
```scheme
(sub-seq '(1 2 3)) =>
Expand Down
20 changes: 10 additions & 10 deletions labs/lab05.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ it, for instance, as follows:
```

Adding two infinite streams can be done recursively. Since the streams are infinite, we do not have
to check the emptiness of any input streams.
to check the emptiness of any input streams.
::: details Solution: `stream-add`
```scheme
(define (stream-add s1 s2)
Expand All @@ -31,7 +31,7 @@ to check the emptiness of any input streams.
```
:::

The definition of the Fibonacci sequence
The definition of the Fibonacci sequence
$F(0)=0$, $F(1)=1$, and $F(n)=F(n-1) + F(n-2)$ for $n>1$ can be reformulated as follows:
```scheme
0 1 1 2 3 5 8 13 ... ; F(n-2) - Fibonacci sequence
Expand Down Expand Up @@ -69,7 +69,7 @@ define a structure for a graph:
```

The following graph
![](/img/6n-graph.svg){ style="width: 50%; margin: auto;" }
![](/img/6n-graph.svg){ style="width: 50%; margin: auto;" class="inverting-image"}

is represented as follows:
```scheme
Expand All @@ -82,10 +82,10 @@ is represented as follows:

Given a graph $G$, a [Hamiltonian path](https://en.wikipedia.org/wiki/Hamiltonian_path) is a path
visiting each vertex of $G$ exactly once. We will represent a path as a list of consecutive nodes in
the path. The above graph `gr` has a Hamiltonian path `(3 2 1 5 4 6)`.
the path. The above graph `gr` has a Hamiltonian path `(3 2 1 5 4 6)`.

Write a function `(find-hamiltonian-path g)` which takes a graph as its input and returns a
Hamiltonian path, if it exists, and `#f` otherwise. E.g.
Hamiltonian path, if it exists, and `#f` otherwise. E.g.
```scheme
(find-hamiltonian-path gr) => (3 2 1 5 4 6)
(find-hamiltonian-path (graph '(a b c d) '((a b) (a c) (a d)))) => #f
Expand All @@ -110,7 +110,7 @@ Given a list, we create a list of pairs of consecutive nodes. E.g. `(1 2 3 4)` i
`list` element-wise. Finally, we test whether all these pairs are connected. To do so, we use the
function `(andmap f lst)`. This function is implemented in Racket. It behaves like `map` but
aggregates the results of `f` by `and` function, i.e., once any of the results is `#f`, it returns
`#f` and the last result otherwise.
`#f` and the last result otherwise.
::: details Solution: `check-path`
```scheme
(define (check-path g)
Expand Down Expand Up @@ -142,7 +142,7 @@ compare the perfromance of the two implementations on a larger graph.
## Task 1
Write a function `(stream-mul s1 s2)` taking two infinite streams and multiplying them
elements-wise. Using this function, define an infinite stream `factorial-stream` of factorials $0!,
1!, 2!, 3!,\ldots$.
1!, 2!, 3!,\ldots$.

::: tip
The recursive definition of factorial $f(0)=1$ and $f(n)=n\cdot f(n-1)$ for $n>0$ gives us
Expand All @@ -155,7 +155,7 @@ The recursive definition of factorial $f(0)=1$ and $f(n)=n\cdot f(n-1)$ for $n>0
In your definition, you can use the function `(in-naturals n)` implemented in Racket to define the
stream of natural numbers starting from n.
:::

Once you have the stream of factorials `factorial-stream`, the function `stream-mul` and the stream
of natural numbers `(in-natural 0)` (or even simply `(in-naturals)`), you can define a function
`(exp-stream x)` taking a number `x` and returning the power series representing $e^x$, i.e., $e^x =
Expand Down Expand Up @@ -224,7 +224,7 @@ subsets ordered by their cardinality. To fix this, we have to modify the functio
the result of the recursive call and the newly created subsets. Thus we define a function
`(stream-merge s1 s2 cmp)` which takes two streams and a function `cmp` comparing two elements of
these streams and returns a stream where the values are merged so that the smaller elements come
first.
first.
:::
```scheme
; lazy subsequences
Expand All @@ -235,7 +235,7 @@ first.
([cmp (stream-first s1) (stream-first s2)]
(stream-cons (stream-first s1) (stream-merge (stream-rest s1) s2 cmp)))
(else (stream-cons (stream-first s2) (stream-merge s1 (stream-rest s2) cmp)))))
(define (sub-seq lst)
(if (null? lst)
(stream '())
Expand Down
36 changes: 18 additions & 18 deletions labs/lab07.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ So we had to add the outermost parenthesis, expand the shortcuts $\lambda xy.$ t
x.(\lambda y.$, and put the parenthesis determining the order of the applications, i.e., as the
application is left-associative, $xy(\lambda ab.b)$ is in fact $((x y) (\lambda ab.b))$. The symbol
λ can be entered in DrRacket by pressing `Ctrl+\`. Instead of the dot symbol, the colon symbol is
used.
used.

The module `lambda-calculus.rkt` provides the following functions:
| Function | Description |
Expand All @@ -39,7 +39,7 @@ The module `lambda-calculus.rkt` provides the following functions:
| `(eval expr [info 'quiet])` | finds the normal form of `expr`; if `info` is set to `'verbose`, displays all the steps; if `info` is `'tree`, then all the steps are drawn as trees |

## Exercise 1
Draw the syntax tree of the $\lambda$-expression $(\lambda x.y(xx))(\lambda y.y(xx))$ and determine which variable occurrences are free and which are bound.
Draw the syntax tree of the $\lambda$-expression $(\lambda x.y(xx))(\lambda y.y(xx))$ and determine which variable occurrences are free and which are bound.

We will use the helper function `draw-expr`. First, create the correct representation as an S-expression:
```scheme
Expand All @@ -48,7 +48,7 @@ We will use the helper function `draw-expr`. First, create the correct represent
Then evaluate the following function call:
::: details `(draw-expr '((λ x : (y (x x))) (λ y : (y (x x)))))`
Displays the tree below:
![ex1](/img/lab07-ex1.png)
![ex1](/img/lab07-ex1.png){class="inverting-image"}
:::

An occurrence of a variable $v$ is bound if it is in the syntax tree below the node $\lambda v$ and is free otherwise. So, for our expression, the occurrences of $x$ in the left branch are bound, and they are free in the right branch. The occurrence of $y$ in the left branch is free and bound in the right branch.
Expand All @@ -65,7 +65,7 @@ Try first to draw the tree on paper. Then compare your result with the result re
Find all redexes in $(\lambda x.x y) z ((\lambda u.u) ((\lambda v.v) z))$. Which one is the leftmost outermost redex, and which is the leftmost innermost redex? Reduce the leftmost outermost redex.

::: tip Hint
Try to find the redexes. Then call `(draw-expr expr)`
Try to find the redexes. Then call `(draw-expr expr)`
for `expr` being the following S-expression:
```scheme
'(((λ x : (x y)) z) ((λ u : u) ((λ v : v) z)))
Expand All @@ -81,7 +81,7 @@ Recall that multiplication of two numbers is computed by
$$M \equiv \lambda abc.a(bc).$$
Find the normal form of $M01$ following the normal order reduction strategy, i.e., compute $0\cdot
1$, which should result in $0$. The numbers $0,1$ are abbreviations for $\lambda$-expressions
$\lambda sz.z$ and $\lambda sz.sz$ respectively.
$\lambda sz.z$ and $\lambda sz.sz$ respectively.

::: tip Hint
Once you do it on paper, check your result in Racket. You can use Racket definitions and semiquoting to make your $\lambda$-expression more readable.
Expand Down Expand Up @@ -111,18 +111,18 @@ these constructions as follows (the final two calls check that it behaves as exp
(define T '(λ x : (λ y : x)))
(define F '(λ x : (λ y : y)))
(define CONS
(define CONS
'(λ a : (λ b : (λ z : ((z a) b)))))
(eval `(((,CONS a) b) ,T))
(eval `(((,CONS a) b) ,F))
```
Write a $\lambda$-expression swapping components of a given pair $p$.

Write a $\lambda$-expression swapping components of a given pair $p$.

::: tip Hint
The desired $\lambda$-expression should take a pair $p$ and return another pair with swapped components.
So the expression should start with $\lambda pz.z??$ where the question marks are the components of the returned pair.
The desired $\lambda$-expression should take a pair $p$ and return another pair with swapped components.
So the expression should start with $\lambda pz.z??$ where the question marks are the components of the returned pair.
:::

::: details Solution
Expand All @@ -142,7 +142,7 @@ Once you have it, define `SWAP` and check that it correctly swaps the components

## Exercise 6
Since we can create pairs, we can create lists as in Racket. We represent the empty list by the false value $F$. Now we can
create a list `'(a b)` by
create a list `'(a b)` by
```scheme
(define lst `((,CONS a) ((,CONS b) ,F)))
Expand All @@ -153,22 +153,22 @@ create a list `'(a b)` by
Write a $\lambda$-expression $NULL?$ testing if a list is empty, i.e., it returns $T$ if it is empty and $F$ otherwise.

::: tip Hint
A list is either a pair or $F$ if it is empty. Let denote it by $p$.
A list is either a pair or $F$ if it is empty. Let denote it by $p$.
Recall the definition of the zero test from the lecture
$$Z\equiv \lambda x.xF\neg F,$$
where $\neg\equiv \lambda x.xFT$.
where $\neg\equiv \lambda x.xFT$.
We need something similar for the list $p$. So our desired $\lambda$-expression should look like
$\lambda p.pe_1e_2$ where $e_1,e_2$ have to be filled by suitable $\lambda$-expressions serving as
arguments for $p$. If $p$ is empty (i.e., $p\equiv F$), then $p$ is just a projection into the
second argument. Thus $e_2$ should be $T$, i.e., we have $\lambda p.pe_1T$. If we substitute
for $p$ a pair (i.e. $p \equiv \lambda z.zab$), we obtain $(\lambda z.zab)e_1T$. Thus $e_1$ is
going to be substituted for $z$, and consequently, it will be applied to $a$ and $b$, i.e., we would
end up with $e_1abT$. Since the result in this case should be $F$, we need the result of $e_1ab$ to
be $\neg$ because $\neg F\to^\beta T$.
be $\neg$ because $\neg F\to^\beta T$.
:::

::: details Solution
$\lambda p.p(\lambda ab.\neg)T$
$\lambda p.p(\lambda ab.\neg)T$
:::

Check your solution in Racket.
Expand Down Expand Up @@ -199,7 +199,7 @@ $$S\equiv \lambda wyx.y(wyx)$$
for adding $1$. The computation of the desired $\lambda$-expression can be expressed in Racket as
follows:
```scheme
(define len
(define len
(lambda (p) (if (null? p)
0
(+ (len (cdr p)) 1))))
Expand Down Expand Up @@ -227,7 +227,7 @@ Check your solution in Racket:
(,S (r (lst ,F)))))))
(eval `((,Y ,LEN) ,F)) ; => 0
(eval `((,Y ,LEN) ((,CONS a) ,F))) ; => 1
(eval `((,Y ,LEN) ((,CONS a) ,F))) ; => 1
(eval `((,Y ,LEN) ((,CONS a) ((,CONS b) ,F)))) ; => 2
```
:::
Loading

0 comments on commit 106a388

Please sign in to comment.