我有两个Prolog的实现,函数是决定给定的数字是奇数还是偶数
第一个正常工作
even1(0).
even1(X) :- X>0 ,X1 is X-1, odd1(X1).
odd1(1).
odd1(X) :- X>1 , X1 is X-1, even1(X1).
Run Code Online (Sandbox Code Playgroud)
even1(2)返回true
但第二个不能正常工作
even2(0).
even2(X) :- X>0 , odd2(X-1).
odd2(1).
odd2(X) :- X>1 , even2(X-1).
Run Code Online (Sandbox Code Playgroud)
even2(2)返回false可以有人向我解释什么是两者之间的区别?
Prolog是一种关系语言,而不是一种功能语言.因此,当您调用时odd2(X-1),谓词参数X-1不会被计算为表达式,而是被解释为复合词:
?- functor(X-1, Name, Arity).
Name = (-),
Arity = 2.
Run Code Online (Sandbox Code Playgroud)
您可以检查Prolog通过使用系统跟踪功能证明查询时会发生什么:
?- trace.
true.
[trace] ?- even2(2).
Call: (8) even2(2) ? creep
Call: (9) 2>0 ? creep
Exit: (9) 2>0 ? creep
Call: (9) odd2(2-1) ? creep
Call: (10) 2-1>0 ? creep
Exit: (10) 2-1>0 ? creep
Call: (10) even2(2-1-1) ? creep
Call: (11) 2-1-1>0 ? creep
Fail: (11) 2-1-1>0 ? creep
Fail: (10) even2(2-1-1) ? creep
Fail: (9) odd2(2-1) ? creep
Fail: (8) even2(2) ? creep
false.
Run Code Online (Sandbox Code Playgroud)
请注意,表达式的2-1-1计算结果为零,但作为复合项,调用even2(2-1-1)不会与谓词的基本情况统一even2(0):
?- even2(2-1-1) = even2(0).
false.
?- 2-1-1 = 0.
false.
Run Code Online (Sandbox Code Playgroud)
因此,Prolog尝试第二个子句,并且调用最终未通过X>0检查.请注意>/2,通过作为算术比较谓词,它会在实际比较之前评估其参数.