Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
fp:homework01 [2023/03/21 20:09] pdmatei |
fp:homework01 [2023/03/22 08:44] (current) pdmatei |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== H01. Functional Sets ====== | + | ====== Homework 1. Sets as functions ====== |
| ===== Problem statement ===== | ===== Problem statement ===== | ||
| Line 9: | Line 9: | ||
| In our implementation, $math[U] will be the set of integers, hence we shall encode only **sets of integers**. Hence, the type of a set will be: | In our implementation, $math[U] will be the set of integers, hence we shall encode only **sets of integers**. Hence, the type of a set will be: | ||
| <code scala> | <code scala> | ||
| - | type Set = Int => Boolean | + | Int => Boolean |
| </code> | </code> | ||
| Line 29: | Line 29: | ||
| **1.** Write a function ''singleton'' which takes an integer and returns **the set** containing only that integer: | **1.** Write a function ''singleton'' which takes an integer and returns **the set** containing only that integer: | ||
| <code scala> | <code scala> | ||
| - | def singleton(x: Int): Set = ??? | + | def singleton(x: Int): Int => Boolean = ??? |
| </code> | </code> | ||
| Line 37: | Line 37: | ||
| **2.** Write a function ''member'' which takes a set and an integer and checks if the integer is a member of the set. Note that ''member'' should be defined and called as a curry function: | **2.** Write a function ''member'' which takes a set and an integer and checks if the integer is a member of the set. Note that ''member'' should be defined and called as a curry function: | ||
| <code scala> | <code scala> | ||
| - | def member(e: Int)(set: Set): Boolean = ??? | + | def member(set: Int => Boolean)(e: Int): Boolean = ??? |
| </code> | </code> | ||
| Line 43: | Line 43: | ||
| <code scala> | <code scala> | ||
| - | def fromBounds(start: Int, stop: Int): Set = ??? | + | def fromBounds(start: Int, stop: Int): Int => Boolean = ??? |
| </code> | </code> | ||
| - | **5.** Write the function which performs the union of two sets: | + | **4.** Write a function which performs the intersection of two sets: |
| <code scala> | <code scala> | ||
| - | def union(set1: Set, set2: Set): Set = ??? | + | def intersection(set1: Int => Boolean, set2: Int => Boolean): Int => Boolean = ??? |
| </code> | </code> | ||
| - | **6.** Write a function which computes the complement of a set with respect to the set of integers: | + | **5.** Write the function which performs the union of two sets: |
| <code scala> | <code scala> | ||
| - | def complement(s1: Set): Set = ??? | + | def union(set1: Int => Boolean, set2: Int => Boolean): Int => Boolean = ??? |
| </code> | </code> | ||
| - | **6.** Write a function which computes the sum of value ''b'' to all elements from a set, for given **bounds**. Use a tail-end recursive function: | + | **6.** Write a function which computes the sum of all elements from a set, for given **bounds**. Use a tail-end recursive function: |
| <code scala> | <code scala> | ||
| - | def sumSet(b: Int)(start: Int, stop: Int)(set: Set): Int = { | + | def sumSet(start: Int, stop: Int, set: Int => Boolean): Int = { |
| def auxSum(crt: Int, acc: Int): Int = ??? | def auxSum(crt: Int, acc: Int): Int = ??? | ||
| ??? | ??? | ||
| Line 64: | Line 64: | ||
| </code> | </code> | ||
| - | **7.** Generalise the previous function such that we can **fold** a set using any binary commutative operation over integers. Make sure this is a **left** fold: Folding the set: ''{x,y,z}'' with ''b'' should produce: ''((b op x) op y) op z'' | + | **7.** Generalise the previous function such that we can **fold** a set using any binary commutative operation over integers: |
| <code scala> | <code scala> | ||
| - | def foldLeftSet | + | def foldSet( |
| - | (b:Int) // initial value | + | start: Int, // bounds (inclusive) |
| - | (op: (Int,Int) => Int) // folding operation | + | stop: Int, |
| - | (start: Int, stop: Int) // bounds (inclusive) | + | op: (Int, Int) => Int, // folding operation |
| - | (set: Set): Int = ??? // the set to be folded | + | initial: Int, // initial value |
| + | set: Int => Boolean // the set to be folded | ||
| + | ): Int = ??? | ||
| </code> | </code> | ||
| - | **7.** Implement an alternative to the previous function, namely **foldRight**. Applying ''foldRight'' on the set ''{x,y,z}'' with ''b'' should produce: ''a op (b op (c op b))''. Use direct recursion instead of tail recursion. | + | **8.** Implement a function ''forall'' which checks if all elements in a given range of a set satisfy a predicate (condition). (Such a condition may be that all elements from given bounds are even numbers). |
| <code scala> | <code scala> | ||
| - | def foldRightSet | + | def forall( |
| - | (b:Int) // initial value | + | start: Int, // start value (inclusive) |
| - | (op: (Int,Int) => Int) // folding operation | + | stop: Int, // stop value (inclusive) |
| - | (start: Int, stop: Int) // bounds (inclusive) | + | condition: Int => Boolean, // condition to be checked |
| - | (set: Set): Int = ??? // the set to be folded | + | set: Int => Boolean // set to be checked |
| + | ): Boolean = ??? | ||
| </code> | </code> | ||
| - | **X.** Implement operation ''filter'' which takes a set and returns another one containing only those elements that satisfy the predicate: | + | **9.** Implement a function ''exists'' which checks if a predicate holds for **some** element from the range of a set. Hint: it is easier to implement ''exists'' using the logical relation: $math[ \exists x. P(X) \iff \lnot \forall x.\lnot P(X)]. |
| <code scala> | <code scala> | ||
| - | def filter(p: Int => Boolean)(set: Set): Set = ??? | + | /* implement a function exists, using forall */ |
| + | def exists( | ||
| + | start: Int, // start value (inclusive) | ||
| + | stop: Int, // stop value (inclusive) | ||
| + | condition: Int => Boolean, // condition to be checked | ||
| + | set: Int => Boolean // set | ||
| + | ): Boolean = ??? | ||
| </code> | </code> | ||
| - | |||
| - | **X.** Implement a function which **partitions** a set into two sets. The left-most contains those elements that satisfy the predicate, while the right-most contains those elements that do not satisfy the predicate. Use pairs. A pair is constructed with simple parentheses: ''(1,2)''. Suppose ''val p: (Int,Int)'' is a pair of two integers. Then ''p._1'' is the left-most part of the pair while ''p._2'' is the right-most part of the pair. | ||
| - | <code scala> | ||
| - | def partition(p: Int => Boolean)(set: Set): (Set,Set) = ??? | ||
| - | </code> | ||
| - | |||
| - | **8.** Implement a function ''forall'' which checks if all elements in a given range of a set satisfy a predicate (condition). (Such a condition may be that all elements from given bounds are even numbers). | ||
| - | <code scala> | ||
| - | def forall(cond: Int => Boolean) // condition to be checked | ||
| - | (start: Int, stop: Int) // start,stop values (inclusive) | ||
| - | (set: Set): Boolean // set to be checked | ||
| - | = ??? | ||
| - | </code> | ||
| - | |||
| - | **9.** Implement a function ''exists'' which checks if a predicate holds for **some** element from the range of a set. Hint: it is easier to implement ''exists'' using the logical relation: $math[ \exists x. P(X) \iff \lnot \forall x.\lnot P(X)]. | ||
| - | |||
| - | **X** | ||