Вот решение, которое использует очереди и потоки SWI-Prolog. Он использует старый существующий API и что-то делает с Двигателями Тарау . Я предполагаю, что создание потока скопирует шаблон и цель. И тогда я предполагаю, что очередь отправки снова сделает копию каждого решения.
Таким образом, по сравнению с классическим findall у вас будет излишек на одном шаблоне и целевой копии, но в противном случае он также будет копировать каждое решение как классический findall. Источник на гисте здесь . Но, модифицируя threadall2, который выполняет сбор, можно также реализовать все виды агрегатов:
% threadall(+Term, +Goal, -List)
threadall(T, G, L) :-
message_queue_create(J, [max_size(1)]),
thread_create(threadall3(T, G, J), _, [detached(true)]),
thread_get_message(J, A),
threadall2(J, A, L),
message_queue_destroy(J).
% threadall3(+Term, +Goal, +Queue)
threadall3(T, G, J) :-
G, thread_send_message(J, the(T)), fail.
threadall3(_, _, J) :-
thread_send_message(J, no).
% threadall2(+Queue, +Term, -List)
threadall2(J, the(T), [T|L]) :- !,
thread_get_message(J, A),
threadall2(J, A, L).
threadall2(_, no, []).
Вот пример запуска. Надеюсь, я правильно сделал бухгалтерию. Поток был создан с помощью detach (true), поэтому нам не нужен некоторый дескриптор, когда поток завершается. Очередь сообщений явно уничтожена. Вот несколько примеров выполнения SWI-Prolog, мы видим, что он работает как положено:
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.23)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
?- threadall(X, between(0, 5, X), L).
L = [0, 1, 2, 3, 4, 5].
?- threadall(X-Y, (between(0, 2, X),
threadall(Z, between(0, 2, Z), Y)), L).
L = [0-[0, 1, 2], 1-[0, 1, 2], 2-[0, 1, 2]].
Наш код реализует только обычный счастливый путь: мы реализуем только сообщения the/1
и no/0
. Кроме того, поскольку мы не используем setup_call_cleanup/3
, также небезопасно использовать решение с прерываниями. Также последний аргумент не является стойким. Все это оставлено читателю для выполнения этих дополнительных требований и соответствующих альтернативных путей.