Prolog 通过单个元素扩展列表列表

Prolog 通过单个元素扩展列表列表,prolog,Prolog,我试图在ProLog中解决以下问题。我是初学者 定义一个谓词extend,使得ifXss和Yss是 如果可以通过添加 元素X到Xss中每个元素的末尾,例如 ?- extend(g, [[e], [b, c, f], [k, h]], Yss). Yss = [[e, g], [b, c, f, g], [k, h, g]] 我已尝试以下操作,但出现错误消息: extend(X, [], []). extend(X, [[Firstxss,_] | Restxss], Yss) :-

我试图在ProLog中解决以下问题。我是初学者

定义一个谓词
extend
,使得if
Xss
Yss
是 如果可以通过添加 元素
X
Xss
中每个元素的末尾,例如

?- extend(g, [[e], [b, c, f], [k, h]], Yss).

Yss = [[e, g], [b, c, f, g], [k, h, g]]
我已尝试以下操作,但出现错误消息:

extend(X, [], []).

extend(X, [[Firstxss,_] | Restxss], Yss) :-
    Firstxss is [Firstxss,_|X],
    Yss is  [Yss | [Firstxss,_]],        
    Xss is Restxss,
    extend(X, Xss, Yss).
我的意见如下:

?- extend(g, [[e], [b, c, f], [k, h]], Yss).
它返回:

false.

我想我有一个有效的输入,我不明白为什么它返回为false。

首先,这里有一个单例变量
X

extend(X, [], []).
最好说
extend(u,[],[])
,因为你再也不会提到X了。理解这种情况的原因很重要。在Prolog中,所有操作都是由于变量之间的关系而发生的。如果变量仅出现在一个位置,则它不参与任何关系,因此应将其替换为
。(如果您进行了这样的更改,而代码似乎毫无意义,请停止并研究它,因为它总是意味着您误解了某些内容。)

其次,
is/2
用于计算算术表达式。这里面没有数学运算:
Firstxss是[Firstxss,124; X]
所以你把它和
=
混淆了。这确实是一个双重打击,因为在Prolog中,
=
并不意味着赋值,而是意味着统一。因此,在Prolog中没有真正的情况,您将拥有
X=X+1
或类似的东西,这正是您在这里所做的,试图为不同的目的重用变量

在本条款中,
Firstxss
是什么意思?它看起来像是头部第二个参数中嵌套列表的第一项:换句话说,如果调用
extend(g,[[e],[b,c,f],[k,h]],Yss)
,那么
Firstxss=e
Firstxss
的值永远不能更改。它只能在递归调用中恢复。因此,当您立即说
Firstxss是[Firstxss,124; X]
时,Prolog看到的是
b=[b,124;]
。这并不统一,您的谓词在这一点上失败。说它是先进的。您在下一行使用
Yss
时也会犯同样的错误

从关系上考虑你的问题会有帮助。你也有错误的基本情况。你的基本情况是什么?在这种情况下,您已经到达列表的末尾,您应该怎么做?附加X。这是您的基本情况:

extend(X, [], [X]).
现在想想在其他情况下你想做什么:你有头和尾巴。你如何扩展?延伸尾部,结果是头部附加到延伸的尾部。试着自己写这个条款,没那么难

一旦你有了它,扩展嵌套列表的机制很简单:你测试头部,看看它是否是一个列表。如果是,在头部和尾部重复出现!像这样:

extend(X, [Y|Ys], Result) :-
  (is_list(Y) -> extend(X, Y, Y1) ; Y1 = Y),
  ... % use Y1 as Y in building the result

首先,这里有一个单例变量
X

extend(X, [], []).
最好说
extend(u,[],[])
,因为你再也不会提到X了。理解这种情况的原因很重要。在Prolog中,所有操作都是由于变量之间的关系而发生的。如果变量仅出现在一个位置,则它不参与任何关系,因此应将其替换为
。(如果您进行了这样的更改,而代码似乎毫无意义,请停止并研究它,因为它总是意味着您误解了某些内容。)

其次,
is/2
用于计算算术表达式。这里面没有数学运算:
Firstxss是[Firstxss,124; X]
所以你把它和
=
混淆了。这确实是一个双重打击,因为在Prolog中,
=
并不意味着赋值,而是意味着统一。因此,在Prolog中没有真正的情况,您将拥有
X=X+1
或类似的东西,这正是您在这里所做的,试图为不同的目的重用变量

在本条款中,
Firstxss
是什么意思?它看起来像是头部第二个参数中嵌套列表的第一项:换句话说,如果调用
extend(g,[[e],[b,c,f],[k,h]],Yss)
,那么
Firstxss=e
Firstxss
的值永远不能更改。它只能在递归调用中恢复。因此,当您立即说
Firstxss是[Firstxss,124; X]
时,Prolog看到的是
b=[b,124;]
。这并不统一,您的谓词在这一点上失败。说它是先进的。您在下一行使用
Yss
时也会犯同样的错误

从关系上考虑你的问题会有帮助。你也有错误的基本情况。你的基本情况是什么?在这种情况下,您已经到达列表的末尾,您应该怎么做?附加X。这是您的基本情况:

extend(X, [], [X]).
现在想想在其他情况下你想做什么:你有头和尾巴。你如何扩展?延伸尾部,结果是头部附加到延伸的尾部。试着自己写这个条款,没那么难

一旦你有了它,扩展嵌套列表的机制很简单:你测试头部,看看它是否是一个列表。如果是,在头部和尾部重复出现!像这样:

extend(X, [Y|Ys], Result) :-
  (is_list(Y) -> extend(X, Y, Y1) ; Y1 = Y),
  ... % use Y1 as Y in building the result

由于您希望对外部列表的每个元素都执行相同的操作,因此对于
maplist/3
,这是一项非常漂亮的任务。您可以使用
append/3
通过以下附加元素扩展列表:

?- append([1,2],[element],Z).
Z = [1, 2, element].
但是,您需要在
maplist/3
中使用两个缺少参数的
append/3
,因此,将第一个参数附加到第二个参数是合适的。要实现这一点,可以编写一个辅助谓词,用fir调用
append/3
?- x_lists_extended(X, Xss, [[e, g], [b, c, f, g], [k, h, g]]).
X = g,
Xss = [[e], [b, c, f], [k, h]] ;
false.