将列表推送到堆栈作为一个元素没有括号

时间:2009-10-30 09:19:29

标签: prolog

我有像[1,2,+]这样的列表中的元素列表,我想将它们作为一个元素推送到堆栈中。我可以通过将它们放在方括号之间来做到这一点,但这会使括号出现在输出中。例如,我想将列表[1,2,+]的元素推送到堆栈:

stack([1,2,+],S,Y).

stack的位置:

stack(T,S,[T|S]).

问题在于,如果我将更多表达式压入堆栈,它们将具有嵌套括号。例如,我会得到[[+,1,2],[*,3,4]],但我想要[+,1,2,*,3,4]。我怎么能做到这一点?

3 个答案:

答案 0 :(得分:2)

你可以'压扁'列表:

| ?- List = [[+,1,2],[*,3,4]], flatten(List, FlatList).

List = [[+,1,2],[*,3,4]]
FlatList = [+,1,2,*,3,4]

Prolog解释器通常包含一个列表库,它将具有展平谓词,但这里有一个实现(来自SWI-Prolog的列表库):

flatten(List, FlatList) :-
flatten(List, [], FlatList0), !,
FlatList = FlatList0.

flatten(Var, Tl, [Var|Tl]) :-
  var(Var), !.
flatten([], Tl, Tl) :- !.
flatten([Hd|Tl], Tail, List) :- !,
  flatten(Hd, FlatHeadTail, List), 
  flatten(Tl, Tail, FlatHeadTail).
flatten(NonList, Tl, [NonList|Tl]).

答案 1 :(得分:2)

我不完全理解你的问题,总体目标是什么, 但也许你想要这样的东西。

stack(el(X, Y, Z), StackTail, [X, Y, Z | StackTail]).

如果您的堆栈元素都是三元组,那么不要将它们表示为三个元素的列表。这不是节省空间的。相反,将它们表示为术语el/3

另外,我知道您不希望您的堆栈成为复杂术语的列表, 但是原子术语列表。 stack/3的上述定义将会解开 推送时的el/3术语,弹出时会构建它。

答案 2 :(得分:1)

添加两个规则到堆栈应该可以解决问题。

由于这看起来很像家庭作业,我不会给出一个列表,但你需要一个新规则,其中第一个参数显式是一个列表,其中的项以递归方式预先附加到现有堆栈。

如果你写过member/2append/2,那么你应该没有问题。