Homework 1. Sets as functions

Sets are unordered collections of unique elements. There are several ways to store sets. One of them relies on characteristic functions. Such functional sets are especially useful if we expect many insert/retrieve operations and less traversals in our code.

A characteristic function of a set $ A \subseteq U$ is a function $ f: U \rightarrow \{0,1\}$ which assigns $ f(x) = 1$ for each element $ x \in A$ and $ f(x) = 0$ for each element $ x \not\in A$ .

In our implementation, $ U$ will be the set of integers, hence we shall encode only sets of integers. Hence, the type of a set will be:

type Set = Int => Boolean

For instance, the set $ \{1,2,3\}$ will be encoded by the anonymous function:

(x: Int) => (x == 1 || x == 2 || x == 3)

Also, the empty set can be encoded as:

(x: Int) => false

while the entire set of integers may be encoded as:

(x: Int) => true

1. Write a function singleton which takes an integer and returns the set containing only that integer:

def singleton(x: Int): Set = ???

Note that singleton could have been equivalently defined as: def singleton(x: Int)(e: Int): Boolean = ???, however, the previous variant is more legible, in the sense that it highlights the idea that we are returning set objects, namely characteristic functions.

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:

def member(e: Int)(set: Set): Boolean = ???

3. Write a function ins which inserts a new element in a set. More precisely, given $ x$ and $ set$ , ins returns a new set $ \{x\} \cup set$ .

def ins(x: Int)(set: Set): Set = ???

4. Write a function fromBounds which takes two integer bounds start and stop and returns the set $ \{start, start+1, \ldots, stop\}$ . It is guaranteed that $ start \leq stop$ (you do not need to check this condition in your implementation).

def fromBounds(start: Int, stop: Int): Set = ???

5. Write the function which performs the union of two sets:

def union(set1: Set, set2: Set): Set = ???

6. Write a function which computes the complement of a set with respect to the set of integers:

def complement(s1: Set): Set = ???

7. 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:

  def sumSet(b: Int)(start: Int, stop: Int)(set: Set): Int = {
    def auxSum(crt: Int, acc: Int): Int = ???
    ???
  }

8. 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

  def foldLeftSet
     (b:Int)                  // initial value 
     (op: (Int,Int) => Int)   // folding operation
     (start: Int, stop: Int)  // bounds (inclusive)
     (set: Set): Int = ???    // the set to be folded

9. 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.

  def foldRightSet
     (b:Int)                  // initial value 
     (op: (Int,Int) => Int)   // folding operation
     (start: Int, stop: Int)  // bounds (inclusive)
     (set: Set): Int = ???    // the set to be folded

10. Implement operation filter which takes a set and returns another one containing only those elements that satisfy the predicate:

def filter(p: Int => Boolean)(set: Set): Set = ???

11. 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. E.g. (1,2) is a pair of two integers. Suppose val p: (Int,Int) is another 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.

  def partition(p: Int => Boolean)(set: Set): (Set,Set) = ???

12. 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).

  def forall(cond: Int => Boolean) // condition to be checked
            (start: Int, stop: Int) // start,stop values (inclusive)
            (set: Set): Boolean  // set to be checked
            = ???

13. 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: $ \exists x. P(X) \iff \lnot \forall x.\lnot P(X)$ .

14. Implement the function setOfDivByK which returns the set of integers divisible by a value k. Use the appropriate functions you have defined.

def setOfDivByK(k: Int): Set = ??

15. Implement the function moreDivs which verifies if set1 contains more divisors of k than set2, over the range [start,stop]. Use any combination of the previous functions you have defined for your implementation.

def moreDivs(k: Int)(start: Int, stop:Int)(set1: Set, set2: Set): Boolean = ???
  • Please follow the Submission guidelines which are the same for all homework.
  • To solve your homework, download the Project template, import it in IntellIJ, and you are all set. Do not rename the project manually, as this may cause problems with IntellIJ.