[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Jul 19 18:56:37 1993 
Subject:Stacks 
From:Anthony Worrall 
Volume-ID:930719.07 

Here are some thoughts of a country bumpkin :-)


In order to get the following behaviour I think we need to change our (my)
ideas about the stack.

1.
    : [a],[%hd()%] =>
    ** [ a ]
2.
    : [a],{%hd()%} =>
    ** {a}

The first case fails because the call to "hd" takes a popstackmark as
argument. The second case fails because the change in stacklength is
used to determine the size of the vector and "hd" does not change
the stacklength.

The traditional stack can be thought of as a list where a push is
equivalent to cons-ing an item on to the stack and a pop is equivalent
to dest-ing the stack

ie
    PUSH item         item :: STACK -> STACK
    POP               dest(STACK) -> STACK

Now consider the stack to be a list of lists. A push is then equivalent to
cons-ing an item on to the first list in the stack and a pop is equivalent
to dest-ing the first non-empty list in the stack.

ie

    PUSH item       item :: (hd(STACK)) -> hd(STACK);
    POP             for i from 1 to length(STACK) do
                        unless STACK(i) == [] then
                            dest(STACK(i)) -> STACK(i);
                            quitloop;
                         endunless;
                    endfor
                    (check for stack underflow)

The opener% is then equivalent to cons-ing an empty list onto the stack
and %closer takes the first list from the stack and creates the appropriate
structure.

    opener%         [] :: STACK -> STACK;
    %closer         destlist(dest(STACK) -> STACK).consXXX

This gives a clear way of thinking about an open stack which can
achieve the desired result. The problem then is how to implement this
in an efficient manner. Any ideas?


Anthony.Worrall@Reading.ac.uk