那么,如何以声明方式阅读
remove([X|Xs], [X|Ys]) :-
Xs = [_,_|_],
remove(Xs,Ys).
最重要的是您首先要了解:- 的实际含义。
头部 :- 身体.
这意味着:只要 Body 成立,我们可以得出结论,Head 也成立。注意箭头相当不直观的方向。它从右到左。而不是从左到右,当你总结某事时通常非正式地写。然而,错误指向了我们“从中”得到什么的方向。
为了更好地看到这一点,您可以输入 Body 作为查询!
?- Xs = [_,_|_], remove(Xs,Ys).
Xs = [A, B],
Ys = [B] ;
Xs = [A, B, C],
Ys = [A, C] ;
...
所以我们得到了所有答案,除了Xs 的元素少于两个的答案。
请注意,在程序上,事情完全是在另一个方向发生的——这对初学者来说非常困惑。更重要的是,由于 Prolog 使用了两个“非传统”特性:时间回溯和变量——我的意思是 real 变量,意思是所有可能的术语——而不是你从命令式和函数式语言中知道的这些编译时构造.在这些语言中,变量是运行时值的持有者。具体的价值观。在 Prolog 中,变量也存在于运行时。有关更多信息,请参阅Difference between logic programming and functional programming
还有一个问题,我不确定你是否理解。想想:
?- remove(Xs, [1,2]).
Xs = [1, A, 2] ;
false.
这里删除了什么?没有什么!恰恰相反,我们在列表中添加了另一个元素。出于这个原因,remove/2 这个名字在 Prolog 中并不理想——它让我们想起了面向命令的编程语言,这些语言强制给出一些参数,而另一些参数是计算出来的。起初您可能认为这无关紧要,毕竟它只是一个名称。但是不要忘记,在编程时,您通常没有时间考虑所有这些。所以一个好的关系名称可能更可取。
要找到一个,只需从以下类型开始:list_list/2,然后细化list_removed/2 或list__without_2nd_last/2。