如何在Scala中利用分布性规则实现表达式的简化?
我想编写一个scala程序,使用分配性规则简化这个数学表达式: a*b+a*c=a(b+c) 为了解决此示例,我快速编写了以下代码:如何在Scala中利用分布性规则实现表达式的简化?,scala,pattern-matching,Scala,Pattern Matching,我想编写一个scala程序,使用分配性规则简化这个数学表达式: a*b+a*c=a(b+c) 为了解决此示例,我快速编写了以下代码: object Test { sealed abstract class Expr case class Var(name: String) extends Expr case class BinOp(operator: String, left: Expr, right: Expr) extends Expr def main(args:
object Test {
sealed abstract class Expr
case class Var(name: String) extends Expr
case class BinOp(operator: String, left: Expr, right: Expr) extends Expr
def main(args: Array[String]) {
val expr = BinOp("+", BinOp("*", Var("a"), Var("b")), BinOp("*", Var("a"), Var("c")))
println(simplify(expr)) //outputs "a(b + c)"
}
def simplify(expr: Expr) : String = expr match {
case BinOp("+", BinOp("*", Var(x), Var(a)), BinOp("*", Var(y), Var(b))) if (x == y) => "" + x + "*(" + a + " + " + b + ")"
case _ => "" //no matter for the test since I test the first case statically
}
}
有没有更好的方法来实现这一点
管理操作数顺序的最佳方法是什么,而不必为每个组合重复大小写(会很难看?事实上,这些表达方式是什么
a*b+a*c=a(b+c)
a*b+c*a=a(b+c)
b*a+a*c=a(b+c)
b*a+c*a=a(b+c)如果
Expr
保持交换律,则必须
def simplify(expr: Expr) : String = expr match {
case expr @ BinOp("+", BinOp("*", Var(x), Var(a)), BinOp("*", Var(y), Var(b))) => {
def another(that: String) = {
Seq((x, a), (a, x)) find (_._1 == that) map (_._2)
}
val byY = another(y).map(z => BinOp("+", Var(y), BinOp("*", Var(z), Var(b)))) // combine by y
val byB = another(b).map(z => BinOp("+", Var(b), BinOp("*", Var(z), Var(y)))) // combine by b
(byY orElse byB getOrElse expr).toString
}
case _ => "" //no matter for the test since I test the first case statically
}
byY
和byB
具有相同的结构。这不是最好的,您可能会重用一些代码:P如果
Expr
保持交换律,它必须是
def simplify(expr: Expr) : String = expr match {
case expr @ BinOp("+", BinOp("*", Var(x), Var(a)), BinOp("*", Var(y), Var(b))) => {
def another(that: String) = {
Seq((x, a), (a, x)) find (_._1 == that) map (_._2)
}
val byY = another(y).map(z => BinOp("+", Var(y), BinOp("*", Var(z), Var(b)))) // combine by y
val byB = another(b).map(z => BinOp("+", Var(b), BinOp("*", Var(z), Var(y)))) // combine by b
(byY orElse byB getOrElse expr).toString
}
case _ => "" //no matter for the test since I test the first case statically
}
byY
和byB
具有相同的结构。这不是最好的,您可能会重用一些代码:P如果首先将交换规则应用于所有+
和*
链,使操作数按字母顺序排列,该怎么办?对于所有交换等价的表达式,总是有一个唯一的表达式。您也可以将其扩展到用于组,只需抽象地将整个表达式本身视为一个“单词”(Unicode排序)。如果您首先将交换规则应用于所有+
和*
链,使操作数按字母顺序排列,该怎么办?对于所有交换等价的表达式,总是有一个唯一的表达式。您也可以将其扩展到用于组,只需抽象地将整个表达式本身看作一个“单词”(Unicode排序)。