开发者

Prolog predicate defined as boolean OR of 2 goals?

I'm wondering how to make a predicate in Prolog which evaluates to "true" if eit开发者_运维百科her one of its goals is provable.

I have this program:

adjacent(place1, place2).
distance(X, Y, 1) :-
    adjacent(X, Y) ; adjacent(Y, X).

After consulting it into Prolog, if I type:

> distance(place1, place2, 1)

I receive this output:

true;
false.

I'm wondering if there is a way to make a distance predicate which just returns a single answer of "true" if either of adjacent(X, Y) or adjacent(Y, X) is provable.

Forgive me if anything in this post is confusing, I don't have the best understanding of Prolog, but hopefully this question is understandable. Thanks.


You can use the once/1 predicate to make sure that there is no backtracking.

The disjunction operator ; introduces the possibility of backtracking, which is why Prolog will wait for you to tell it to explore any further solutions there might be.

once is defined in terms of the "cut" (!) which throws away any previous backtracking "choice-points" there might be. It could be worth reading up on cut.


btw, the predicate evaluates as true. the next answer is because you ask prolog for alternate answers (different ways to get the result etc) and prolog ofc says that false, there are no other ways.

basically you dont really have to worry about it unless you specifically want to have just one answer (interface).

in that case, you should use cut/once.


An explanation of why once/1 can check if any goals are true. To expand on Nick's answer.

Seen below, once finds the fact that evaluates to true no matter where it is and stops immediately.

% undesired behaviour
?- false;true;true.
true ;
true.
% desired behaviour
?- once(false;true;true).
true.

Let's look at Prolog's implementation of once

once(Goal) :-
    call(Goal),
    !.

Wow, that was simple. What does ! do?

Discard all choice points created since entering the predicate in which the cut appears. In other words, commit to the clause in which the cut appears and discard choice points that have been created by goals to the left of the cut in the current clause. According to SWI-Prolog documentation

In simple terms ! prevents backtracking upon success. When Prolog sees the first false, it backtracks to check if true could be found, when it found the first true, it is satisfied and stops because of !.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜