'How can I define Prolog rule to achieve bidirectional query?
I have defined
double(X,Y) :- Y is X*2.
and when I query double(3,Y), I get Y=6.
But when I query double(X,6), I cannot get X=3.
Is it possible to define a rule that works in both directions?
Solution 1:[1]
I would probably do something like this:
double(X,Y) :- nonvar(X), Y is X * 2 .
double(X,Y) :- nonvar(Y), X is Y / 2 .
Though that does leave you with the possibility of getting 2 solutions when both arguments are instantiated (double(3,1.5). will succeed twice).
You could fix that in a number of ways:
Using a cut to eliminate the extraneous choice point.
double(X,Y) :- nonvar(X), Y is X * 2 , ! . double(X,Y) :- nonvar(Y), X is Y / 2 .Adding an additional type check.
double(X,Y) :- nonvar(X), var(Y), Y is X * 2 . double(X,Y) :- nonvar(Y), X is Y / 2 .Or more:
double(X,Y) :- nonvar(X), nonvar(Y), X =:= Y . double(X,Y) :- nonvar(X), var(Y), Y is X * 2 . double(X,Y) :- var(X), nonvar(Y), X is Y / 2 .If you went that route, one could add a 4th case, if you wanted, that would produce an infinite sequence of numbers and their doubles:
double(X,Y) :- nonvar(X), nonvar(Y), X =:= Y . double(X,Y) :- nonvar(X), var(Y), Y is X * 2 . double(X,Y) :- var(X), nonvar(Y), X is Y / 2 . double(X,Y) :- var(X), var(Y), between(0,infinity), Y is X * 2.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Nicholas Carey |
