【问题标题】:Prolog Cut operatorProlog Cut 运算符
【发布时间】:2017-10-17 20:26:32
【问题描述】:

我将我的知识库定义为:

edge(mammal,isa,animal).
edge(human,isa,mammal).
edge(simba,isa,human).

edge(animal,swim,bybirth).
edge(human,swim,mustlearn).

path(X,Y) :- edge(X,isa,Y).
path(X,Y) :- edge(X,isa,Z), path(Z,Y).

swim(X,Y) :- edge(X,swim,Y).
swim(X,Y) :- path(X,Z), swim(Z,Y).

现在,要使用上述知识库,我使用以下内容:

?- swim(simba,bybirth).
?- swim(simba,mustlearn).

对于这两个查询,Prolog 都返回 true。我希望 Prolog 首先在本地检查属性游泳,然后查看直接父级,依此类推。一旦我们知道辛巴“必须学会”游泳,它就应该停止搜索,不应该再看下去了。因此,它应该为第一个查询返回 false,为第二个查询返回 true。

我知道必须通过限制回溯来完成。我尝试使用 cut 而不是运算符,但没有成功。有没有办法做到这一点?

【问题讨论】:

    标签: prolog prolog-cut


    【解决方案1】:

    我试过了,也遇到了问题。我认为这可能有效:

    swim(X,Y) :- once((edge(X,swim,Y); path(X,Z), swim(Z,Y))).
    

    它不起作用,因为如果 Y 在途中已经实例化,那么第一步将无法统一,它将尝试通过 human 中间的第二条路线。所以即使查询只产生一个结果,它也可以被愚弄产生swim(simba, bybirth)。解决方案是强制 Prolog 提交到另一个变量上的绑定,然后在提交后检查该绑定:

    swim(X,Y) :- 
        once((edge(X,swim,Method); path(X,Z), swim(Z,Method))), 
        Method = Y.
    

    这告诉Prolog,只有一种方法可以到达这个方法,所以找到那个方法,然后它一定是Y。如果你找到错误的方法,它不会继续搜索,它只会失败.试试看!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-27
      • 2014-01-30
      • 2018-03-08
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多