【问题标题】:Predicate order change causes infinite loop谓词顺序更改导致无限循环
【发布时间】:2021-12-07 20:03:22
【问题描述】:

所以我有一个适用于未实例化变量 nat_cset(N,Cs) 的谓词,它将自然数与计数集 Sn = {1,2,...,N} 相关联。

nat_cset_(0,Acc,Acc).
nat_cset_(N,Acc,Cs) :- N #> 0, N_1 #= N - 1,  nat_cset_(N_1, [N|Acc], Cs).
nat_cset(N,Cs) :- nat_cset_(N,[],Cs).

我注意到的一件事是,以下查询 nat_cset(N,Cs), N = 6. 进入了一个无限循环,而 N = 6, nat_cset(N,Cs). 没有:

?- nat_cset(N,Cs), N = 6, false.
...
?- N = 6, nat_cset(N,Cs), false.
false

发生这种情况是因为在第二个查询中,prolog 它应该只寻找 N = 6 的解决方案,而在第一个查询中,prolog 将搜索 N = 6 的无限解决方案。

我的问题是,这是nat_cset/2 的“适当”行为还是不受欢迎的行为?我在某处读到,谓词更改解决方案的顺序使其不单调并消除其纯度,但同时我想不出一种方法使 nat_cset/2 有任何不同。

抱歉这个菜鸟问题,很多概念对我来说都是新的,我仍在努力处理它们。

【问题讨论】:

  • length(X, N), N = 6 相同。
  • 请阅读failure-slice 上的推荐问题。这正是它存在的原因。
  • 我只是想跳上火车并建议不要不加选择地使用约束,直到您更好地理解没有它们的 Prolog。您还应该首先问自己:“我要解决什么问题”。您当前遇到的可能是attribute substitution。简单来说,“如果你只有一把锤子,一切看起来都像钉子”。此外,顺序一直很重要,这一直到 decidability 恕我直言。

标签: prolog failure-slice


【解决方案1】:

查询

?- nat_cset(N,Cs), N = 6, false.

具有完全相同的终止属性 ?- nat_cset(N,Cs), false, N = 6

所以目标N = 6 在这种情况下对终止没有任何影响,1。只有加在前面才会影响终止。

正如already 所说,不如从使用successor-arithmetics 而不是clpfd/clpz 的程序开始。它们更简单,并且仍然公开了理解故障切片所需的相关属性。


1 这假定 N = 6 总是终止,就像在 Scryer 中的 clpz 和 SWI 中的 clpfd 一样。对于一般的协程,情况不一定如此。想想freeze(N, inf), N = 6

【讨论】:

    猜你喜欢
    • 2012-04-02
    • 1970-01-01
    • 2014-12-16
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 2020-08-27
    • 2021-05-07
    相关资源
    最近更新 更多