I want to create generators (for ScalaCheck) to generate propositional formula. If I create a generator to generate formulas with the variable and and-logic operator (example: A and B) all is right. But if i add or, implies and not, ScalaCheck generates Exception: java.lang.StackOverflowError
.
import org.scalacheck.Prop
import org.scalacheck.Properties
import org.scalacheck.Gen
object FormulaWffSpecification extends Properties("FormulaWff") {
abstract class FormulaWff {
def size: Int
def depths: Int
}
case class And(left: FormulaWff, right: FormulaWff) extends FormulaWff
case class Or(left: FormulaWff, right: FormulaWff) extends FormulaWff
case class Implies(left: FormulaWff, right: FormulaWff) extends FormulaWff
case class Not(son: FormulaWff) extends FormulaWff
case class Var(string: String) extends FormulaWff
val genAnd = for {
left <- myGenFormula
right <- myGenFormula
} yield And(left, right)
val genOr = for {
left <- myGenFormula
right <- myGenFormula
} yield Or(left, right)
val genImplies = for {
left <- myGenFormula
right <- myGenFormula
} yield Implies(left, right)
val genNot = for {
son <- myGenFormula
} yield Not(son)
val genVar = Gen.oneOf(Var("A"),Var("B"))
def myGenFormula: Gen[FormulaWff] =
Gen.lzy(Gen.oneOf(genVar, genAnd, genImplies, genOr, genNot))
property("size(t) <= 2^(depths(t) + 1) - 1") = {
Prop.forAll(myGenFormula) { f: FormulaWff =>
f.size <= Math.pow(2, f.depths + 1) - 1
}
}
}