I’m defining a class BddNode
and I’d like to validate a relationship every time I construct a new instance. I have some ugly code which does the trick, but I’d guess there’s a prettier or more idiomatic way. I’d appreciate a suggestion to improve this.
Each time a new object of class BddNode
is constructed, two objects (positive
and negative
) of class Bdd
are given. These two given objects may be of class BddNode
in which case I want to assert that label < child.label
. But when a child is of class BddTerm
then no such assertion should be made for that child object.
Later on in the development of the project, I’m going to want to compare such objects often by label. I didn’t want to define <, >, and = methods because I thought it would be confusing (and cause problems) if such object are equal simply because they have the same label. Can I define < and > methods which compare the labels, while maintaining the semantics of = to really mean whether the objects are the same? Will the fact that a<b
is false and a>b
is false does not imply a=b
cause grief later on?
So I guess there are really two questions here:
- what is the best way to assert assumptions within the object constructor?
- can/should I redefine
<
and>
to have very different semantics than=
?
abstract class Bdd (ident:Int) {
}
object Bdd {
var count = 2
def nextCount():Int = {
count += 1
count - 1
}
}
case class BddNode(label:Int, positive:Bdd, negative:Bdd) extends Bdd(Bdd.nextCount()) {
// THIS METHOD IS UGLY
def validateChild(child:Bdd):Unit= {
// a BddTerm may be a child of any BddNode
// but if a BddNode is a child, then the ident of the child must be strictly > ident of parent
child match {
case child:BddNode => assert(child.label > label, "expecting child.label > this.label, got "+ child.label +">="+ label)
case _:BddTerm => Unit
}
}
validateChild(positive)
validateChild(negative)
override def toString = {
"{"+label+"+"+positive+"-"+negative+"}"
}
}
abstract class BddTerm(ident:Int) extends Bdd(ident) {
}
object BddTrue extends BddTerm(1) {
override def toString = "T"
}
object BddFalse extends BddTerm(0) {
override def toString = "F"
}
object BddTest {
def main(args:Array[String]):Unit = {
println("true = "+BddTrue)
println("false= "+BddFalse)
val bdd1 = BddNode(3,BddTrue,BddFalse)
val bdd2 = BddNode(2,BddFalse,BddTrue)
val bdd3 = BddNode(1,bdd1,bdd2)
println("node1 = "+bdd1)
println("node2 = "+bdd2)
println("node3 = "+bdd3)
}
}```