Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prolog: Failure driven loops

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.

like image 301
Zoran Avatar asked Oct 24 '12 20:10

Zoran


People also ask

Can fail predicate be used for looping in Prolog?

Well, Prolog automatically tries to backtrack when it fails. So, adding a goal which always fails (such as the built in predicate fail/0 which has no effect but to make Prolog fail) at the end of a clause, will force Prolog to backtrack over all the other goals in that clause until it has tried all the possibilities.

What is the use of fail in Prolog?

As its name suggests, fail/0 is a special symbol that will immediately fail when Prolog encounters it as a goal. That may not sound too useful, but remember: when Prolog fails, it tries to backtrack . Thus fail/0 can be viewed as an instruction to force backtracking.

What is repeat in Prolog?

repeat :- repeat. Thus repeat succeeds when first called, thanks to the first clause. If the Prolog interpreter subsequently backtracks, the second clause ( repeat :- repeat. ) is tried. This initiates a new call to repeat , which succeeds via the first clause, and so on.


1 Answers

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]

like image 57
CapelliC Avatar answered Sep 20 '22 02:09

CapelliC