序言。艰难的开端

时间:2016-05-18 18:46:34

标签: prolog

一开始:我是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.
  1. 什么是find_kth_e?功能?关系? (是的,我知道函数是一种关系)。
  2. 结果为3。没关系。但为什么第二个结果是false
  3. 让我们考虑一个修改版本:

    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替换为_的事实应该无关紧要。

    请解释。

1 个答案:

答案 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,您可以看到“成功!”没有显示。