在Prolog中枚举解
我想将非确定性目标的解决方案在Prolog中枚举解,prolog,swi-prolog,Prolog,Swi Prolog,我想将非确定性目标的解决方案nondet_-goal成对枚举(索引,值),其中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
nondet_-goal
成对枚举(索引,值)
,其中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).
快速测试用例可能如下所示:
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)].
我想知道是否有更好的方法来获取值和索引。理想情况下,如果不需要生成所有解决方案的完整列表。谢谢你的帮助
干杯,
Jacek我会“封装”您的代码,它已经很好地工作了——除了可重入性。那么,让我们开始为这个抽象选择一个名称:
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_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].
编辑:
你能发布一个解决方案的例子吗?我的意思是输出的一个例子经典的方法是使用findall/3或类似的谓词,但这样你会生成一个完整的解决方案列表…只是为我给出的例子添加了输出。@coder,你能详细介绍一下“经典方法”吗。如何使用
findall
生成索引?findall((索引,值),目标(索引,值,可能还有其他参数),L)。
这将存储使目标在L中成功的所有对(索引,值),您可以通过使用成员(Out,L)一次获取一对。当然,你的目标是findnsols,但是你需要发布代码或者以上面的格式使用它。你能发布一个解决方案示例吗?我的意思是输出的一个例子经典的方法是使用findall/3或类似的谓词,但这样你会生成一个完整的解决方案列表…只是为我给出的例子添加了输出。@coder,你能详细介绍一下“经典方法”吗。如何使用findall
生成索引?findall((索引,值),目标(索引,值,可能还有其他参数),L)。
这将存储使目标在L中成功的所有对(索引,值),您可以通过使用成员(Out,L)一次获取一对。当然,你的目标是FindNSOL,但是你需要发布代码或者以上面的格式使用它。谢谢你,很好。我忽略了一个事实,即G
和S
可能相互依赖,并且不确定如何编写规则。尽管如此,我还是想知道是否有办法摆脱nb_{s/g}etval。。。让我们介绍另一个小抽象。嗯。。。但这是隐藏而不是摆脱nb_xxx
操作。不管怎样,谢谢你的建议。谢谢你,很好。我忽略了一个事实,即G
和S
可能相互依赖,并且不确定如何编写规则。尽管如此,我还是想知道是否有办法摆脱nb_{s/g}etval。。。让我们介绍另一个小抽象。嗯。。。但这是隐藏而不是摆脱nb_xxx
操作。无论如何,谢谢你的建议。