关于如何从列表谓词中执行此特定查询删除的一些疑问

时间:2013-05-09 08:07:21

标签: prolog

我对此 del / 3 谓词的查询工作有疑问:

/* BASE CASE: If I delete X from List and X is the HEAD of List, NewList is
              the Tail of List
*/
del(X, [X|Tail], Tail).

/* GENERAL CASE: If the head of List is not X then the program have to delete
                 X in the Tail of List
*/
del(X, [Y|Tail], [Y|Tail1]) :- del(X, Tail, Tail1).

谓词逻辑非常简单:删除X项形成一个列表,创建一个没有X的新列表:如果X在列表的头部,则newlist就是它的尾部。否则,如果X项目不在列表的头部,请尝试在Tail中找到它(并删除),创建一个新的尾部Tail1。

好的,所以我对谓词逻辑没有任何问题但是我在尝试理解这个查询的工作方式时遇到了一些问题(我必须在另一个程序中使用它):

del([Top1|Stack1], [[a,b,c],[],[]], Stacks1).

因此,此查询必须从 [[a,b,c],[],[]] 中删除 [Top1 | Stack1] ,这是一个堆栈列表(在这种特殊情况下,我有3个堆栈:[a,b,c]和2个空堆栈:[])生成一个名为 Stacks1

的新堆栈列表

如果我尝试执行查询的跟踪,我会得到这个:

[trace]  ?- del([Top1|Stack1], [[a,b,c],[],[]], Stacks1).
   Call: (7) del([_G389|_G390], [[a, b, c], [], []], _G412) ? creep
   Exit: (7) del([a, b, c], [[a, b, c], [], []], [[], []]) ? creep
Top1 = a,
Stack1 = [b, c],
Stacks1 = [[], []] .

我有一些困难要理解为什么: [Top1 | Stack1] 与第一个堆栈统一 [a,b,c]

编辑: 我认为也许可以这样工作:Stacks列表是: [[a,b,c],[],[]] 这是一个列表列表其中第一个列表是: [a,b,c] (即此列表列表的 head **

所以当我写道: [Top1 | Stack1] 发生时:

Top1 = [a,b,c] * Stack1 = [[],[]] *

恰好 Top1 是堆栈列表中的第一个堆栈,而 Stack1 是其他堆栈的列表。

所以当我写谓词时:

 del([Top1|Stack1], Stacks, Stacks1).

(例如: Stacks = [[a,b,c],[],[]]

它以这种方式工作:

最好的Top1与堆栈列表中的第一个堆栈: [a,b,c] 并从堆栈列表中删除它...

当我执行简单查询时,我的dount与Prolog语义相关:

del(b, [a,b,c], NewList).

从列表中删除b项,NewList = [a,c]

但是当我知道要删除的项目的字段是这样的: [Head | Tail] 是要删除的Head项吗?

1 个答案:

答案 0 :(得分:3)

查询D=[[a,b,c],[],[]], del([A|B], D, C)[A|B]个元素中选择与D匹配的任何列表。这里唯一的可能是[A|B]=[a,b,c],剩下的就是C=[[],[]]

一般del完全回溯,逐一找到所有可能性。这里只有一种可能性。

为了更好地了解del,请尝试以下操作:

2 ?- del(X,[A,B,C],D).
X = A,
D = [B, C] ;
X = B,
D = [A, C] ;
X = C,
D = [A, B] ;
false.

它并没有试图找到" X;它只是从可能性(第二个参数)中逐个挑选它。这就是谓词所说的那样。

当然如果列表被实例化为基础术语,有些可能不匹配并且将被拒绝,从而产生对要搜索的值的印象:

4 ?- del(b, [a,b,c,d], R).
R = [a, c, d] ;
false.

5 ?- del(b, [a,b,X,d], R).
R = [a, X, d] ;
X = b,
R = [a, b, d] ;
false.

术语[A|B]只匹配任何非空列表(或逻辑变量):

6 ?- del([A|B], [[a],b,X,d], R).
A = a,
B = [],
R = [b, X, d] ;
X = [A|B],
R = [[a], b, d] ;
false.

7 ?- del([A|B], [[a],b,[],d], R).
A = a,
B = [],
R = [b, [], d] ;
false.

所以,例如del([A|B], [[1,2,3], [4,5], [], [6]], R)将从此示例调用的第二个参数中的4个列表中选择任何非空列表,并且当它执行此操作时,它会将A绑定到head元素并B选择列表的其余元素。

这个谓词在野外被称为select/3。 :)


插图:

del(X, [X|Tail], Tail).

     X        X
     --------------------
              T        T
              a        a
              i        i
              l        l

del(X, [Y|Tail], [Y|Tail1]) :- del(X, Tail, Tail1).

              Y        Y
     --------------------
              T        T
       /      .        a
     X -      .        i
       \      .        l
              .        1
              l