从我对确定性谓词的理解来看:
确定性谓词= 1解决方案
非确定性谓词=多种解决方案
是否有任何类型的规则可以检测谓词是一个还是另一个?就像查看搜索树一样
答案 0 :(得分:10)
关于这些概念,没有明确的,普遍接受的共识。但是,它们通常基于观察到的答案,而不是基于解决方案的数量。在某些情况下,这些概念与实施有关。非确定性可能意味着:保持选择点开放。有时确定意味着:永远不会创造一个选择点。
要了解差异,请考虑目标length(L, 1)
。它有多少解决方案? L = [a]
是一个,L = [23]
另一个......但所有这些解决方案都用一个答案替换紧凑地表示:L = [_]
因此包含无限多个解决方案。
无论如何,在我所知的所有实现中,length(L, 1)
都是一个确定的目标。
现在考虑目标repeat
,其中只有一个解决方案,但答案无限多。这个目标被认为是不确定的。
如果您对约束感兴趣,事情会变得更加发展。在library(clpfd)
中,目标X #> Y, Y #> X
没有解决方案,但仍有一个答案。将其与repeat
结合起来:无限多的答案,没有解决方案。
此外,目标append(Xs, Ys, [])
只有一个解决方案,也只有一个答案,但在许多实现中它被认为是不确定的,因为在这些实现中,它会使选择点保持打开状态。
在理想的实现中,没有解决方案就没有答案(false
除外),并且只有在有多个答案时才会存在非确定性。但是,在一般情况下,所有这些都是不可判定的。
因此,无论何时使用这些概念,都要确定事物的含义。相当明确地说:多个答案,多个解决方案,不会打开(不必要的)选择点。
答案 1 :(得分:0)
你需要了解det,semidet和undet之间的区别,它不仅仅是解决方案的数量。
因为Prolog中没有循环控制操作符,所以循环(不是递归)被构造为生成'序列的序列。谓词(undet)后跟循环体。您还可以使用一些findall-group谓词作为列表存储解决方案,稍后使用member / 2谓词进行循环。
因此,程序的任何部分都是循环结构的一部分或者是常规流程的一部分。因此,几乎在预期用途中设计det和undet谓词存在差异。如果你可以使用一个序列,你总是做不准确的并且如此评论它。在swi-prolog中有一个很好的单元测试扩展,它可以检查你的谓词总是相同的det / semidet / undet(semidet的使用方式与undet相同,但作为'如果&#的头部39;建设)。
因此,差异在于预先设计,并且不应该在已有的谓词中出现这个问题。这是一个很好的做法,总是在评论中评论预期用法。
% member(?El, ?List) is undet.
答案 2 :(得分:-1)
Deterministic
:总是成功,只有一个答案对同一个输入总是相同的。想一下三个项目的静态列表,并告诉您的函数返回值1。你每次都会得到相同的答案。另外,算术功能。 1 + 1 = 2. X + Y = Z.
Semi-deterministic
:对于同一输入,单个答案的成功总是相同,但它可能会失败。考虑一个带有数字列表的函数,并询问您的函数列表中是否存在某个数字。它要么根据给出的列表的内容和要求的数量而做,要么不做。
Non-deterministic
:只有一个答案成功,但在不同的运行中可以表现出不同的行为,即使对于相同的输入也是如此。想想任何math.random(min,max)
函数,如random/3
从本质上讲,这完全独立于选择点的概念,因为选择点是Prolog的功能。我认为这些术语的Prolog混淆源于Prolog可以找到一个答案,然后返回并尝试另一个解决方案,你必须使用剪切运算符!
来告诉它你要丢弃你的选择明确指出。