在特殊情况下生成正数

时间:2010-07-19 18:46:29

标签: prolog

我正在寻找转换此代码的可能性

zero(0).
positive(X) :- \+ zero(X).

以便像

一样调用
?- positive(X).

将为X生成值。

实际上,只有具有X特定值的调用才能正确测试,但不能生成任何值。

感谢。

2 个答案:

答案 0 :(得分:0)

此处发布的代码不会正确测试任何内容,除了负数,然后只是意外(即使停止的时钟每天两次:-)):

positive(X) :- \+ zero(0).

如果无法满足其参数,则\+/1谓词会成功。换句话说,只要不能满足zero(0),它就会产生真实。但zero(0) 总是满意(这是事实!)。所以positive(X)这里将为任何X产生错误 - 包括0!

我认为你的意思是:

positive(X) :- \+ zero(X).

也失败了,但是以一种更有趣的方式。请记住,如果有任何方式来满足其参数,则\+/1会失败。如果您查询:

?- positive(1).

它会将X绑定到1,并查看是否可以满足zero(X)的约束X必须为1.不是,所以positive(1)将产生真。

但是,如果您查询:

?- positive(X).

你问是否可以满足zero(X) 而不受X 的约束。 可以通过将X绑定到0来实现此目的,这意味着某些X可以满足zero(X) - 这将导致\+ zero(X)屈服假的。

更接近的一步是尝试:

positive(X) :- X > 0.

也将负数考虑在内。这将为positive(1)positive(0)positive(-1)提供正确的答案。但是,它不会生成数字。如果你试试这个:

?- positive(X).

你会得到:

ERROR: >/2: Arguments are not sufficiently instantiated

因为你还没有充分说明X对于>/2谓词生效是什么 - 不能在未实例化的对象上调用算术运算符(也就是自由变量,在这种情况下也就是X)。这通常会导致您的“生成一些整数”方法出现问题。

但是,您可以指定要从中获取值的特定数值范围,并让Prolog从那里继续:

positive(X) :- X > 0.
genPositive(X) :- between(-100, 100, X), positive(X).

答案 1 :(得分:0)

你可以写得非常简单

positive(1).
positive(X) :- positive(Y), X is Y + 1.

这确实会起作用

?- positive(X).
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
etc

但请记住,这不是尾递归,这种算法是指数复杂的。 我的意思是:

 ?- time((positive(X),X>4000)).
% 8,010,001 inferences, 3.70 CPU in 3.73 seconds (99% CPU, 2163038 Lips)
X = 4001.

请注意产生4000个阳性的时间。

但如果我们这样做的话:

positive1(X) :- from(1,X).

from(From,From).
from(From,X):-From1 is From + 1, from(From1,X).

现在一切都很快:

 ?- time((positive1(X),X>4000)).
% 8,002 inferences, 0.00 CPU in 0.00 seconds (?% CPU, Infinite Lips)
X = 4001.