那么,如何以声明方式阅读
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 使用了两个“非传统”特性:时间回溯和变量——我的意思是真实变量,意思是所有可能的术语——而不是你从命令式和函数式语言中知道的这些编译时构造。在这些语言中,变量是运行时值的持有者。具体的价值观。在 Prolog 中,变量也存在于运行时。有关更多信息,请参阅逻辑编程和函数式编程之间的区别
还有一个问题,我不确定你是否理解。考虑到:
?- remove(Xs, [1,2]).
Xs = [1, A, 2] ;
false.
这里删除了什么?没有什么!恰恰相反,我们在列表中添加了另一个元素。出于这个原因,这个名字remove/2
在 Prolog 中并不理想——它让我们想起了面向命令的编程语言,这些语言强制一些参数是给定的,而另一些是计算的。起初您可能认为这无关紧要,毕竟它只是一个名称。但是不要忘记,在编程时,您通常没有时间考虑所有这些。所以一个好的关系名称可能更可取。
要找到一个,从类型开始:list_list/2
,然后细化list_removed/2
or list__without_2nd_last/2
。