/* Stack (Rosetta code) in Picat. http://rosettacode.org/wiki/Stack#Prolog """ A stack is a container of elements with last in, first out access policy. Sometimes it also called LIFO. The stack is accessed through its top. The basic stack operations are: push stores a new element onto the stack top; pop returns the last pushed stack element, while removing it from the stack; empty tests if the stack contains no elements. Sometimes the last pushed stack element is made accessible for immutable access (for read) or mutable access (for write): top (sometimes called peek to keep with the p theme) returns the topmost element without modifying the stack. Stacks allow a very simple hardware implementation. They are common in almost all processors. In programming, stacks are also very popular for their way (LIFO) of resource management, usually memory. Nested scopes of language objects are naturally implemented by a stack (sometimes by multiple stacks). This is a classical way to implement local variables of a re-entrant or recursive subprogram. Stacks are also used to describe a formal computational framework. See stack machine. Many algorithms in pattern matching, compiler construction (e.g. recursive descent parsers), and machine learning (e.g. based on tree traversal) have a natural representation in terms of stacks. Task Create a stack supporting the basic operations: push, pop, empty. """ This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ main => go. % Functiona approach go => L = [], empty(L), L2 = L.push(1).push(2).push(3), println(L2), println(top=L2.top), L3 = L2.pop(E1).pop(E2).pop(E3), println([e1=E1,e2=E2,e3=E3]), println(l3=L3), empty(L3), println(ok), nl. go => true. % {{trans|Prolog}} go2 => L = [], empty(L), push2(1,L,L2), push2(2,L2,L3), push2(3,L3,L4), println(L4), top2(L4,Top), println(top=Top), pop2(L4,E1,L5), pop2(L5,E2,L6), pop2(L6,E3,L7), println([e1=E1,e2=E2,e3=E3]), println(l7=L7), empty(L7), println(ok), nl. go2 => true. % Functional % push(L,E) % - push E to top of L % - returns the stack [E] ++ L push(L,E) = [E] ++ L. % pop(L,E) % - removes the first element of L: E % - returns the rest pop(L,E) = Rest, not empty(L) => L = [E|Rest]. % Is the stack empty? empty([]). top(L) = L.first. % {{trans|Prolog}} % push2(Element,Stack,New ) % True if New is [Element|Stack] push2(Element,Stack,[Element|Stack]). % pop2(Stack,Top,New) % True if Top and New are head and tail, respectively, of Stack pop2([Top|Stack],Top,Stack). top2([Top|Stack],Top). % empty2(Stack) % True if Stack is empty empty2([]).