如何检查Prolog规则是否已启动?

如何检查Prolog规则是否已启动?,prolog,artificial-intelligence,Prolog,Artificial Intelligence,我需要检查一条规则是否已经“触发”,然后再触发它。我的意思是,在断言一个新事实之前,我需要知道在上一个循环迭代中是否已经断言了相同的事实 我试图使用一个列表,但我认为它们对我的问题不那么“友好”。我还可以用什么来做这件事呢?我把上面的评论重新表述一下,作为进一步阐述的答案 您可以考虑在生成解决方案后强制失败的循环,并强制Prolog回溯和探索其他可能性: failure_driven_loop(Info):- generate(Info,Term), fail. failure_driven_

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


我试图使用一个列表,但我认为它们对我的问题不那么“友好”。我还可以用什么来做这件事呢?

我把上面的评论重新表述一下,作为进一步阐述的答案

您可以考虑在生成解决方案后强制失败的循环,并强制Prolog回溯和探索其他可能性:

failure_driven_loop(Info):- generate(Info,Term), fail. 
failure_driven_loop(Info). 
(示例来自)。在本例中,
Term
记录一个解决方案,
generate/2
为给定的
Info
生成解决方案。当所有解决方案都已用尽时,需要第二个子句使循环成功

一旦生成了一个解决方案,第一个子句将失败,执行将返回,即Prolog将尝试为
生成(信息,术语)
找到不同的证明,对于
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
记录。正如@capelical所指出的,如果您的程序回溯,则断言不会撤消,因此故障驱动循环将保留您的解决方案:

:- dynamic solution/1.

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

我将我的上述评论重新表述为一个答案,以便对此进行更详细的阐述

您可以考虑在生成解决方案后强制失败的循环,并强制Prolog回溯和探索其他可能性:

failure_driven_loop(Info):- generate(Info,Term), fail. 
failure_driven_loop(Info). 
(示例来自)。在本例中,
Term
记录一个解决方案,
generate/2
为给定的
Info
生成解决方案。当所有解决方案都已用尽时,需要第二个子句使循环成功

一旦生成了一个解决方案,第一个子句将失败,执行将返回,即Prolog将尝试为
生成(信息,术语)
找到不同的证明,对于
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
记录。正如@capelical所指出的,如果您的程序回溯,则断言不会撤消,因此故障驱动循环将保留您的解决方案:

:- dynamic solution/1.

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

成功应用规则后,您可以使用
assert
记录该规则,并检查该规则以前是否已断言过。这是在假设您只需要对每个规则应用一次的情况下进行的(而不是对每个可能的输入只应用一次)。需要更精细的簿记,但我不能在评论中说明。我不明白为什么这个问题被搁置,我完全清楚。你可以编写一个检查的元解释器,但如果你是新手,这不太可能实现。不过,这是我倾向于尝试的方法。讨论了一些简单的元解释器,包括一个可以检测冗余规则的元解释器。试一试,它可能正是你所需要的。一个问题:你的意思不是“在断言一个新事实之前”,你的意思是“在输入一个子句之前”,对吗?@TonyH:你可以试试
…(事实->真;断言(事实)),…
,正如亚历山大已经建议的那样。当然,请注意,如果您的程序(在Prolog中通常如此)需要回溯,那么这些断言不会撤消。这一事实可能会让你重新考虑名单的“友好性”…谢谢大家的回复。我很抱歉被误解了。。我试图更好地说明我需要什么:我在系统中插入事实,在输入数据的末尾,事实被处理以获得解决方案,这很好。但我需要检查是否存在其他解决方案(与第一个不同或部分不同)。为此,我需要知道哪些规则已经触发(在上一个循环中)以触发不同的规则(如果存在)。如何执行此操作?成功应用规则后,您可以使用
assert
记录该规则,并检查该规则以前是否已断言过。这是在假设您只需要对每个规则应用一次的情况下进行的(而不是对每个可能的输入只应用一次)。需要更精细的簿记,但我不能在评论中说明。我不明白为什么这个问题被搁置,我完全清楚。你可以编写一个检查的元解释器,但如果你是新手,这不太可能实现。不过,这是我倾向于尝试的方法。讨论了一些简单的元解释器,包括一个可以检测冗余规则的元解释器。试一试,它可能正是你所需要的。一个问题:你的意思不是“在断言一个新事实之前”,你的意思是“在输入一个子句之前”,对吗?@TonyH:你可以试试
…(事实->真;断言(事实)),…
,正如亚历山大已经建议的那样。当然,请注意,如果您的程序(在Prolog中通常如此)需要回溯,那么这些断言不会撤消。这一事实可能会让你重新考虑名单的“友好性”…谢谢大家的回复。我很抱歉被误解了。。我试图更好地说明我需要什么:我在系统中插入事实,在输入数据的末尾,事实被处理以获得解决方案,这很好。但我需要检查是否存在其他解决方案(与第一个不同或部分不同)。要做到这一点,我需要知道哪些规则是正确的