一开始:我是Prolog的初学者,但我不得不承认,由于其他范式的事实,语言很奇怪。
find_kth_e(X, [X|_], 1).
find_kth_e(X, [_|T], K) :- K > 1, K1 is K-1, find_kth_e(X, T, K1).
?- find_kth_e(X, [1,2,3,4,5], 3).
X = 3 ;
false.
find_kth_e
?功能?关系? (是的,我知道函数是一种关系)。3
。没关系。但为什么第二个结果是false
?让我们考虑一个修改版本:
find_kth_e(X, [X|_], 1).
find_kth_e(X, [_|T], K) :- K > 1, K1 is K-1, find_kth_e(_, T, K1).
?- find_kth_e(X, [1,2,3,4,5], 3).
X = 3 ;
false.
唯一的区别在于:find_kth_e(X, [_|T], K) :- K > 1, K1 is K-1, find_kth_e(_, T, K1).
。我将X
替换为_
。现在:
?- find_kth_e(X, [1,2,3,4,5], 3).
true ;
false.
答案是真实而错误的。为什么没有3
?毕竟,结果应该由第一版函数返回 - 我的意思是find_kth_e(X, [X|_], 1)
。因此,我将X
替换为_
的事实应该无关紧要。
请解释。
答案 0 :(得分:1)
作为@EugeneSh。说,Prolog有谓词。 谓词可能包含一个或多个谓词子句(您的有两个)。 谓词在其参数之间定义 relation 。
?- find_kth_e(X, [1,2,3,4,5], 3).
X = 3 ;
false.
在此示例中,您询问X
是否是列表[1,2,3,4,5]
的第3个参数。 Prolog以X = 3
成功。但是在谓词中有一个选择点,这意味着Prolog在成功之前在代码中遇到了一个位置,可以探索另一个决策。当您按下;
时,您告诉Prolog探索该替代方案(Prolog 回溯)。 Prolog发现在X = 3
之后没有更多的解决方案,所以Prolog说“假”。
当您用X
替换_
时,您表示您不关心第一个参数是什么:
?- find_kth_e(_, [1,2,3,4,5], 3).
true ;
false.
在第一个查询中,Prolog成功找到了第3个元素,但是你表示你不关心那个元素是什么。所以Prolog成功并且只说“真实”。而且,和以前一样,选择点在那里。您的;
告诉Prolog 回溯到选择点,它找不到更多解决方案,因此最终显示“false”。
这是您可以做的另一项小测试,以显示成功与失败:
?- find_kth_e(X, [a,b,c,d,e], 3), write('Success!'), nl.
Success!
X = c ;
false.
自find_kth_e/3
成功以来,Prolog继续撰写“成功!”的write/1
声明。然后显示X = c
(Prolog显示在整个子句完成执行后导致成功的所有变量)。
这是一个失败案例:
?- find_kth_e(X, [a,b,c,d,e], 6), write('Success!'), nl.
false.
?-
find_kth_e/3
无法找到第6个元素,因此失败了。由于先前声明失败,Prolog没有继续并执行write/1
,您可以看到“成功!”没有显示。