我需要检查一条规则是否已经“解雇”,然后重新启动它。我的意思是在断言一个新事实之前,我需要知道在前一个循环迭代中是否已经声明了相同的事实。
我尝试使用列表,但我认为他们对我的问题并不那么“友好”。还有什么可以用来做到这一点?
答案 0 :(得分:1)
我在上面的评论中重述了一些答案,详细阐述了它。
您可能会考虑在生成解决方案后失败驱动的循环失败并强制Prolog回溯并探索其他可能性:
failure_driven_loop(Info):- generate(Info,Term), fail.
failure_driven_loop(Info).
(例如来自Paul Brna's book)。在此示例中,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).