Jason
Jason

Reputation: 443

How to make a condition to end the query in prolog?

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

Answers (1)

repeat
repeat

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:

  • It can, however, tell us if the above goal terminates universally.
  • If Prolog returns no—it does2—we know that sym_amigos/2 terminates universally.

Footnote 1: symm/2 covers the common idiom "symmetric closure".
Footnote 2: SWI-Prolog does not reply no but false instead.

Upvotes: 4

Related Questions