1

我需要在再次触发之前检查规则是否已经“触发”。我的意思是在断言一个新事实之前,我需要知道在之前的循环迭代中是否已经断言了相同的事实。

我尝试使用列表,但我认为它们对我的问题并不那么“友好”。我还能用什么来做到这一点?

4

1 回答 1

1

我将上面的评论改写为一个答案,以详细说明它。

您可能会考虑在生成解决方案后会失败的故障驱动循环,并迫使 Prolog 回溯并探索其他可能性:

failure_driven_loop(Info):- generate(Info,Term), fail. 
failure_driven_loop(Info). 

(示例来自Paul Brna 的书)。在此示例Term中,记录一个解决方案并generate/2为给定的Info. 当所有解决方案都用尽时,需要第二个子句才能使循环成功。

一旦生成了一个解决方案,第一个子句失败并且执行回溯,即,Prolog 将尝试为 找到不同的证明generate(Info,Term),这通常会涉及不同的子句,无论是generate/2它自己还是直接或间接调用的谓词之一generate/2。如果您想确保一旦generate/2使用了它的一个子句,它就不应该尝试重复使用相同的子句,您应该添加削减,即,而不是

generate(Info,Term) :- solve_somehow(Info,Term).
generate(Info,Term) :- solve_in_some_other_way(Info,Term).

你应该写

generate(Info,Term) :- solve_somehow(Info,Term), !.
generate(Info,Term) :- solve_in_some_other_way(Info,Term), !.

找到的解决方案generate/2可以用 记录下来assert。正如@CapelliC 所指出的,如果您的程序回溯,则断言不会撤消,因此故障驱动循环会保留您的解决方案:

:- dynamic solution/1.

failure_driven_loop(Info):- generate(Info,Term), assert(solution(Term)), fail. 
failure_driven_loop(Info). 
于 2013-07-12T21:12:41.810 回答