Could someone explain to me what this is doing?
(\+ setof((P1,C),P^R^Bag,PS) -> ...
otherwise ->...
I have read the documentation of setof; my understanding is that the thrid argument gets unified with the facts.
However, I can't make sense of the code snippet above.
The full snippet is:
solve_task_bt(go(Target),Agenda,ClosedSet,F,G,NewPos,RR,BackPath) :-
Agenda = [Current|Rest],
Current = [c(F,G,P)|RPath],
NewAgenda = Rest,
Bag = search(P,P1,R,C),
(\+ setof((P1,C),P^R^Bag,PS) -> solve_task_bt(go(Target),Rest,[Current|ClosedSet],F,G,NewPos,RR,BackPath);
otherwise ->
setof((P1,C),P^R^Bag,PS),
addChildren(PS,RPath,Current,NewAgenda,Target,Result),
NewClosedSet = [Current|ClosedSet],
NewestAgenda = Result,
solve_task_bt(go(Target),NewestAgenda,NewClosedSet,F1,G1,Pos,P|RPath,BackPath)
). % backtrack search
So, just focusing on the
setof/3Let's replace
Bagby its syntactic equivalent set a line earlier:The description of
setof/3says that itSo in this case,
setof/3will call (give the expression to the Prolog processor to prove)search(P,P1,R,C), and when this succeeds, collect the resulting valuesP1,Cas a conjunction(P1,C)(which is really special, why not use a 2-element list?) and put everything intoPSLet's just try a runnable example similar to the above, using a list instead of the conjunction and using different names:
Notice that you can write
without the compiler warning about "singleton variables", whereas
will give you a complaint:
and there is a reason for that:
PandRare visible at "clause level". Here we addPandRto the head, which gives us good printout later.Closed solution
The we can do:
Bagnow contains all possible solutions[X,Y]for:where we don't care about the values of the (
P,R) tuple outside of the inner goal. Values ofPandRare invisible outside the goal called bysetof/3, backtracking stays "internal".Alternative solution for
[X,Y]due to differing (P,R) are collapsed bysetof/3. If one was usingbagof/3instead:In effect, the query to the Prolog Processor is:
Open solution
In this case,
Bagcontains all solutions for a fixed (P,R) tuple, and Prolog allows you to backtrack over the possible (P,R) at the level of thesetof/3predicate. VariablesPandRare "visible outside" ofsetof/3.In effect, the query to the Prolog Processor is:
A problem of notation
This would be clearer if Prolog had had a Lambda operator to indicate where the cross-level attach points (i.e. between metapredicate and predicate) are. Assuming what is in
setof/3stays insetof/3(the opposite attitude of Prolog), one would be able to write:or
and
Or one could simply write
which would also make clear what is going as variables are not exported outside of the clause they appear in.