Serberuss
Serberuss

Reputation: 2387

Prolog - Simplifying rules or statements

I've been looking at ways in which Prolog can automatically simplify statements. This is because I am planning to receive Prolog statements from an external source and won't necessarily be manually created.

I've seen from questions such as this: Simplify Expressions in Prolog that mathematical expressions can be simplified and Prolog handles that quite well.

However I'm wondering if it can do something else. Consider the following:

and(X, Y) :- X, Y.

simplified(X) :- X.

?- simplified(and(5 > 3, 5 > 3)).

In this example I have a simple and statement that takes in two values. In this example though the two statements are the same and so are pointless. I'm wondering if Prolog has a way or if there is a way of detecting this to remove it so that it only evaluates the statement once instead of twice thus simplifying the call that it needs to do.

I hope that makes sense and I realise that the question is probably a bit of a weird one but there is a specific reason I have for wanting to know this and plan to do something more complicated later on if it is possible.

Thanks in advance.

Upvotes: 0

Views: 365

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476574

You could construct a predicate that simplifies the expression.

For example we know that and(X, Y) where X and Y are equal, is equal to X itself.

So we can write a predicate like:

simplify(and(X1, X2), Y1) :-
    simplify(X1, Y1),
    simplify(X2, Y2),
    Y1 == Y2,
    !.
simplify(or(X1, X2), Y1) :-
    simplify(X1, Y2),
    simplify(X2, Y1),
    Y1 == Y2,
    !.
simplify(not(not(X)), Y) :-
    simplify(X, Y),
    !.
 simplify(X, X).

Here we thus define three rules: and(X, X) is equal to X, or(X, X) is equal to X, and not(not(X)) is equal to X. We make extra calls since it is possible to have not(not(and(3 < 5, 3 < 5))), so we still want to simplify the inner value. We then thus obtain:

?- simplify(not(not(and(3 < 5, 3 < 5))), X).
X =  (3<5).

Other items can be added (before the last clause in the previous code fragment) like:

simplify(X > Y, S) :-
    simplify(Y < X, S).

simplify(X >= Y, S) :-
    simplify(Y =< X, S).

Such that for example and(5 < 3, 3 > 5) is simplified to 3 < 5 as well.

Upvotes: 1

Related Questions