Reputation: 443
i'm new in prolog, so i have done a program which have a method to query something, but when i use it, it keeps yielding results even when it should end.
amigos(juanarjona,omarpacheco).
amigos(juanarjona,jasonancona).
amigos(juanarjona,jorgebolio).
amigos(juanarjona,gerardoadrian).
amigos(Amigo,Amigoslista):-!,amigos(Amigoslista,Amigo).
for example, when i execute
amigos(X,juanarjona).
it should give me just this answers:
X = omarpacheco ; X = jasonancona ; X = jorgebolio ; X = gerardoadrian ;
but what it really do is to repeat those answers without end like this
X = omarpacheco ; X = jasonancona ; X = jorgebolio ; X = gerardoadrian ; X = omarpacheco ; X = jasonancona ; X = jorgebolio ; X = gerardoadrian . . . . . . . . . . . . (repeating)...........
so, that's why i'm recurring to you guys, i need to know how to establish a condition which do not let repeating the answers. Sorry for my bad english by the way.
I Forgot to say that it must be with just one predicate in this case "amigos"
Upvotes: 0
Views: 950
Reputation: 18726
It's easy: Use two predicates instead of one!
The first predicate comprises facts only:
amigos(juanarjona, omarpacheco). amigos(juanarjona, jasonancona). amigos(juanarjona, jorgebolio). amigos(juanarjona, gerardoadrian).
The second one—built on top of the first one—provides the symmetric closure1:
sym_amigos(X, Y) :- amigos(X, Y). sym_amigos(X, Y) :- amigos(Y, X).
Sample query using SICStus Prolog 4.3.2:
| ?- sym_amigos(P, Q). P = juanarjona, Q = omarpacheco ? ; P = juanarjona, Q = jasonancona ? ; P = juanarjona, Q = jorgebolio ? ; P = juanarjona, Q = gerardoadrian ? ; P = omarpacheco, Q = juanarjona ? ; P = jasonancona, Q = juanarjona ? ; P = jorgebolio, Q = juanarjona ? ; P = gerardoadrian, Q = juanarjona ? ; no
As your fact base gets larger and larger, looking at all the concrete answers gets tiresome... So, to check if sym_amigos/2
terminates universally, we can run a query like this one:
| ?- sym_amigos(P, Q), % looking for amigos ... false. % ... we discard every candidate solution. no % "no" means "terminates universally"
Above query can never yield any solution—after all, it is a conjunction with the goal false/0
:
no
—it does2—we know that sym_amigos/2
terminates universally.Footnote 1:
meta-predicate symm/2
covers the common idiom "symmetric closure".
Footnote 2: SWI-Prolog does not reply no
but false
instead.
Upvotes: 4