我正在尝试在ProLog中解决以下问题。我是初学者。
定义谓词extend
,以便Xss
和Yss
列出
然后,如果extend(X, Xss, Yss)
可以通过添加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.
我认为我有一个有效的输入,我不明白为什么它会以char array1[4];
// ...
array1[3] = 0;
答案 0 :(得分:3)
由于你想对外部列表的每个元素做同样的事情,这对maplist/3
来说是一个非常漂亮的任务。您可以使用append/3
通过其他元素扩展列表,如下所示:
?- append([1,2],[element],Z).
Z = [1, 2, element].
但是,您希望append/3
中有两个缺少参数的maplist/3
,因此将第一个参数附加到第二个参数是合适的。要实现这一点,你可以编写一个辅助谓词,调用append/3
并翻转前两个参数,例如:
flippedappend(X,Y,Z) :-
append(Y,X,Z).
在此基础上,您可以像这样定义实际关系:
x_lists_extended(X,Xss,Yss) :-
maplist(flippedappend([X]),Xss,Yss).
您的示例查询会产生所需的结果:
?- x_lists_extended(g, [[e], [b, c, f], [k, h]], Yss).
Yss = [[e, g], [b, c, f, g], [k, h, g]].
请注意,您也可以反过来使用此谓词:
?- x_lists_extended(X, Xss, [[e, g], [b, c, f, g], [k, h, g]]).
X = g,
Xss = [[e], [b, c, f], [k, h]] ;
false.
答案 1 :(得分:1)
首先,这里有一个单例变量X
:
extend(X, [], []).
最好说extend(_, [], [])
,因为你再也不会引用X.了解为什么会这样,这很重要。在Prolog中,所有操作都是由于变量所在的关系而发生的。如果变量只出现在一个地方,那么它就不会参与任何关系,因此应该用_
替换。 (如果你进行了这样的修改并且代码似乎是无稽之谈,请停止并研究它,因为它总是意味着你误解了某些东西。)
其次,is/2
用于评估算术表达式。这里没有数学:Firstxss is [Firstxss,_|X]
所以你把它与=
混淆了。这真是一个双重打击,因为=
不意味着在Prolog中分配,这意味着统一。因此Prolog中没有真正的情况,你会有X = X+1
或类似的东西,这正是你在这里做的事情,试图为不同的目的重用一个变量。
本条款中Firstxss
的含义是什么?看起来它是头部第二个参数中嵌套列表中的第一个项目:换句话说,如果您调用了extend(g, [[e], [b, c, f], [k, h]], Yss)
,那么Firstxss = e
。 Firstxss
的值永远不会改变。它只能在递归调用中反弹。因此,当您立即说Firstxss is [Firstxss,_|X]
时,Prolog看到的是b = [b,_|<another var>]
。这并没有统一,你的谓词在这一点上失败了。不管怎样,说它先进了。你在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