2010-08-16 55 views
2

我希望表達式(X-X)被簡化爲0簡化表達F#

type aexpr = 
| CstI of int 
| Var of string 
| Add of aexpr * aexpr 
| Sub of aexpr * aexpr 
| Mul of aexpr * aexpr;; 

let rec simplify expr = 
match expr with 
| Add(CstI(n1), CstI(n2)) ->CstI(n1 + n2) 
| Sub(CstI(n1), CstI(n2)) ->CstI(n1 - n2) 
| Mul(CstI(n1), CstI(n2)) ->CstI(n1 * n2) 
| Add(e, CstI(0)) -> simplify e 
| Add(CstI(0), e) -> simplify e 
| Sub(CstI(0), e) -> simplify e 
| Sub(e, CstI(0)) -> simplify e 
| Sub(Var(x1), Var(x2)) when x1.Equals(x2) -> CstI(0) // <- not working 
| Mul(CstI(0), e) -> CstI(0) 
| Mul(e, CstI(0)) -> CstI(0) 
| Mul(CstI(1), e) -> simplify e 
| Mul(e, CstI(1)) -> simplify e 
| _ -> expr;; 

這不這樣做。我沒有看到我做錯了什麼。希望你能幫助我:)

編輯: 它編譯好,但它什麼都不做。 IE瀏覽器。

let e = Mul(CstI(1), Add(CstI(4), Sub(Var("x"), Var("x"))));; 

在F#互動:

let result = simplify e;; 
val result : aexpr = Add (CstI 4,Sub (Var "x",Var "x")) 

結果應該是CstI 4

回答

6

simplify (Sub (Var "x", Var "x"))工作得很好。您的示例不起作用的原因是simplify不遍歷整個樹,因此樹的Sub (Var "x", Var "x")部分從未簡化過。

總之,您錯過了Sub (e,e) -> Sub (simplify e, simplify e)的情況,其他運營商也一樣。

+2

請注意,即使進行此更改,您可能需要運行多個通行才能獲得完全簡化的結果。例如。你最終希望減少'Sub(CstI 5,Add(CstI 1,CstI 2))'不僅僅是'Sub(CstI 5,CstI 3)',而是一直到'CstI 2'。 – kvb 2010-08-16 20:46:33

+0

好趕上!謝謝! – 2010-08-16 21:12:23

0

似乎在這裏工作。你沒有用字符串比較來處理一個區分大小寫的問題,對嗎?

+0

查看更新的問題。 – 2010-08-16 20:31:20