Вопрос

I used the following failure driven loop to list everything without using semicolons.

happiness(fred,5).
happiness(john,3).
happiness(grace,2).

someGoal(X) :-
        happiness(X,Y), write(Y), tab(4), fail.

In query mode, I get this as expected

?- someGoal(_).
5    3    2 

How can I insert these numbers into a list rather than writing them to screen? I could not handle this within someGoal since backtracking seems implicit.

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

Решение

You are right, backtracking it's the way Prolog handles alternatives.

Use findall/3, that collect all alternatives using backtracking 'internally':

someGoal(X, Values) :-
    findall(Value, happiness(X, Value), Values).

Then ?- someGoal(_, Values). will instance Values = [5, 3, 2]

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

Failure-driven loops often leave certain parts open and unspecified that sooner or later will cause some problems. In particular the precise quantification of variables is easily left open. Often, such loops can be avoided alltogether. In your example it is not clear to me why you have an argument to someGoal/1 at all. At least you do not use it. So several questions arise:

  1. What do you expect if there is no matching value? Your original program prints nothing and fails.

  2. What do you expect if there are redundant entries? Do you want things to be printed several times?

  3. Do you insist on the precise order of values, or could you imagine another order?

  4. Why are you interested in seeing the values at all? Most of the time you either want to see them associated with concrete names, or you want some aggregate of it, like the sum or average.

Given that I do not know the answer to these, I can offer you several solutions. I will take your example with one additional (redundant) fact:

happiness(fred,5).
happiness(john,3).
happiness(john,3).
happiness(grace,2).

?- setof(P-H,happiness(P,H), PHs).
PHs = [fred-5, grace-2, john-3].

?- setof(H,P^happiness(P,H), PHs).
PHs = [2, 3, 5].

?- bagof(H,P^happiness(P,H), PHs).
PHs = [5, 3, 3, 2].
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top