Simplify Expressions in Prolog

2020-07-26 11:50发布

问题:

I wanted to ask how I can simplify expressions like:

1+2+a*5+0/b-c*0
= 3+a*5

And especially how can I separate such expressions in lists.

回答1:

It's actually kind of fun in Prolog, because you don't need to do anything too magical to make it work.

?- X-Y = 1+2+a*5+0/b-c*0.
X = 1+2+a*5+0/b,
Y = c*0.

So you could start by doing something like this:

simplify(C, C) :- atom(C) ; number(C).
simplify(X+Y, X1+Y1) :- simplify(X, X1), simplify(Y, Y1).
simplify(X*Y, X1*Y1) :- simplify(X, X1), simplify(Y, Y1).
simplify(X/Y, X1/Y1) :- simplify(X, X1), simplify(Y, Y1).
simplify(X-Y, X1-Y1) :- simplify(X, X1), simplify(Y, Y1).

This is an identity transform: it doesn't do anything.

?- simplify(1+2+a*5+0/b-c*0, Result).
Result = 1+2+a*5+0/b-c*0.

Now you can add rules for specific cases:

simplify(X*0, 0).
simplify(0*X, 0).

Now you get multiple results:

?- simplify(1+2+a*5+0/b-c*0, Result).
Result = 1+2+a*5+0/b-c*0 ;
Result = 1+2+a*5+0/b-0 ;

You could add a rule for constant folding:

simplify(X+Y, C)     :- number(X), number(Y), C is X+Y.

You know, just have fun with it.

Lists aren't really any easier to work with, but you can make them using the "univ" operator: =..:

?- 1+2+a*5+0/b-c*0 =.. R.
R = [-, 1+2+a*5+0/b, c*0].


标签: prolog