我正在尝试用 Haskell 实现一种算法来操作数学表达式。我有这个数据类型:
data Exp = Var String | IVal Int | Add Exp Exp
这对我的问题来说已经足够了。
给定一组表达式转换,例如:
(加 ab) => (加 b)
(加 (加 ab) c) => (加 a (加 bc))
和一个表达式,例如:x = (Add (Add xy) (Add zt)),我想找到x附近的所有表达式。假设 x 的邻域定义为: y in Neighborhood(x) 如果 y 可以在单个变换内从 x 到达。
我是 Haskell 的新手。我什至不确定 Haskell 是否适合这项工作。
最终目标是获得一个函数:等效 x,它返回一组与 x 等效的所有表达式。换句话说,在 x 的邻域的闭包中的所有表达式的集合(给定一组变换)。
现在,我有以下内容:
import Data.List(nub)
import Data.Set
data Exp = IVal Int
| Scalar String
| Add Exp Exp
deriving (Show, Eq, Ord)
commu (Add a b) = (Add b a)
commu x = x
assoc (Add (Add a b) c) = (Add a (Add b c))
assoc (Add a (Add b c)) = (Add (Add a b) c)
assoc x = x
neighbors x = [commu x, assoc x]
equiv :: [Exp] -> [Exp]
equiv closure
| closure == closureUntilNow = closure
| otherwise = equiv closureUntilNow
where closureUntilNow = nub $ closure ++ concat [neighbors x|x<-closure]
但它可能比需要的慢(nub 是 O(n^2))并且缺少一些术语。
例如,如果你有 f = (x+y)+z,那么,你将不会得到 (x+z)+y,还有一些其他的。