0 prolog transitive-closure non-termination failure-slice
我想知道为什么在这些情况下程序会无限递归:
?- love(kay, amanda).
Run Code Online (Sandbox Code Playgroud)
和
?- love(rob, amanda).
Run Code Online (Sandbox Code Playgroud)
这是代码:
love(amanda, kay).
love(kay, geo).
love(geo, rob).
love(X, Y) :-
love(X, Z),
love(Z, Y).
love(X, Y) :-
love(Y, X).
Run Code Online (Sandbox Code Playgroud)
First, your program always goes into an infinite loop. No matter what names you are using. Even ?- loves(amanda, kay). loops. To better see this rather ask ?- loves(amanda, kay), false. Why am I so sure that your program always loops?
To see this, we need some falsework. By adding goals false into your program, we get a new program requiring less (or equal) inferences.
love(amanda, kay) :- false.
love(kay, geo) :- false.
love(geo, rob) :- false.
love(X, Y) :-
love(X, Z), false,
love(Z, Y).
love(X, Y) :- false,
love(Y, X).Run Code Online (Sandbox Code Playgroud)
Because this fragment (called a failure-slice) does not terminate, your original program will not terminate. As you can see, all the persons have been removed. And thus actual names cannot influence the outcome.
If you want to fix commutativity, rather introduce a further predicate:
love2(X, Y) :- love1(X, Y).
love2(X, Y) :- love1(Y, X).
Run Code Online (Sandbox Code Playgroud)
And to include the transitive closure, use closure/3:
love3(X, Y) :-
closure(love2, X, Y).
Run Code Online (Sandbox Code Playgroud)