我认为这在Scala by Example 一书中以 PDF 形式提供,可从 scala lang 网站获得(参见第 7 章)。我的建议是使用案例类来表示您的表达式,然后使用模式匹配来简化表达式:
首先,让我们定义一个表达式特征,用于表示各种表达式。
scala> trait Expr { def simplify:Expr = this }
defined trait Expr
在这里,我让 Expr trait 实现了一个默认simplify
方法,该方法只返回扩展 trait 的对象。所以让我们添加一些简单的表达式:
scala> case object True extends Expr
defined module True
scala> case object False extends Expr
defined module False
scala> case class Var(name:String) extends Expr { override def toString = name }
defined class Var
True
并在你的例子中False
代表1
和。将用于表示尚无真值的变量,例如您的示例中的 x、y、a 和 b。Var 还覆盖了使打印输出更漂亮的方法:)nil
Var
toString
现在来看看和/或有点棘手的情况。让我们定义这些:
scala> case class And(a:Expr, b:Expr) extends Expr {
| override def simplify = (a.simplify, b.simplify) match {
| case (True,x) => x
| case (x,True) => x
| case (False,x) => False
| case (x,False) => False
| case (x,y) => And(x,y)
| }
| }
defined class And
scala> case class Or(a:Expr, b:Expr) extends Expr {
| override def simplify = (a.simplify, b.simplify) match {
| case (True,x) => True
| case (x,True) => True
| case (False,x) => x
| case (x,False) => x
| case (x,y) => Or(x,y)
| }
| }
defined class Or
And
并且Or
都覆盖特征中的simplify
方法Expr
并返回其自身及其子表达式的简化版本。现在,这些可用于构建表达式以及更简单的 True、False 和 Var 表达式:
scala> val X = Var("X"); val Y = Var("Y"); val A = Var("A"); val B = Var("B")
X: Var = X
Y: Var = Y
A: Var = A
B: Var = B
scala> And(X, True).simplify
res10: Expr = X
scala> And(X, And(Y, False)).simplify
res11: Expr = False
scala> And(X, Or(Y, False)).simplify
res12: Expr = And(X,Y)
scala> Or(True, And(X, Or(Y, False))).simplify
res13: Expr = True
最后我们为 not 添加一个表达式:
scala> case class Not(a:Expr) extends Expr {
| override def simplify = a.simplify match {
| case True => False
| case False => True
| case And(x,y) => Or(Not(x),Not(y))
| case Or(x,y) => And(Not(x),Not(y))
| case Not(x) => x
| case x => Not(x)
| }
| }
defined class Not
现在我们可以表示您示例中的表达式。但是对于某些表达式,这个 Not case 类不会做一个完整的简化,例如
scala> Not(Or(Not(X),Y)).simplify
res41: Expr = And(Not(Not(X)),Not(Y))
所以我们可以定义一个递归函数Not
来尝试简化表达式,直到它不能再简化它:
scala> case class Not(a:Expr) extends Expr {
| override def simplify = recursiveSimplify(a, a)
| private def recursiveSimplify(curExpr:Expr, lastExpr:Expr):Expr = if(curExpr != lastExpr) {
| val newExpr = curExpr.simplify match {
| case True => False
| case False => True
| case Var(x) => Not(Var(x))
| case Not(x) => x
| case And(x,y) => Or(Not(x), Not(y))
| case Or(x,y) => And(Not(x), Not(y))
| }
| recursiveSimplify(newExpr, curExpr)
| } else {
| lastExpr
| }
| }
defined class Not
现在前面的表达式简化为:
scala> Not(Or(Not(X),Y)).simplify
res42: Expr = Or(Not(X),Y)