Вопрос

i write this programm for give me this result : "X=john" "Y=jane"

likes(john,mary).
likes(mary,jane).
likes(l,k).

likes(X,Y) :- likes(X,Z), likes(Z,Y).

but if run this programm such that this result: i think the programm get in loop ! i want to stop after true answer !

1 ?- likes(X,Y).
X = john,
Y = mary ;
X = mary,
Y = jane ;
X = l,
Y = k ;
X = john,
Y = jane ;
ERROR: Out of local stack

i have the error ! how solving this problem ?

by debugging :

[debug] 3 ?- likes(john,Y).
 T Call: (6) likes(john, _G2162)
 T Exit: (6) likes(john, mary)
Y = mary ;
 T Redo: (6) likes(john, _G2162)
 T Call: (7) likes(john, _G2267)
 T Exit: (7) likes(john, mary)
 T Call: (7) likes(mary, _G2162)
 T Exit: (7) likes(mary, jane)
 T Exit: (6) likes(john, jane)
Y = jane ;
 T Redo: (7) likes(mary, _G2162)
 T Call: (8) likes(mary, _G2267)
 T Exit: (8) likes(mary, jane)
 T Call: (8) likes(jane, _G2162)
 T Call: (9) likes(jane, _G2267)
 T Call: (10) likes(jane, _G2267)
 T Call: (11) likes(jane, _G2267)
 T Call: (12) likes(jane, _G2267)
 T Call: (13) likes(jane, _G2267)
 T Call: (14) likes(jane, _G2267)
 T Call: (15) likes(jane, _G2267)

and so on .. why likes(jane, _G2267) ??????

Это было полезно?

Решение 3

Your code:

likes(john,mary).          % {1}
likes(mary,jane).          % {2}
likes(l,k).                % {3}

likes(X,Y) :-              % {4}
    likes(X,Z),            % {5} 
    likes(Z,Y).            % {6}

The query likes(john,Y) proceeds as follows:

likes(john,Y)? 
%% {1}  Y = mary.        ; redo
%% {4}  likes(john,Y) :-
   %% {5}  likes(john,Z)?
      %% {1}  Z=mary.
   %% {6}  likes(mary,Y)?
      %% {2}  Y=jane.        ; redo
      %% {4}  likes(mary,Y) :-
         %% {5}  likes(mary,Z2)?
            %% {2}  Z2=jane,
         %% {6}  likes(jane,Y)?
            %% {4}  likes(jane,Y):-
               %% {5}  likes(jane,Z3)?
                  %% {4}  likes(jane,Z3):-
                     %% {5}  likes(jane,Z4)?
                     ............

and that's what you see in the debugger.

To prevent this behaviour, rename your transitive closure predicate, as follows:

likes(john,mary).          % {1b}
likes(mary,jane).          % {2b}
likes(l,k).                % {3b}

pals(X,Y) :-               % {4b}
    likes(X,Z),            % {5b} 
    pals(Z,Y).             % {6b}

Другие советы

If you need "X=john" "Y=jane" then you have to rename:

likes(X,Y) :- likes(X,Z), likes(Z,Y).

for other name, example:

likestransitive(X,Y) :- likes(X,Z), likes(Z,Y).

Thus you can obtain the solution that you need:

1 ?- transitivelikes(X,Y).    
X = john,    
Y = jane;    
false.

Your query (both X and Y are variables) is far too "broad" for the way you defined likes/2

Try

?- likes(john, Y).

What does the prolog engine do? Well, it searches in its facts database.


First it finds that (1st rule)

likes(john, mary).

so john likes mary.


Then it finds that

likes(john,Y) :-
    likes(john,Z),
    likes(Z,Y).

so it asks itself: for what Z is it true that likes(john,Z)? Well, the database says that likes(john, mary), so Z = mary. Let's put it in the rule:

likes(john,Y) :-
    likes(john,mary),
    likes(mary,Y).

so it asks itself: for what Y is it true that likes(mary,Y)? Well, the database says that likes(mary, jane), so Y = jane. Let's put it in the rule:

likes(john,jane) :-
    likes(john,mary),
    likes(mary,jane).

so john likes jane.


Now we have a problem. Look closely to the second query:

likes(john,Y) :-
    likes(john,Z),
    .....

uh-oh.

John likes someone if john likes someone (and, .....)

well, on the first try we were lucky: the Prolog engine found Y = jane, Z = mary because we have the following rules

likes(john,mary).
likes(mary,jane).

and it stopped. But then it asked itself, again:

likes(john,Y) ?

we already used the first two rules, so let's try with the third one:

likes(X,Y) :-
    likes(X,Z),
    likes(Z,Y).

troubles!

likes(john,Someone) :-
    likes(john,Someone2), ..... 

likes(john,Someone2) :-
    likes(john,Someone3), .....

likes(john,Someone3) :-
    likes(john,Someone4), .....

and so on..

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top