Question

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.

Was it helpful?

Solution

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]

OTHER TIPS

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].
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top