枚举Prolog中的解决方案

时间:2018-01-15 12:30:49

标签: prolog swi-prolog

我希望将非确定性目标nondet_goal的解决方案枚举为(Index, Value)对,其中Index是返回的每个值的索引。我设法使用nb_setvalnb_getval这样做:

nb_setval(g_idx, 0),
findnsols(3, (Idx, Val), (nondet_goal(Val), nb_getval(g_idx, Idx), Idx1 is Idx + 1, nb_setval(g_idx, Idx1)), Out).

快速测试案例可能如下所示:

L = [a,b,c,d,e],
nb_setval(g_idx, 0),
findnsols(3, (Idx, It), (member(It, L), nb_getval(g_idx, Idx), Idx1 is Idx + 1, nb_setval(g_idx, Idx1)), Out).

产生预期的输出:

Out = [(0, a),  (1, b),  (2, c)] ;
Out = [(3, d),  (4, e)].

我想知道是否有更好的方式来获取值和索引。理想情况下,如果它不需要生成所有解决方案的完整列表。任何帮助表示赞赏。

干杯,   亚切克

1 个答案:

答案 0 :(得分:2)

我会封装'你的代码已经运行良好 - 除了重入之外。所以,让我们开始为这个抽象选择一个名称:

enumerate_indexed_solutions(G, S, L) :-
   nb_setval(g_idx, 0),
   findnsols(3, I-S, (
     G,
     nb_getval(g_idx, I), I1 is I + 1, nb_setval(g_idx, I1)
   ), L).

产生:

?- enumerate_indexed_solutions(member(V,[a,b,c,d,e]),V,L).
L = [0-a, 1-b, 2-c] ;
L = [3-d, 4-e].

编辑:

enumerate_indexed :- nb_setval(g_idx, 0).
enumerate_indexed(I) :-
  nb_getval(g_idx, I), I1 is I + 1, nb_setval(g_idx, I1).

enumerate_indexed_solutions(G, S, L) :-
  enumerate_indexed,
  findnsols(3, I-S, (G, enumerate_indexed(I)), L).