I am writing a recursive search procedures that is supposed to generate a list (actually two lists, but for now, lets consider one).
The procedure progresses in the search space via recursive calls, and at each step, checks if a condition holds. If it does then a element is added to the list and if the condition doesn’t hold the list stays the same for the next iteration.
Usually, one uses the [First | Rest] accumulator pattern to generate a First that gets appended during recursion to Rest, but in my case First may be omitted sometimes.
I am blanking on the pattern to use …
much appreciating any thoughts,
thanks
p.s. in the arg list there are indeed two [First_1 | Rest_1], [First_2, Rest_2] and each First_1 and First_2 can independently be omitted due to a condition that holds or doesn’t hold.
Edit:
I could use global variables as accumulators and use the recursion to simply search across the search space, … to avoid dealing with accumulators and their respective variant calls under different conditions.
You can always use listing/1,2 to see the DCG converted to native code.
One place loaded with lots of working examples of recursive list construction is in the SWI-Prolog source code on GitHub.
Having spent much time browsing those files I know that Jan W. uses the conditional (-> ;) often with the pattern you seek. However searching for that is not easy but the code often also uses = [] and that does lead to examples of what you seek, e.g. (ref)
%! zipper_members_(+Zipper, -Members) is det.
%
% Simplified version of zipper_members/2 from library(zip). We already
% have a lock on the zipper and by moving this here we avoid
% dependency on another library.
%
% @tbd: should we cache this?
zipper_members_(Zipper, Members) :-
zipper_goto(Zipper, first),
zip_members__(Zipper, Members).
zip_members__(Zipper, [Name|T]) :-
zip_file_info_(Zipper, Name, _Attrs),
( zipper_goto(Zipper, next)
-> zip_members__(Zipper, T)
; T = []
).
Right, the T= patterns comes to mind, but if i insert it in the head of an argument then i end up with composite list of empty lists which needs flattening – something i wanted to avoid.
That is confusing. T is the tail but you are noting head which is typically used with the variable H.
The problem with trying to find more practical and simple examples is that as the others have noted, this is typically done with DCG or EDCG.
Earlier I checked to see if RosettaCode had a nice FizzBuzz example for Prolog doing what you wanted but the examples there were so terrible I didn’t even want to reference them.
EDIT
Since what you need seems similar to partition/4 here is the code behind the predicate
%! partition(:Pred, +List, ?Included, ?Excluded) is det.
%
% Filter elements of List according to Pred. True if Included
% contains all elements for which call(Pred, X) succeeds and
% Excluded contains the remaining elements.
%
% @see include/3, exclude/3, partition/5.
partition(Pred, List, Included, Excluded) :-
partition_(List, Pred, Included, Excluded).
partition_([], _, [], []).
partition_([H|T], Pred, Incl, Excl) :-
( call(Pred, H)
-> Incl = [H|I],
partition_(T, Pred, I, Excl)
; Excl = [H|E],
partition_(T, Pred, Incl, E)
).