Files
mercury/library/stack.m
Julien Fischer 94535ec121 Fix spelling and formatting throughout the system.
configure.ac:
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
library/*.m:
ssdb/*.m:
runtime/mercury_conf.h.in:
runtime/*.[ch]:
scripts/Mmake.vars.in:
trace/*.[ch]:
util/*.c:
	Fix spelling and doubled-up words.

	Delete trailing whitespace.

	Convert tabs into spaces (where appropriate).
2015-12-02 18:46:14 +11:00

156 lines
4.5 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
%---------------------------------------------------------------------------%
% Copyright (C) 1994-1995, 1997-1999, 2005-2006, 2011-2012 The University of Melbourne.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
%
% File: stack.m.
% Main author: fjh.
% Stability: high.
%
% This file contains a `stack' ADT.
% Stacks are implemented here using lists.
%
%---------------------------------------------------------------------------%
:- module stack.
:- interface.
:- import_module list.
%---------------------------------------------------------------------------%
:- type stack(T).
% `init(Stack)' is true iff `Stack' is an empty stack.
%
:- pred init(stack(T)::out) is det.
:- func init = stack(T).
% `is_empty(Stack)' is true iff `Stack' is an empty stack.
%
:- pred is_empty(stack(T)::in) is semidet.
% `is_full(Stack)' is intended to be true iff `Stack'
% is a stack whose capacity is exhausted. This implementation
% allows arbitrary-sized stacks, so is_full always fails.
%
:- pred is_full(stack(T)::in) is semidet.
% `push(Elem, Stack0, Stack)' is true iff `Stack' is
% the stack which results from pushing `Elem' onto the top
% of `Stack0'.
%
:- pred push(T::in, stack(T)::in, stack(T)::out) is det.
:- func push(stack(T), T) = stack(T).
% `push_list(Elems, Stack0, Stack)' is true iff `Stack'
% is the stack which results from pushing the elements of the
% list `Elems' onto the top of `Stack0'.
%
:- pred push_list(list(T)::in, stack(T)::in, stack(T)::out) is det.
:- func push_list(stack(T), list(T)) = stack(T).
% `top(Stack, Elem)' is true iff `Stack' is a non-empty
% stack whose top element is `Elem'.
%
:- pred top(stack(T)::in, T::out) is semidet.
% `det_top' is like `top' except that it will
% call error/1 rather than failing if given an empty stack.
%
:- pred det_top(stack(T)::in, T::out) is det.
:- func det_top(stack(T)) = T.
% `pop(Elem, Stack0, Stack)' is true iff `Stack0' is
% a non-empty stack whose top element is `Elem', and `Stack'
% the stack which results from popping `Elem' off `Stack0'.
%
:- pred pop(T::out, stack(T)::in, stack(T)::out) is semidet.
% `det_pop' is like `pop' except that it will
% call error/1 rather than failing if given an empty stack.
%
:- pred det_pop(T::out, stack(T)::in, stack(T)::out) is det.
% `depth(Stack, Depth)' is true iff `Stack' is a stack
% containing `Depth' elements.
%
:- pred depth(stack(T)::in, int::out) is det.
:- func depth(stack(T)) = int.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
:- import_module require.
%---------------------------------------------------------------------------%
:- type stack(T)
---> stack(list(T)).
stack.init = Stack :-
stack.init(Stack).
stack.init(stack([])).
stack.is_empty(stack([])).
stack.is_full(_) :-
semidet_fail.
stack.push(!.Stack, X) = !:Stack :-
stack.push(X, !Stack).
stack.push(Elem, !Stack) :-
!.Stack = stack(Elems),
!:Stack = stack([Elem | Elems]).
stack.push_list(!.Stack, Xs) = !:Stack :-
stack.push_list(Xs, !Stack).
stack.push_list([], !Stack).
stack.push_list([Elem | Elems], !Stack) :-
stack.push(Elem, !Stack),
stack.push_list(Elems, !Stack).
stack.top(stack([Elem | _]), Elem).
stack.det_top(Stack) = X :-
stack.det_top(Stack, X).
stack.det_top(Stack, Elem) :-
(
Stack = stack([Elem | _])
;
Stack = stack([]),
error("stack.det_top: top of empty stack")
).
stack.pop(Elem, !Stack) :-
!.Stack = stack([Elem | Elems]),
!:Stack = stack(Elems).
stack.det_pop( Elem, !Stack) :-
(
!.Stack = stack([Elem | Elems]),
!:Stack = stack(Elems)
;
!.Stack = stack([]),
error("stack.det_pop: pop from empty stack")
).
stack.depth(Stack) = Depth :-
stack.depth(Stack, Depth).
stack.depth(Stack, Depth) :-
Stack = stack(Elems),
list.length(Elems, Depth).
%---------------------------------------------------------------------------%
:- end_module stack.
%---------------------------------------------------------------------------%