Surprisingly a difference between the coding variants is, that the 1st variant produces more backtrack points. Below test shows, that 1st variant produces 6 backtrack points, 2nd produces 4, and a 3rd variant using a generator-fail-loop produces also 4.
Code: Select all
class predicates
nondetpred1 : (unsigned X [out])
nondeterm.
clauses
nondetpred1(X) :-
X = std::cIterate(2).
class predicates
nondetpred2 : (
unsigned X,
unsigned Y [out])
nondeterm.
clauses
nondetpred2(_X, Y) :-
Y = std::cIterate(2).
class predicates
nondetpred3 : (
unsigned X,
unsigned Y,
unsigned Z [out])
nondeterm.
clauses
nondetpred3(_X, _Y, Z) :-
Z = std::cIterate(2).
class predicates
procbody : (
unsigned X,
unsigned Y,
unsigned Z).
clauses
procbody(X, Y, Z) :-
stdIo::write("(", X, ", ", Y, ", ", Z, " [", programControl::getBackTrackPoints(), "]", ") ").
class predicates
foreach_ : (
function_nd{Type} Gen,
predicate{Type} Body).
clauses
foreach_(Gen, Body) :-
Item = Gen(),
Body(Item),
fail.
foreach_(_, _).
clauses
run() :-
stdIo::write("[", programControl::getBackTrackPoints(), "]\n"),
foreach nondetpred1(X) do
foreach nondetpred2(X, Y) do
foreach nondetpred3(X, Y, Z) do
procbody(X, Y, Z)
end foreach
end foreach
end foreach,
stdIo::write("\n---\n"),
foreach
nondetpred1(X),
nondetpred2(X, Y),
nondetpred3(X, Y, Z) do
procbody(X, Y, Z)
end foreach,
stdIo::write("\n---\n"),
foreach_(
{
= tuple(X, Y, Z) :-
nondetpred1(X),
nondetpred2(X, Y),
nondetpred3(X, Y, Z)
},
{ (tuple(X, Y, Z)) :- procbody(X, Y, Z) }).
Regards
Martin