shithub: pprolog

Download patch

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).