2010-08-16 5 views
2

Je veux l'expression (x-x) à être simplifiée à 0.simplifier l'expression 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;; 

Cela ne le fait pas. Je ne vois pas ce que je fais de mal. J'espère que vous pouvez m'aider :)

Editer: Compile bien mais ne fait rien. C'est à dire.

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

En f # interactive:

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

Résultat devrait être CstI 4

Répondre

6

simplify (Sub (Var "x", Var "x")) fonctionne très bien. La raison pour laquelle votre exemple ne fonctionne pas est que simplify ne traverse pas l'arbre entier, donc la partie Sub (Var "x", Var "x") de l'arbre n'est jamais simplifiée.

En bref, il vous manque un cas Sub (e,e) -> Sub (simplify e, simplify e) et le même pour les autres opérateurs.

+2

Notez que même avec cette modification, vous devrez peut-être exécuter plusieurs passes pour obtenir un résultat entièrement simplifié. Par exemple. vous voudriez finalement réduire 'Sub (CstI 5, Add (CstI 1, CstI 2))' pas seulement 'Sub (CstI 5, CstI 3)', mais tout le chemin 'CstI 2'. – kvb

+0

Bonne prise! Merci! –

0

Il semble fonctionner ici. Vous n'êtes pas confronté à un problème de sensibilité à la casse avec la comparaison de chaînes, n'est-ce pas?

+0

Voir la question mise à jour. –