/** This trait defines the AbstractSet type. Classes that inherit * from AbstractSet must implement at least the following methods: * contains, add and remove * * This trait defines two methods: addAll and removeAll */ trait AbstractSet { def contains(n: Int): Boolean def add(n: Int): AbstractSet def remove(n: Int): AbstractSet def addAll(lst: Iterable[Int]): AbstractSet = lst.foldLeft(this)((s, elem) => s add elem) def removeAll(lst: Iterable[Int]): AbstractSet = lst.foldLeft(this)((s, elem) => s remove elem) } /** This is the MutableSet class. * * The add and remove methods should modify the instance of the * set on which they are called. */ class MutableSet extends AbstractSet { def contains(n: Int): Boolean = // Your Code Here def add(n: Int): MutableSet = { // Your Code Here this } def remove(n: Int): MutableSet = { // Your Code Here this } } /** This is the ImmutableSet class. * * The add and remove methods should NOT modify the instance of * the set on which they are called. */ class ImmutableSet extends AbstractSet { // Your Code Here } trait LockingSet extends AbstractSet { abstract override def add(n: Int): AbstractSet = synchronized { super.add(n) } abstract override def remove(n: Int): AbstractSet = synchronized { super.remove(n) } abstract override def contains(n: Int): Boolean = synchronized { super.contains(n) } } trait LoggingSet extends AbstractSet { // Your Code Here } /*************************************************************** *************** BEGIN UNIT TESTING LIBRARY CODE *************** *************************************************************** * The following code defines a simple unit testing library for * MutableSet and ImmutableSet. It defines a simple "domain- * specific language" for testing sets of integers. * * You are not expected to understand this code. */ /** Takes an arbitrary number of tests and prints the result of * the tests. A big "FAILED" message should be printed if any * test fails. */ def asserting(tests: (String, Boolean)*) { tests.foreach { test => val msg = test._1 val pass_? = test._2 if (pass_?) println("Passed: " + msg) else println("FAILED: " + msg) } } /** The Numbers class represents a range of numbers. * * It defines some convenient utility methods to test * sets and see whether they have these numbers or not. */ class Numbers(nums: Iterable[Int]) extends Iterable[Int] { def containsNoneFrom_:(s: AbstractSet): Boolean = { ((nums map (s contains _)) exists (_ == true)) == false } def containsAllFrom_:(s: AbstractSet): Boolean = { ((nums map (s contains _)) exists (_ == false)) == false } def elements = nums.elements } /** These values define ranges of odd numbers, even numbers, * and all numbers. */ val allNumbers = new Numbers(1 to 10) val evenNumbers = new Numbers((1 to 10) filter (_ % 2 == 0)) val oddNumbers = new Numbers((1 to 10) filter (_ % 2 != 0)) /*************************************************************** **************** END UNIT TESTING LIBRARY CODE **************** ***************************************************************/ /** What follows are the unit tests for MutableSet and ImmutableSet. * This code uses the "domain-specific language" defined in the * unit testing library above. */ val m1 = new MutableSet val m2 = new MutableSet asserting ( "m1 contains no numbers" -> (m1 containsNoneFrom_: allNumbers), "m2 contains no numbers" -> (m2 containsNoneFrom_: allNumbers) ) val m3 = m1 addAll allNumbers asserting ( "m1 contains all numbers" -> (m1 containsAllFrom_: allNumbers), "m2 still contains no numbers" -> (m2 containsNoneFrom_: allNumbers), "m3 contains all numbers" -> (m3 containsAllFrom_: allNumbers) ) m3 addAll evenNumbers m3 removeAll evenNumbers asserting ( "m1 contains no even numbers" -> (m1 containsNoneFrom_: evenNumbers), "m1 contains all odd numbers" -> (m1 containsAllFrom_: oddNumbers), "m3 contains no even numbers" -> (m3 containsNoneFrom_: evenNumbers), "m3 contains all odd numbers" -> (m3 containsAllFrom_: oddNumbers) ) m2 addAll evenNumbers asserting ( "m2 contains all even numbers" -> (m2 containsAllFrom_: evenNumbers), "m2 contains no odd numbers" -> (m2 containsNoneFrom_: oddNumbers) ) val i1 = new ImmutableSet val i2 = new ImmutableSet asserting ( "i1 contains no numbers" -> (i1 containsNoneFrom_: allNumbers), "i2 contains no numbers" -> (i2 containsNoneFrom_: allNumbers) ) val i3 = i1 addAll allNumbers asserting ( "i1 still contains no numbers" -> (i1 containsNoneFrom_: allNumbers), "i3 contains all numbers" -> (i3 containsAllFrom_: allNumbers) ) val _i3 = i3 addAll evenNumbers val i4 = i3 removeAll evenNumbers val _i4 = _i3 removeAll evenNumbers asserting ( "i3 still contains all numbers" -> (i3 containsAllFrom_: allNumbers), "i4 contains no even numbers" -> (i4 containsNoneFrom_: evenNumbers), "i4 contains all odd numbers" -> (i4 containsAllFrom_: oddNumbers), "_i4 contains no even numbers" -> (_i4 containsNoneFrom_: evenNumbers), "_i4 contains all odd numbers" -> (_i4 containsAllFrom_: oddNumbers) ) val i5 = i2 addAll evenNumbers asserting ( "i2 still contains no numbers" -> (i2 containsNoneFrom_: allNumbers), "i5 contains all even numbers" -> (i5 containsAllFrom_: evenNumbers), "i5 contains no odd numbers" -> (i5 containsNoneFrom_: oddNumbers) ) ()