数式を操作するアルゴリズムを Haskell で実装しようとしています。私はこのデータ型を持っています:
data Exp = Var String | IVal Int | Add Exp Exp
私の質問にはこれで十分です。
一連の式変換が与えられた場合、たとえば次のようになります。
(ab を追加) => (ba を追加)
(Add (Add ab) c) => (Add a (Add bc))
x = (Add (Add xy) (Add zt)) のような式で、x の近傍にあるすべての式を見つけたいと考えています。x の近傍が y in Neighborhood(x) として定義されている場合、x から 1 回の変換で y に到達できる場合。
私は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 などは得られません。