Prolog跳过一些回溯分支

Prolog跳过一些回溯分支,prolog,Prolog,我试图生成一些卡库罗斯,生成而不是解决 我有所有的规则来生成它,但是第一个结果是毫无意义的,它们就像正方形 现在,我想跳过一些分支,例如15000,以查看在该点生成的kakuro 我尝试过使用一个辅助变量,但当它失败时,Kakuro生成器会再次启动 您可以在知识库中保留一个类似计数器的动态谓词,每次执行主谓词时该谓词都会增加。计数器的值随断言和收回而改变,即它不是主谓词中的变量,而是全局存储的值 在主谓词中,如果您添加了计数器应高于某个跳过值的条件,那么您将强制对指定迭代次数的实际规则进行回溯

我试图生成一些卡库罗斯,生成而不是解决

我有所有的规则来生成它,但是第一个结果是毫无意义的,它们就像正方形

现在,我想跳过一些分支,例如15000,以查看在该点生成的kakuro

我尝试过使用一个辅助变量,但当它失败时,Kakuro生成器会再次启动


您可以在知识库中保留一个类似计数器的动态谓词,每次执行主谓词时该谓词都会增加。计数器的值随
断言
收回
而改变,即它不是主谓词中的变量,而是全局存储的值

在主谓词中,如果您添加了计数器应高于某个跳过值的条件,那么您将强制对指定迭代次数的实际规则进行回溯

作为一个例子,考虑内置谓词<代码>置换/ 2 < /代码>,计算列表的排列(注意:使用SWI PROLO测试,其他解释器具有不同的内置谓词)。示例输出:

?- permutation([1,2,3,4,5],L).
L = [1, 2, 3, 4, 5] ;
L = [1, 2, 3, 5, 4] ;
L = [1, 2, 4, 3, 5] ;
L = [1, 2, 4, 5, 3] ;
L = [1, 2, 5, 3, 4] ;
L = [1, 2, 5, 4, 3] ;
?- get_permutations([1,2,3,4,5],L2,5).
L2 = [1, 2, 5, 4, 3] ;
L2 = [1, 3, 2, 4, 5] ;
L2 = [1, 3, 2, 5, 4] 
如果要跳过查询中的前5次迭代,可以使用以下代码:

:- dynamic iteration_nr/1.

iteration_nr(0).

get_permutations(L1,L2,Skip) :-
    permutation(L1,L2),
    iteration_nr(N),
    N2 is N+1,
    retract(iteration_nr(N)),
    asserta(iteration_nr(N2)),
    Skip < N2.     % force backtracking here if counter < Skip
请注意,此处使用的是
asserta
(即开始时断言),而不是不推荐使用的普通
assert
。还请注意,计数器将保留该值,因此当您在同一会话中第二次运行时,结果将不同。要重置计数器,可以使用单独的初始化谓词,例如:

init_and_get_permutations(L1,L2,Skip) :-
    retractall(iteration_nr(_)),
    asserta(iteration_nr(0)),
    get_permutations(L1,L2,Skip).

进一步注意:
assert
retract
的使用实际上并不被认为是“干净的”Prolog编程,因为它是过程性的,并且改变了知识库。但是,对于某些应用程序,它可能很有用。

我不知道它是如何工作的,但它确实有用。我需要这个快速测试我的规则,稍后我会阅读。谢谢!注意点,你在做什么?动态删除和添加规则到您的知识库中,不是吗?好消息,未来的杰尔曼会很感激的。