如果您的Prolog有某種非backtrackable分配的,就像SWI-Prolog的'global' variables,你可以實現(注意,頭腦簡單的代碼)以這樣的方式
:- meta_predicate solutions(0, ?).
:- meta_predicate solutions(+, 0, ?).
solutions(G, L) :-
solutions(G, G, L).
solutions(P, G, L) :-
(nb_current(solutions_depth, C) -> true ; C=1),
D is C+1,
nb_setval(solutions_depth, D),
atom_concat(solutions_depth_, D, Store),
nb_setval(Store, []),
( G,
nb_getval(Store, T),
nb_setval(Store, [P|T]),
fail
; nb_getval(Store, R)
),
nb_delete(Store),
nb_setval(solutions_depth, C),
reverse(R, L).
的「全局」變量導致用法更高效的執行WRT動態數據庫(assert/retract),以及(在SWI-prolog中)甚至可以在多線程應用程序中使用。
編輯
由於@false評論,移動的切割(多個)之前反向/ 2,並且引入了一個堆棧重入調用:例如
?- solutions(X-Ys,(between(1,3,X),solutions(Y,between(1,5,Y),Ys)),S).
S = [1-[1, 2, 3, 4, 5], 2-[1, 2, 3, 4, 5], 3-[1, 2, 3, 4, 5]].
編輯
下面是解決方案/ 3的變體,按順序構建結果列表,以避免最終的反向/ 2調用。將結果添加到列表尾部有點棘手...
solutions(P, G, L) :-
(nb_current(solutions_depth, C) -> true ; C=1),
D is C+1,
nb_setval(solutions_depth, D),
atom_concat(solutions_depth_, D, Store),
( G,
(nb_current(Store, U/B) -> B = [P|R], Q = U/R ; Q = [P|T]/T),
nb_setval(Store, Q),
fail
; (nb_current(Store, L/[]) -> true ; L = [])
),
nb_delete(Store),
nb_setval(solutions_depth, C).
是否有意義反映找到的解決方案的順序? – false