错误:未定义的过程:(+)/ 2

时间:2012-06-11 08:41:20

标签: prolog primes

我是SWI-Prolog的新手,我想检查Prolog中的主要功能。

prime(N) :-
    N > 1,
    M is N - 1,
    check(N, M).

check(_, 1).
check(N, M) :-
    M > 1,
    R is N - M * N / M,
    R > 0,
    P is M - 1,
    check(N, P).

但是当我在Prolog中询问2 + 2(*)/2(/)/2,...等其他运营商时,请说:undefined procedure: (+)/2。 我认为这是seetell。我重新分配see(user)tell(user),但此错误再次发生。 为什么呢?

3 个答案:

答案 0 :(得分:6)

在您使用的SWI prolog 6.0.2分区中返回浮点数。因此prime(13)将失败,因为余数为0.整数除法使用运算符//。但请检查prolog SWI函数remmod

此外,您希望在第一次定义check后进行剪切,否则prolog将探索第二个定义,该定义将返回false。 Cut确保在检查了小于N的所有自然数之后,它会成功停止。

以下是更正后的代码,其行为符合SWI Prolog 6.0.2中的要求。

prime(N) :-
    N > 1,
    M is N - 1,
    check(N, M).

check(_, 1) :- !.
check(N, M) :-
    M > 1,
    R is N mod M,
    R > 0,
    P is M - 1,
    check(N, P).

答案 1 :(得分:3)

关于您的错误,请查看:

?- 2+2.
ERROR: Undefined procedure: (+)/2

?- X is 2+2.    
X = 4 

你应该在Prolog中使用is来强制评估算术表达式。尝试在SWI-Prolog的提示符下输入“help(is).”。

但是你的算法在两个帐户上效率非常低。首先,您通过所有前面的数字检查候选编号的可分性,而只有那些不大于其平方根的候选编号就足够了(如果a*b=na >= sqrt(n)b =< sqrt(n))。

然后,您按相反的顺序进行测试。较小因子的倍数比较大因子更频繁,因此当按升序完成时,测试将会更早地被切断,从而使整个程序运行得更快 。最后,除了2:

之外,无需使用任何偶数进行测试
prime(2).
prime(N) :- N > 1,
    N mod 2 > 0,              % is odd
    M is floor(sqrt(N+1)),    % round-off paranoia 
    check(N, M, 3).

check(N, M, F) :- F>M.
check(N, M, F) :- F=<M,
    N mod F > 0,
    F1 is F + 2,              % test by odds only
    check(N, M, F1).

primesFromTo(F,T,X):-
  between(F,T,X), prime(X).

答案 2 :(得分:2)

您提到seetell:这些都是非常老式的内置谓词。最好避免它们。使用[file]加载文件,使用make重新加载文件。

要更好地实施测试质数,请参阅this answer