【问题标题】:Infinite loop inference Prolog无限循环推理 Prolog
【发布时间】:2019-01-29 16:48:26
【问题描述】:

当推理电机被激活以进行必要的推理时,会生成一个无限循环。

规则和事实已根据我正在使用的元解释器的特定语法定义。

规则是一个五元组,其中第二个字段是规则的结果,而第三个字段是激活规则的条件。

循环是通过nextID这个词更新id(I1)引起的,我用这个来确保每次assert id都递增这是我的知识库:

规则:

rule(1,[gn(Name,Surname,I1),retract(nextID(I)),nextID(I1)],
and([person(Name,Surname),nextID(I),call_p(I1 is I+1),Name=='john']),1,1).

事实:

fact(1,nextID(0),1).
fact(2,person(john,black),1).

我应该如何修改规则以不创建无限循环?

【问题讨论】:

  • 不,不是语法错误
  • nextID (0) 是无效的语法。应该是nextID(0)。其他所有复合词都是一样的(Name == 'john' 除外)。
  • 在 Prolog 中编写复合项时,仿函数和左括号之间不能有空格。因此,例如,您想要fact(1, nextID(0), 1). 而不是fact (1, nextID (0), 1). 但是由于您显然已经运行了此代码并遇到了循环,我想您在这里输入的方式与实际情况不同。
  • 空格来自复制和粘贴,但我向你保证,在代码中没有。
  • 然后空格会返回语法错误,而在我的情况下,语法是正确的,但问题正在执行中

标签: prolog inference-engine


【解决方案1】:

根据您对规则字段的描述,我希望该规则有不同的表述:

rule(
    1,
    [retract(nextID(I)), call_p(I1 is I+1), assertz(nextID(I1), gn(Name,Surname,I1)], 
    and([person(Name,Surname), Name == 'john']),
    1,
    1
).

这相当于:

IF
    person(Name,Surname), Name == 'john'
THEN
    retract(nextID(I)), call_p(I1 is I+1),
    assertz(nextID(I1), gn(Name,Surname,I1)

但如果不了解规则引擎的详细信息,就很难准确判断。

更新

考虑到事实的表述,尤其是fact(1,nextID(0),1),但是我不认为对retract/1 和assertz/1 的嵌入式调用会起作用。 call_p/1 不是从规则中调用 Prolog 目标的转义机制吗?

【讨论】:

  • 执行的效果是它不断地创建新的nextID,因此总是调用规则。我希望循环在gn 断言和nextID 更新后停止
  • 我在回答中建议的替代规则表述不是这种情况吗?
  • 规则的第二个字段仅用于assert 和retract,要执行断言插入事实来断言就足够了,而无需指定命令assert,而对于@ 987654332@ 需要指定。 call_p (I1 is I + 1) 应放在规则的第三个字段中,否则 call_p 将被视为复合词。
  • 可以用retractall代替retract吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多