如何简化基本算术表达式?
e.g。
module ExprOps where
simplify :: Expr -> Expr
simplify (Plus(Var"x") (Const 0)) = Var "x"
我该怎么做?
module Expr where
-- Variables are named by strings, assumed to be identifiers.
type Variable = String
-- Representation of expressions.
data Expr = Const Integer
| Var Variable
| Plus Expr Expr
| Minus Expr Expr
| Mult Expr Expr
deriving (Eq, Show)
我想到的简化是:
0*e = e*0 = 0
1*e = e*1 = 0+e = e+0 = e-0 = e
并简化常量子表达式,例如:加(Const 1)(Const 2)将成为Const 3.我不希望连接变量(或变量和常量):Var“st”是Var“s”的不同变量。
我想要实现的是创建一个类似上面的模块,它使用一个名为simplify :: Expr->Expr
的函数
答案 0 :(得分:11)
嗯,你有正确的通用模型。您只需要更多规则并递归应用简化过程。
simplify :: Expr -> Expr
simplify (Mult (Const 0) x) = Const 0
simplify (Mult x (Const 0)) = Const 0
simplify (Plus (Const 0) x) = simplify x
simplify (Plus x (Const 0)) = simplify x
simplify (Mult (Const 1) x) = simplify x
simplify (Mult x (Const 1)) = simplify x
simplify (Minus x (Const 0)) = simpify x
simplify (Plus (Const x) (Const y)) = Const (x + y)
simplify (Minus (Const x) (Const y)) = Const (x - y)
simplify (Mult (Const x) (Const y)) = Const (x * y)
simplify x = x
答案 1 :(得分:1)
几十年前,我做了类似这样的AI类项目。 该类使用了LISP,所以我做的第一件事就是将表达式从中缀表示法转换为S表达式。
然后,这是一个递归地遍历“树”并在每个节点处应用一组规则的问题。例如如果此节点包含操作数均为常量的操作,请立即执行操作并将结果替换为该节点。
一旦基本功能到位,就需要向系统添加新的简化规则。
最后,S-Expression被转换回中缀符号以供显示。
答案 2 :(得分:1)
只是举个例子,这是一个简化你给出的表达式的函数。我们的想法是,从上到下尝试每个简化定义,直到等号左侧的一个模式匹配为止。如果没有任何已知的方法可以进一步简化,最后一个定义的目的是打破递归。
simplify :: Expr -> Expr
simplify (Plus l (Const 0)) = simplify l
simplify (Plus (Const 0) r ) = simplify r
simplify x = x
答案 3 :(得分:0)
我们是否在谈论理性,如GMP的理性?如果是这样,那么可以通过将第二个参数变为其倒数然后乘以来简化除法。
除此之外,乘法是多次加法,除法是多次减法。
正如米奇在评论中所说,我们可以提供一些关于你想要简化的更多信息。