ref: 48c0638c7be3f99f2512be42fbb6b3946df26463
parent: a37ae2f0170499be1a95031d24ff86aac5cf46f1
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Sat Jul 10 06:45:58 EDT 2021
Add findall/3 implemented in prolog
--- a/stdlib.pl
+++ b/stdlib.pl
@@ -167,6 +167,46 @@
).
% Basic list predicates
+
member(X, [X|_]).
member(X, [_|Tail]) :-
member(X, Tail).
+
+% Additional type tests
+
+callable(T) :- atom(T) ; compound(T).
+
+list([]).
+list([_|T]) :- list(T).
+
+partial_list(T) :- var(T).
+partial_list([_|T]) :- partial_list(T).
+
+% type assertions (throws an error if false)
+
+is_callable(T) :- callable(T), ! ; type_error(callable, T).
+
+is_nonvar(T) :- nonvar(T), ! ; instantiation_error.
+
+is_list_or_partial_list(T) :- (list(T) ; partial_list(T)), ! ; type_error(list, T).
+
+% All solutions
+
+findall(Template, Goal, Instances) :-
+ is_nonvar(Goal),
+ is_callable(Goal),
+ is_list_or_partial_list(Instances),
+ system:asserta('find all'([])),
+ call(Goal),
+ system:asserta('find all'(solution(Template))),
+ fail.
+findall(Template, Goal, Instances) :-
+ findall_collect([], Instances).
+
+findall_collect(Acc, Instances) :-
+ retract('find all'(Item)),
+ !,
+ findall_collect(Item, Acc, Instances).
+findall_collect([], Instances, Instances).
+findall_collect(solution(T), Acc, Instances) :-
+ findall_collect([T|Acc], Instances).