I have list of elemen开发者_开发知识库ts in a list like [1,2,+]
and I want to push them as a one element onto a stack. I can do that by putting them between square brackets but this will make brackets appear in the output. For Example, I want to push the elements of the list [1,2,+] onto a stack:
stack([1,2,+],S,Y).
Where stack
is:
stack(T,S,[T|S]).
The problem is that if I push more expressions onto the stack, they will have nested brackets. For example, I would get [[+,1,2],[*,3,4]]
, but I want [+,1,2,*,3,4]
. How can I accomplish this?
You can 'flatten' the list:
| ?- List = [[+,1,2],[*,3,4]], flatten(List, FlatList).
List = [[+,1,2],[*,3,4]]
FlatList = [+,1,2,*,3,4]
Prolog interpreters often include a list library which will have a flatten predicate, but here is one implementation (from SWI-Prolog's lists library):
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]).
I don't completely understand your question and what is the overall goal, but maybe you want something like this.
stack(el(X, Y, Z), StackTail, [X, Y, Z | StackTail]).
If your stack elements are all triples, then do not represent them as lists of three elements. This is not space efficient. Rather, represent them as terms el/3
.
Also, I understand that you do not want your stack to be a list of complex terms,
but a list of atomic terms. The above definition of stack/3
will unravel
the el/3
term when pushing and will build it when popping.
Adding two more rules to stack should do the trick.
As this looks a lot like homework, I won't give a listing, but you will need a new rule where the first argument is explicitly a list, the items of which are recursively prepended to the existing stack.
If you've written member/2
and append/2
, you should have no problem with this.
精彩评论