我希望将非确定性目标nondet_goal
的解决方案枚举为(Index, Value)
对,其中Index
是返回的每个值的索引。我设法使用nb_setval
,nb_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)].
我想知道是否有更好的方式来获取值和索引。理想情况下,如果它不需要生成所有解决方案的完整列表。任何帮助表示赞赏。
干杯, 亚切克
答案 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).