diff --git a/.classpath b/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..f8c97a1a50c241bde37add8a04026001a5c71ea6 --- /dev/null +++ b/.classpath @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="src" path="tests"/> + <classpathentry kind="src" path="examples"/> + <classpathentry kind="con" path="ch.epfl.lamp.sdt.launching.SCALA_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="lib" path="/usr/local/scala/lib/scala-compiler.jar" sourcepath="/usr/local/scala/src/scala-compiler-src.jar"/> + <classpathentry kind="lib" path="lib/scalatest-0.9.5.jar"/> + <classpathentry kind="lib" path="lib/specs-1.5.0.jar"/> + <classpathentry kind="lib" path="lib/ScalaCheck-1.5.jar" sourcepath="lib/ScalaCheck-1.5-src.jar"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/.project b/.project new file mode 100644 index 0000000000000000000000000000000000000000..53529d627c0b2637d820297752aebcafb12c5757 --- /dev/null +++ b/.project @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>funcheck</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>ch.epfl.lamp.sdt.core.scalabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>ch.epfl.lamp.sdt.core.scalanature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/examples/funpm/logic/DPLL.scala b/examples/funpm/logic/DPLL.scala index 0a559139acf14d14c062de2d8ce19c4524b32a5d..b9004b6f67fde8817a4d8f844e0027f590c501b7 100644 --- a/examples/funpm/logic/DPLL.scala +++ b/examples/funpm/logic/DPLL.scala @@ -32,7 +32,7 @@ object DPLL { /** * Finds the unit literals in a formula */ - def find_one_literals( cs : ClauseSet) : Set[Literal] = + def find_one_literals( cs : ClauseSet) : Clause = new ListSet() ++ (cs.flatMap(c => if( c.size == 1) List(c.toArray(0)) else Nil)).elements diff --git a/lib/ScalaCheck-1.5-src.jar b/lib/ScalaCheck-1.5-src.jar new file mode 100644 index 0000000000000000000000000000000000000000..49771420824b55e95a835af1c76eef4338248f8a Binary files /dev/null and b/lib/ScalaCheck-1.5-src.jar differ diff --git a/lib/specs-1.5.0.jar b/lib/specs-1.5.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..25439fbabfdd6db2a5f3f3499b2752efefb94544 Binary files /dev/null and b/lib/specs-1.5.0.jar differ diff --git a/src/scala/collection/Multiset.scala b/src/scala/collection/Multiset.scala index 448b558e9f78d42ac9e93249b73a51612eca44ff..c506a7323ddc5cc00feacde4893afa10b93f5994 100644 --- a/src/scala/collection/Multiset.scala +++ b/src/scala/collection/Multiset.scala @@ -53,6 +53,9 @@ trait Multiset[A] extends (A => Int) with Collection[A]{ */ def ** (that: Multiset[A]): Multiset[A] + /** @return this multiset as set. */ + def asSet: Set[A] + //structural equality /** Compares this multiset with another object and returns true, iff the diff --git a/src/scala/collection/immutable/EmptyMultiset.scala b/src/scala/collection/immutable/EmptyMultiset.scala index 803f9a7677e3f407e69cfaeb5488be718781481e..c688a80f35626282b9dd2b8f9a01b4110a15a54c 100644 --- a/src/scala/collection/immutable/EmptyMultiset.scala +++ b/src/scala/collection/immutable/EmptyMultiset.scala @@ -19,4 +19,6 @@ class EmptyMultiset[A] extends Multiset[A] with Helper[A]{ override def --(elems: Iterable[A]): Multiset[A] = empty override def elements: Iterator[A] = Iterator.empty + + override def asSet: Set[A] = new EmptySet[A] } diff --git a/src/scala/collection/immutable/HashMultiset.scala b/src/scala/collection/immutable/HashMultiset.scala index 1cfdd1b501bcadd8d0a060d758d5720259abb524..2f10c0ba9f1af873b85a9d998c3af12459f837e0 100644 --- a/src/scala/collection/immutable/HashMultiset.scala +++ b/src/scala/collection/immutable/HashMultiset.scala @@ -18,27 +18,25 @@ class HashMultiset[A] private[immutable] (private val map: Map[A,Int]) extends M override def apply(elem: A): Int = map.getOrElse(elem,0) override def intersect (that: collection.Multiset[A]): Multiset[A] = { - def inner(entries: List[A], result: Multiset[A]): Multiset[A] = entries match { + def inner(entries: List[A], result: Map[A,Int]): Map[A,Int] = entries match { case Nil => result - case elem :: rest => - assert(!result.contains(elem)) - inner(rest, result ++ int2list(elem, min(this(elem),that(elem)))) + case elem :: rest => inner(rest, result.update(elem, min(this(elem),that(elem)))) } - inner(this.toList,empty) + new HashMultiset[A](inner(asSet.toList,new HashMap[A,Int].empty)) } override def ++ (elems: Iterable[A]): Multiset[A] = { - val that: Multiset[A] = iterable2multiset(elems) - def inner(entries: List[A], result: Multiset[A]): Multiset[A] = entries match { + val that = iterable2multiset(elems) + + def inner(entries: List[A], result: Map[A,Int]): Map[A,Int] = entries match { case Nil => result case elem :: rest => - assert(!result.contains(elem)) - result ++ (int2list(elem,max(this(elem),that(elem)))) + inner(rest, result.update(elem,max(result.getOrElse(elem,0),that(elem)))) } - inner(elems.toList, empty) + new HashMultiset[A](inner(that.asSet.toList, map)) } @@ -52,18 +50,18 @@ class HashMultiset[A] private[immutable] (private val map: Map[A,Int]) extends M } override def --(elems: Iterable[A]): Multiset[A] = { + val that = iterable2multiset(elems) def inner(entries: List[A], result: Map[A,Int]): Map[A,Int] = entries match { case Nil => result case elem :: rest => - result.get(elem) match { - case None => inner(rest,result) - case Some(n) => - assert (n > 0) - inner(rest, result.update(elem,n-1)) - } + val diff = result.getOrElse(elem,0) - that(elem) + if(diff > 0) + inner(rest, result.update(elem,diff)) + else + inner(rest, result - elem) } - new HashMultiset[A](inner(elems.toList,map)) + new HashMultiset[A](inner(that.asSet.toList,map)) } override def elements: Iterator[A] = { @@ -76,4 +74,6 @@ class HashMultiset[A] private[immutable] (private val map: Map[A,Int]) extends M inner(map.keys.toList, Nil).elements } + override def asSet: Set[A] = HashSet.empty[A] ++ map.keys + } diff --git a/src/scala/collection/immutable/Multiset.scala b/src/scala/collection/immutable/Multiset.scala index 0010e48cc163dfbb8ec3548aeec77a0542233f76..6a4c89d85c888a154179de29e7f6e0270d440126 100644 --- a/src/scala/collection/immutable/Multiset.scala +++ b/src/scala/collection/immutable/Multiset.scala @@ -40,5 +40,4 @@ trait Multiset[A] extends AnyRef with collection.Multiset[A]{ // A \ {elems} final def - (elems: A*): Multiset[A] = this -- elems - } diff --git a/tests/scalatest/examples/MultisetSpec.scala b/tests/scalatest/examples/MultisetSpec.scala index b51266fa851ec0068d627f95a63c100aca262881..24a5498ad4dfb346ad092bbe1f3d72d10e108ffd 100644 --- a/tests/scalatest/examples/MultisetSpec.scala +++ b/tests/scalatest/examples/MultisetSpec.scala @@ -43,11 +43,11 @@ class MultisetSpec extends Spec with ShouldMatchers { filled1 should equal (filled2) } - it("should held be empty if intersected with an empty multiset") { + it("should held be empty if intersected with an empty multiset.") { val mset = HashMultiset(1,1,2) val empty = HashMultiset.empty[Int] - + //check that "**" and "intersect" are indeed alias one of the other (empty ** empty) should equal (empty) (empty intersect empty) should equal (empty) @@ -58,6 +58,35 @@ class MultisetSpec extends Spec with ShouldMatchers { (mset intersect empty) should equal (empty) } + it("should not change when interseced/unified with itself.") { + val mset = HashMultiset(1,1,2,0,3) + + (mset ** mset) should equal (mset) + (mset ++ mset) should equal (mset) + } + + it("should decrease the cardinality of an element when removed.") { + val mset = HashMultiset(1,2,1) + + (mset -- List(1)) should equal (HashMultiset(1,2)) + (mset -- List(1)) should equal (HashMultiset(2,1)) + (mset -- List(1,2)) should equal (HashMultiset(1)) + (mset -- List(1,1,2)) should be ('empty) + + ((mset -- List(1)).apply(1)) should be (1) + ((mset -- List(1)).apply(2)) should be (1) + ((mset -- List(2)).apply(1)) should be (2) + (mset -- List(1,1,2)) should not contain (0) + } + it("should never contains an element with cardinality lower than zero.") { + val mset = HashMultiset(1) + + (mset -- List(1)) should be ('empty) + (mset -- List(1,1)) should be ('empty) + (mset -- List(1,1)) should not contain (0) + + ((mset -- List(1,1)) ++ List(1)) should contain (1) + } } }