2

在这个程序之前,我在下面的例子中看到过元素 X 是否属于字符串 L。

这个例子的代码如下:

member2(X, [X|_]).
member2(X,[_|T]):- member2(X,T).

我有一个表示基本情况的事实(如果 X 元素在列表的头部,则它属于列表),并且如果元素 X 不是头部,则使用该规则在列表的尾部递归搜索。 ..

这个版本对我来说非常晦涩难懂,有人建议我以这种方式查看它以了解它是如何工作的:

member2(X, [X|_]).
member2(X,Y):- Y = [_|T],
               member2(X,T).

所以意思就更清楚了:

我有一个代表基本情况的事实(如果 X 元素位于列表的头部,则它属于列表)。

规则说我必须证明两件事:

1) Y = [_|T] 这是真的,因为匿名变量 _ 与任何东西统一

2)递归搜索尾列表中的元素X

好的,现在我在理解这个新练习时遇到了问题,我必须编写一个 SWI Prolog 程序,给定两个字符串,将第二个字符串连接到第三个字符串中的第一个字符串

解决方案是:

myappend([], L, L).
myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).

我有一些问题要理解它是如何工作的

我知道事实代表基本情况:当第一个参数是 void 列表 [] 而第二个参数是非 void 列表时,第一个参数和第二个参数的连接是第二个参数列表(这等于第三个参数)

该规则表示第一个参数不是空列表的一般情况......所以我认为当这种情况发生时,它会删除 L1 参数的头部(第一个列表的头部),直到这是一个空列表 [] ,所以我将有基本情况,第三个参数统一到第二个......然后做回溯......

但是我很难理解该规则是如何运作的:

myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).

我正在尝试做类似前面示例的操作,并将其翻译成更通俗易懂的逻辑形式,因为这种方式对我来说非常不清楚……但我不知道该怎么做……我该怎么做

这个规则背后的逻辑是什么?这是什么意思?

4

2 回答 2

1
myappend([], L, L).

myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).

第二条规则的更长版本:

myappend(L1, L2, Concat) :- 
    L1 = [HeadL1|RestL1], Concat = [HeadConcat|RestConcat], 
    HeadL1 = HeadConcat,
    myappend(RestL1,L2,RestConcat).

第一条规则意味着,如果第一个列表为空,则连接的列表与第二个列表相同。

第二条规则意味着,最终列表将由第一个列表的第一个元素X以及一个由第一个列表和第二个列表L的其余部分连接而成的列表组成。请注意,第一个参数只有在它是一个列表并且它不为空时才能统一,这是由于 的约束。L1L2[X|L1]

您可以将谓词视为测试第一个、第二个和第三个参数是否具有第一个和第二个连接的关系是第三个参数。由于在 Prolog 中提取列表的头元素既简单又高效,因此上面的解决方案挑选出第一个元素,匹配它们([X|L1][X|L])并测试其余元素是否满足串联关系。

于 2012-12-20T15:04:03.577 回答
-1

串联([ ],L,L)。

串联([X | L1]、L2、[X | L]):- 串联(L1、L2、L)。

在这里,我们在现有列表的末尾添加元素/列表。

连接(现有列表,元素,[现有列表|元素])

1 -> 如果列表为空,则连接列表将是第二个列表。以第二个语句为例:现有列表 = [1,2]
添加元素 3

连接([X|L1],L2,[X|L]):- 连接(L1,L2,L)。

连接 ([1|2], 3, [1|x]):-

连接 ([2],3,[2|y]):- (x= [2|y];)

连接 ([], 3, 3)。(y = 3;)

因此最终列表变为 [1,2,3]。

于 2017-11-27T01:15:19.870 回答