This is mercury_library.info, produced by makeinfo version 4.8 from
library.texi_pp.

INFO-DIR-SECTION The Mercury Programming Language
START-INFO-DIR-ENTRY
* Mercury Library: (mercury_library).  The Mercury Library Reference Manual.
END-INFO-DIR-ENTRY

   This file documents the Mercury standard library, version 14.01.1.

   Copyright (C) 1995-1997,1999-2014 The University of Melbourne.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the entire resulting derived work is distributed under the terms
of a permission notice identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions.


File: mercury_library.info,  Node: pprint,  Next: pqueue,  Prev: parsing_utils,  Up: Top

48 pprint
*********

     %--------------------------------------------------%
     % vim:ts=4 sw=4 expandtab tw=0 wm=0 ft=mercury
     %--------------------------------------------------%
     % Copyright (C) 2000-2007, 2010-2011 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: pprint.m
     % Main author: rafe
     % Stability: medium
     %
     % NOTE: this module has now been superceded by pretty_printer.m which is
     % more economical, produces better output, has better control over
     % the amount of output produced, and supports user-specifiable formatting
     % for arbitrary types.
     %
     % ABOUT
     % -----
     %
     % This started off as pretty much a direct transliteration of Philip Wadler's
     % Haskell pretty printer described in "A Prettier Printer", available at
     % http://cm.bell-labs.com/cm/cs/who/wadler/topics/recent.html
     %
     % Several changes have been made to the algorithm to preserve linear running
     % time under a strict language and to ensure scalability to extremely large
     % terms without thrashing the VM system.
     %
     % Wadler's approach has three main advantages:
     % 1. the layout algebra is small and quite intuitive (more so than Hughes');
     % 2. the pretty printer is optimal in the sense that it will never generate
     %    output that over-runs the specified width unless that is unavoidable; and
     % 3. the pretty printer is bounded in that it never needs to look more than
     %    k characters ahead to make a formatting decision.
     %
     % I have made the following changes:
     %
     % (a) rather than having group/1 as a non-primitive function (for
     % allowing line-breaks to be converted into spaces at the pretty
     % printer's discretion) over docs, I have extended the doc type to
     % include a `GROUP' constructor and made the appropriate algorithmic
     % changes.  Because `UNION' only arises as a consequence of processing
     % a 'GROUP' it turns out to be simpler to do away with `UNION'
     % altogether and convert clauses that process `UNION' terms to
     % processing `GROUP's.
     %
     % (b) Flattened `line' breaks become empty strings rather than spaces.
     %
     % (c) The third change is the introduction of the `LABEL' constructor,
     % which acts much like `NEST', except that indentation is defined
     % using a string rather than a number of spaces.  This is useful for,
     % e.g., multi-line compiler errors and warnings that should be
     % prefixed with the offending source file and line number.
     %
     % (d) The formatting decision procedure has been altered to preserve
     % linear runtime behaviour in a strict language.
     %
     % (e) Naively marking up a term as a doc has the drawback that the
     % resulting doc is significantly larger than the original term.
     % Worse, any sharing structure in the original term leads to
     % duplicated sub-docs, which can cause an exponential blow-up in the
     % size of the doc w.r.t. the source term.  To get around this problem
     % I have introduced the 'DOC' constructor which causes on-demand
     % conversion of arguments.
     %
     % [This is not true laziness in the sense that the 'DOC', once
     % evaluated, will be overwritten with its value.  This approach would
     % lead to garbage retention and not solve the page thrashing behaviour
     % otherwise experienced when converting extremely large terms.
     % Instead, each 'DOC' is reevaluated each time it is examined.  This
     % trades off computation time for space.]
     %
     % I have added several obvious general purpose formatting functions.
     %
     %
     % USAGE
     % -----
     %
     % There are two stages in pretty printing an object of some type T:
     % 1. convert the object to a pprint.doc using the constructor functions
     %    described below or by simply calling pprint.to_doc/[1,2];
     % 2. call pprint.write/[4,5] or pprint.to_string/2 passing the display width
     %    and the doc.
     %
     %
     % EXAMPLES
     % --------
     %
     % The doc/1 type class has types string, char, int, float and doc as instances.
     % Hence these types can all be converted to docs by applying doc/1.
     % This happens automatically to the arguments of ++/2. Users may find it
     % convenient to add other types as instances of the doc/1 type class.
     %
     % Below are some docs followed by the ways they might be displayed by the
     % pretty printer given various line widths.
     %
     % 1. "Hello " ++ line ++ "world"
     %
     %   Hello
     %   world
     %
     % 2. group("Hello " ++ line ++ "world")
     %
     %   Hello world
     %
     %   Hello
     %   world
     %
     % 3. group("Hello " ++ nest(3, line ++ "world"))
     %
     %   Hello world
     %
     %   Hello
     %      world
     %
     % 4. group("Goodbye " ++ nest(3, line ++ "cruel " ++ line ++ "world")
     %
     %   Goodbye cruel world
     %
     %   Goodbye
     %      cruel
     %      world
     %
     % 5. group("Goodbye " ++ nest(3, line ++ group("cruel " ++ line ++ "world")))
     %
     %   Goodbye cruel world
     %
     %   Goodbye
     %      cruel world
     %
     %   Goodbye
     %      cruel
     %      world
     %
     % 6. label("Look! ", line ++
     %                    group("Goodbye " ++
     %                          nest(3, line ++ group("cruel " ++ line ++ "world"))))
     %
     %   Look! Goodbye cruel world
     %
     %   Look! Goodbye
     %   Look!    cruel world
     %
     %   Look! Goodbye
     %   Look!    cruel
     %   Look!    world
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module pprint.
     :- interface.

     :- import_module char.
     :- import_module io.
     :- import_module list.
     :- import_module stream.
     :- import_module string.
     :- import_module univ.

     %--------------------------------------------------%

         % Clients must translate data structures into docs for
         % the pretty printer to display.
         %
     :- type doc.

         % This typeclass can be used to simplify the construction of docs.
         %
     :- typeclass doc(T) where [
         % Convert a T to a doc, placing a limit on how much of the term
         % will be fully converted as follows:
         %
         % doc(_, f         ) = f
         % doc(N, f(A, B, C)) = f/3 if N =< 0
         % doc(N, f(A, B, C)) = some representation of the term whereby
         %   A is converted as doc(N - 1, A),
         %   B is converted as doc(N - 2, B), and
         %   C is converted as doc(N - 3, C)
         %   - if there are more than N arguments, the N+1th and subsequent
         %     arguments should be replaced with a single ellipsis.
         %
         func doc(int, T) = doc
     ].

     :- instance doc(doc).
     :- instance doc(string).
     :- instance doc(int).
     :- instance doc(float).
     :- instance doc(char).

         % Fully convert an instance of doc/1.
         %
     :- func doc(T) = doc <= (doc(T)).

         % An alternative to the <>/2 concatenation operator that works
         % on members of the doc/1 typeclass.
         %
     :- func T1 ++ T2 = doc <= (doc(T1), doc(T2)).

         % The empty document corresponding to the null string.
         %
     :- func nil                 = doc.

         % The document consisting of a single string.
         %
         % NOTE: since string is now an instance of the doc/1
         % type class, it is simpler to just apply the doc/1
         % method.
         %
     :- func text(string)        = doc.

         % The composition of two docs with no intervening space.
         %
         % NOTE: with the addition of the doc/1 type class, it is
         % simpler to construct compound docs using ++/2.
         %
     :- func doc `<>` doc        = doc.

         % The newline document. In a group doc (see below) the pretty printer
         % may choose to instead `flatten' all line docs into nil docs in order
         % to fit a doc on a single line.
         %
     :- func line                = doc.

         % Any `line' docs in the body that are not flattened out by the
         % pretty printer are followed by the given number of spaces
         % (nested `nest's add up).
         %
     :- func nest(int, T)        = doc <= (doc(T)).

         % Identical to a nest doc except that indentation is extended with
         % a string label rather than some number of spaces.
         %
     :- func label(string, T)    = doc <= (doc(T)).

         % A group doc gives the pretty printer a choice: if the doc can be printed
         % without line wrapping then it does so (all line, label, nest and group
         % directives within the group are ignored); otherwise the pretty printer
         % treats the group body literally, although nested group docs remain as
         % choice points.
         %
     :- func group(T)            = doc <= (doc(T)).

         % This function can be used to convert strings, chars, ints and floats
         % to their text doc equivalents.
         %
         % NOTE: since these types are now instances of the doc/1 type class,
         % it is simpler to just apply the doc/1 method to these types.
         %
     :- func poly(string.poly_type) = doc.

         % Shorthand for doc ++ line ++ doc.
         %
     :- func doc `</>` doc       = doc.

         % Various bracketing functions.
         %
         %   bracketed(L, R, Doc) = L ++ Doc ++ R
         %       parentheses(Doc) = bracketed("(", ")", Doc)
         %          brackets(Doc) = bracketed("[", "]", Doc)
         %            braces(Doc) = bracketed("{", "}", Doc)
         %
     :- func bracketed(T1, T2, T3)  = doc <= (doc(T1), doc(T2), doc(T3)).
     :- func parentheses(T)         = doc <= (doc(T)).
     :- func brackets(T)            = doc <= (doc(T)).
     :- func braces(T)              = doc <= (doc(T)).

         % packed(Sep, [X1, X2, .., Xn]) = G1 `<>` G2 `<>` .. `<>` Gn where
         % Gi = group(line `<>` Xi `<>` Sep), except for Gn where
         % Gn = group(line `<>` Xn).
         %
         % For the singleton list case, packed(Sep, [X]) = group(line `<>` X).
         %
         % The resulting doc tries to pack as many items on a line as possible.
         %
     :- func packed(T1, list(T2)) = doc <= (doc(T1), doc(T2)).

         % A variant of the above whereby only the first N elements of the list
         % are formatted and the rest are replaced by a single ellipsis.
         %
     :- func packed(int, T1, list(T2)) = doc <= (doc(T1), doc(T2)).

         % packed_cs(Xs) = packed(comma_space, Xs).
         %
         % For example, to pretty print a Mercury list of docs one might use
         %
         %   brackets(nest(2, packed_cs(Xs)))
         %
     :- func packed_cs(list(T)) = doc <= (doc(T)).

         % A variant of the above whereby only the first N elements of the list
         % are formatted and the rest are replaced by a single ellipsis.
         %
     :- func packed_cs(int, list(T)) = doc <= (doc(T)).

         % This is like a depth-limited version of packed_cs/1 that first calls
         % to_doc/2 on each member of the argument list.
         %
     :- func packed_cs_to_depth(int, list(T)) = doc.

         % This is like a version of packed_cs_to_depth/1 that first calls
         % univ_value/1 for each member of the argument list.
         %
     :- func packed_cs_univ_args(int, list(univ)) = doc.

         % separated(PP, Sep, [X1,...,Xn]) =
         %   PP(X1) `<>` Sep `<>` ... Sep `<>` PP(Xn)
         %
     :- func separated(func(T1) = doc, T2, list(T1)) = doc <= (doc(T2)).

         % Handy punctuation docs and versions with following
         % spaces and/or line breaks.
         %
     :- func comma               = doc.
     :- func semic               = doc.      % Semicolon.
     :- func colon               = doc.
     :- func space               = doc.
     :- func comma_space         = doc.
     :- func semic_space         = doc.
     :- func colon_space         = doc.
     :- func comma_line          = doc.
     :- func semic_line          = doc.
     :- func colon_line          = doc.
     :- func space_line          = doc.
     :- func comma_space_line    = doc.
     :- func semic_space_line    = doc.
     :- func colon_space_line    = doc.
     :- func ellipsis            = doc.      % "...".

         % Performs word wrapping at the end of line, taking whitespace sequences
         % as delimiters separating words.
         %
     :- func word_wrapped(string) = doc.

         % Convert arbitrary terms to docs. This requires std_util.functor/3 to work
         % on all components of the object being converted. The second version
         % places a maximum depth on terms which are otherwise truncated in the
         % manner described in the documentation for the doc/2 method of the doc/1
         % type class.
         %
         % This may throw an exception or cause a runtime abort if the term
         % in question has user-defined equality.
         %
     :- func to_doc(T)           = doc.
     :- func to_doc(int, T)      = doc.

         % Convert docs to pretty printed strings. The int argument specifies
         % a line width in characters.
         %
     :- func to_string(int, doc) = string.

         % Write docs out in pretty printed format. The int argument specifies
         % a page width in characters.
         %
     :- pred write(int::in, T::in, io::di, io::uo) is det <= doc(T).

         % Write docs to the specified string writer stream in pretty printed
         % format. The int argument specifies a page width in characters.
         %
     :- pred write(Stream::in, int::in, T::in, State::di, State::uo) is det
         <= ( doc(T), stream.writer(Stream, string, State) ).

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: pqueue,  Next: pretty_printer,  Prev: pprint,  Up: Top

49 pqueue
*********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1994-1995, 1997, 1999, 2003-2007, 2009 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: pqueue.m.
     % Main author: conway.
     % Stability: high.
     %
     % This module implements a priority queue ADT.
     %
     % A pqueue is a priority queue.  A priority queue holds a collection
     % of key-value pairs; the interface provides operations to create
     % an empty priority queue, to insert a key-value pair into a priority
     % queue, and to remove the element with the lowest key.
     %
     % Insertion/removal is not guaranteed to be "stable"; that is,
     % if you insert two values with the same key, the order in which
     % they will be removed is unspecified.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module pqueue.
     :- interface.

     :- import_module assoc_list.

     %--------------------------------------------------%

     :- type pqueue(K, V).

         % Create an empty priority queue.
         %
     :- func pqueue.init = pqueue(K, V).
     :- pred pqueue.init(pqueue(K, V)::out) is det.

         % True iff the priority queue is empty.
         %
     :- pred pqueue.is_empty(pqueue(K, V)::in) is semidet.

         % Insert a value V with key K into a priority queue
         % and return the new priority queue.
         %
     :- func pqueue.insert(pqueue(K, V), K, V) = pqueue(K, V).
     :- pred pqueue.insert(K::in, V::in, pqueue(K, V)::in, pqueue(K, V)::out)
         is det.

         % Extract the smallest key-value pair from the priority queue without
         % removing it.  Fails if the priority queue is empty.
         %
     :- pred pqueue.peek(pqueue(K, V)::in, K::out, V::out) is semidet.

         % Extract the smallest key from the priority queue without removing it.
         % Fails if the priority queue is empty.
         %
     :- pred pqueue.peek_key(pqueue(K, V)::in, K::out) is semidet.

         % Extract the smallest value from the priority queue without removing
         % it.  Fails if the priority queue is empty.
         %
     :- pred pqueue.peek_value(pqueue(K, V)::in, V::out) is semidet.

         % As above, but calls error/1 if the priority queue is empty.
         %
     :- pred pqueue.det_peek(pqueue(K, V)::in, K::out, V::out) is det.
     :- func pqueue.det_peek_key(pqueue(K, V)) = K.
     :- func pqueue.det_peek_value(pqueue(K, V)) = V.

         % Remove the smallest item from the priority queue.
         % Fails if the priority queue is empty.
         %
     :- pred pqueue.remove(K::out, V::out, pqueue(K, V)::in, pqueue(K, V)::out)
         is semidet.

         % As above, but calls error/1 if the priority queue is empty.
         %
     :- pred pqueue.det_remove(K::out, V::out, pqueue(K, V)::in, pqueue(K, V)::out)
         is det.

         % Merges all the entries of one priority queue with another, returning
         % the merged list.
         %
     :- func pqueue.merge(pqueue(K, V), pqueue(K, V)) = pqueue(K, V).
     :- pred pqueue.merge(pqueue(K, V)::in, pqueue(K, V)::in, pqueue(K, V)::out)
         is det.

         % Extract all the items from a priority queue by repeated
         % removal, and place them in an association list.
         %
     :- func pqueue.to_assoc_list(pqueue(K, V)) = assoc_list(K, V).
     :- pred pqueue.to_assoc_list(pqueue(K, V)::in, assoc_list(K, V)::out)
         is det.

         % Insert all the key-value pairs in an association list
         % into a priority queue.
         %
     :- func pqueue.assoc_list_to_pqueue(assoc_list(K, V)) = pqueue(K, V).
     :- pred pqueue.assoc_list_to_pqueue(assoc_list(K, V)::in, pqueue(K, V)::out)
         is det.

         % A synonym for pqueue.assoc_list_to_pqueue/1.
         %
     :- func pqueue.from_assoc_list(assoc_list(K, V)) = pqueue(K, V).

         % length(PQueue) = Length.
         %
         % Length is the number of items in PQueue
         %
     :- func pqueue.length(pqueue(K, V)) = int.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: pretty_printer,  Next: prolog,  Prev: pqueue,  Up: Top

50 pretty_printer
*****************

     %--------------------------------------------------%
     % vim: ts=4 sw=4 expandtab tw=0 wm=0 ft=mercury
     %--------------------------------------------------%
     % Copyright (C) 2007, 2009-2011 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: pretty_printer.m
     % Main author: rafe
     % Stability: medium
     %
     % This module defines a doc type for formatting and a pretty printer for
     % displaying docs.
     %
     % The doc type includes data constructors for outputting strings, newlines,
     % forming groups, indented blocks, and arbitrary values.
     %
     % The key feature of the algorithm is this: newlines in a group are ignored if
     % the group can fit on the remainder of the current line.  [The algorithm is
     % similar to those of Oppen and Wadler, although it uses neither coroutines or
     % laziness.]
     %
     % When a newline is printed, indentation is also output according to the
     % current indentation level.
     %
     % The pretty printer includes special support for formatting Mercury style
     % terms in a way that respects Mercury's operator precedence and
     % bracketing rules.
     %
     % The pretty printer takes a parameter specifying a collection of user-defined
     % formatting functions for handling certain types rather than using the
     % default built-in mechanism.  This allows one to, say, format maps as
     % sequences of (key -> value) pairs rather than exposing the underlying
     % 234-tree structure.
     %
     % The amount of output produced is controlled via limit parameters.  Three
     % kinds of limits are supported: the output line width, the maximum number of
     % lines to be output, and a limit on the depth for formatting arbitrary terms.
     % Output is replaced with ellipsis ("...") when limits are exceeded.
     %
     %--------------------------------------------------%

     :- module pretty_printer.
     :- interface.

     :- import_module deconstruct.
     :- import_module list.
     :- import_module io.
     :- import_module stream.
     :- import_module type_desc.
     :- import_module univ.

     %--------------------------------------------------%

     :- type doc
         --->    str(string)
                 % Output a literal string. Strings containing newlines, hard tabs,
                 % etc. will lead to strange output.

         ;       nl
                 % Output a newline, followed by indentation, iff the enclosing
                 % group does not fit on the current line and starting a new line
                 % adds more space.

         ;       hard_nl
                 % Always outputs a newline, followed by indentation.

         ;       docs(docs)
                 % An embedded sequence of docs.

         ;       format_univ(univ)
                 % Use a specialised formatter if available, otherwise use the
                 % generic formatter.

         ;       format_list(list(univ), doc)
                 % Pretty print a list of items using the given doc as a separator
                 % between items.

         ;       format_term(string, list(univ))
                 % Pretty print a term with zero or more arguments. If the term
                 % corresponds to a Mercury operator it will be printed with
                 % appropriate fixity and, if necessary, in parentheses. The term
                 % name will be quoted and escaped if necessary.

         ;       format_susp((func) = doc)
                 % The argument is a suspended computation used to lazily produce a
                 % doc. If the formatting limit has been reached then just "..." is
                 % output, otherwise the suspension is evaluated and the resulting
                 % doc is used. This is useful for formatting large structures
                 % without using more resources than required. Expanding a
                 % suspended computation reduces the formatting limit by one.

         ;       pp_internal(pp_internal).
                 % pp_internal docs are used in the implementation and cannot
                 % be exploited by user code.

     :- type docs == list(doc).

         % This type is private to the implementation. It cannot be exploited by
         % user code.
         %
     :- type pp_internal.

         % indent(IndentString, Docs):
         %
         % Append IndentString to the current indentation while printing Docs.
         % Indentation is printed after each newline that is output.
         %
     :- func indent(string, docs) = doc.

         % indent(Docs) = indent("  ", Docs).
         %   A convenient abbreviation.
         %
     :- func indent(docs) = doc.

         % group(Docs):
         %
         % If Docs can be output on the remainder of the current line by ignoring
         % any nls in Docs, then do so. Otherwise nls in Docs are printed
         % (followed by any indentation). The formatting test is applied recursively
         % for any subgroups in Docs.
         %
     :- func group(docs) = doc.

         % format(X) = format_univ(univ(X)):
         % A convenient abbreviation.
         %
     :- func format(T) = doc.

         % format_arg(Doc) has the effect of formatting any term in Doc as though
         % it were an argument in a Mercury term by enclosing it in parentheses if
         % necessary.
         %
     :- func format_arg(doc) = doc.

         % The pretty-printer limit type, used to control conversion by
         % format_univ, format_list, and format_term.
         %
         % A limit of linear(N) formats the first N functors before truncating
         % output to "...".
         %
         % A limit of triangular(N) formats a term t(X1, ..., Xn) by applying a
         % limit of triangular(N - 1) when formatting X1, triangular(N - 2) when
         % formatting X2, ..., and triangular(N - n) when formatting Xn.
         % The cost of formatting the term t(X1, ..., Xn) as a whole is just one,
         % so a sequence of terms T1, T2, ... is formatted with limits
         % triangular(N), triangular(N - 1), ... respectively.  When the
         % limit is exhausted, terms are output as just "...".
         %
     :- type formatting_limit
         --->    linear(int)                 % Print this many functors.
         ;       triangular(int).            % Print first arg with limit N-1,
                                             % second arg with limit N-2, ...

         % The type of generic formatting functions.
         % The first argument is the univ of the value to be formatted.
         % The second argument is the list of argument type_descs for
         % the type of the first argument.
         %
     :- type formatter == ( func(univ, list(type_desc)) = doc ).

         % A formatter_map maps types to pps.  Types are identified by module name,
         % type name, and type arity.
         %
     :- type formatter_map.

         % Construct a new formatter_map.
         %
     :- func new_formatter_map = formatter_map.

         % set_formatter(ModuleName, TypeName, TypeArity, Formatter, FMap):
         %
         % Update FMap to use Formatter to format the type
         % ModuleName.TypeName/TypeArity.
         %
     :- func set_formatter(string, string, int, formatter, formatter_map) =
         formatter_map.



         % format(Stream, FMap, LineWidth, MaxLines, Limit, Doc, !State):
         %
         % Format Doc to fit on lines of LineWidth chars, truncating after
         % MaxLines lines, fomatting format_univ(_) docs using specialised
         % formatters Formatters starting with pretty-printer limits Limit.
         %
     :- pred write_doc_to_stream(Stream, noncanon_handling, formatter_map, int, int,
         formatting_limit, doc, State, State)
         <= stream.writer(Stream, string, State).
     :- mode write_doc_to_stream(in, in(canonicalize), in, in, in, in, in,
         di, uo) is det.
     :- mode write_doc_to_stream(in, in(include_details_cc), in, in, in, in, in,
         di, uo) is cc_multi.

         % Convenience predicates.  A user-configurable set of type-specific
         % formatters and formatting parameters are attached to the I/O state.
         % The I/O state-specific format predicate below uses this settings.
         %
     :- type pp_params
         --->    pp_params(
                     pp_line_width   :: int,             % Line width in characters.
                     pp_max_lines    :: int,             % Max lines to output.
                     pp_limit        :: formatting_limit % Term formatting limit.
                 ).

         % An initial default formatter_map is provided for the most commonly
         % used types in the Mercury standard library (array, char, float,
         % int, map, string, etc.)
         %
         % The default formatter_map may also be updated by users' modules
         % (e.g., in initialisation goals).
         %
         % These defaults are thread local (i.e., changes made by one thread to
         % the default formatter_map will not be visible in another thread).
         %
     :- pred get_default_formatter_map(formatter_map::out, io::di, io::uo) is det.
     :- pred set_default_formatter_map(formatter_map::in, io::di, io::uo) is det.
     :- pred set_default_formatter(string::in, string::in, int::in, formatter::in,
         io::di, io::uo) is det.

         % The initial default pp_params are pp_params(78, 100, triangular(100)).
         % These defaults are thread local (i.e., changes made by one thread to
         % the default pp_params will not be visible in another thread).
         %
     :- pred get_default_params(pp_params::out, io::di, io::uo) is det.
     :- pred set_default_params(pp_params::in, io::di, io::uo) is det.

         % write_doc(Doc, !IO):
         % write_doc(FileStream, Doc, !IO):
         %
         % Format Doc to io.stdout_stream or FileStream respectively, using
         % write_doc_to stream, with include_details_cc, the default formatter_map,
         % and the default pp_params.
         %
     :- pred write_doc(doc::in, io::di, io::uo) is det.
     :- pred write_doc(io.output_stream::in, doc::in, io::di, io::uo) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: prolog,  Next: queue,  Prev: pretty_printer,  Up: Top

51 prolog
*********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1997-2003, 2005-2006, 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: prolog.m.
     % Main author: fjh.
     % Stability: high.
     %
     % This file contains predicates that are intended to help people
     % porting Prolog programs, or writing programs in the intersection
     % of Mercury and Prolog.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module prolog.
     :- interface.

     :- import_module list.
     :- import_module pair.
     :- import_module univ.

     %--------------------------------------------------%
     %
     % Prolog arithmetic operators
     %

     :- pred T =:= T.            % In Mercury, just use =
     :- mode in =:= in is semidet.

     :- pred T =\= T.            % In Mercury, just use \=
     :- mode in =\= in is semidet.

     /*******
     is/2 is currently defined in int.m, for historical reasons.

     :- pred is(T, T) is det.        % In Mercury, just use =
     :- mode is(uo, di) is det.
     :- mode is(out, in) is det.
     ******/

     %--------------------------------------------------%
     %
     % Prolog term comparison operators
     %

     :- pred T == T.             % In Mercury, just use =
     :- mode in == in is semidet.

     :- pred T \== T.            % In Mercury, just use \=
     :- mode in \== in is semidet.

     % Prolog's so-called "univ" operator, `=..'.
     % Note: this is not related to Mercury's "univ" type!
     % In Mercury, use `deconstruct.deconstruct' instead.

     :- pred T =.. univ_result.
     :- mode in =.. out is det.
         %
         % Note that the Mercury =.. is a bit different to the Prolog
         % one.  We could make it slightly more similar by overloading '.'/2,
         % but that would cause ambiguities that might prevent type
         % inference in a lot of cases.
         %
     % :- type univ_result ---> '.'(string, list(univ)).
     :- type univ_result == pair(string, list(univ)).

         % arg/3.
         % In Mercury, use arg/4 (defined in module deconstruct) instead:
         %
         %   arg(ArgNum, Term, Data) :-
         %       deconstruct.arg(Term, canonicalize, ArgNum - 1, Data).
         %
     :- pred arg(int::in, T::in, univ::out) is semidet.

         % det_arg/3: like arg/3, but calls error/1 rather than failing
         % if the index is out of range.
         %
     :- pred det_arg(int::in, T::in, univ::out) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: queue,  Next: random,  Prev: prolog,  Up: Top

52 queue
********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1994-1995, 1997-1999, 2003-2006, 2011 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: queue.m.
     % Main author: fjh.
     % Stability: high.
     %
     % This file contains a `queue' ADT.
     % A queue holds a sequence of values, and provides operations
     % to insert values at the end of the queue (queue.put) and remove them from
     % the front of the queue (queue.get).
     %
     % This implementation is in terms of a pair of lists.
     % The put and get operations are amortized constant-time.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module queue.
     :- interface.

     :- import_module list.

     %--------------------------------------------------%

     :- type queue(T).

         % `queue.init(Queue)' is true iff `Queue' is an empty queue.
         %
     :- func queue.init = queue(T).
     :- pred queue.init(queue(T)::out) is det.

         % 'queue_equal(Q1, Q2)' is true iff Q1 and Q2 contain the same
         % elements in the same order.
         %
     :- pred queue.equal(queue(T)::in, queue(T)::in) is semidet.

         % `queue.is_empty(Queue)' is true iff `Queue' is an empty queue.
         %
     :- pred queue.is_empty(queue(T)::in) is semidet.

         % `queue.is_full(Queue)' is intended to be true iff `Queue' is a queue
         % whose capacity is exhausted. This implementation allows arbitrary-sized
         % queues, so queue.is_full always fails.
         %
     :- pred queue.is_full(queue(T)::in) is semidet.

         % `queue.put(Elem, Queue0, Queue)' is true iff `Queue' is the queue
         % which results from appending `Elem' onto the end of `Queue0'.
         %
     :- func queue.put(queue(T), T) = queue(T).
     :- pred queue.put(T::in, queue(T)::in, queue(T)::out) is det.

         % `queue.put_list(Elems, Queue0, Queue)' is true iff `Queue' is the queue
         % which results from inserting the items in the list `Elems' into `Queue0'.
         %
     :- func queue.put_list(queue(T), list(T)) = queue(T).
     :- pred queue.put_list(list(T)::in, queue(T)::in, queue(T)::out) is det.

         % `queue.first(Queue, Elem)' is true iff `Queue' is a non-empty queue
         % whose first element is `Elem'.
         %
     :- pred queue.first(queue(T)::in, T::out) is semidet.

         % `queue.get(Elem, Queue0, Queue)' is true iff `Queue0' is a non-empty
         % queue whose first element is `Elem', and `Queue' the queue which results
         % from removing that element from the front of `Queue0'.
         %
     :- pred queue.get(T::out, queue(T)::in, queue(T)::out) is semidet.

         % `queue.length(Queue, Length)' is true iff `Queue' is a queue
         % containing `Length' elements.
         %
     :- func queue.length(queue(T)) = int.
     :- pred queue.length(queue(T)::in, int::out) is det.

         % `queue.list_to_queue(List, Queue)' is true iff `Queue' is a queue
         % containing the elements of List, with the first element of List at
         % the head of the queue.
         %
     :- func queue.list_to_queue(list(T)) = queue(T).
     :- pred queue.list_to_queue(list(T)::in, queue(T)::out) is det.

         % A synonym for queue.list_to_queue/1.
         %
     :- func queue.from_list(list(T)) = queue(T).

         % `queue.to_list(Queue) = List' is the inverse of queue.from_list/1.
         %
     :- func queue.to_list(queue(T)) = list(T).

         % `queue.delete_all(Elem, Queue0, Queue)' is true iff `Queue' is the same
         % queue as `Queue0' with all occurrences of `Elem' removed from it.
         %
     :- func queue.delete_all(queue(T), T) = queue(T).
     :- pred queue.delete_all(T::in, queue(T)::in, queue(T)::out) is det.

         % `queue.put_on_front(Queue0, Elem) = Queue' pushes `Elem' on to
         % the front of `Queue0', giving `Queue'.
         %
     :- func queue.put_on_front(queue(T), T) = queue(T).
     :- pred queue.put_on_front(T::in, queue(T)::in, queue(T)::out) is det.

         % `queue.put_list_on_front(Queue0, Elems) = Queue' pushes `Elems'
         % on to the front of `Queue0', giving `Queue' (the Nth member
         % of `Elems' becomes the Nth member from the front of `Queue').
         %
     :- func queue.put_list_on_front(queue(T), list(T)) = queue(T).
     :- pred queue.put_list_on_front(list(T)::in, queue(T)::in, queue(T)::out)
         is det.

         % `queue.get_from_back(Elem, Queue0, Queue)' removes `Elem' from
         % the back of `Queue0', giving `Queue'.
         %
     :- pred queue.get_from_back(T::out, queue(T)::in, queue(T)::out) is semidet.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: random,  Next: rational,  Prev: queue,  Up: Top

53 random
*********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1994-1998,2001-2006, 2011 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: random.m
     % Main author: conway
     % Stability: low
     %
     % Define a set of random number generator predicates. This implementation
     % uses a threaded random-number supply.  The supply can be used in a
     % non-unique way, which means that each thread returns the same list of
     % random numbers.  However, this may not be desired so in the interests
     % of safety it is also declared with (backtrackable) unique modes.
     %
     % The coefficients used in the implementation were taken from Numerical
     % Recipes in C (Press et al), and are originally due to Knuth.  These
     % coefficients are described as producing a "Quick and Dirty" random number
     % generator, which generates the numbers very quickly but not necessarily
     % with a high degree of quality.  As with all random number generators,
     % the user is advised to consider carefully whether this generator meets
     % their requirements in terms of "randomness".  For applications which have
     % special needs (e.g. cryptographic key generation), a generator such as
     % this is unlikely to be suitable.
     %
     % Note that random number generators of this type have several known
     % pitfalls which the user may need to avoid:
     %
     %	1) The high bits tend to be more random than the low bits.  If
     %	you wish to generate a random integer within a given range, you
     %	should something like 'div' to reduce the random numbers to the
     %	required range rather than something like 'mod' (or just use
     %	random.random/5).
     %
     %	2) Similarly, you should not try to break a random number up into
     %	components.  Instead, you should generate each number with a
     %	separate call to this module.
     %
     %	3) There can be sequential correlation between successive calls,
     %	so you shouldn't try to generate tuples of random numbers, for
     %	example, by generating each component of the tuple in sequential
     %	order.  If you do, it is likely that the resulting sequence will
     %	not cover the full range of possible tuples.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module random.
     :- interface.

     :- import_module list.

     %--------------------------------------------------%

     	% The type `random.supply' represents a supply of random numbers.
         %
     :- type random.supply.

     	% random.init(Seed, RS): creates a supply of random numbers RS
     	% using the specified Seed.
     	%
     :- pred random.init(int::in, random.supply::uo) is det.

     	% random.random(Num, RS0, RS): extracts a number Num in the
     	% range 0 .. RandMax from the random number supply RS0, and
     	% binds RS to the new state of the random number supply.
         %
     :- pred random.random(int, random.supply, random.supply).
     :- mode random.random(out, mdi, muo) is det.
     :- mode random.random(out, in, out) is det.

     	% random.random(Low, Range, Num, RS0, RS): extracts a number Num
     	% in the range Low .. (Low + Range - 1) from the random number
     	% supply RS0, and binds RS to the new state of the random number
     	% supply.  For best results, the value of Range should be no greater
     	% than about 100.
     	%
     :- pred random.random(int, int, int, random.supply, random.supply).
     :- mode random.random(in, in, out, mdi, muo) is det.
     :- mode random.random(in, in, out, in, out) is det.

     	% random.randmax(RandMax, RS0, RS): binds RandMax to the maximum
     	% random number that can be returned from the random number
     	% supply RS0, and returns RS = RS0.
     	%
     :- pred random.randmax(int, random.supply, random.supply).
     :- mode random.randmax(out, mdi, muo) is det.
     :- mode random.randmax(out, in, out) is det.

     	% random.randcount(RandCount, RS0, RS): binds RandCount to the
     	% number of distinct random numbers that can be returned from the
     	% random number supply RS0, and returns RS = RS0.  This will be one
     	% more than the number returned by randmax/3.
     	%
     :- pred random.randcount(int, random.supply, random.supply).
     :- mode random.randcount(out, mdi, muo) is det.
     :- mode random.randcount(out, in, out) is det.

     	% random.permutation(List0, List, RS0, RS):
     	% binds List to a random permutation of List0,
     	% and binds RS to the new state of the random number supply.
     	%
     :- pred random.permutation(list(T), list(T), random.supply, random.supply).
     :- mode random.permutation(in, out, mdi, muo) is det.
     :- mode random.permutation(in, out, in, out) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: rational,  Next: rbtree,  Prev: random,  Up: Top

54 rational
***********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1997-1998, 2003-2006 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: rational.m.
     % Authors: aet Apr 1998. (with plagiarism from rat.m)
     % Stability: high.
     %
     % Implements a rational number type and a set of basic operations on
     % rational numbers.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module rational.
     :- interface.

     :- import_module integer.

     %--------------------------------------------------%

     :- type rational.

     :- pred '<'(rational::in, rational::in) is semidet.

     :- pred '>'(rational::in, rational::in) is semidet.

     :- pred '=<'(rational::in, rational::in) is semidet.

     :- pred '>='(rational::in, rational::in) is semidet.

     :- func rational.rational(int) = rational.

     :- func rational.rational(int, int) = rational.

     :- func rational.from_integer(integer) = rational.

     :- func rational.from_integers(integer, integer) = rational.

     % :- func float(rational) = float.

     :- func '+'(rational) = rational.

     :- func '-'(rational) = rational.

     :- func rational + rational = rational.

     :- func rational - rational = rational.

     :- func rational * rational = rational.

     :- func rational / rational = rational.

     :- func rational.numer(rational) = integer.

     :- func rational.denom(rational) = integer.

     :- func rational.abs(rational) = rational.

     :- func rational.reciprocal(rational) = rational.

     :- func rational.one = rational.

     :- func rational.zero = rational.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: rbtree,  Next: require,  Prev: rational,  Up: Top

55 rbtree
*********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1995-2000, 2003-2007, 2011 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: rbtree.m.
     % Main author: petdr.
     % Stability: medium.
     %
     % Contains an implementation of red black trees.
     %
     % *** Exit conditions of main predicates ***
     % insert:
     %   fails if key already in tree.
     % update:
     %   changes value of key already in tree.  fails if key doesn't exist.
     % transform_value:
     %   looks up an existing value in the tree, applies a transformation to the
     %   value and then updates the value.  fails if the key doesn't exist.
     % set:
     %   inserts or updates. Never fails.
     %
     % insert_duplicate:
     %   inserts duplicate keys into the tree, never fails.  Search doesn't
     %   yet support looking for duplicates.
     %
     % delete:
     %   deletes a node from the tree if it exists.
     % remove:
     %   fails if node to remove doesn't exist in the tree.
     %
     % lookup:
     %   Aborts program if key looked up doesn't exist.
     % search:
     %   Fails if key looked up doesn't exist.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module rbtree.
     :- interface.

     :- import_module assoc_list.
     :- import_module list.

     %--------------------------------------------------%

     :- type rbtree(Key, Value).

         % Initialise the data structure.
         %
     :- func rbtree.init = rbtree(K, V).
     :- pred rbtree.init(rbtree(K, V)::uo) is det.

         % Initialise an rbtree containing the given key-value pair.
         %
     :- func rbtree.singleton(K, V) = rbtree(K, V).

         % Check whether a tree is empty.
         %
     :- pred rbtree.is_empty(rbtree(K, V)::in) is semidet.

         % Inserts a new key-value pair into the tree.
         % Fails if key already in the tree.
         %
     :- pred rbtree.insert(K::in, V::in, rbtree(K, V)::in, rbtree(K, V)::out)
         is semidet.

         % Updates the value associated with a key.
         % Fails if the key does not exist.
         %
     :- pred rbtree.update(K::in, V::in, rbtree(K, V)::in, rbtree(K, V)::out)
         is semidet.

         % Update the value at the given key by applying the supplied
         % transformation to it.  Fails if the key is not found.  This is faster
         % than first searching for the value and then updating it.
         %
     :- pred rbtree.transform_value(pred(V, V)::in(pred(in, out) is det), K::in,
         rbtree(K, V)::in, rbtree(K, V)::out) is semidet.

         % Sets a value regardless of whether key exists or not.
         %
     :- func rbtree.set(rbtree(K, V), K, V) = rbtree(K, V).
     :- pred rbtree.set(K::in, V::in, rbtree(K, V)::in, rbtree(K, V)::out) is det.

         % Insert a duplicate key into the tree.
         %
     :- func rbtree.insert_duplicate(rbtree(K, V), K, V) = rbtree(K, V).
     :- pred rbtree.insert_duplicate(K::in, V::in,
         rbtree(K, V)::in, rbtree(K, V)::out) is det.

     :- pred rbtree.member(rbtree(K, V)::in, K::out, V::out) is nondet.

         % Search for a key-value pair using the key.
         % Fails if the key does not exist.
         %
     :- pred rbtree.search(rbtree(K, V)::in, K::in, V::out) is semidet.

         % Lookup the value associated with a key.
         % Throws an exception if the key does not exist.
         %
     :- func rbtree.lookup(rbtree(K, V), K) = V.
     :- pred rbtree.lookup(rbtree(K, V)::in, K::in, V::out) is det.

         % Search for a key-value pair using the key.  If there is no entry
         % for the given key, returns the pair for the next lower key instead.
         % Fails if there is no key with the given or lower value.
         %
     :- pred rbtree.lower_bound_search(rbtree(K, V)::in, K::in, K::out, V::out)
         is semidet.

         % Search for a key-value pair using the key.  If there is no entry
         % for the given key, returns the pair for the next lower key instead.
         % Throws an exception if there is no key with the given or lower value.
         %
     :- pred rbtree.lower_bound_lookup(rbtree(K, V)::in, K::in, K::out, V::out)
         is det.

         % Search for a key-value pair using the key.  If there is no entry
         % for the given key, returns the pair for the next higher key instead.
         % Fails if there is no key with the given or higher value.
         %
     :- pred rbtree.upper_bound_search(rbtree(K, V)::in, K::in, K::out, V::out)
         is semidet.

         % Search for a key-value pair using the key.  If there is no entry
         % for the given key, returns the pair for the next higher key instead.
         % Throws an exception if there is no key with the given or higher value.
         %
     :- pred rbtree.upper_bound_lookup(rbtree(K, V)::in, K::in, K::out, V::out)
         is det.

         % Delete the key-value pair associated with a key.
         % Does nothing if the key does not exist.
         %
     :- func rbtree.delete(rbtree(K, V), K) = rbtree(K, V).
     :- pred rbtree.delete(K::in, rbtree(K, V)::in, rbtree(K, V)::out) is det.

         % Remove the key-value pair associated with a key.
         % Fails if the key does not exist.
         %
     :- pred rbtree.remove(K::in, V::out, rbtree(K, V)::in, rbtree(K, V)::out)
         is semidet.

         % Deletes the node with the minimum key from the tree,
         % and returns the key and value fields.
         %
     :- pred rbtree.remove_smallest(K::out, V::out,
         rbtree(K, V)::in, rbtree(K, V)::out) is semidet.

         % Deletes the node with the maximum key from the tree,
         % and returns the key and value fields.
         %
     :- pred rbtree.remove_largest(K::out, V::out,
         rbtree(K, V)::in, rbtree(K, V)::out) is semidet.

         % Returns an in-order list of all the keys in the rbtree.
         %
     :- func rbtree.keys(rbtree(K, V)) = list(K).
     :- pred rbtree.keys(rbtree(K, V)::in, list(K)::out) is det.

         % Returns a list of values such that the keys associated with the
         % values are in-order.
         %
     :- func rbtree.values(rbtree(K, V)) = list(V).
     :- pred rbtree.values(rbtree(K, V)::in, list(V)::out) is det.

         % Count the number of elements in the tree.
         %
     :- func rbtree.count(rbtree(K, V)) = int.
     :- pred rbtree.count(rbtree(K, V)::in, int::out) is det.

     :- func rbtree.assoc_list_to_rbtree(assoc_list(K, V)) = rbtree(K, V).
     :- pred rbtree.assoc_list_to_rbtree(assoc_list(K, V)::in, rbtree(K, V)::out)
         is det.

     :- func rbtree.from_assoc_list(assoc_list(K, V)) = rbtree(K, V).

     :- func rbtree.rbtree_to_assoc_list(rbtree(K, V)) = assoc_list(K, V).
     :- pred rbtree.rbtree_to_assoc_list(rbtree(K, V)::in, assoc_list(K, V)::out)
         is det.

     :- func rbtree.to_assoc_list(rbtree(K, V)) = assoc_list(K, V).

     :- func rbtree.foldl(func(K, V, T) = T, rbtree(K, V), T) = T.
     :- pred rbtree.foldl(pred(K, V, T, T), rbtree(K, V), T, T).
     :- mode rbtree.foldl(pred(in, in, in, out) is det, in, in, out) is det.
     :- mode rbtree.foldl(pred(in, in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode rbtree.foldl(pred(in, in, di, uo) is det, in, di, uo) is det.
     :- mode rbtree.foldl(pred(in, in, in, out) is semidet, in, in, out)
         is semidet.
     :- mode rbtree.foldl(pred(in, in, mdi, muo) is semidet, in, mdi, muo)
         is semidet.
     :- mode rbtree.foldl(pred(in, in, di, uo) is semidet, in, di, uo)
         is semidet.

     :- pred rbtree.foldl2(pred(K, V, T, T, U, U), rbtree(K, V), T, T, U, U).
     :- mode rbtree.foldl2(pred(in, in, in, out, in, out) is det,
         in, in, out, in, out) is det.
     :- mode rbtree.foldl2(pred(in, in, in, out, mdi, muo) is det,
         in, in, out, mdi, muo) is det.
     :- mode rbtree.foldl2(pred(in, in, in, out, di, uo) is det,
         in, in, out, di, uo) is det.
     :- mode rbtree.foldl2(pred(in, in, di, uo, di, uo) is det,
         in, di, uo, di, uo) is det.
     :- mode rbtree.foldl2(pred(in, in, in, out, in, out) is semidet,
         in, in, out, in, out) is semidet.
     :- mode rbtree.foldl2(pred(in, in, in, out, mdi, muo) is semidet,
         in, in, out, mdi, muo) is semidet.
     :- mode rbtree.foldl2(pred(in, in, in, out, di, uo) is semidet,
         in, in, out, di, uo) is semidet.

     :- pred rbtree.foldl3(pred(K, V, T, T, U, U, W, W), rbtree(K, V),
         T, T, U, U, W, W).
     :- mode rbtree.foldl3(pred(in, in, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out) is det.
     :- mode rbtree.foldl3(pred(in, in, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out) is semidet.
     :- mode rbtree.foldl3(pred(in, in, in, out, in, out, di, uo) is det,
         in, in, out, in, out, di, uo) is det.
     :- mode rbtree.foldl3(pred(in, in, in, out, di, uo, di, uo) is det,
         in, in, out, di, uo, di, uo) is det.
     :- mode rbtree.foldl3(pred(in, in, di, uo, di, uo, di, uo) is det,
         in, di, uo, di, uo, di, uo) is det.

     :- func rbtree.map_values(func(K, V) = W, rbtree(K, V)) = rbtree(K, W).
     :- pred rbtree.map_values(pred(K, V, W), rbtree(K, V), rbtree(K, W)).
     :- mode rbtree.map_values(pred(in, in, out) is det, in, out) is det.
     :- mode rbtree.map_values(pred(in, in, out) is semidet, in, out) is semidet.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: require,  Next: rtree,  Prev: rbtree,  Up: Top

56 require
**********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1993-1999, 2003, 2005-2006, 2010-2011 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: require.m.
     % Main author: fjh.
     % Stability: medium to high.
     %
     % This module provides features similar to <assert.h> in C.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module require.
     :- interface.

         % error(Message):
         %
         % Throw a `software_error(Message)' exception.
         % This will normally cause execution to abort with an error message.
         %
     :- pred error(string::in) is erroneous.

         % func_error(Message):
         %
         % An expression that results in a `software_error(Message)'
         % exception being thrown.
         %
     :- func func_error(string) = _ is erroneous.

     %--------------------------------------------------%

         % sorry(Module, What):
         %
         % Call error/1 with the string
         % "Module: Sorry, not implemented: What".
         %
         % Use this for features that should be implemented (or at least could be
         % implemented).
         %
     :- func sorry(string, string) = _ is erroneous.
     :- pred sorry(string::in, string::in) is erroneous.

         % sorry(Module, Proc, What):
         %
         % Call error/1 with the string
         % "Module: Proc: Sorry, not implemented: What".
         %
         % Use this for features that should be implemented,
         % or at least could be implemented.
         %
     :- func sorry(string, string, string) = _ is erroneous.
     :- pred sorry(string::in, string::in, string::in) is erroneous.

         % unexpected(Module, Message):
         %
         % Call error/1 with the string
         % "Module: Unexpected: What".
         %
         % Use this to handle cases which are not expected to arise (i.e. bugs).
         %
     :- func unexpected(string, string) = _ is erroneous.
     :- pred unexpected(string::in, string::in) is erroneous.

         % unexpected(Module, Proc, Message):
         %
         % Call error/1 with the string
         % "Module: Proc: Unexpected: What".
         %
         % Use this to handle cases which are not expected to arise (i.e. bugs).
         %
     :- func unexpected(string, string, string) = _ is erroneous.
     :- pred unexpected(string::in, string::in, string::in) is erroneous.

     %--------------------------------------------------%

         % require(Goal, Message):
         %
         % Call goal, and call error(Message) if Goal fails.
         % This is not as useful as you might imagine, since it requires
         % that the goal not produce any output variables. In most circumstances,
         % you should use an explicit if-then-else with a call to error/1,
         % or one of its wrappers, in the "else".
         %
     :- pred require((pred)::((pred) is semidet), string::in) is det.

         % expect(Goal, Module, Message):
         %
         % Call Goal, and call unexpected(Module, Message) if Goal fails.
         %
     :- pred expect((pred)::((pred) is semidet), string::in, string::in) is det.

         % expect(Goal, Module, Proc, Message):
         %
         % Call Goal, and call unexpected(Module, Proc, Message) if Goal fails.
         %
     :- pred expect((pred)::((pred) is semidet), string::in, string::in,
         string::in) is det.

         % expect_not(Goal, Module, Message):
         %
         % Call Goal, and call unexpected(Module, Message) if Goal succeeds.
         %
     :- pred expect_not((pred)::((pred) is semidet), string::in, string::in) is det.

         % expect_not(Goal, Module, Proc, Message):
         %
         % Call Goal, and call unexpected(Module, Proc, Message) if Goal succeeds.
         %
     :- pred expect_not((pred)::((pred) is semidet), string::in, string::in,
         string::in) is det.

     %--------------------------------------------------%

         % report_lookup_error(Message, Key):
         %
         % Call error/1 with an error message that is appropriate for
         % the failure of a lookup operation involving the specified Key.
         % The error message will include Message and information about Key.
         %
     :- pred report_lookup_error(string::in, K::in) is erroneous.

         % report_lookup_error(Message, Key, Value):
         %
         % Call error/1 with an error message that is appropriate for
         % the failure of a lookup operation involving the specified Key and Value.
         % The error message will include Message and information about Key
         % and Value.
         %
     :- pred report_lookup_error(string::in, K::in, V::unused) is erroneous.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: rtree,  Next: set,  Prev: require,  Up: Top

57 rtree
********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 2006-2007 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: rtree.m.
     % Main author: gjd.
     % Stability: low.
     %
     % This module provides a region tree (R-tree) ADT.  A region tree associates
     % values with regions in some space, e.g. rectangles in the 2D plane, or
     % bounding spheres in 3D space.  Region trees accept spatial queries, e.g. a
     % typical usage is "find all pubs within a 2km radius".
     %
     % This module also provides the typeclass region(K) which allows the user to
     % define new regions and spaces.  Three "builtin" instances for region(K)
     % are provided: region(interval), region(box) and region(box3d)
     % corresponding to "square" regions in one, two and three dimensional spaces
     % respectively.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module rtree.
     :- interface.

     :- import_module list.

     %--------------------------------------------------%

     :- type rtree(K, V).

     :- typeclass region(K) where [

             % Succeeds iff two regions intersect.
             %
         pred intersects(K::in, K::in) is semidet,

             % Succeeds iff the first region is contained within the second.
             %
         pred contains(K::in, K::in) is semidet,

             % Returns the "size" of a region.
             % e.g. for a two dimensional box one possible measure of "size"
             %      would be the area.
             %
         func size(K) = float,

             % Return a region that contains both input regions.
             % The region returned should be minimal region that contains
             % both input regions.
             %
         func bounding_region(K, K) = K,

             % Computes the size of the bounding region returned by
             % bounding_region/2, i.e.
             %
             % bounding_region_size(K1, K2) = size(bounding_region(K1, K2)).
             %
             % While the above definition would suffice, a more efficient
             % implementation often exists, e.g. for intervals:
             %
             % bounding_region_size(interval(X0, X1), interval(Y0, Y1)) =
             %       max(X1, Y1) - min(X0, Y0).
             %
             % This version is more efficient since it does not create a
             % temporary interval.
             %
         func bounding_region_size(K, K) = float
     ].

     %--------------------------------------------------%

         % Initialize an empty rtree.
         %
     :- func rtree.init = (rtree(K, V)::uo) is det <= region(K).

         % Succeeds iff the given rtree is empty.
         %
     :- pred rtree.is_empty(rtree(K, V)::in) is semidet.

         % Insert a new key and corresponding value into an rtree.
         %
     :- func rtree.insert(K, V, rtree(K, V)) = rtree(K, V) <= region(K).
     :- pred rtree.insert(K::in, V::in, rtree(K, V)::in, rtree(K, V)::out)
         is det <= region(K).

         % Delete a key-value pair from an rtree.
         % Assumes that K is either the key for V, or is contained in the key
         % for V.
         %
         % Fails if the key-value pair is not in the tree.
         %
     :- pred rtree.delete(K::in, V::in, rtree(K, V)::in, rtree(K, V)::out)
         is semidet <= region(K).

         % Search for all values with keys that intersect the query key.
         %
     :- func rtree.search_intersects(rtree(K, V), K) = list(V) <= region(K).

         % Search for all values with keys that contain the query key.
         %
     :- func rtree.search_contains(rtree(K, V), K) = list(V) <= region(K).

         % search_general(KTest, VTest, T) = V.
         %
         % Search for all values V with associated keys K that satisfy
         % KTest(K) /\ VTest(V).  The search assumes that for all K1, K2
         % such that K1 contains K2, then if KTest(K2) holds we have that
         % KTest(K1) also holds.
         %
         % We have that:
         %
         %   search_intersects(T, K, Vs)
         %       <=> search_general(intersects(K), true, T, Vs)
         %
         %   search_contains(T, K, Vs)
         %       <=> search_general(contains(K), true, T, Vs)
         %
     :- func rtree.search_general(pred(K)::in(pred(in) is semidet),
         pred(V)::in(pred(in) is semidet), rtree(K, V)::in) = (list(V)::out)
         is det.

         % search_first(KTest, VTest, Max, T, V, L).
         %
         % Search for a value V with associated key K such that
         % KTest(K, _) /\ VTest(V, L) is satisfied and there does not exist a
         % V' with K' such that KTest(K', _) /\ VTest(V', L') /\ (L' < L) is
         % satisfied.  Fail if no such key-value pair exists.
         %
         % The search assumes that for all K1, K2 such that
         % K1 contains K2, then if KTest(K2, L2) holds we have that
         % KTest(K1, L1) holds with L2 >= L1.
         %
         % If there exist multiple key-value pairs that satisfy the above
         % conditions, then one of the candidates is chosen arbitrarily.
         %
     :- pred rtree.search_first(pred(K, L), pred(V, L), rtree(K, V), L, V, L).
     :- mode rtree.search_first(pred(in, out) is semidet,
         pred(in, out) is semidet, in, in, out, out) is semidet.

         % search_general_fold(KTest, VPred, T, !A).
         %
         % Apply accumulator VPred to each key-value pair K-V that satisfies
         % KTest(K).  The same assumptions for KTest from search_general apply
         % here.
         %
     :- pred rtree.search_general_fold(pred(K), pred(K, V, A, A), rtree(K, V),
         A, A).
     :- mode rtree.search_general_fold(pred(in) is semidet,
         pred(in, in, in, out) is det, in, in, out) is det.
     :- mode rtree.search_general_fold(pred(in) is semidet,
         pred(in, in, di, uo) is det, in, di, uo) is det.

         % Perform a traversal of the rtree, applying an accumulator predicate
         % for each key-value pair.
         %
     :- pred rtree.fold(pred(K, V, A, A), rtree(K, V), A, A).
     :- mode rtree.fold(pred(in, in, in, out) is det, in, in, out) is det.
     :- mode rtree.fold(pred(in, in, di, uo) is det, in, di, uo) is det.
     :- mode rtree.fold(pred(in, in, in, out) is semidet, in, in, out)
         is semidet.

         % Apply a transformation predicate to all the values in an rtree.
         %
     :- pred rtree.map_values(pred(K, V, W), rtree(K, V), rtree(K, W)).
     :- mode rtree.map_values(pred(in, in, out) is det, in, out) is det.
     :- mode rtree.map_values(pred(in, in, out) is semidet, in, out)
         is semidet.

     %--------------------------------------------------%
     %
     % Pre-defined regions
     %

         % An interval type represented as interval(Min, Max).
         %
     :- type interval
         --->    interval(float, float).

         % A 2D axis aligned box represented as box(XMin, XMax, YMin, YMax).
         %
     :- type box
         --->    box(float, float, float, float).

         % A 3D axis aligned box represented as
         % box(XMin, XMax, YMin, YMax, ZMin, ZMax).
         %
     :- type box3d
         --->    box3d(float, float, float, float, float, float).

     :- instance region(interval).
     :- instance region(box).
     :- instance region(box3d).

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: set,  Next: set_bbbtree,  Prev: rtree,  Up: Top

58 set
******

     %--------------------------------------------------%
     % vim: ts=4 sw=4 et ft=mercury
     %--------------------------------------------------%
     % Copyright (C) 1994-1997, 1999-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: set.m.
     % Main authors: conway, fjh, benyi.
     % Stability: high.
     %
     % This module provides a set ADT.
     % The implementation represents sets using ordered lists.
     % This file just calls the equivalent predicates in set_ordlist.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module set.
     :- interface.

     :- import_module bool.
     :- import_module list.

     %--------------------------------------------------%

     :- type set(T).

         % `set.init(Set)' is true iff `Set' is an empty set.
         %
     :- func set.init = set(T).
     :- pred set.init(set(T)::uo) is det.

         % `set.list_to_set(List, Set)' is true iff `Set' is the set
         % containing only the members of `List'.
         %
     :- pred set.list_to_set(list(T)::in, set(T)::out) is det.
     :- func set.list_to_set(list(T)) = set(T).

         % Synonyms for set.list_to_set/1.
         %
     :- func set.from_list(list(T)) = set(T).
     :- func set.set(list(T)) = set(T).

         % `set.sorted_list_to_set(List, Set)' is true iff `Set' is the set
         % containing only the members of `List'.  `List' must be sorted
         % and must not contain any duplicates.
         %
     :- pred set.sorted_list_to_set(list(T)::in, set(T)::out) is det.
     :- func set.sorted_list_to_set(list(T)) = set(T).

         % A synonym for set.sorted_list_to_set/1.
         %
     :- func set.from_sorted_list(list(T)) = set(T).

         % `set.to_sorted_list(Set, List)' is true iff `List' is the list
         % of all the members of `Set', in sorted order without any
         % duplicates.
         %
     :- pred set.to_sorted_list(set(T)::in, list(T)::out) is det.
     :- func set.to_sorted_list(set(T)) = list(T).

         % `set.singleton_set(Elem, Set)' is true iff `Set' is the set
         % containing just the single element `Elem'.
         %
     :- pred set.singleton_set(T, set(T)).
     :- mode set.singleton_set(in, out) is det.
     :- mode set.singleton_set(out, in) is semidet.

     :- func set.make_singleton_set(T) = set(T).

     :- pred set.is_singleton(set(T)::in, T::out) is semidet.

         % `set.equal(SetA, SetB)' is true iff
         % `SetA' and `SetB' contain the same elements.
         %
     :- pred set.equal(set(T)::in, set(T)::in) is semidet.

     :- pred set.empty(set(T)::in) is semidet.

     :- pred set.non_empty(set(T)::in) is semidet.

         % A synonym for set.empty/1.
         %
     :- pred set.is_empty(set(T)::in) is semidet.

         % `set.subset(SetA, SetB)' is true iff `SetA' is a subset of `SetB'.
         %
     :- pred set.subset(set(T)::in, set(T)::in) is semidet.

         % `set.superset(SetA, SetB)' is true iff `SetA' is a
         % superset of `SetB'.
         %
     :- pred set.superset(set(T)::in, set(T)::in) is semidet.

         % `set.member(X, Set)' is true iff `X' is a member of `Set'.
         %
     :- pred set.member(T, set(T)).
     :- mode set.member(in, in) is semidet.
     :- mode set.member(out, in) is nondet.

         % `set_is_member(X, Set, Result)' returns
         % `Result = yes' iff `X' is a member of `Set'.
         %
     :- pred set.is_member(T::in, set(T)::in, bool::out) is det.

         % `set.contains(Set, X)' is true iff `X' is a member of `Set'.
         %
     :- pred set.contains(set(T)::in, T::in) is semidet.

         % `set.insert(X, Set0, Set)' is true iff `Set' is the union of
         % `Set0' and the set containing only `X'.
         %
     :- func set.insert(set(T), T) = set(T).
     :- pred set.insert(T::in, set(T)::in, set(T)::out) is det.

         % `set.insert_new(X, Set0, Set)' is true iff `Set0' does not contain
         % `X', and `Set' is the union of `Set0' and the set containing only `X'.
         %
     :- pred set.insert_new(T::in, set(T)::in, set(T)::out) is semidet.

         % `set.insert_list(Xs, Set0, Set)' is true iff `Set' is the union of
         % `Set0' and the set containing only the members of `Xs'.
         %
     :- func set.insert_list(set(T), list(T)) = set(T).
     :- pred set.insert_list(list(T)::in, set(T)::in, set(T)::out) is det.

         % `set.delete(X, Set0, Set)' is true iff `Set' is the relative
         % complement of `Set0' and the set containing only `X', i.e.
         % if `Set' is the set which contains all the elements of `Set0'
         % except `X'.
         %
     :- func set.delete(set(T), T) = set(T).
     :- pred set.delete(T::in, set(T)::in, set(T)::out) is det.

         % `set.delete_list(Set0, Xs, Set)' is true iff `Set' is the relative
         % complement of `Set0' and the set containing only the members of
         % `Xs'.
         %
     :- func set.delete_list(set(T), list(T)) = set(T).
     :- pred set.delete_list(list(T)::in, set(T)::in, set(T)::out) is det.

         % `set.remove(X, Set0, Set)' is true iff `Set0' contains `X',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only `X', i.e.  if `Set' is the set which contains
         % all the elements of `Set0' except `X'.
         %
     :- pred set.remove(T::in, set(T)::in, set(T)::out) is semidet.

         % `set.remove_list(Xs, Set0, Set)' is true iff `Xs' does not
         % contain any duplicates, `Set0' contains every member of `Xs',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only the members of `Xs'.
         %
     :- pred set.remove_list(list(T)::in, set(T)::in, set(T)::out) is semidet.

         % `set.remove_least(Elem, Set0, Set)' is true iff
         % `Set0' is not empty, `Elem' is the smallest element in `Set0'
         % (with elements ordered using the standard ordering given
         % by compare/3), and `Set' is the set containing all the
         % elements of `Set0' except `Elem'.
         %
     :- pred set.remove_least(T::out, set(T)::in, set(T)::out) is semidet.

         % `set.union(SetA, SetB, Set)' is true iff `Set' is the union of
         % `SetA' and `SetB'.  If the sets are known to be of different
         % sizes, then for efficiency make `SetA' the larger of the two.
         % (The current implementation using sorted lists with duplicates
         % removed is not sensitive to the ordering of the input arguments,
         % but other set implementations may be, so observing this convention
         % will make it less likely that you will encounter problems if
         % the implementation is changed.)
         %
     :- func set.union(set(T), set(T)) = set(T).
     :- pred set.union(set(T)::in, set(T)::in, set(T)::out) is det.

         % `set.union_list(A, B)' is true iff `B' is the union of
         % all the sets in `A'.
         %
     :- func set.union_list(list(set(T))) = set(T).

         % `set.power_union(A, B)' is true iff `B' is the union of
         % all the sets in `A'.
         %
     :- func set.power_union(set(set(T))) = set(T).
     :- pred set.power_union(set(set(T))::in, set(T)::out) is det.

         % `set.intersect(SetA, SetB, Set)' is true iff `Set' is the
         % intersection of `SetA' and `SetB'. If the two sets are
         % known to be unequal in size, then making SetA be the larger
         % set will usually be more efficient.
         % (The current implementation, using sorted lists with duplicates
         % removed is not sensitive to the ordering of the input arguments
         % but other set implementations may be, so observing this convention
         % will make it less likely that you will encounter problems if
         % the implementation is changed.)
         %
     :- func set.intersect(set(T), set(T)) = set(T).
     :- pred set.intersect(set(T)::in, set(T)::in, set(T)::out) is det.

         % `set.power_intersect(A, B)' is true iff `B' is the intersection of
         % all the sets in `A'.
         %
     :- func set.power_intersect(set(set(T))) = set(T).
     :- pred set.power_intersect(set(set(T))::in, set(T)::out) is det.

         % `set.intersect_list(A, B)' is true iff `B' is the intersection of
         % all the sets in `A'.
         %
     :- func set.intersect_list(list(set(T))) = set(T).

         % `set.difference(SetA, SetB, Set)' is true iff `Set' is the
         % set containing all the elements of `SetA' except those that
         % occur in `SetB'.
         %
     :- func set.difference(set(T), set(T)) = set(T).
     :- pred set.difference(set(T)::in, set(T)::in, set(T)::out) is det.

         % `set.count(Set, Count)' is true iff `Set' has `Count' elements.
         % i.e. `Count' is the cardinality (size) of the set.
         %
     :- func set.count(set(T)) = int.
     :- pred set.count(set(T)::in, int::out) is det.

         % Support for higher order set processing.

         % map(F, S) =
         %   list_to_set(list.map(F, to_sorted_list(S))).
         %
     :- func set.map(func(T1) = T2, set(T1)) = set(T2).
     :- pred set.map(pred(T1, T2), set(T1), set(T2)).
     :- mode set.map(pred(in, out) is det, in, out) is det.
     :- mode set.map(pred(in, out) is cc_multi, in, out) is cc_multi.
     :- mode set.map(pred(in, out) is semidet, in, out) is semidet.
     :- mode set.map(pred(in, out) is multi, in, out) is multi.
     :- mode set.map(pred(in, out) is nondet, in, out) is nondet.

         % set.map_fold(P, S0, S, A0, A) :-
         %   L0 = set.to_sorted_list(S0),
         %   list.map_foldl(P, L0, L, A0, A),
         %   S = set.list_to_set(L).
         %
     :- pred set.map_fold(pred(T1, T2, T3, T3), set(T1), set(T2), T3, T3).
     :- mode set.map_fold(pred(in, out, in, out) is det, in, out, in, out) is det.
     :- mode set.map_fold(pred(in, out, mdi, muo) is det, in, out, mdi, muo) is det.
     :- mode set.map_fold(pred(in, out, di, uo) is det, in, out, di, uo) is det.
     :- mode set.map_fold(pred(in, out, in, out) is semidet, in, out,
         in, out) is semidet.
     :- mode set.map_fold(pred(in, out, mdi, muo) is semidet, in, out,
         mdi, muo) is semidet.
     :- mode set.map_fold(pred(in, out, di, uo) is semidet, in, out,
         di, uo) is semidet.

         % Return the set of items for which the given predicate succeeds.
         % set.filter(P, S) =
         %   sorted_list_to_set(list.filter(P, to_sorted_list(S))).
         %
     :- func set.filter(pred(T1), set(T1)) = set(T1).
     :- mode set.filter(pred(in) is semidet, in) = out is det.
     :- pred set.filter(pred(T1), set(T1), set(T1)).
     :- mode set.filter(pred(in) is semidet, in, out) is det.

         % Return the set of items for which the given predicate succeeds,
         % and the set of items for which it fails.
         %
     :- pred set.filter(pred(T1), set(T1), set(T1), set(T1)).
     :- mode set.filter(pred(in) is semidet, in, out, out) is det.

         % set.filter_map(PF, S) =
         %   list_to_set(list.filter_map(PF, to_sorted_list(S))).
         %
     :- pred set.filter_map(pred(T1, T2), set(T1), set(T2)).
     :- mode set.filter_map(in(pred(in, out) is semidet), in, out) is det.
     :- func set.filter_map(func(T1) = T2, set(T1)) = set(T2).
     :- mode set.filter_map(func(in) = out is semidet, in) = out is det.

         % set.fold(F, S, A) =
         %   list.foldl(F, to_sorted_list(S), A).
         %
     :- func set.fold(func(T, A) = A, set(T), A) = A.
     :- func set.foldl(func(T, A) = A, set(T), A) = A.

     :- pred set.fold(pred(T, A, A), set(T), A, A).
     :- mode set.fold(pred(in, in, out) is det, in, in, out) is det.
     :- mode set.fold(pred(in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode set.fold(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode set.fold(pred(in, in, out) is semidet, in, in, out) is semidet.
     :- mode set.fold(pred(in, mdi, muo) is semidet, in, mdi, muo) is semidet.
     :- mode set.fold(pred(in, di, uo) is semidet, in, di, uo) is semidet.

     :- pred set.foldl(pred(T, A, A), set(T), A, A).
     :- mode set.foldl(pred(in, in, out) is det, in, in, out) is det.
     :- mode set.foldl(pred(in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode set.foldl(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode set.foldl(pred(in, in, out) is semidet, in, in, out) is semidet.
     :- mode set.foldl(pred(in, mdi, muo) is semidet, in, mdi, muo) is semidet.
     :- mode set.foldl(pred(in, di, uo) is semidet, in, di, uo) is semidet.

     :- pred set.fold2(pred(T, A, A, B, B), set(T), A, A, B, B).
     :- mode set.fold2(pred(in, in, out, in, out) is det, in,
         in, out, in, out) is det.
     :- mode set.fold2(pred(in, in, out, mdi, muo) is det, in,
         in, out, mdi, muo) is det.
     :- mode set.fold2(pred(in, in, out, di, uo) is det, in,
         in, out, di, uo) is det.
     :- mode set.fold2(pred(in, in, out, in, out) is semidet,
         in, in, out, in, out) is semidet.
     :- mode set.fold2(pred(in, in, out, mdi, muo) is semidet,
         in, in, out, mdi, muo) is semidet.
     :- mode set.fold2(pred(in, in, out, di, uo) is semidet,
         in, in, out, di, uo) is semidet.

     :- pred set.foldl2(pred(T, A, A, B, B), set(T), A, A, B, B).
     :- mode set.foldl2(pred(in, in, out, in, out) is det, in,
         in, out, in, out) is det.
     :- mode set.foldl2(pred(in, in, out, mdi, muo) is det, in,
         in, out, mdi, muo) is det.
     :- mode set.foldl2(pred(in, in, out, di, uo) is det, in,
         in, out, di, uo) is det.
     :- mode set.foldl2(pred(in, in, out, in, out) is semidet,
         in, in, out, in, out) is semidet.
     :- mode set.foldl2(pred(in, in, out, mdi, muo) is semidet,
         in, in, out, mdi, muo) is semidet.
     :- mode set.foldl2(pred(in, in, out, di, uo) is semidet,
         in, in, out, di, uo) is semidet.

     :- pred set.fold3(pred(T, A, A, B, B, C, C), set(T), A, A, B, B, C, C).
     :- mode set.fold3(pred(in, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out) is det.
     :- mode set.fold3(pred(in, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, mdi, muo) is det.
     :- mode set.fold3(pred(in, in, out, in, out, di, uo) is det, in,
         in, out, in, out, di, uo) is det.
     :- mode set.fold3(pred(in, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out) is semidet.
     :- mode set.fold3(pred(in, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, mdi, muo) is semidet.
     :- mode set.fold3(pred(in, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, di, uo) is semidet.

     :- pred set.foldl3(pred(T, A, A, B, B, C, C), set(T), A, A, B, B, C, C).
     :- mode set.foldl3(pred(in, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out) is det.
     :- mode set.foldl3(pred(in, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, mdi, muo) is det.
     :- mode set.foldl3(pred(in, in, out, in, out, di, uo) is det, in,
         in, out, in, out, di, uo) is det.
     :- mode set.foldl3(pred(in, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out) is semidet.
     :- mode set.foldl3(pred(in, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, mdi, muo) is semidet.
     :- mode set.foldl3(pred(in, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, di, uo) is semidet.

     :- pred set.fold4(pred(T, A, A, B, B, C, C, D, D), set(T), A, A, B, B,
         C, C, D, D).
     :- mode set.fold4(pred(in, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out) is det.
     :- mode set.fold4(pred(in, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, mdi, muo) is det.
     :- mode set.fold4(pred(in, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, di, uo) is det.
     :- mode set.fold4(pred(in, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out) is semidet.
     :- mode set.fold4(pred(in, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set.fold4(pred(in, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, di, uo) is semidet.

     :- pred set.foldl4(pred(T, A, A, B, B, C, C, D, D), set(T), A, A, B, B,
         C, C, D, D).
     :- mode set.foldl4(pred(in, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out) is det.
     :- mode set.foldl4(pred(in, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, mdi, muo) is det.
     :- mode set.foldl4(pred(in, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, di, uo) is det.
     :- mode set.foldl4(pred(in, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out) is semidet.
     :- mode set.foldl4(pred(in, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set.foldl4(pred(in, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, di, uo) is semidet.

     :- pred set.fold5(pred(T, A, A, B, B, C, C, D, D, E, E), set(T), A, A, B, B,
         C, C, D, D, E, E).
     :- mode set.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set.foldl5(pred(T, A, A, B, B, C, C, D, D, E, E), set(T), A, A, B, B,
         C, C, D, D, E, E).
     :- mode set.foldl5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set.foldl5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set.foldl5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set.foldl5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set.foldl5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set.foldl5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set.fold6(pred(T, A, A, B, B, C, C, D, D, E, E, F, F), set(T),
         A, A, B, B, C, C, D, D, E, E, F, F).
     :- mode set.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set.foldl6(pred(T, A, A, B, B, C, C, D, D, E, E, F, F), set(T),
         A, A, B, B, C, C, D, D, E, E, F, F).
     :- mode set.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet.

         % all_true(Pred, Set) succeeds iff Pred(Element) succeeds
         % for all the elements of Set.
         %
     :- pred all_true(pred(T)::in(pred(in) is semidet), set(T)::in) is semidet.

         % set.divide(Pred, Set, TruePart, FalsePart):
         % TruePart consists of those elements of Set for which Pred succeeds;
         % FalsePart consists of those elements of Set for which Pred fails.
         %
     :- pred set.divide(pred(T)::in(pred(in) is semidet), set(T)::in,
         set(T)::out, set(T)::out) is det.

         % set_divide_by_set(DivideBySet, Set, InPart, OutPart):
         % InPart consists of those elements of Set which are also in DivideBySet;
         % OutPart consists of those elements of which are not in DivideBySet.
         %
     :- pred set.divide_by_set(set(T)::in, set(T)::in, set(T)::out, set(T)::out)
         is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: set_bbbtree,  Next: set_ctree234,  Prev: set,  Up: Top

59 set_bbbtree
**************

     %--------------------------------------------------%
     % vim: ts=4 sw=4 et ft=mercury
     %--------------------------------------------------%
     % Copyright (C) 1995-1997, 1999-2006, 2010-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: set_bbbtree.m.
     % Main authors: benyi.
     % Stability: low.
     %
     % This module implements sets using bounded balanced binary trees.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module set_bbbtree.
     :- interface.

     :- import_module bool.
     :- import_module list.

     %--------------------------------------------------%

     :- type set_bbbtree(T).

         % `set_bbbtree.init(Set)' returns an initialized empty set.
         %
     :- func set_bbbtree.init = set_bbbtree(T).
     :- pred set_bbbtree.init(set_bbbtree(T)::uo) is det.

         % `set_bbbtree.empty(Set) is true iff `Set' is contains no elements.
         %
     :- pred set_bbbtree.empty(set_bbbtree(T)::in) is semidet.

         % A synonym for the above.
         %
     :- pred set_bbbtree.is_empty(set_bbbtree(T)::in) is semidet.

     :- pred set_bbbtree.non_empty(set_bbbtree(T)::in) is semidet.

         % `set_bbbtree.count(Set, Count)' is true iff `Set' has `Count' elements.
         % i.e. `Count' is the cardinality (size) of the set.
         %
     :- func set_bbbtree.count(set_bbbtree(T)) = int.
     :- pred set_bbbtree.count(set_bbbtree(T)::in, int::out) is det.

         % `set_bbbtree.member(X, Set)' is true iff `X' is a member of `Set'.
         % O(lg n) for (in, in) and O(1) for (out, in).
         %
     :- pred set_bbbtree.member(T, set_bbbtree(T)).
     :- mode set_bbbtree.member(in, in) is semidet.
     :- mode set_bbbtree.member(out, in) is nondet.

         % `set_bbbtree.is_member(X, Set, Result)' is true iff `X' is a member
         % of `Set'.
         %
     :- pred set_bbbtree.is_member(T::in, set_bbbtree(T)::in, bool::out) is det.

         % `set_bbbtree.contains(Set, X)' is true iff `X' is a member of `Set'.
         % O(lg n).
         %
     :- pred set_bbbtree.contains(set_bbbtree(T)::in, T::in) is semidet.

         % `set_bbbtree.least(Set, X)' is true iff `X' is smaller than all
         % the other members of `Set'.
         %
     :- pred set_bbbtree.least(set_bbbtree(T), T).
     :- mode set_bbbtree.least(in, out) is semidet.
     :- mode set_bbbtree.least(in, in) is semidet.

         % `set_bbbtree.largest(Set, X)' is true iff `X' is larger than all
         % the other members of `Set'.
         %
     :- pred set_bbbtree.largest(set_bbbtree(T), T).
     :- mode set_bbbtree.largest(in, out) is semidet.
     :- mode set_bbbtree.largest(in, in) is semidet.

         % `set_bbbtree.singleton_set(X, Set)' is true iff `Set' is the set
         % containing just the single element `X'.
         %
     :- pred set_bbbtree.singleton_set(T, set_bbbtree(T)).
     :- mode set_bbbtree.singleton_set(in, out) is det.
     :- mode set_bbbtree.singleton_set(in, in) is semidet.
     :- mode set_bbbtree.singleton_set(out, in) is semidet.

     :- func set_bbbtree.make_singleton_set(T) = set_bbbtree(T).

     :- pred set_bbbtree.is_singleton(set_bbbtree(T)::in, T::out) is semidet.

         % `set_bbbtree.equal(SetA, SetB)' is true iff `SetA' and `SetB'
         % contain the same elements.
         %
     :- pred set_bbbtree.equal(set_bbbtree(T)::in, set_bbbtree(T)::in) is semidet.

         % `set_bbbtree.insert(X, Set0, Set)' is true iff `Set' is the union of
         % `Set0' and the set containing only `X'.
         %
     :- pred set_bbbtree.insert(T, set_bbbtree(T), set_bbbtree(T)).
     :- mode set_bbbtree.insert(di, di, uo) is det.
     :- mode set_bbbtree.insert(in, in, out) is det.

     :- func set_bbbtree.insert(set_bbbtree(T), T) = set_bbbtree(T).

         % `set_bbbtree.insert_new(X, Set0, Set)' is true iff `Set0' does not
         % contain `X', and `Set' is the union of `Set0' and the set containing
         % only `X'.
         %
     :- pred set_bbbtree.insert_new(T::in,
         set_bbbtree(T)::in, set_bbbtree(T)::out) is semidet.

         % `set_bbbtree.insert_list(Xs, Set0, Set)' is true iff `Set' is
         % the union of `Set0' and the set containing only the members of `Xs'.
         %
     :- pred set_bbbtree.insert_list(list(T)::in,
         set_bbbtree(T)::in, set_bbbtree(T)::out) is det.

     :- func set_bbbtree.insert_list(set_bbbtree(T), list(T)) = set_bbbtree(T).

         % `set_bbbtree.delete(X, Set0, Set)' is true iff `Set' is the relative
         % complement of `Set0' and the set containing only `X', i.e.
         % if `Set' is the set which contains all the elements of `Set0'
         % except `X'.
         %
     :- pred set_bbbtree.delete(T, set_bbbtree(T), set_bbbtree(T)).
     :- mode set_bbbtree.delete(in, di, uo) is det.
     :- mode set_bbbtree.delete(in, in, out) is det.

     :- func set_bbbtree.delete(set_bbbtree(T), T) = set_bbbtree(T).

         % `set_bbbtree.delete_list(Xs, Set0, Set)' is true iff `Set' is the
         % relative complement of `Set0' and the set containing only the members
         % of `Xs'.
         %
     :- pred set_bbbtree.delete_list(list(T)::in,
         set_bbbtree(T)::in, set_bbbtree(T)::out) is det.

     :- func set_bbbtree.delete_list(set_bbbtree(T), list(T)) = set_bbbtree(T).

         % `set_bbbtree.remove(X, Set0, Set)' is true iff `Set0' contains `X',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only `X', i.e.  if `Set' is the set which contains
         % all the elements of `Set0' except `X'.
         %
     :- pred set_bbbtree.remove(T::in, set_bbbtree(T)::in, set_bbbtree(T)::out)
         is semidet.

         % `set_bbbtree.remove_list(Xs, Set0, Set)' is true iff Xs does not
         % contain any duplicates, `Set0' contains every member of `Xs',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only the members of `Xs'.
         %
     :- pred set_bbbtree.remove_list(list(T)::in,
         set_bbbtree(T)::in, set_bbbtree(T)::out) is semidet.

         % `set_bbbtree.remove_least(X, Set0, Set)' is true iff the union if
         % `X' and `Set' is `Set0' and `X' is smaller than all the elements of
         % `Set'.
         %
     :- pred set_bbbtree.remove_least(T::out,
         set_bbbtree(T)::in, set_bbbtree(T)::out) is semidet.

         % `set_bbbtree.remove_largest(X, Set0, Set)' is true iff the union if
         % `X' and `Set' is `Set0' and `X' is larger than all the elements of
         % `Set'.
         %
     :- pred set_bbbtree.remove_largest(T::out,
         set_bbbtree(T)::in, set_bbbtree(T)::out) is semidet.

         % `set_bbbtree.list_to_set(List, Set)' is true iff `Set' is the set
         % containing only the members of `List'. O(n lg n)
         %
     :- pred set_bbbtree.list_to_set(list(T)::in, set_bbbtree(T)::out) is det.

     :- func set_bbbtree.list_to_set(list(T)) = set_bbbtree(T).

         % A synonym for set_bbtree.list_to_set/1.
         %
     :- func set_bbbtree.from_list(list(T)) = set_bbbtree(T).

         % `set_bbbtree.sorted_list_to_set(List, Set)' is true iff `Set' is the
         % set containing only the members of `List'.
         % `List' must be sorted. O(n).
         %
     :- pred set_bbbtree.sorted_list_to_set(list(T)::in, set_bbbtree(T)::out)
         is det.

     :- func set_bbbtree.sorted_list_to_set(list(T)) = set_bbbtree(T).

         % A synonym for set_bbbtree.sorted_list_to_set/1.
         %
     :- func set_bbbtree.from_sorted_list(list(T)) = set_bbbtree(T).

         % `set_bbbtree.sorted_list_to_set_len(List, Set, N)' is true iff
         % `Set' is the set containing only the members of `List' and `N'
         % is the length of the list. If the length of the list is already known
         % then a noticeable speed improvement can be expected over
         % `set_bbbtree.sorted_list_to_set' as a significant cost involved
         % with `set_bbbtree.sorted_list_to_set' is the call to list.length.
         % `List' must be sorted. O(n).
         %
     :- pred set_bbbtree.sorted_list_to_set_len(list(T)::in, set_bbbtree(T)::out,
         int::in) is det.

         % `set_bbbtree.to_sorted_list(Set, List)' is true iff `List' is the
         % list of all the members of `Set', in sorted order. O(n).
         %
     :- pred set_bbbtree.to_sorted_list(set_bbbtree(T), list(T)).
     :- mode set_bbbtree.to_sorted_list(di, uo) is det.
     :- mode set_bbbtree.to_sorted_list(in, out) is det.

     :- func set_bbbtree.to_sorted_list(set_bbbtree(T)) = list(T).

         % `set_bbbtree.union(SetA, SetB, Set)' is true iff `Set' is the union
         % of `SetA' and `SetB'.
         %
     :- pred set_bbbtree.union(set_bbbtree(T)::in, set_bbbtree(T)::in,
         set_bbbtree(T)::out) is det.

     :- func set_bbbtree.union(set_bbbtree(T), set_bbbtree(T)) = set_bbbtree(T).

         % `set_bbbtree.union_list(Sets) = Set' is true iff `Set' is the union
         % of all the sets in `Sets'
         %
     :- func set_bbbtree.union_list(list(set_bbbtree(T))) = set_bbbtree(T).

         % `set_bbbtree.power_union(Sets, Set)' is true iff `Set' is the union
         % of all the sets in `Sets'
         %
     :- pred set_bbbtree.power_union(set_bbbtree(set_bbbtree(T))::in,
         set_bbbtree(T)::out) is det.

     :- func set_bbbtree.power_union(set_bbbtree(set_bbbtree(T))) = set_bbbtree(T).

         % `set_bbbtree.intersect(SetA, SetB, Set)' is true iff `Set' is the
         % intersection of `SetA' and `SetB'.
         %
     :- pred set_bbbtree.intersect(set_bbbtree(T)::in, set_bbbtree(T)::in,
         set_bbbtree(T)::out) is det.

     :- func set_bbbtree.intersect(set_bbbtree(T), set_bbbtree(T)) = set_bbbtree(T).

         % `set_bbbtree.power_intersect(Sets, Set) is true iff `Set' is the
         % intersection of the sets in `Sets'.
         %
     :- pred set_bbbtree.power_intersect(set_bbbtree(set_bbbtree(T))::in,
         set_bbbtree(T)::out) is det.

     :- func set_bbbtree.power_intersect(set_bbbtree(set_bbbtree(T)))
         = set_bbbtree(T).

         % `set_bbbtree.intersect_list(Sets) = Set is true iff `Set' is the
         % intersection of the sets in `Sets'.
         %
     :- func set_bbbtree.intersect_list(list(set_bbbtree(T))) = set_bbbtree(T).

         % `set_bbtree.difference(SetA, SetB, Set)' is true iff `Set' is the
         %  set containing all the elements of `SetA' except those that
         % occur in `SetB'.
         %
     :- pred set_bbbtree.difference(set_bbbtree(T)::in, set_bbbtree(T)::in,
         set_bbbtree(T)::out) is det.

     :- func set_bbbtree.difference(set_bbbtree(T), set_bbbtree(T))
         = set_bbbtree(T).

         % `set_bbbtree.subset(SetA, SetB)' is true iff all the elements of
         % `SetA' are also elements of `SetB'.
         %
     :- pred set_bbbtree.subset(set_bbbtree(T)::in, set_bbbtree(T)::in) is semidet.

         % `set_bbbtree.superset(SetA, SetB)' is true iff all the elements of
         % `SetB' are also elements of `SetA'.
         %
     :- pred set_bbbtree.superset(set_bbbtree(T)::in, set_bbbtree(T)::in)
         is semidet.

     :- func set_bbbtree.fold(func(T1, T2) = T2, set_bbbtree(T1), T2) = T2.
     :- pred set_bbbtree.fold(pred(T1, T2, T2), set_bbbtree(T1), T2, T2).
     :- mode set_bbbtree.fold(pred(in, in, out) is det, in, in, out) is det.
     :- mode set_bbbtree.fold(pred(in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode set_bbbtree.fold(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode set_bbbtree.fold(pred(in, in, out) is semidet, in, in, out)
         is semidet.
     :- mode set_bbbtree.fold(pred(in, mdi, muo) is semidet, in, mdi, muo)
         is semidet.
     :- mode set_bbbtree.fold(pred(in, di, uo) is semidet, in, di, uo)
         is semidet.

     :- pred set_bbbtree.fold2(pred(T1, T2, T2, T3, T3), set_bbbtree(T1),
         T2, T2, T3, T3).
     :- mode set_bbbtree.fold2(pred(in, in, out, in, out) is det, in,
         in, out, in, out) is det.
     :- mode set_bbbtree.fold2(pred(in, in, out, mdi, muo) is det, in,
         in, out, mdi, muo) is det.
     :- mode set_bbbtree.fold2(pred(in, in, out, di, uo) is det, in,
         in, out, di, uo) is det.
     :- mode set_bbbtree.fold2(pred(in, in, out, in, out) is semidet, in,
         in, out, in, out) is semidet.
     :- mode set_bbbtree.fold2(pred(in, in, out, mdi, muo) is semidet, in,
         in, out, mdi, muo) is semidet.
     :- mode set_bbbtree.fold2(pred(in, in, out, di, uo) is semidet, in,
         in, out, di, uo) is semidet.

     :- pred set_bbbtree.fold3(pred(T1, T2, T2, T3, T3, T4, T4),
         set_bbbtree(T1), T2, T2, T3, T3, T4, T4).
     :- mode set_bbbtree.fold3(pred(in, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out) is det.
     :- mode set_bbbtree.fold3(pred(in, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, mdi, muo) is det.
     :- mode set_bbbtree.fold3(pred(in, in, out, in, out, di, uo) is det, in,
         in, out, in, out, di, uo) is det.
     :- mode set_bbbtree.fold3(pred(in, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out) is semidet.
     :- mode set_bbbtree.fold3(pred(in, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, mdi, muo) is semidet.
     :- mode set_bbbtree.fold3(pred(in, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, di, uo) is semidet.

     :- pred set_bbbtree.fold4(pred(T1, T2, T2, T3, T3, T4, T4, T5, T5),
         set_bbbtree(T1), T2, T2, T3, T3, T4, T4, T5, T5).
     :- mode set_bbbtree.fold4(
         pred(in, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out) is det.
     :- mode set_bbbtree.fold4(
         pred(in, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_bbbtree.fold4(
         pred(in, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, di, uo) is det.
     :- mode set_bbbtree.fold4(
         pred(in, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out) is semidet.
     :- mode set_bbbtree.fold4(
         pred(in, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_bbbtree.fold4(
         pred(in, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_bbbtree.fold5(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6),
         set_bbbtree(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6).
     :- mode set_bbbtree.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_bbbtree.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_bbbtree.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_bbbtree.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_bbbtree.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_bbbtree.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_bbbtree.fold6(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7),
         set_bbbtree(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7).
     :- mode set_bbbtree.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_bbbtree.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_bbbtree.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_bbbtree.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_bbbtree.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_bbbtree.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet.

         % all_true(Pred, Set) succeeds iff Pred(Element) succeeds
         % for all the elements of Set.
         %
     :- pred all_true(pred(T)::in(pred(in) is semidet), set_bbbtree(T)::in)
         is semidet.

     :- func set_bbbtree.map(func(T1) = T2, set_bbbtree(T1)) = set_bbbtree(T2).

     :- func set_bbbtree.filter_map(func(T1) = T2, set_bbbtree(T1))
         = set_bbbtree(T2).
     :- mode set_bbbtree.filter_map(func(in) = out is semidet, in) = out is det.

         % set_bbbtree.filter(Pred, Items, Trues):
         % Return the set of items for which Pred succeeds.
         %
     :- pred set_bbbtree.filter(pred(T)::in(pred(in) is semidet),
         set_bbbtree(T)::in, set_bbbtree(T)::out) is det.

         % set_bbbtree.filter(Pred, Items, Trues, Falses):
         % Return the set of items for which Pred succeeds,
         % and the set for which it fails.
         %
     :- pred set_bbbtree.filter(pred(T)::in(pred(in) is semidet),
         set_bbbtree(T)::in, set_bbbtree(T)::out, set_bbbtree(T)::out) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: set_ctree234,  Next: set_ordlist,  Prev: set_bbbtree,  Up: Top

60 set_ctree234
***************

     %--------------------------------------------------%
     % vim: ts=4 sw=4 et ft=mercury
     %--------------------------------------------------%
     % Copyright (C) 2005-2006, 2010-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: set_ctree234.m.
     % Author: zs.
     % Stability: high.
     %
     % This module implements sets using 2-3-4 trees extended with element counts.
     % This representation has higher constant factors for most operations than
     % ordered lists, but it has much better worst-case complexity, and is likely
     % to be faster for large sets. Specifically,
     %
     % - the cost of lookups is only logarithmic in the size of the set, not linear;
     %
     % - for operations that are intrinsically linear in the size of one input
     %   operand or the other, the counts allow us to choose to be linear in the
     %   size of the smaller set.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module set_ctree234.
     :- interface.

     :- import_module bool.
     :- import_module list.

     %--------------------------------------------------%

     :- type set_ctree234(_T).

         % `set_ctree234.init = Set' is true iff `Set' is an empty set.
         %
     :- func set_ctree234.init = set_ctree234(T).

         % `set_ctree234.singleton_set(Elem, Set)' is true iff `Set' is the set
         % containing just the single element `Elem'.
         %
     :- pred set_ctree234.singleton_set(T, set_ctree234(T)).
     :- mode set_ctree234.singleton_set(in, out) is det.
     :- mode set_ctree234.singleton_set(out, in) is semidet.

     :- func set_ctree234.make_singleton_set(T) = set_ctree234(T).

     :- pred set_ctree234.is_singleton(set_ctree234(T)::in, T::out) is semidet.

         % `set_ctree234.empty(Set)' is true iff `Set' is an empty set.
         %
     :- pred set_ctree234.empty(set_ctree234(_T)::in) is semidet.

     :- pred set_ctree234.is_empty(set_ctree234(_T)::in) is semidet.

     :- pred set_ctree234.non_empty(set_ctree234(T)::in) is semidet.

         % `set_ctree234.member(X, Set)' is true iff `X' is a member of `Set'.
         %
     :- pred set_ctree234.member(T, set_ctree234(T)).
     :- mode set_ctree234.member(in, in) is semidet.
     :- mode set_ctree234.member(out, in) is nondet.

         % `set_ctree234.one_member(Set, X)' is true iff `X' is a member of `Set'.
         %
     :- pred set_ctree234.one_member(set_ctree234(T)::in, T::out) is nondet.

         % `set_ctree234.is_member(Set, X, Result)' returns
         % `Result = yes' iff `X' is a member of `Set'.
         %
     :- func set_ctree234.is_member(set_ctree234(T), T) = bool.
     :- pred set_ctree234.is_member(set_ctree234(T)::in, T::in, bool::out) is det.

         % `set_ctree234.contains(Set, X)' is true iff `X' is a member of `Set'.
         %
     :- pred set_ctree234.contains(set_ctree234(T)::in, T::in) is semidet.

         % `set_ctree234.list_to_set(List) = Set' is true iff `Set' is the set
         % containing only the members of `List'.
         %
     :- func set_ctree234.list_to_set(list(T)) = set_ctree234(T).

     :- func set_ctree234.from_list(list(T)) = set_ctree234(T).

         % `set_ctree234.sorted_list_to_set(List) = Set' is true iff `Set' is
         % the set containing only the members of `List'. `List' must be sorted.
         %
     :- func set_ctree234.sorted_list_to_set(list(T)) = set_ctree234(T).

         % `set_ctree234.to_sorted_list(Set) = List' is true iff `List' is the
         % list of all the members of `Set', in sorted order.
         %
     :- func set_ctree234.to_sorted_list(set_ctree234(T)) = list(T).

         % `set_ctree234.equal(SetA, SetB)' is true iff
         % `SetA' and `SetB' contain the same elements.
         %
     :- pred set_ctree234.equal(set_ctree234(T)::in, set_ctree234(T)::in)
         is semidet.

         % `set_ctree234.subset(SetA, SetB)' is true iff `SetA' is a subset of
         % `SetB'.
         %
     :- pred set_ctree234.subset(set_ctree234(T)::in, set_ctree234(T)::in)
         is semidet.

         % `set_ctree234.superset(SetA, SetB)' is true iff `SetA' is a
         % superset of `SetB'.
         %
     :- pred set_ctree234.superset(set_ctree234(T)::in, set_ctree234(T)::in)
         is semidet.

         % `set_ctree234.insert(X, Set0, Set)' is true iff `Set' is the union
         % of `Set0' and the set containing only `X'.
         %
     :- func set_ctree234.insert(T, set_ctree234(T)) = set_ctree234(T).
     :- pred set_ctree234.insert(T::in, set_ctree234(T)::in, set_ctree234(T)::out)
         is det.

         % `set_ctree234.insert_new(X, Set0, Set)' is true iff `Set0' does
         % not contain `X', and `Set' is the union of `Set0' and the set containing
         % only `X'.
         %
     :- pred set_ctree234.insert_new(T::in,
         set_ctree234(T)::in, set_ctree234(T)::out) is semidet.

         % `set_ctree234.insert_list(Xs, Set0, Set)' is true iff `Set' is the
         % union of `Set0' and the set containing only the members of `Xs'.
         %
     :- func set_ctree234.insert_list(list(T), set_ctree234(T)) = set_ctree234(T).
     :- pred set_ctree234.insert_list(list(T)::in,
         set_ctree234(T)::in, set_ctree234(T)::out) is det.

         % `set_ctree234.delete(X, Set0, Set)' is true iff `Set' is the
         % relative complement of `Set0' and the set containing only `X', i.e.
         % if `Set' is the set which contains all the elements of `Set0'
         % except `X'.
         %
     :- func set_ctree234.delete(T, set_ctree234(T)) = set_ctree234(T).
     :- pred set_ctree234.delete(T::in, set_ctree234(T)::in, set_ctree234(T)::out)
         is det.

         % `set_ctree234.delete_list(Xs, Set0, Set)' is true iff `Set' is the
         % relative complement of `Set0' and the set containing only the members
         % of `Xs'.
         %
     :- func set_ctree234.delete_list(list(T), set_ctree234(T)) = set_ctree234(T).
     :- pred set_ctree234.delete_list(list(T)::in,
         set_ctree234(T)::in, set_ctree234(T)::out) is det.

         % `set_ctree234.remove(X, Set0, Set)' is true iff `Set0' contains `X',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only `X', i.e.  if `Set' is the set which contains
         % all the elements of `Set0' except `X'.
         %
     :- pred set_ctree234.remove(T::in, set_ctree234(T)::in, set_ctree234(T)::out)
         is semidet.

         % `set_ctree234.remove_list(Xs, Set0, Set)' is true iff Xs does not
         % contain any duplicates, `Set0' contains every member of `Xs',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only the members of `Xs'.
         %
     :- pred set_ctree234.remove_list(list(T)::in,
         set_ctree234(T)::in, set_ctree234(T)::out) is semidet.

         % `set_ctree234.remove_least(X, Set0, Set)' is true iff `X' is the
         % least element in `Set0', and `Set' is the set which contains all the
         % elements of `Set0' except `X'.
         %
     :- pred set_ctree234.remove_least(T::out,
         set_ctree234(T)::in, set_ctree234(T)::out) is semidet.

         % `set_ctree234.union(SetA, SetB) = Set' is true iff `Set' is the union
         % of `SetA' and `SetB'.
         %
     :- func set_ctree234.union(set_ctree234(T), set_ctree234(T)) = set_ctree234(T).
     :- pred set_ctree234.union(set_ctree234(T)::in, set_ctree234(T)::in,
         set_ctree234(T)::out) is det.

         % `set_ctree234.union_list(A, B)' is true iff `B' is the union of
         % all the sets in `A'
         %
     :- func set_ctree234.union_list(list(set_ctree234(T))) = set_ctree234(T).
     :- pred set_ctree234.union_list(list(set_ctree234(T))::in,
         set_ctree234(T)::out) is det.

         % `set_ctree234.power_union(A) = B' is true iff `B' is the union of
         % all the sets in `A'
         %
     :- func set_ctree234.power_union(set_ctree234(set_ctree234(T)))
         = set_ctree234(T).
     :- pred set_ctree234.power_union(set_ctree234(set_ctree234(T))::in,
         set_ctree234(T)::out) is det.

         % `set_ctree234.intersect(SetA, SetB) = Set' is true iff `Set' is the
         % intersection of `SetA' and `SetB'.
         %
     :- func set_ctree234.intersect(set_ctree234(T), set_ctree234(T))
         = set_ctree234(T).
     :- pred set_ctree234.intersect(set_ctree234(T)::in, set_ctree234(T)::in,
         set_ctree234(T)::out) is det.

         % `set_ctree234.power_intersect(A, B)' is true iff `B' is the
         % intersection of all the sets in `A'.
         %
     :- func set_ctree234.power_intersect(set_ctree234(set_ctree234(T)))
         = set_ctree234(T).

         % `set_ctree234.intersect_list(A) = B' is true iff `B' is the
         % intersection of all the sets in `A'.
         %
     :- func set_ctree234.intersect_list(list(set_ctree234(T))) = set_ctree234(T).

         % `set_ctree234.difference(SetA, SetB, Set)' is true iff `Set' is the
         % set containing all the elements of `SetA' except those that
         % occur in `SetB'.
         %
     :- func set_ctree234.difference(set_ctree234(T), set_ctree234(T))
         = set_ctree234(T).
     :- pred set_ctree234.difference(set_ctree234(T)::in, set_ctree234(T)::in,
         set_ctree234(T)::out) is det.

         % `set_ctree234.count(Set, Count)' is true iff `Set' has
         % `Count' elements.
         %
     :- func set_ctree234.count(set_ctree234(T)) = int.

     :- func set_ctree234.map(func(T1) = T2, set_ctree234(T1)) = set_ctree234(T2).
     :- pred set_ctree234.map(pred(T1, T2)::in(pred(in, out) is det),
         set_ctree234(T1)::in, set_ctree234(T2)::out) is det.

     :- pred set_ctree234.filter_map(pred(T1, T2)::in(pred(in, out) is semidet),
         set_ctree234(T1)::in, set_ctree234(T2)::out) is det.

     :- func set_ctree234.filter_map(func(T1) = T2, set_ctree234(T1))
         = set_ctree234(T2).
     :- mode set_ctree234.filter_map(func(in) = out is semidet, in) = out is det.

     :- func set_ctree234.fold(func(T1, T2) = T2, set_ctree234(T1), T2) = T2.
     :- pred set_ctree234.fold(pred(T1, T2, T2), set_ctree234(T1), T2, T2).
     :- mode set_ctree234.fold(pred(in, in, out) is det, in, in, out) is det.
     :- mode set_ctree234.fold(pred(in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode set_ctree234.fold(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode set_ctree234.fold(pred(in, in, out) is semidet, in, in, out)
         is semidet.
     :- mode set_ctree234.fold(pred(in, mdi, muo) is semidet, in, mdi, muo)
         is semidet.
     :- mode set_ctree234.fold(pred(in, di, uo) is semidet, in, di, uo)
         is semidet.

     :- pred set_ctree234.fold2(pred(T1, T2, T2, T3, T3), set_ctree234(T1),
         T2, T2, T3, T3) is det.
     :- mode set_ctree234.fold2(pred(in, in, out, in, out) is det,
         in, in, out, in, out) is det.
     :- mode set_ctree234.fold2(pred(in, in, out, mdi, muo) is det,
         in, in, out, mdi, muo) is det.
     :- mode set_ctree234.fold2(pred(in, in, out, di, uo) is det,
         in, in, out, di, uo) is det.
     :- mode set_ctree234.fold2(pred(in, in, out, in, out) is semidet,
         in, in, out, in, out) is semidet.
     :- mode set_ctree234.fold2(pred(in, in, out, mdi, muo) is semidet,
         in, in, out, mdi, muo) is semidet.
     :- mode set_ctree234.fold2(pred(in, in, out, di, uo) is semidet,
         in, in, out, di, uo) is semidet.

     :- pred set_ctree234.fold3(
         pred(T1, T2, T2, T3, T3, T4, T4), set_ctree234(T1),
         T2, T2, T3, T3, T4, T4).
     :- mode set_ctree234.fold3(pred(in, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out) is det.
     :- mode set_ctree234.fold3(pred(in, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, mdi, muo) is det.
     :- mode set_ctree234.fold3(pred(in, in, out, in, out, di, uo) is det, in,
         in, out, in, out, di, uo) is det.
     :- mode set_ctree234.fold3(pred(in, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out) is semidet.
     :- mode set_ctree234.fold3(pred(in, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, mdi, muo) is semidet.
     :- mode set_ctree234.fold3(pred(in, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, di, uo) is semidet.

     :- pred set_ctree234.fold4(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5), set_ctree234(T1),
         T2, T2, T3, T3, T4, T4, T5, T5).
     :- mode set_ctree234.fold4(pred(in, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out) is det.
     :- mode set_ctree234.fold4(pred(in, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_ctree234.fold4(pred(in, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, di, uo) is det.
     :- mode set_ctree234.fold4(
         pred(in, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_ctree234.fold4(
         pred(in, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_ctree234.fold4(
         pred(in, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_ctree234.fold5(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6),
         set_ctree234(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6).
     :- mode set_ctree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_ctree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_ctree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_ctree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_ctree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_ctree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_ctree234.fold6(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7),
         set_ctree234(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7).
     :- mode set_ctree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_ctree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_ctree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_ctree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_ctree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_ctree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet.

         % all_true(Pred, Set) succeeds iff Pred(Element) succeeds
         % for all the elements of Set.
         %
     :- pred set_ctree234.all_true(pred(T)::in(pred(in) is semidet),
         set_ctree234(T)::in) is semidet.

         % Return the set of items for which the predicate succeeds.
         %
     :- pred set_ctree234.filter(pred(T)::in(pred(in) is semidet),
         set_ctree234(T)::in, set_ctree234(T)::out) is det.

         % Return the set of items for which the predicate succeeds,
         % and the set for which it fails.
         %
     :- pred set_ctree234.filter(pred(T)::in(pred(in) is semidet),
         set_ctree234(T)::in, set_ctree234(T)::out, set_ctree234(T)::out) is det.

         % set_ctree234.divide(Pred, Set, TruePart, FalsePart):
         % TruePart consists of those elements of Set for which Pred succeeds;
         % FalsePart consists of those elements of Set for which Pred fails.
         % NOTE: This is the same as filter/4.
         %
     :- pred set_ctree234.divide(pred(T)::in(pred(in) is semidet),
         set_ctree234(T)::in, set_ctree234(T)::out, set_ctree234(T)::out) is det.

         % set_ctree234.divide_by_set(DivideBySet, Set, InPart, OutPart):
         % InPart consists of those elements of Set which are also in
         % DivideBySet; OutPart consists of those elements of which are
         % not in DivideBySet.
         %
     :- pred set_ctree234.divide_by_set(set_ctree234(T)::in, set_ctree234(T)::in,
         set_ctree234(T)::out, set_ctree234(T)::out) is det.

     :- pred verify_depths(set_ctree234(T)::in, list(int)::out) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: set_ordlist,  Next: set_tree234,  Prev: set_ctree234,  Up: Top

61 set_ordlist
**************

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et
     %--------------------------------------------------%
     % Copyright (C) 1996-1997,1999-2002, 2004-2006, 2008-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: set_ordlist.m.
     % Main authors: conway, fjh.
     % Stability: medium.
     %
     % This file contains a `set' ADT.
     % Sets are implemented here as sorted lists without duplicates.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module set_ordlist.
     :- interface.

     :- import_module bool.
     :- import_module list.

     %--------------------------------------------------%

     :- type set_ordlist(_T).

         % `set_ordlist.init(Set)' is true iff `Set' is an empty set.
         %
     :- pred set_ordlist.init(set_ordlist(_T)::uo) is det.
     :- func set_ordlist.init = set_ordlist(T).

         % `set_ordlist.list_to_set(List, Set)' is true iff `Set' is the set
         % containing only the members of `List'.
         %
     :- pred set_ordlist.list_to_set(list(T)::in, set_ordlist(T)::out) is det.
     :- func set_ordlist.list_to_set(list(T)) = set_ordlist(T).

         % A synonym for set_ordlist.list_to_set/1.
         %
     :- func set_ordlist.from_list(list(T)) = set_ordlist(T).

         % `set_ordlist.sorted_list_to_set(List, Set)' is true iff `Set' is
         % the set containing only the members of `List'.  `List' must be sorted.
         %
     :- pred set_ordlist.sorted_list_to_set(list(T)::in, set_ordlist(T)::out)
         is det.
     :- func set_ordlist.sorted_list_to_set(list(T)) = set_ordlist(T).

         % A synonym for set_ordlist.sorted_list_to_set/1.
         %
     :- func set_ordlist.from_sorted_list(list(T)) = set_ordlist(T).

         % `set_ordlist.to_sorted_list(Set, List)' is true iff `List' is the
         % list of all the members of `Set', in sorted order.
         %
     :- pred set_ordlist.to_sorted_list(set_ordlist(T)::in, list(T)::out) is det.
     :- func set_ordlist.to_sorted_list(set_ordlist(T)) = list(T).

         % `set_ordlist.singleton_set(Elem, Set)' is true iff `Set' is the set
         % containing just the single element `Elem'.
         %
     :- pred set_ordlist.singleton_set(T, set_ordlist(T)).
     :- mode set_ordlist.singleton_set(in, out) is det.
     :- mode set_ordlist.singleton_set(out, in) is semidet.

     :- func set_ordlist.make_singleton_set(T) = set_ordlist(T).
     :- pred set_ordlist.is_singleton(set_ordlist(T)::in, T::out) is semidet.

         % `set_ordlist.equal(SetA, SetB)' is true iff
         % `SetA' and `SetB' contain the same elements.
         %
     :- pred set_ordlist.equal(set_ordlist(T)::in, set_ordlist(T)::in) is semidet.

         % `set_ordlist.empty(Set)' is true iff `Set' is an empty set.
         %
     :- pred set_ordlist.empty(set_ordlist(_T)::in) is semidet.
     :- pred set_ordlist.is_empty(set_ordlist(T)::in) is semidet.

     :- pred set_ordlist.non_empty(set_ordlist(T)::in) is semidet.
     :- pred set_ordlist.is_non_empty(set_ordlist(T)::in) is semidet.

         % `set_ordlist.subset(SetA, SetB)' is true iff `SetA' is a subset of
         % `SetB'.
         %
     :- pred set_ordlist.subset(set_ordlist(T)::in, set_ordlist(T)::in) is semidet.

         % `set_ordlist.superset(SetA, SetB)' is true iff `SetA' is a
         % superset of `SetB'.
         %
     :- pred set_ordlist.superset(set_ordlist(T)::in, set_ordlist(T)::in)
         is semidet.

         % `set_ordlist.member(X, Set)' is true iff `X' is a member of `Set'.
         %
     :- pred set_ordlist.member(T, set_ordlist(T)).
     :- mode set_ordlist.member(in, in) is semidet.
     :- mode set_ordlist.member(out, in) is nondet.

         % `set_ordlist.is_member(X, Set, Result)' returns
         % `Result = yes' iff `X' is a member of `Set'.
         %
     :- pred set_ordlist.is_member(T::in, set_ordlist(T)::in, bool::out) is det.

         % `set_ordlist.contains(Set, X)' is true iff `X' is a member of `Set'.
         %
     :- pred set_ordlist.contains(set_ordlist(T)::in, T::in) is semidet.

         % `set_ordlist.insert(X, Set0, Set)' is true iff `Set' is the union
         % of `Set0' and the set containing only `X'.
         %
     :- pred set_ordlist.insert(T::in, set_ordlist(T)::in, set_ordlist(T)::out)
         is det.
     :- func set_ordlist.insert(set_ordlist(T), T) = set_ordlist(T).

         % `set_ordlist.insert_new(X, Set0, Set)' is true iff
         % `Set0' does not contain `X', while `Set' is the union of `Set0'
         % and the set containing only `X'.
         %
     :- pred set_ordlist.insert_new(T::in,
         set_ordlist(T)::in, set_ordlist(T)::out) is semidet.

         % `set_ordlist.insert_list(Xs, Set0, Set)' is true iff `Set' is the
         % union of `Set0' and the set containing only the members of `Xs'.
         %
     :- pred set_ordlist.insert_list(list(T)::in,
         set_ordlist(T)::in, set_ordlist(T)::out) is det.
     :- func set_ordlist.insert_list(set_ordlist(T), list(T)) = set_ordlist(T).

         % `set_ordlist.delete(Set0, X, Set)' is true iff `Set' is the
         % relative complement of `Set0' and the set containing only `X', i.e.
         % if `Set' is the set which contains all the elements of `Set0'
         % except `X'.
         %
     :- pred set_ordlist.delete(T::in, set_ordlist(T)::in, set_ordlist(T)::out)
         is det.
     :- func set_ordlist.delete(set_ordlist(T), T) = set_ordlist(T).

         % `set_ordlist.delete_list(Xs, Set0, Set)' is true iff `Set' is the
         % relative complement of `Set0' and the set containing only the members
         % of `Xs'.
         %
     :- pred set_ordlist.delete_list(list(T)::in,
         set_ordlist(T)::in, set_ordlist(T)::out) is det.
     :- func set_ordlist.delete_list(set_ordlist(T), list(T)) = set_ordlist(T).

         % `set_ordlist.remove(X, Set0, Set)' is true iff `Set0' contains `X',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only `X', i.e.  if `Set' is the set which contains
         % all the elements of `Set0' except `X'.
         %
     :- pred set_ordlist.remove(T::in, set_ordlist(T)::in, set_ordlist(T)::out)
         is semidet.

         % `set_ordlist.remove_list(Xs, Set0, Set)' is true iff Xs does not
         % contain any duplicates, `Set0' contains every member of `Xs',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only the members of `Xs'.
         %
     :- pred set_ordlist.remove_list(list(T)::in,
         set_ordlist(T)::in, set_ordlist(T)::out) is semidet.

         % `set_ordlist.remove_least(X, Set0, Set)' is true iff `X' is the
         % least element in `Set0', and `Set' is the set which contains all the
         % elements of `Set0' except `X'.

     :- pred set_ordlist.remove_least(T::out,
         set_ordlist(T)::in, set_ordlist(T)::out) is semidet.

         % `set_ordlist.union(SetA, SetB, Set)' is true iff `Set' is the union
         % of `SetA' and `SetB'. The efficiency of the union operation is
         % O(card(SetA)+card(SetB)) and is not sensitive to the argument
         % ordering.
         %
     :- pred set_ordlist.union(set_ordlist(T)::in, set_ordlist(T)::in,
         set_ordlist(T)::out) is det.
     :- func set_ordlist.union(set_ordlist(T), set_ordlist(T)) = set_ordlist(T).

         % `set_ordlist.union_list(A, B)' is true iff `B' is the union of
         % all the sets in `A'
         %
     :- pred set_ordlist.union_list(list(set_ordlist(T))::in, set_ordlist(T)::out)
         is det.
     :- func set_ordlist.union_list(list(set_ordlist(T))) = set_ordlist(T).

         % `set_ordlist.power_union(A, B)' is true iff `B' is the union of
         % all the sets in `A'
         %
     :- pred set_ordlist.power_union(set_ordlist(set_ordlist(T))::in,
         set_ordlist(T)::out) is det.
     :- func set_ordlist.power_union(set_ordlist(set_ordlist(T))) = set_ordlist(T).

         % `set_ordlist.intersect(SetA, SetB, Set)' is true iff `Set' is the
         % intersection of `SetA' and `SetB'. The efficiency of the intersection
         % operation is not influenced by the argument order.
         %
     :- pred set_ordlist.intersect(set_ordlist(T), set_ordlist(T), set_ordlist(T)).
     :- mode set_ordlist.intersect(in, in, out) is det.
     :- mode set_ordlist.intersect(in, in, in) is semidet.
     :- func set_ordlist.intersect(set_ordlist(T), set_ordlist(T))
         = set_ordlist(T).

         % `set_ordlist.power_intersect(A, B)' is true iff `B' is the
         % intersection of all the sets in `A'.
         %
     :- pred set_ordlist.power_intersect(set_ordlist(set_ordlist(T))::in,
         set_ordlist(T)::out) is det.
     :- func set_ordlist.power_intersect(set_ordlist(set_ordlist(T)))
         = set_ordlist(T).

         % `set_ordlist.intersect_list(A) = B' is true iff `B' is the
         % intersection of all the sets in `A'.
         %
     :- func set_ordlist.intersect_list(list(set_ordlist(T))) = set_ordlist(T).
     :- pred set_ordlist.intersect_list(list(set_ordlist(T))::in,
         set_ordlist(T)::out) is det.

         % `set_ordlist.difference(SetA, SetB, Set)' is true iff `Set' is the
         % set containing all the elements of `SetA' except those that
         % occur in `SetB'.
         %
     :- pred set_ordlist.difference(set_ordlist(T)::in, set_ordlist(T)::in,
         set_ordlist(T)::out) is det.
     :- func set_ordlist.difference(set_ordlist(T), set_ordlist(T))
         = set_ordlist(T).

         % `set_ordlist.count(Set, Count)' is true iff `Set' has
         % `Count' elements.
         %
     :- pred set_ordlist.count(set_ordlist(T)::in, int::out) is det.
     :- func set_ordlist.count(set_ordlist(T)) = int.

         % Return the set of items for which the given predicate succeeds.
         %
     :- func set_ordlist.filter(pred(T1), set_ordlist(T1)) = set_ordlist(T1).
     :- mode set_ordlist.filter(pred(in) is semidet, in) = out is det.
     :- pred set_ordlist.filter(pred(T1), set_ordlist(T1), set_ordlist(T1)).
     :- mode set_ordlist.filter(pred(in) is semidet, in, out) is det.

         % Return the set of items for which the given predicate succeeds,
         % and the set of items for which it fails.
         %
     :- pred set_ordlist.filter(pred(T1), set_ordlist(T1),
         set_ordlist(T1), set_ordlist(T1)).
     :- mode set_ordlist.filter(pred(in) is semidet, in, out, out) is det.

     :- func set_ordlist.map(func(T1) = T2, set_ordlist(T1)) = set_ordlist(T2).

     :- func set_ordlist.filter_map(func(T1) = T2, set_ordlist(T1))
         = set_ordlist(T2).
     :- mode set_ordlist.filter_map(func(in) = out is semidet, in) = out is det.

     :- pred set_ordlist.filter_map(pred(T1, T2), set_ordlist(T1),
         set_ordlist(T2)).
     :- mode set_ordlist.filter_map(pred(in, out) is semidet, in, out) is det.

     :- func set_ordlist.fold(func(T1, T2) = T2, set_ordlist(T1), T2) = T2.
     :- pred set_ordlist.fold(pred(T1, T2, T2), set_ordlist(T1), T2, T2).
     :- mode set_ordlist.fold(pred(in, in, out) is det, in, in, out) is det.
     :- mode set_ordlist.fold(pred(in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode set_ordlist.fold(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode set_ordlist.fold(pred(in, in, out) is semidet, in, in, out)
         is semidet.
     :- mode set_ordlist.fold(pred(in, mdi, muo) is semidet, in, mdi, muo)
         is semidet.
     :- mode set_ordlist.fold(pred(in, di, uo) is semidet, in, di, uo)
         is semidet.

     :- func set_ordlist.foldl(func(T1, T2) = T2, set_ordlist(T1), T2) = T2.
     :- pred set_ordlist.foldl(pred(T1, T2, T2), set_ordlist(T1), T2, T2).
     :- mode set_ordlist.foldl(pred(in, in, out) is det, in, in, out) is det.
     :- mode set_ordlist.foldl(pred(in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode set_ordlist.foldl(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode set_ordlist.foldl(pred(in, in, out) is semidet, in, in, out)
         is semidet.
     :- mode set_ordlist.foldl(pred(in, mdi, muo) is semidet, in, mdi, muo)
         is semidet.
     :- mode set_ordlist.foldl(pred(in, di, uo) is semidet, in, di, uo)
         is semidet.

     :- pred set_ordlist.fold2(pred(T1, T2, T2, T3, T3), set_ordlist(T1),
         T2, T2, T3, T3).
     :- mode set_ordlist.fold2(pred(in, in, out, in, out) is det, in,
         in, out, in, out) is det.
     :- mode set_ordlist.fold2(pred(in, in, out, mdi, muo) is det, in,
         in, out, mdi, muo) is det.
     :- mode set_ordlist.fold2(pred(in, in, out, di, uo) is det, in,
         in, out, di, uo) is det.
     :- mode set_ordlist.fold2(pred(in, in, out, in, out) is semidet, in,
         in, out, in, out) is semidet.
     :- mode set_ordlist.fold2(pred(in, in, out, mdi, muo) is semidet, in,
         in, out, mdi, muo) is semidet.
     :- mode set_ordlist.fold2(pred(in, in, out, di, uo) is semidet, in,
         in, out, di, uo) is semidet.

     :- pred set_ordlist.foldl2(pred(T1, T2, T2, T3, T3), set_ordlist(T1),
         T2, T2, T3, T3).
     :- mode set_ordlist.foldl2(pred(in, in, out, in, out) is det, in,
         in, out, in, out) is det.
     :- mode set_ordlist.foldl2(pred(in, in, out, mdi, muo) is det, in,
         in, out, mdi, muo) is det.
     :- mode set_ordlist.foldl2(pred(in, in, out, di, uo) is det, in,
         in, out, di, uo) is det.
     :- mode set_ordlist.foldl2(pred(in, in, out, in, out) is semidet, in,
         in, out, in, out) is semidet.
     :- mode set_ordlist.foldl2(pred(in, in, out, mdi, muo) is semidet, in,
         in, out, mdi, muo) is semidet.
     :- mode set_ordlist.foldl2(pred(in, in, out, di, uo) is semidet, in,
         in, out, di, uo) is semidet.

     :- pred set_ordlist.fold3(pred(T1, T2, T2, T3, T3, T4, T4),
         set_ordlist(T1), T2, T2, T3, T3, T4, T4).
     :- mode set_ordlist.fold3(pred(in, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out) is det.
     :- mode set_ordlist.fold3(pred(in, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, mdi, muo) is det.
     :- mode set_ordlist.fold3(pred(in, in, out, in, out, di, uo) is det, in,
         in, out, in, out, di, uo) is det.
     :- mode set_ordlist.fold3(pred(in, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out) is semidet.
     :- mode set_ordlist.fold3(pred(in, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, mdi, muo) is semidet.
     :- mode set_ordlist.fold3(pred(in, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, di, uo) is semidet.

     :- pred set_ordlist.foldl3(pred(T1, T2, T2, T3, T3, T4, T4),
         set_ordlist(T1), T2, T2, T3, T3, T4, T4).
     :- mode set_ordlist.foldl3(pred(in, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out) is det.
     :- mode set_ordlist.foldl3(pred(in, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, mdi, muo) is det.
     :- mode set_ordlist.foldl3(pred(in, in, out, in, out, di, uo) is det, in,
         in, out, in, out, di, uo) is det.
     :- mode set_ordlist.foldl3(pred(in, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out) is semidet.
     :- mode set_ordlist.foldl3(pred(in, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, mdi, muo) is semidet.
     :- mode set_ordlist.foldl3(pred(in, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, di, uo) is semidet.

     :- pred set_ordlist.fold4(pred(T1, T2, T2, T3, T3, T4, T4, T5, T5),
         set_ordlist(T1), T2, T2, T3, T3, T4, T4, T5, T5).
     :- mode set_ordlist.fold4(
         pred(in, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out) is det.
     :- mode set_ordlist.fold4(
         pred(in, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_ordlist.fold4(
         pred(in, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, di, uo) is det.
     :- mode set_ordlist.fold4(
         pred(in, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out) is semidet.
     :- mode set_ordlist.fold4(
         pred(in, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_ordlist.fold4(
         pred(in, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_ordlist.foldl4(pred(T1, T2, T2, T3, T3, T4, T4, T5, T5),
         set_ordlist(T1), T2, T2, T3, T3, T4, T4, T5, T5).
     :- mode set_ordlist.foldl4(
         pred(in, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out) is det.
     :- mode set_ordlist.foldl4(
         pred(in, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_ordlist.foldl4(
         pred(in, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, di, uo) is det.
     :- mode set_ordlist.foldl4(
         pred(in, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out) is semidet.
     :- mode set_ordlist.foldl4(
         pred(in, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_ordlist.foldl4(
         pred(in, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_ordlist.fold5(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6),
         set_ordlist(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6).
     :- mode set_ordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_ordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_ordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_ordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_ordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_ordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_ordlist.foldl5(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6),
         set_ordlist(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6).
     :- mode set_ordlist.foldl5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_ordlist.foldl5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_ordlist.foldl5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_ordlist.foldl5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_ordlist.foldl5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_ordlist.foldl5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_ordlist.fold6(pred(T, A, A, B, B, C, C, D, D, E, E, F, F),
         set_ordlist(T), A, A, B, B, C, C, D, D, E, E, F, F).
     :- mode set_ordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_ordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_ordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_ordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_ordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_ordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_ordlist.foldl6(pred(T, A, A, B, B, C, C, D, D, E, E, F, F),
         set_ordlist(T), A, A, B, B, C, C, D, D, E, E, F, F).
     :- mode set_ordlist.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_ordlist.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_ordlist.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_ordlist.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_ordlist.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_ordlist.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet.

         % all_true(Pred, Set) succeeds iff Pred(Element) succeeds
         % for all the elements of Set.
         %
     :- pred all_true(pred(T)::in(pred(in) is semidet), set_ordlist(T)::in)
         is semidet.

         % set_ordlist.divide(Pred, Set, TruePart, FalsePart):
         % TruePart consists of those elements of Set for which Pred succeeds;
         % FalsePart consists of those elements of Set for which Pred fails.
         %
     :- pred set_ordlist.divide(pred(T)::in(pred(in) is semidet),
         set_ordlist(T)::in, set_ordlist(T)::out, set_ordlist(T)::out) is det.

         % set_ordlist.divide_by_set(DivideBySet, Set, InPart, OutPart):
         % InPart consists of those elements of Set which are also in DivideBySet;
         % OutPart consists of those elements of Set which are not in DivideBySet.
         %
     :- pred set_ordlist.divide_by_set(set_ordlist(T)::in, set_ordlist(T)::in,
         set_ordlist(T)::out, set_ordlist(T)::out) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: set_tree234,  Next: set_unordlist,  Prev: set_ordlist,  Up: Top

62 set_tree234
**************

     %--------------------------------------------------%
     % vim: ts=4 sw=4 et ft=mercury
     %--------------------------------------------------%
     % Copyright (C) 2005-2006, 2009-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: set_tree234.m.
     % Author: zs.
     % Stability: high.
     %
     % This module implements sets using 2-3-4 trees.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module set_tree234.
     :- interface.

     :- import_module bool.
     :- import_module list.
     :- import_module set.

     %--------------------------------------------------%

     :- type set_tree234(_T).

         % `set_tree234.init = Set' is true iff `Set' is an empty set.
         %
     :- func set_tree234.init = set_tree234(T).

         % `set_tree234.singleton_set(Elem, Set)' is true iff `Set' is the set
         % containing just the single element `Elem'.
         %
     :- pred set_tree234.singleton_set(T, set_tree234(T)).
     :- mode set_tree234.singleton_set(in, out) is det.
     :- mode set_tree234.singleton_set(out, in) is semidet.

     :- func set_tree234.make_singleton_set(T) = set_tree234(T).

     :- pred set_tree234.is_singleton(set_tree234(T)::in, T::out) is semidet.

         % `set_tree234.empty(Set)' is true iff `Set' is an empty set.
         %
     :- pred set_tree234.empty(set_tree234(_T)::in) is semidet.

         % A synonym for the above.
         %
     :- pred set_tree234.is_empty(set_tree234(_T)::in) is semidet.

     :- pred set_tree234.non_empty(set_tree234(T)::in) is semidet.
     :- pred set_tree234.is_non_empty(set_tree234(T)::in) is semidet.

         % `set_tree234.member(X, Set)' is true iff `X' is a member of `Set'.
         %
     :- pred set_tree234.member(T, set_tree234(T)).
     :- mode set_tree234.member(in, in) is semidet.
     :- mode set_tree234.member(out, in) is nondet.

         % `set_tree234.is_member(Set, X, Result)' returns
         % `Result = yes' iff `X' is a member of `Set'.
         %
     :- func set_tree234.is_member(set_tree234(T), T) = bool.
     :- pred set_tree234.is_member(set_tree234(T)::in, T::in, bool::out) is det.

         % `set_tree234.contains(Set, X)' is true iff `X' is a member of `Set'.
         %
     :- pred set_tree234.contains(set_tree234(T)::in, T::in) is semidet.

         % `set_tree234.list_to_set(List) = Set' is true iff `Set' is the set
         % containing only the members of `List'.
         %
     :- func set_tree234.list_to_set(list(T)) = set_tree234(T).
     :- pred set_tree234.list_to_set(list(T)::in, set_tree234(T)::out) is det.

     :- func set_tree234.from_list(list(T)) = set_tree234(T).
     :- pred set_tree234.from_list(list(T)::in, set_tree234(T)::out) is det.

         % `set_tree234.sorted_list_to_set(List) = Set' is true iff `Set' is
         % the set containing only the members of `List'. `List' must be sorted.
         %
     :- func set_tree234.sorted_list_to_set(list(T)) = set_tree234(T).
     :- pred set_tree234.sorted_list_to_set(list(T)::in, set_tree234(T)::out) is det.

         % `from_set(Set)' returns a set_tree234 containing only the members of
         % `Set'. Takes O(card(Set)) time and space.
         %
     :- func from_set(set.set(T)) = set_tree234(T).

         % `set_tree234.to_sorted_list(Set) = List' is true iff `List' is the
         % list of all the members of `Set', in sorted order.
         %
     :- func set_tree234.to_sorted_list(set_tree234(T)) = list(T).
     :- pred set_tree234.to_sorted_list(set_tree234(T)::in, list(T)::out) is det.

         % `to_sorted_list(Set)' returns a set.set containing all the members
         % of `Set', in sorted order. Takes O(card(Set)) time and space.
         %
     :- func to_set(set_tree234(T)) = set.set(T).

         % `set_tree234.equal(SetA, SetB)' is true iff
         % `SetA' and `SetB' contain the same elements.
         %
     :- pred set_tree234.equal(set_tree234(T)::in, set_tree234(T)::in) is semidet.

         % `set_tree234.subset(SetA, SetB)' is true iff `SetA' is a subset of
         % `SetB'.
         %
     :- pred set_tree234.subset(set_tree234(T)::in, set_tree234(T)::in) is semidet.

         % `set_tree234.superset(SetA, SetB)' is true iff `SetA' is a
         % superset of `SetB'.
         %
     :- pred set_tree234.superset(set_tree234(T)::in, set_tree234(T)::in)
         is semidet.

         % `set_tree234.insert(X, Set0, Set)' is true iff `Set' is the union
         % of `Set0' and the set containing only `X'.
         %
     :- func set_tree234.insert(T, set_tree234(T)) = set_tree234(T).
     :- pred set_tree234.insert(T::in, set_tree234(T)::in, set_tree234(T)::out)
         is det.

         % `set_tree234.insert_new(X, Set0, Set)' is true iff
         % `Set0' does not contain `X', while `Set' is the union of `Set0'
         % and the set containing only `X'.
         %
     :- pred set_tree234.insert_new(T::in,
         set_tree234(T)::in, set_tree234(T)::out) is semidet.

         % `set_tree234.insert_list(Xs, Set0, Set)' is true iff `Set' is the
         % union of `Set0' and the set containing only the members of `Xs'.
         %
     :- func set_tree234.insert_list(list(T), set_tree234(T)) = set_tree234(T).
     :- pred set_tree234.insert_list(list(T)::in,
         set_tree234(T)::in, set_tree234(T)::out) is det.

         % `set_tree234.delete(X, Set0, Set)' is true iff `Set' is the
         % relative complement of `Set0' and the set containing only `X', i.e.
         % if `Set' is the set which contains all the elements of `Set0'
         % except `X'.
         %
     :- func set_tree234.delete(T, set_tree234(T)) = set_tree234(T).
     :- pred set_tree234.delete(T::in, set_tree234(T)::in, set_tree234(T)::out)
         is det.

         % `set_tree234.delete_list(Xs, Set0, Set)' is true iff `Set' is the
         % relative complement of `Set0' and the set containing only the members
         % of `Xs'.
         %
     :- func set_tree234.delete_list(list(T), set_tree234(T)) = set_tree234(T).
     :- pred set_tree234.delete_list(list(T)::in,
         set_tree234(T)::in, set_tree234(T)::out) is det.

         % `set_tree234.remove(X, Set0, Set)' is true iff `Set0' contains `X',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only `X', i.e.  if `Set' is the set which contains
         % all the elements of `Set0' except `X'.
         %
     :- pred set_tree234.remove(T::in, set_tree234(T)::in, set_tree234(T)::out)
         is semidet.

         % `set_tree234.remove_list(Xs, Set0, Set)' is true iff Xs does not
         % contain any duplicates, `Set0' contains every member of `Xs',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only the members of `Xs'.
         %
     :- pred set_tree234.remove_list(list(T)::in,
         set_tree234(T)::in, set_tree234(T)::out) is semidet.

         % `set_tree234.remove_least(X, Set0, Set)' is true iff `X' is the
         % least element in `Set0', and `Set' is the set which contains all the
         % elements of `Set0' except `X'.
         %
     :- pred set_tree234.remove_least(T::out,
         set_tree234(T)::in, set_tree234(T)::out) is semidet.

         % `set_tree234.union(SetA, SetB) = Set' is true iff `Set' is the union
         % of `SetA' and `SetB'.
         %
     :- func set_tree234.union(set_tree234(T), set_tree234(T)) = set_tree234(T).
     :- pred set_tree234.union(set_tree234(T)::in, set_tree234(T)::in,
         set_tree234(T)::out) is det.

         % `set_tree234.union_list(A, B)' is true iff `B' is the union of
         % all the sets in `A'
         %
     :- func set_tree234.union_list(list(set_tree234(T))) = set_tree234(T).
     :- pred set_tree234.union_list(list(set_tree234(T))::in, set_tree234(T)::out)
         is det.

         % `set_tree234.power_union(A) = B' is true iff `B' is the union of
         % all the sets in `A'
         %
     :- func set_tree234.power_union(set_tree234(set_tree234(T))) = set_tree234(T).
     :- pred set_tree234.power_union(set_tree234(set_tree234(T))::in,
         set_tree234(T)::out) is det.

         % `set_tree234.intersect(SetA, SetB) = Set' is true iff `Set' is the
         % intersection of `SetA' and `SetB'.
         %
     :- func set_tree234.intersect(set_tree234(T), set_tree234(T)) = set_tree234(T).
     :- pred set_tree234.intersect(set_tree234(T)::in, set_tree234(T)::in,
         set_tree234(T)::out) is det.

         % `set_tree234.power_intersect(A, B)' is true iff `B' is the
         % intersection of all the sets in `A'.
         %
     :- func set_tree234.power_intersect(set_tree234(set_tree234(T)))
         = set_tree234(T).
     :- pred set_tree234.power_intersect(set_tree234(set_tree234(T))::in,
         set_tree234(T)::out) is det.

         % `set_tree234.intersect_list(A, B)' is true iff `B' is the
         % intersection of all the sets in `A'.
         %
     :- func set_tree234.intersect_list(list(set_tree234(T))) = set_tree234(T).
     :- pred set_tree234.intersect_list(list(set_tree234(T))::in,
         set_tree234(T)::out) is det.

         % `set_tree234.difference(SetA, SetB, Set)' is true iff `Set' is the
         % set containing all the elements of `SetA' except those that
         % occur in `SetB'.
         %
     :- func set_tree234.difference(set_tree234(T), set_tree234(T))
         = set_tree234(T).
     :- pred set_tree234.difference(set_tree234(T)::in, set_tree234(T)::in,
         set_tree234(T)::out) is det.

         % `set_tree234.count(Set, Count)' is true iff `Set' has
         % `Count' elements.
         %
     :- func set_tree234.count(set_tree234(T)) = int.

     :- func set_tree234.map(func(T1) = T2, set_tree234(T1)) = set_tree234(T2).
     :- pred set_tree234.map(pred(T1, T2)::in(pred(in, out) is det),
         set_tree234(T1)::in, set_tree234(T2)::out) is det.

     :- pred set_tree234.filter_map(pred(T1, T2)::in(pred(in, out) is semidet),
         set_tree234(T1)::in, set_tree234(T2)::out) is det.

     :- func set_tree234.filter_map(func(T1) = T2, set_tree234(T1))
         = set_tree234(T2).
     :- mode set_tree234.filter_map(func(in) = out is semidet, in) = out is det.

     :- func set_tree234.fold(func(T1, T2) = T2, set_tree234(T1), T2) = T2.
     :- pred set_tree234.fold(pred(T1, T2, T2), set_tree234(T1), T2, T2).
     :- mode set_tree234.fold(pred(in, in, out) is det, in, in, out) is det.
     :- mode set_tree234.fold(pred(in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode set_tree234.fold(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode set_tree234.fold(pred(in, in, out) is semidet, in, in, out)
         is semidet.
     :- mode set_tree234.fold(pred(in, mdi, muo) is semidet, in, mdi, muo)
         is semidet.
     :- mode set_tree234.fold(pred(in, di, uo) is semidet, in, di, uo)
         is semidet.

     :- func set_tree234.foldl(func(T1, T2) = T2, set_tree234(T1), T2) = T2.
     :- pred set_tree234.foldl(pred(T1, T2, T2), set_tree234(T1), T2, T2).
     :- mode set_tree234.foldl(pred(in, in, out) is det, in, in, out) is det.
     :- mode set_tree234.foldl(pred(in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode set_tree234.foldl(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode set_tree234.foldl(pred(in, in, out) is semidet, in, in, out)
         is semidet.
     :- mode set_tree234.foldl(pred(in, mdi, muo) is semidet, in, mdi, muo)
         is semidet.
     :- mode set_tree234.foldl(pred(in, di, uo) is semidet, in, di, uo)
         is semidet.

     :- pred set_tree234.fold2(pred(T1, T2, T2, T3, T3), set_tree234(T1),
         T2, T2, T3, T3).
     :- mode set_tree234.fold2(pred(in, in, out, in, out) is det, in,
         in, out, in, out) is det.
     :- mode set_tree234.fold2(pred(in, in, out, mdi, muo) is det, in,
         in, out, mdi, muo) is det.
     :- mode set_tree234.fold2(pred(in, in, out, di, uo) is det, in,
         in, out, di, uo) is det.
     :- mode set_tree234.fold2(pred(in, in, out, in, out) is semidet, in,
         in, out, in, out) is semidet.
     :- mode set_tree234.fold2(pred(in, in, out, mdi, muo) is semidet, in,
         in, out, mdi, muo) is semidet.
     :- mode set_tree234.fold2(pred(in, in, out, di, uo) is semidet, in,
         in, out, di, uo) is semidet.

     :- pred set_tree234.foldl2(pred(T1, T2, T2, T3, T3), set_tree234(T1),
         T2, T2, T3, T3).
     :- mode set_tree234.foldl2(pred(in, in, out, in, out) is det, in,
         in, out, in, out) is det.
     :- mode set_tree234.foldl2(pred(in, in, out, mdi, muo) is det, in,
         in, out, mdi, muo) is det.
     :- mode set_tree234.foldl2(pred(in, in, out, di, uo) is det, in,
         in, out, di, uo) is det.
     :- mode set_tree234.foldl2(pred(in, in, out, in, out) is semidet, in,
         in, out, in, out) is semidet.
     :- mode set_tree234.foldl2(pred(in, in, out, mdi, muo) is semidet, in,
         in, out, mdi, muo) is semidet.
     :- mode set_tree234.foldl2(pred(in, in, out, di, uo) is semidet, in,
         in, out, di, uo) is semidet.

     :- pred set_tree234.fold3(
         pred(T1, T2, T2, T3, T3, T4, T4), set_tree234(T1),
         T2, T2, T3, T3, T4, T4).
     :- mode set_tree234.fold3(pred(in, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out) is det.
     :- mode set_tree234.fold3(pred(in, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, mdi, muo) is det.
     :- mode set_tree234.fold3(pred(in, in, out, in, out, di, uo) is det, in,
         in, out, in, out, di, uo) is det.
     :- mode set_tree234.fold3(pred(in, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out) is semidet.
     :- mode set_tree234.fold3(pred(in, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, mdi, muo) is semidet.
     :- mode set_tree234.fold3(pred(in, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, di, uo) is semidet.

     :- pred set_tree234.foldl3(
         pred(T1, T2, T2, T3, T3, T4, T4), set_tree234(T1),
         T2, T2, T3, T3, T4, T4).
     :- mode set_tree234.foldl3(pred(in, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out) is det.
     :- mode set_tree234.foldl3(pred(in, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, mdi, muo) is det.
     :- mode set_tree234.foldl3(pred(in, in, out, in, out, di, uo) is det, in,
         in, out, in, out, di, uo) is det.
     :- mode set_tree234.foldl3(pred(in, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out) is semidet.
     :- mode set_tree234.foldl3(pred(in, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, mdi, muo) is semidet.
     :- mode set_tree234.foldl3(pred(in, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, di, uo) is semidet.

     :- pred set_tree234.fold4(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5), set_tree234(T1),
         T2, T2, T3, T3, T4, T4, T5, T5).
     :- mode set_tree234.fold4(pred(in, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out) is det.
     :- mode set_tree234.fold4(pred(in, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_tree234.fold4(pred(in, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, di, uo) is det.
     :- mode set_tree234.fold4(
         pred(in, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_tree234.fold4(
         pred(in, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_tree234.fold4(
         pred(in, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_tree234.foldl4(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5), set_tree234(T1),
         T2, T2, T3, T3, T4, T4, T5, T5).
     :- mode set_tree234.foldl4(pred(in, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out) is det.
     :- mode set_tree234.foldl4(pred(in, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_tree234.foldl4(pred(in, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, di, uo) is det.
     :- mode set_tree234.foldl4(
         pred(in, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_tree234.foldl4(
         pred(in, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_tree234.foldl4(
         pred(in, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_tree234.fold5(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6),
         set_tree234(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6).
     :- mode set_tree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_tree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_tree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_tree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_tree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_tree234.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_tree234.foldl5(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6),
         set_tree234(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6).
     :- mode set_tree234.foldl5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_tree234.foldl5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_tree234.foldl5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_tree234.foldl5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_tree234.foldl5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_tree234.foldl5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_tree234.fold6(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7),
         set_tree234(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7).
     :- mode set_tree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_tree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_tree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_tree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_tree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_tree234.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_tree234.foldl6(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7),
         set_tree234(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7).
     :- mode set_tree234.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_tree234.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_tree234.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_tree234.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_tree234.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_tree234.foldl6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet.

         % all_true(Pred, Set) succeeds iff Pred(Element) succeeds
         % for all the elements of Set.
         %
     :- pred set_tree234.all_true(pred(T)::in(pred(in) is semidet),
         set_tree234(T)::in) is semidet.

         % Return the set of items for which the predicate succeeds.
         %
     :- func set_tree234.filter(pred(T)::in(pred(in) is semidet),
         set_tree234(T)::in) = (set_tree234(T)::out) is det.
     :- pred set_tree234.filter(pred(T)::in(pred(in) is semidet),
         set_tree234(T)::in, set_tree234(T)::out) is det.

         % Return the set of items for which the predicate succeeds,
         % and the set for which it fails.
         %
     :- pred set_tree234.filter(pred(T)::in(pred(in) is semidet),
         set_tree234(T)::in, set_tree234(T)::out, set_tree234(T)::out) is det.

         % set_tree234.divide(Pred, Set, TruePart, FalsePart):
         % TruePart consists of those elements of Set for which Pred succeeds;
         % FalsePart consists of those elements of Set for which Pred fails.
         %
     :- pred set_tree234.divide(pred(T)::in(pred(in) is semidet),
         set_tree234(T)::in, set_tree234(T)::out, set_tree234(T)::out) is det.

         % set_tree234.divide_by_set(DivideBySet, Set, InPart, OutPart):
         % InPart consists of those elements of Set which are also in
         % DivideBySet; OutPart consists of those elements of which are
         % not in DivideBySet.
         %
     :- pred set_tree234.divide_by_set(set_tree234(T)::in, set_tree234(T)::in,
         set_tree234(T)::out, set_tree234(T)::out) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: set_unordlist,  Next: solutions,  Prev: set_tree234,  Up: Top

63 set_unordlist
****************

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et
     %--------------------------------------------------%
     % Copyright (C) 1995-1997,1999-2002, 2004-2006, 2010-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: set_unordlist.m.
     % Main authors: conway, fjh.
     % Stability: medium.
     %
     % This file contains a `set' ADT.
     % Sets are implemented here as unsorted lists, which may contain duplicates.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module set_unordlist.
     :- interface.

     :- import_module bool.
     :- import_module list.

     %--------------------------------------------------%

     :- type set_unordlist(_T).

         % `set_unordlist.init(Set)' is true iff `Set' is an empty set.
         %
     :- func set_unordlist.init = set_unordlist(T).
     :- pred set_unordlist.init(set_unordlist(_T)::uo) is det.

         % `set_unordlist.list_to_set(List, Set)' is true iff `Set' is the set
         % containing only the members of `List'.
         %
     :- func set_unordlist.list_to_set(list(T)) = set_unordlist(T).
     :- pred set_unordlist.list_to_set(list(T)::in, set_unordlist(T)::out) is det.

         % A synonym for set_unordlist.list_to_set/1.
         %
     :- func set_unordlist.from_list(list(T)) = set_unordlist(T).

         % `set_unordlist.sorted_list_to_set(List, Set)' is true iff `Set' is
         % the set containing only the members of `List'.  `List' must be sorted.
         %
     :- pred set_unordlist.sorted_list_to_set(list(T)::in, set_unordlist(T)::out)
         is det.
     :- func set_unordlist.sorted_list_to_set(list(T)) = set_unordlist(T).

         % A synonym for set_unordlist.sorted_list_to_set/1.
         %
     :- func set_unordlist.from_sorted_list(list(T)) = set_unordlist(T).

         % `set_unordlist.to_sorted_list(Set, List)' is true iff `List' is the
         % list of all the members of `Set', in sorted order.
         %
     :- pred set_unordlist.to_sorted_list(set_unordlist(T)::in, list(T)::out)
         is det.
     :- func set_unordlist.to_sorted_list(set_unordlist(T)) = list(T).

         % `set_unordlist.singleton_set(Elem, Set)' is true iff `Set' is the set
         % containing just the single element `Elem'.
         %
     :- pred set_unordlist.singleton_set(T, set_unordlist(T)).
     :- mode set_unordlist.singleton_set(in, out) is det.
     :- mode set_unordlist.singleton_set(in, in) is semidet.     % Implied.
     :- mode set_unordlist.singleton_set(out, in) is semidet.

     :- func set_unordlist.make_singleton_set(T) = set_unordlist(T).

     :- pred set_unordlist.is_singleton(set_unordlist(T)::in, T::out) is semidet.

         % `set_unordlist.equal(SetA, SetB)' is true iff
         % `SetA' and `SetB' contain the same elements.
         %
     :- pred set_unordlist.equal(set_unordlist(T)::in, set_unordlist(T)::in)
         is semidet.

         % `set_unordlist.empty(Set)' is true iff `Set' is an empty set.
         %
     :- pred set_unordlist.empty(set_unordlist(_T)::in) is semidet.

     :- pred set_unordlist.non_empty(set_unordlist(_T)::in) is semidet.

     :- pred set_unordlist.is_empty(set_unordlist(_T)::in) is semidet.

         % `set_unordlist.subset(SetA, SetB)' is true iff `SetA' is a subset of
         % `SetB'.
         %
     :- pred set_unordlist.subset(set_unordlist(T)::in, set_unordlist(T)::in)
         is semidet.

         % `set_unordlist.superset(SetA, SetB)' is true iff `SetA' is a
         % superset of `SetB'.
         %
     :- pred set_unordlist.superset(set_unordlist(T)::in, set_unordlist(T)::in)
         is semidet.

         % `set_unordlist.member(X, Set)' is true iff `X' is a member of `Set'.
         %
     :- pred set_unordlist.member(T, set_unordlist(T)).
     :- mode set_unordlist.member(in, in) is semidet.
     :- mode set_unordlist.member(out, in) is nondet.

         % `set_unordlist.is_member(X, Set, Result)' returns
         % `Result = yes' iff `X' is a member of `Set'.
         %
     :- pred set_unordlist.is_member(T::in, set_unordlist(T)::in, bool::out)
         is det.

         % `set_unordlist.contains(Set, X)' is true iff
         % `X' is a member of `Set'.
         %
     :- pred set_unordlist.contains(set_unordlist(T)::in, T::in) is semidet.

         % `set_unordlist.insert(X, Set0, Set)' is true iff `Set' is the union
         % of `Set0' and the set containing only `X'.
         %
     :- pred set_unordlist.insert(T, set_unordlist(T), set_unordlist(T)).
     :- mode set_unordlist.insert(di, di, uo) is det.
     :- mode set_unordlist.insert(in, in, out) is det.

     :- func set_unordlist.insert(set_unordlist(T), T) = set_unordlist(T).

         % `set_unordlist.insert_new(X, Set0, Set)' is true iff `Set0' does
         % not contain `X', and `Set' is the union of `Set0' and the set containing
         % only `X'.
         %
     :- pred set_unordlist.insert_new(T::in,
         set_unordlist(T)::in, set_unordlist(T)::out) is semidet.

         % `set_unordlist.insert_list(Xs, Set0, Set)' is true iff `Set' is the
         % union of `Set0' and the set containing only the members of `Xs'.
         %
     :- pred set_unordlist.insert_list(list(T)::in,
         set_unordlist(T)::in, set_unordlist(T)::out) is det.

     :- func set_unordlist.insert_list(set_unordlist(T), list(T))
         = set_unordlist(T).

         % `set_unordlist.delete(X, Set0, Set)' is true iff `Set' is the
         % relative complement of `Set0' and the set containing only `X', i.e.
         % if `Set' is the set which contains all the elements of `Set0'
         % except `X'.
         %
     :- pred set_unordlist.delete(T, set_unordlist(T), set_unordlist(T)).
     :- mode set_unordlist.delete(in, di, uo) is det.
     :- mode set_unordlist.delete(in, in, out) is det.

     :- func set_unordlist.delete(set_unordlist(T), T) = set_unordlist(T).

         % `set_unordlist.delete_list(Xs, Set0, Set)' is true iff `Set' is the
         % relative complement of `Set0' and the set containing only the members
         % of `Xs'.
         %
     :- pred set_unordlist.delete_list(list(T)::in,
         set_unordlist(T)::in, set_unordlist(T)::out) is det.

     :- func set_unordlist.delete_list(set_unordlist(T), list(T))
         = set_unordlist(T).

         % `set_unordlist.remove(X, Set0, Set)' is true iff `Set0' contains `X',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only `X', i.e.  if `Set' is the set which contains
         % all the elements of `Set0' except `X'.
         %
     :- pred set_unordlist.remove(T::in,
         set_unordlist(T)::in, set_unordlist(T)::out) is semidet.

         % `set_unordlist.remove_list(Xs, Set0, Set)' is true iff Xs does not
         % contain any duplicates, `Set0' contains every member of `Xs',
         % and `Set' is the relative complement of `Set0' and the set
         % containing only the members of `Xs'.
         %
     :- pred set_unordlist.remove_list(list(T)::in,
         set_unordlist(T)::in, set_unordlist(T)::out) is semidet.

         % `set_unordlist.remove_least(X, Set0, Set)' is true iff `X' is the
         % least element in `Set0', and `Set' is the set which contains all the
         % elements of `Set0' except `X'.
         %
     :- pred set_unordlist.remove_least(T::out,
         set_unordlist(T)::in, set_unordlist(T)::out) is semidet.

         % `set_unordlist.union(SetA, SetB, Set)' is true iff `Set' is the union
         % of `SetA' and `SetB'.  If the sets are known to be of different
         % sizes, then for efficiency make `SetA' the larger of the two.
         %
     :- pred set_unordlist.union(set_unordlist(T)::in, set_unordlist(T)::in,
         set_unordlist(T)::out) is det.

     :- func set_unordlist.union(set_unordlist(T), set_unordlist(T))
         = set_unordlist(T).

         % `set_unordlist.union_list(A) = B' is true iff `B' is the union of
         % all the sets in `A'
         %
     :- func set_unordlist.union_list(list(set_unordlist(T))) = set_unordlist(T).

         % `set_unordlist.power_union(A, B)' is true iff `B' is the union of
         % all the sets in `A'
         %
     :- pred set_unordlist.power_union(set_unordlist(set_unordlist(T))::in,
         set_unordlist(T)::out) is det.

     :- func set_unordlist.power_union(set_unordlist(set_unordlist(T)))
         = set_unordlist(T).

         % `set_unordlist.intersect(SetA, SetB, Set)' is true iff `Set' is the
         % intersection of `SetA' and `SetB'.
         %
     :- pred set_unordlist.intersect(set_unordlist(T)::in, set_unordlist(T)::in,
         set_unordlist(T)::out) is det.

     :- func set_unordlist.intersect(set_unordlist(T), set_unordlist(T))
         = set_unordlist(T).

         % `set_unordlist.power_intersect(A, B)' is true iff `B' is the
         % intersection of all the sets in `A'
         %
     :- pred set_unordlist.power_intersect(set_unordlist(set_unordlist(T))::in,
         set_unordlist(T)::out) is det.

     :- func set_unordlist.power_intersect(set_unordlist(set_unordlist(T)))
         = set_unordlist(T).

         % `set_unordlist.intersect_list(A, B)' is true iff `B' is the
         % intersection of all the sets in `A'
         %
     :- func set_unordlist.intersect_list(list(set_unordlist(T)))
         = set_unordlist(T).

         % `set_unordlist.difference(SetA, SetB, Set)' is true iff `Set' is the
         % set containing all the elements of `SetA' except those that
         % occur in `SetB'
         %
     :- pred set_unordlist.difference(set_unordlist(T)::in, set_unordlist(T)::in,
         set_unordlist(T)::out) is det.

     :- func set_unordlist.difference(set_unordlist(T), set_unordlist(T))
         = set_unordlist(T).

     :- func set_unordlist.count(set_unordlist(T)) = int.
     :- pred set_unordlist.count(set_unordlist(T)::in, int::out) is det.

     :- func set_unordlist.map(func(T1) = T2, set_unordlist(T1))
         = set_unordlist(T2).

     :- func set_unordlist.filter_map(func(T1) = T2, set_unordlist(T1))
         = set_unordlist(T2).
     :- mode set_unordlist.filter_map(func(in) = out is semidet, in) = out is det.

     :- func set_unordlist.fold(func(T1, T2) = T2, set_unordlist(T1), T2) = T2.
     :- pred set_unordlist.fold(pred(T1, T2, T2), set_unordlist(T1), T2, T2).
     :- mode set_unordlist.fold(pred(in, in, out) is det, in, in, out) is det.
     :- mode set_unordlist.fold(pred(in, mdi, muo) is det, in, mdi, muo) is det.
     :- mode set_unordlist.fold(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode set_unordlist.fold(pred(in, in, out) is semidet, in, in, out)
         is semidet.
     :- mode set_unordlist.fold(pred(in, mdi, muo) is semidet, in, mdi, muo)
         is semidet.
     :- mode set_unordlist.fold(pred(in, di, uo) is semidet, in, di, uo)
         is semidet.

     :- pred set_unordlist.fold2(pred(T1, T2, T2, T3, T3), set_unordlist(T1),
         T2, T2, T3, T3).
     :- mode set_unordlist.fold2(pred(in, in, out, in, out) is det, in,
         in, out, in, out) is det.
     :- mode set_unordlist.fold2(pred(in, in, out, mdi, muo) is det, in,
         in, out, mdi, muo) is det.
     :- mode set_unordlist.fold2(pred(in, in, out, di, uo) is det, in,
         in, out, di, uo) is det.
     :- mode set_unordlist.fold2(pred(in, in, out, in, out) is semidet, in,
         in, out, in, out) is semidet.
     :- mode set_unordlist.fold2(pred(in, in, out, mdi, muo) is semidet, in,
         in, out, mdi, muo) is semidet.
     :- mode set_unordlist.fold2(pred(in, in, out, di, uo) is semidet, in,
         in, out, di, uo) is semidet.

     :- pred set_unordlist.fold3(pred(T1, T2, T2, T3, T3, T4, T4),
         set_unordlist(T1), T2, T2, T3, T3, T4, T4).
     :- mode set_unordlist.fold3(pred(in, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out) is det.
     :- mode set_unordlist.fold3(pred(in, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, mdi, muo) is det.
     :- mode set_unordlist.fold3(pred(in, in, out, in, out, di, uo) is det, in,
         in, out, in, out, di, uo) is det.
     :- mode set_unordlist.fold3(pred(in, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out) is semidet.
     :- mode set_unordlist.fold3(pred(in, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, mdi, muo) is semidet.
     :- mode set_unordlist.fold3(pred(in, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, di, uo) is semidet.

     :- pred set_unordlist.fold4(pred(T1, T2, T2, T3, T3, T4, T4, T5, T5),
         set_unordlist(T1), T2, T2, T3, T3, T4, T4, T5, T5).
     :- mode set_unordlist.fold4(
         pred(in, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out) is det.
     :- mode set_unordlist.fold4(
         pred(in, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_unordlist.fold4(
         pred(in, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, di, uo) is det.
     :- mode set_unordlist.fold4(
         pred(in, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out) is semidet.
     :- mode set_unordlist.fold4(
         pred(in, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_unordlist.fold4(
         pred(in, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_unordlist.fold5(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6),
         set_unordlist(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6).
     :- mode set_unordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is det, in,
         in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_unordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is det, in,
         in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_unordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is det, in,
         in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_unordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, in, out) is semidet, in,
         in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_unordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, mdi, muo) is semidet, in,
         in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_unordlist.fold5(
         pred(in, in, out, in, out, in, out, in, out, di, uo) is semidet, in,
         in, out, in, out, in, out, in, out, di, uo) is semidet.

     :- pred set_unordlist.fold6(
         pred(T1, T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7),
         set_unordlist(T1), T2, T2, T3, T3, T4, T4, T5, T5, T6, T6, T7, T7).
     :- mode set_unordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is det,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is det.
     :- mode set_unordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is det.
     :- mode set_unordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is det,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is det.
     :- mode set_unordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, in, out) is semidet.
     :- mode set_unordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, mdi, muo) is semidet.
     :- mode set_unordlist.fold6(
         pred(in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet,
         in, in, out, in, out, in, out, in, out, in, out, di, uo) is semidet.

         % all_true(Pred, Set) succeeds iff Pred(Element) succeeds
         % for all the elements of Set.
         %
     :- pred set_unordlist.all_true(pred(T)::in(pred(in) is semidet),
         set_unordlist(T)::in) is semidet.

         % Return the set of items for which the predicate succeeds.
         %
     :- pred set_unordlist.filter(pred(T)::in(pred(in) is semidet),
         set_unordlist(T)::in, set_unordlist(T)::out) is det.

         % Return the set of items for which the predicate succeeds,
         % and the set for which it fails.
         %
     :- pred set_unordlist.filter(pred(T)::in(pred(in) is semidet),
         set_unordlist(T)::in, set_unordlist(T)::out, set_unordlist(T)::out) is det.

         % set_unordlist.divide(Pred, Set, TruePart, FalsePart):
         % TruePart consists of those elements of Set for which Pred succeeds;
         % FalsePart consists of those elements of Set for which Pred fails.
         % NOTE: this is the same as filter/4.
         %
     :- pred set_unordlist.divide(pred(T)::in(pred(in) is semidet),
         set_unordlist(T)::in, set_unordlist(T)::out, set_unordlist(T)::out) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: solutions,  Next: sparse_bitset,  Prev: set_unordlist,  Up: Top

64 solutions
************

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1994-2007 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: solutions.m.
     % Main author: fjh.
     % Stability: medium.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module solutions.
     :- interface.

     :- import_module bool.
     :- import_module list.
     :- import_module set.

     %--------------------------------------------------%

         % solutions/2 collects all the solutions to a predicate and returns
         % them as a list in sorted order, with duplicates removed.
         % solutions_set/2 returns them as a set.  unsorted_solutions/2 returns
         % them as an unsorted list with possible duplicates; since there are
         % an infinite number of such lists, this must be called from a context
         % in which only a single solution is required.
         %
     :- pred solutions(pred(T), list(T)).
     :- mode solutions(pred(out) is multi, out(non_empty_list)) is det.
     :- mode solutions(pred(out) is nondet, out) is det.

     :- func solutions(pred(T)) = list(T).
     :- mode solutions(pred(out) is multi) = out(non_empty_list) is det.
     :- mode solutions(pred(out) is nondet) = out is det.

     :- func solutions_set(pred(T)) = set(T).
     :- mode solutions_set(pred(out) is multi) = out is det.
     :- mode solutions_set(pred(out) is nondet) = out is det.

     :- pred solutions_set(pred(T), set(T)).
     :- mode solutions_set(pred(out) is multi, out) is det.
     :- mode solutions_set(pred(out) is nondet, out) is det.

     :- pred unsorted_solutions(pred(T), list(T)).
     :- mode unsorted_solutions(pred(out) is multi, out(non_empty_list))
         is cc_multi.
     :- mode unsorted_solutions(pred(out) is nondet, out) is cc_multi.

     :- func aggregate(pred(T), func(T, U) = U, U) = U.
     :- mode aggregate(pred(out) is multi, func(in, in) = out is det, in)
         = out is det.
     :- mode aggregate(pred(out) is nondet, func(in, in) = out is det, in)
         = out is det.

         % aggregate/4 generates all the solutions to a predicate,
         % sorts them and removes duplicates, then applies an accumulator
         % predicate to each solution in turn:
         %
         % aggregate(Generator, Accumulator, Acc0, Acc) <=>
         %   solutions(Generator, Solutions),
         %   list.foldl(Accumulator, Solutions, Acc0, Acc).
         %
     :- pred aggregate(pred(T), pred(T, U, U), U, U).
     :- mode aggregate(pred(out) is multi, pred(in, in, out) is det,
         in, out) is det.
     :- mode aggregate(pred(out) is multi, pred(in, di, uo) is det,
         di, uo) is det.
     :- mode aggregate(pred(out) is nondet, pred(in, di, uo) is det,
         di, uo) is det.
     :- mode aggregate(pred(out) is nondet, pred(in, in, out) is det,
         in, out) is det.

         % aggregate2/6 generates all the solutions to a predicate,
         % sorts them and removes duplicates, then applies an accumulator
         % predicate to each solution in turn:
         %
         % aggregate2(Generator, Accumulator, AccA0, AccA, AccB0, AccB) <=>
         %   solutions(Generator, Solutions),
         %   list.foldl2(Accumulator, Solutions, AccA0, AccA, AccB0, AccB).
         %
     :- pred aggregate2(pred(T), pred(T, U, U, V, V), U, U, V, V).
     :- mode aggregate2(pred(out) is multi, pred(in, in, out, in, out) is det,
         in, out, in, out) is det.
     :- mode aggregate2(pred(out) is multi, pred(in, in, out, di, uo) is det,
         in, out, di, uo) is det.
     :- mode aggregate2(pred(out) is nondet, pred(in, in, out, di, uo) is det,
         in, out, di, uo) is det.
     :- mode aggregate2(pred(out) is nondet, pred(in, in, out, in, out) is det,
         in, out, in, out) is det.

         % unsorted_aggregate/4 generates all the solutions to a predicate
         % and applies an accumulator predicate to each solution in turn.
         % Declaratively, the specification is as follows:
         %
         % unsorted_aggregate(Generator, Accumulator, Acc0, Acc) <=>
         %   unsorted_solutions(Generator, Solutions),
         %   list.foldl(Accumulator, Solutions, Acc0, Acc).
         %
         % Operationally, however, unsorted_aggregate/4 will call the
         % Accumulator for each solution as it is obtained, rather than
         % first building a list of all the solutions.
         %
     :- pred unsorted_aggregate(pred(T), pred(T, U, U), U, U).
     :- mode unsorted_aggregate(pred(out) is multi, pred(in, in, out) is det,
         in, out) is cc_multi.
     :- mode unsorted_aggregate(pred(out) is multi, pred(in, in, out) is cc_multi,
         in, out) is cc_multi.
     :- mode unsorted_aggregate(pred(out) is multi, pred(in, di, uo) is det,
         di, uo) is cc_multi.
     :- mode unsorted_aggregate(pred(out) is multi, pred(in, di, uo) is cc_multi,
         di, uo) is cc_multi.
     :- mode unsorted_aggregate(pred(muo) is multi, pred(mdi, di, uo) is det,
         di, uo) is cc_multi.
     :- mode unsorted_aggregate(pred(out) is nondet, pred(in, di, uo) is det,
         di, uo) is cc_multi.
     :- mode unsorted_aggregate(pred(out) is nondet, pred(in, di, uo) is cc_multi,
         di, uo) is cc_multi.
     :- mode unsorted_aggregate(pred(out) is nondet, pred(in, in, out) is det,
         in, out) is cc_multi.
     :- mode unsorted_aggregate(pred(out) is nondet, pred(in, in, out) is cc_multi,
         in, out) is cc_multi.
     :- mode unsorted_aggregate(pred(muo) is nondet, pred(mdi, di, uo) is det,
         di, uo) is cc_multi.

         % unsorted_aggregate2/6 generates all the solutions to a predicate
         % and applies an accumulator predicate to each solution in turn.
         % Declaratively, the specification is as follows:
         %
         % unsorted_aggregate2(Generator, Accumulator, !Acc1, !Acc2) <=>
         %   unsorted_solutions(Generator, Solutions),
         %   list.foldl2(Accumulator, Solutions, !Acc1, !Acc2).
         %
         % Operationally, however, unsorted_aggregate2/6 will call the
         % Accumulator for each solution as it is obtained, rather than
         % first building a list of all the solutions.
         %
     :- pred unsorted_aggregate2(pred(T), pred(T, U, U, V, V), U, U, V, V).
     :- mode unsorted_aggregate2(pred(out) is multi,
         pred(in, in, out, in, out) is det, in, out, in, out) is cc_multi.
     :- mode unsorted_aggregate2(pred(out) is multi,
         pred(in, in, out, in, out) is cc_multi, in, out, in, out) is cc_multi.
     :- mode unsorted_aggregate2(pred(out) is multi,
         pred(in, in, out, di, uo) is det, in, out, di, uo) is cc_multi.
     :- mode unsorted_aggregate2(pred(out) is multi,
         pred(in, in, out, di, uo) is cc_multi, in, out, di, uo) is cc_multi.
     :- mode unsorted_aggregate2(pred(out) is nondet,
         pred(in, in, out, in, out) is det, in, out, in, out) is cc_multi.
     :- mode unsorted_aggregate2(pred(out) is nondet,
         pred(in, in, out, in, out) is cc_multi, in, out, in, out) is cc_multi.
     :- mode unsorted_aggregate2(pred(out) is nondet,
         pred(in, in, out, di, uo) is det, in, out, di, uo) is cc_multi.
     :- mode unsorted_aggregate2(pred(out) is nondet,
         pred(in, in, out, di, uo) is cc_multi, in, out, di, uo) is cc_multi.

         % This is a generalization of unsorted_aggregate which allows the
         % iteration to stop before all solutions have been found.
         % Declaratively, the specification is as follows:
         %
         %   do_while(Generator, Filter, !Acc) :-
         %       unsorted_solutions(Generator, Solutions),
         %       do_while_2(Solutions, Filter, !Acc).
         %
         %   do_while_2([], _, !Acc).
         %   do_while_2([X | Xs], Filter, !Acc) :-
         %       Filter(X, More, !Acc),
         %       ( More = yes ->
         %           do_while_2(Xs, Filter, !Acc)
         %       ;
         %           true
         %       ).
         %
         % Operationally, however, do_while/4 will call the Filter
         % predicate for each solution as it is obtained, rather than
         % first building a list of all the solutions.
         %
     :- pred do_while(pred(T), pred(T, bool, T2, T2), T2, T2).
     :- mode do_while(pred(out) is multi, pred(in, out, in, out) is det, in, out)
         is cc_multi.
     :- mode do_while(pred(out) is multi, pred(in, out, di, uo) is det, di, uo)
         is cc_multi.
     :- mode do_while(pred(out) is multi, pred(in, out, di, uo) is cc_multi, di, uo)
         is cc_multi.
     :- mode do_while(pred(out) is nondet, pred(in, out, in, out) is det, in, out)
         is cc_multi.
     :- mode do_while(pred(out) is nondet, pred(in, out, di, uo) is det, di, uo)
         is cc_multi.
     :- mode do_while(pred(out) is nondet, pred(in, out, di, uo) is cc_multi, di, uo)
         is cc_multi.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: sparse_bitset,  Next: stack,  Prev: solutions,  Up: Top

65 sparse_bitset
****************

     %--------------------------------------------------%
     % vim: ts=4 sw=4 et ft=mercury
     %--------------------------------------------------%
     % Copyright (C) 2000-2007, 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: sparse_bitset.m.
     % Author: stayl.
     % Stability: medium.
     %
     % This module provides an ADT for storing sets of integers.
     % If the integers stored are closely grouped, a sparse_bitset
     % is much more compact than the representation provided by set.m,
     % and the operations will be much faster.
     %
     % Efficiency notes:
     %
     % A sparse bitset is represented as a sorted list of pairs of integers.
     % For a pair `Offset - Bits', `Offset' is a multiple of `int.bits_per_int'.
     % The bits of `Bits' describe which of the elements of the range
     % `Offset' .. `Offset + bits_per_int - 1' are in the set.
     % Pairs with the same value of `Offset' are merged.
     % Pairs for which `Bits' is zero are removed.
     %
     % The values of `Offset' in the list need not be contiguous multiples
     % of `bits_per_int', hence the name _sparse_ bitset.
     %
     % A sparse_bitset is suitable for storing sets of integers which
     % can be represented using only a few `Offset - Bits' pairs.
     % In the worst case, where the integers stored are not closely
     % grouped, a sparse_bitset will take more memory than an
     % ordinary set, but the operations should not be too much slower.
     %
     % In the asymptotic complexities of the operations below,
     % `rep_size(Set)' is the number of pairs needed to represent `Set',
     % and `card(Set)' is the number of elements in `Set'.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module sparse_bitset.
     :- interface.

     :- import_module enum.
     :- import_module list.
     :- import_module term.

     :- use_module set.

     %--------------------------------------------------%

     :- type sparse_bitset(T). % <= enum(T).

         % Return an empty set.
         %
     :- func init = sparse_bitset(T).
     :- pred init(sparse_bitset(T)::out) is det.

     :- pred empty(sparse_bitset(T)).
     :- mode empty(in) is semidet.
     :- mode empty(out) is det.

     :- pred is_empty(sparse_bitset(T)::in) is semidet.

     :- pred is_non_empty(sparse_bitset(T)::in) is semidet.

         % `equal(SetA, SetB' is true iff `SetA' and `SetB' contain the same
         % elements. Takes O(min(rep_size(SetA), rep_size(SetB))) time.
         %
     :- pred equal(sparse_bitset(T)::in, sparse_bitset(T)::in) is semidet.

         % `list_to_set(List)' returns a set containing only the members of `List'.
         % In the worst case this will take O(length(List)^2) time and space.
         % If the elements of the list are closely grouped, it will be closer
         % to O(length(List)).
         %
     :- func list_to_set(list(T)) = sparse_bitset(T) <= enum(T).
     :- pred list_to_set(list(T)::in, sparse_bitset(T)::out) is det <= enum(T).

         % `sorted_list_to_set(List)' returns a set containing only the members
         % of `List'. `List' must be sorted. Takes O(length(List)) time and space.
         %
     :- func sorted_list_to_set(list(T)) = sparse_bitset(T) <= enum(T).
     :- pred sorted_list_to_set(list(T)::in, sparse_bitset(T)::out)
         is det <= enum(T).

         % `from_set(Set)' returns a bitset containing only the members of `Set'.
         % Takes O(card(Set)) time and space.
         %
     :- func from_set(set.set(T)) = sparse_bitset(T) <= enum(T).

         % `to_sorted_list(Set)' returns a list containing all the members of `Set',
         % in sorted order. Takes O(card(Set)) time and space.
         %
     :- func to_sorted_list(sparse_bitset(T)) = list(T) <= enum(T).
     :- pred to_sorted_list(sparse_bitset(T)::in, list(T)::out) is det <= enum(T).

         % `to_sorted_list(Set)' returns a set.set containing all the members
         % of `Set', in sorted order. Takes O(card(Set)) time and space.
         %
     :- func to_set(sparse_bitset(T)) = set.set(T) <= enum(T).

         % `make_singleton_set(Elem)' returns a set containing just the single
         % element `Elem'.
         %
     :- func make_singleton_set(T) = sparse_bitset(T) <= enum(T).

         % Note: set.m contains the reverse mode of this predicate, but it is
         % difficult to implement both modes using the representation in this
         % module.
         %
     :- pred singleton_set(sparse_bitset(T)::out, T::in) is det <= enum(T).

         % Is the given set a singleton, and if yes, what is the element?
         %
     :- pred is_singleton(sparse_bitset(T)::in, T::out) is semidet <= enum(T).

         % `subset(Subset, Set)' is true iff `Subset' is a subset of `Set'.
         % Same as `intersect(Set, Subset, Subset)', but may be more efficient.
         %
     :- pred subset(sparse_bitset(T)::in, sparse_bitset(T)::in) is semidet.

         % `superset(Superset, Set)' is true iff `Superset' is a superset of `Set'.
         % Same as `intersect(Superset, Set, Set)', but may be more efficient.
         %
     :- pred superset(sparse_bitset(T)::in, sparse_bitset(T)::in) is semidet.

         % `contains(Set, X)' is true iff `X' is a member of `Set'.
         % Takes O(rep_size(Set)) time.
         %
     :- pred contains(sparse_bitset(T)::in, T::in) is semidet <= enum(T).

         % `member(X, Set)' is true iff `X' is a member of `Set'.
         % Takes O(rep_size(Set)) time.
         %
     :- pred member(T, sparse_bitset(T)) <= enum(T).
     :- mode member(in, in) is semidet.
     :- mode member(out, in) is nondet.

         % `insert(Set, X)' returns the union of `Set' and the set containing
         % only `X'. Takes O(rep_size(Set)) time and space.
         %
     :- func insert(sparse_bitset(T), T) = sparse_bitset(T) <= enum(T).
     :- pred insert(T::in, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is det <= enum(T).

         % `insert_new(X, Set0, Set)' returns the union of `Set' and the set
         % containing only `X' if `Set0' does not already contain `X'; if it does,
         % it fails. Takes O(rep_size(Set)) time and space.
         %
     :- pred insert_new(T::in, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is semidet <= enum(T).

         % `insert_list(Set, X)' returns the union of `Set' and the set containing
         % only the members of `X'. Same as `union(Set, list_to_set(X))', but may be
         % more efficient.
         %
     :- func insert_list(sparse_bitset(T), list(T)) = sparse_bitset(T) <= enum(T).
     :- pred insert_list(list(T)::in, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is det <= enum(T).

         % `delete(Set, X)' returns the difference of `Set' and the set containing
         % only `X'. Takes O(rep_size(Set)) time and space.
         %
     :- func delete(sparse_bitset(T), T) = sparse_bitset(T) <= enum(T).
     :- pred delete(T::in, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is det <= enum(T).

         % `delete_list(Set, X)' returns the difference of `Set' and the set
         % containing only the members of `X'. Same as
         % `difference(Set, list_to_set(X))', but may be more efficient.
         %
     :- func delete_list(sparse_bitset(T), list(T)) = sparse_bitset(T) <= enum(T).
     :- pred delete_list(list(T)::in, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is det <= enum(T).

         % `remove(X, Set0, Set)' returns in `Set' the difference of `Set0'
         % and the set containing only `X', failing if `Set0' does not contain `X'.
         % Takes O(rep_size(Set)) time and space.
         %
     :- pred remove(T::in, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is semidet <= enum(T).

         % `remove_list(X, Set0, Set)' returns in `Set' the difference of `Set0'
         % and the set containing all the elements of `X', failing if any element
         % of `X' is not in `Set0'. Same as `subset(list_to_set(X), Set0),
         % difference(Set0, list_to_set(X), Set)', but may be more efficient.
         %
     :- pred remove_list(list(T)::in, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is semidet <= enum(T).

         % `remove_leq(Set, X)' returns `Set' with all elements less than or equal
         % to `X' removed. In other words, it returns the set containing all the
         % elements of `Set' which are greater than `X'.
         %
     :- func remove_leq(sparse_bitset(T), T) = sparse_bitset(T) <= enum(T).
     :- pred remove_leq(T::in, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is det <= enum(T).

         % `remove_gt(Set, X)' returns `Set' with all elements greater than `X'
         % removed. In other words, it returns the set containing all the elements
         % of `Set' which are less than or equal to `X'.
         %
     :- func remove_gt(sparse_bitset(T), T) = sparse_bitset(T) <= enum(T).
     :- pred remove_gt(T::in, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is det <= enum(T).

         % `remove_least(Set0, X, Set)' is true iff `X' is the least element in
         % `Set0', and `Set' is the set which contains all the elements of `Set0'
         % except `X'. Takes O(1) time and space.
         %
     :- pred remove_least(T::out, sparse_bitset(T)::in, sparse_bitset(T)::out)
         is semidet <= enum(T).

         % `union(SetA, SetB)' returns the union of `SetA' and `SetB'. The
         % efficiency of the union operation is not sensitive to the argument
         % ordering. Takes O(rep_size(SetA) + rep_size(SetB)) time and space.
         %
     :- func union(sparse_bitset(T), sparse_bitset(T)) = sparse_bitset(T).
     :- pred union(sparse_bitset(T)::in, sparse_bitset(T)::in,
         sparse_bitset(T)::out) is det.

         % `union_list(Sets, Set)' returns the union of all the sets in Sets.
         %
     :- func union_list(list(sparse_bitset(T))) = sparse_bitset(T).
     :- pred union_list(list(sparse_bitset(T))::in, sparse_bitset(T)::out) is det.

         % `intersect(SetA, SetB)' returns the intersection of `SetA' and `SetB'.
         % The efficiency of the intersection operation is not sensitive to the
         % argument ordering. Takes O(rep_size(SetA) + rep_size(SetB)) time and
         % O(min(rep_size(SetA)), rep_size(SetB)) space.
         %
     :- func intersect(sparse_bitset(T), sparse_bitset(T)) = sparse_bitset(T).
     :- pred intersect(sparse_bitset(T)::in, sparse_bitset(T)::in,
         sparse_bitset(T)::out) is det.

         % `intersect_list(Sets, Set)' returns the intersection of all the sets
         % in Sets.
         %
     :- func intersect_list(list(sparse_bitset(T))) = sparse_bitset(T).
     :- pred intersect_list(list(sparse_bitset(T))::in, sparse_bitset(T)::out)
         is det.

         % `difference(SetA, SetB)' returns the set containing all the elements
         % of `SetA' except those that occur in `SetB'. Takes
         % O(rep_size(SetA) + rep_size(SetB)) time and O(rep_size(SetA)) space.
         %
     :- func difference(sparse_bitset(T), sparse_bitset(T)) = sparse_bitset(T).
     :- pred difference(sparse_bitset(T)::in, sparse_bitset(T)::in,
         sparse_bitset(T)::out) is det.

         % divide(Pred, Set, InPart, OutPart):
         % InPart consists of those elements of Set for which Pred succeeds;
         % OutPart consists of those elements of Set for which Pred fails.
         %
     :- pred divide(pred(T)::in(pred(in) is semidet), sparse_bitset(T)::in,
         sparse_bitset(T)::out, sparse_bitset(T)::out) is det <= enum(T).

         % divide_by_set(DivideBySet, Set, InPart, OutPart):
         % InPart consists of those elements of Set which are also in DivideBySet;
         % OutPart consists of those elements of Set which are not in DivideBySet.
         %
     :- pred divide_by_set(sparse_bitset(T)::in, sparse_bitset(T)::in,
         sparse_bitset(T)::out, sparse_bitset(T)::out) is det <= enum(T).

         % `count(Set)' returns the number of elements in `Set'.
         % Takes O(card(Set)) time.
         %
     :- func count(sparse_bitset(T)) = int <= enum(T).

         % `foldl(Func, Set, Start)' calls Func with each element of `Set'
         % (in sorted order) and an accumulator (with the initial value of `Start'),
         % and returns the final value. Takes O(card(Set)) time.
         %
     :- func foldl(func(T, U) = U, sparse_bitset(T), U) = U <= enum(T).

     :- pred foldl(pred(T, U, U), sparse_bitset(T), U, U) <= enum(T).
     :- mode foldl(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode foldl(pred(in, in, out) is det, in, in, out) is det.
     :- mode foldl(pred(in, in, out) is semidet, in, in, out) is semidet.
     :- mode foldl(pred(in, in, out) is nondet, in, in, out) is nondet.
     :- mode foldl(pred(in, di, uo) is cc_multi, in, di, uo) is cc_multi.
     :- mode foldl(pred(in, in, out) is cc_multi, in, in, out) is cc_multi.

     :- pred foldl2(pred(T, U, U, V, V), sparse_bitset(T), U, U, V, V) <= enum(T).
     :- mode foldl2(pred(in, di, uo, di, uo) is det, in, di, uo, di, uo) is det.
     :- mode foldl2(pred(in, in, out, di, uo) is det, in, in, out, di, uo) is det.
     :- mode foldl2(pred(in, in, out, in, out) is det, in, in, out, in, out) is det.
     :- mode foldl2(pred(in, in, out, in, out) is semidet, in, in, out, in, out)
         is semidet.
     :- mode foldl2(pred(in, in, out, in, out) is nondet, in, in, out, in, out)
         is nondet.
     :- mode foldl2(pred(in, di, uo, di, uo) is cc_multi, in, di, uo, di, uo)
         is cc_multi.
     :- mode foldl2(pred(in, in, out, di, uo) is cc_multi, in, in, out, di, uo)
         is cc_multi.
     :- mode foldl2(pred(in, in, out, in, out) is cc_multi, in, in, out, in, out)
         is cc_multi.

         % `foldr(Func, Set, Start)' calls Func with each element of `Set'
         % (in reverse sorted order) and an accumulator (with the initial value
         % of `Start'), and returns the final value. Takes O(card(Set)) time.
         %
     :- func foldr(func(T, U) = U, sparse_bitset(T), U) = U <= enum(T).

     :- pred foldr(pred(T, U, U), sparse_bitset(T), U, U) <= enum(T).
     :- mode foldr(pred(in, di, uo) is det, in, di, uo) is det.
     :- mode foldr(pred(in, in, out) is det, in, in, out) is det.
     :- mode foldr(pred(in, in, out) is semidet, in, in, out) is semidet.
     :- mode foldr(pred(in, in, out) is nondet, in, in, out) is nondet.
     :- mode foldr(pred(in, di, uo) is cc_multi, in, di, uo) is cc_multi.
     :- mode foldr(pred(in, in, out) is cc_multi, in, in, out) is cc_multi.

     :- pred foldr2(pred(T, U, U, V, V), sparse_bitset(T), U, U, V, V) <= enum(T).
     :- mode foldr2(pred(in, di, uo, di, uo) is det, in, di, uo, di, uo) is det.
     :- mode foldr2(pred(in, in, out, di, uo) is det, in, in, out, di, uo) is det.
     :- mode foldr2(pred(in, in, out, in, out) is det, in, in, out, in, out) is det.
     :- mode foldr2(pred(in, in, out, in, out) is semidet, in, in, out, in, out)
         is semidet.
     :- mode foldr2(pred(in, in, out, in, out) is nondet, in, in, out, in, out)
         is nondet.
     :- mode foldr2(pred(in, di, uo, di, uo) is cc_multi, in, di, uo, di, uo)
         is cc_multi.
     :- mode foldr2(pred(in, in, out, di, uo) is cc_multi, in, in, out, di, uo)
         is cc_multi.
     :- mode foldr2(pred(in, in, out, in, out) is cc_multi, in, in, out, in, out)
         is cc_multi.

         % all_true(Pred, Set) succeeds iff Pred(Element) succeeds
         % for all the elements of Set.
         %
     :- pred all_true(pred(T)::in(pred(in) is semidet), sparse_bitset(T)::in)
         is semidet <= enum(T).

         % `filter(Pred, Set) = TrueSet' returns the elements of Set for which
         % Pred succeeds.
         %
     :- func filter(pred(T), sparse_bitset(T)) = sparse_bitset(T) <= enum(T).
     :- mode filter(pred(in) is semidet, in) = out is det.

         % `filter(Pred, Set, TrueSet, FalseSet)' returns the elements of Set
         % for which Pred succeeds, and those for which it fails.
         %
     :- pred filter(pred(T), sparse_bitset(T), sparse_bitset(T), sparse_bitset(T))
         <= enum(T).
     :- mode filter(pred(in) is semidet, in, out, out) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: stack,  Next: std_util,  Prev: sparse_bitset,  Up: Top

66 stack
********

     %--------------------------------------------------%
     % 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).

     	% `stack.init(Stack)' is true iff `Stack' is an empty stack.
     	%
     :- pred stack.init(stack(T)::out) is det.
     :- func stack.init = stack(T).

     	% `stack.is_empty(Stack)' is true iff `Stack' is an empty stack.
     	%
     :- pred stack.is_empty(stack(T)::in) is semidet.

     	% `stack.is_full(Stack)' is intended to be true iff `Stack'
     	% is a stack whose capacity is exhausted.  This implementation
     	% allows arbitrary-sized stacks, so stack.is_full always fails.
     	%
     :- pred stack.is_full(stack(T)::in) is semidet.

     	% `stack.push(Elem, Stack0, Stack)' is true iff `Stack' is
     	% the stack which results from pushing `Elem' onto the top
     	% of `Stack0'.
     	%
     :- pred stack.push(T::in, stack(T)::in, stack(T)::out) is det.
     :- func stack.push(stack(T), T) = stack(T).

     	% `stack.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 stack.push_list(list(T)::in, stack(T)::in, stack(T)::out) is det.
     :- func stack.push_list(stack(T), list(T)) = stack(T).

     	% `stack.top(Stack, Elem)' is true iff `Stack' is a non-empty
     	% stack whose top element is `Elem'.
     	%
     :- pred stack.top(stack(T)::in, T::out) is semidet.

     	% `stack.det_top' is like `stack.top' except that it will
     	% call error/1 rather than failing if given an empty stack.
     	%
     :- pred stack.det_top(stack(T)::in, T::out) is det.
     :- func stack.det_top(stack(T)) = T.

     	% `stack.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 stack.pop(T::out, stack(T)::in, stack(T)::out) is semidet.

     	% `stack.det_pop' is like `stack.pop' except that it will
     	% call error/1 rather than failing if given an empty stack.
     	%
     :- pred stack.det_pop(T::out, stack(T)::in, stack(T)::out) is det.

     	% `stack.depth(Stack, Depth)' is true iff `Stack' is a stack
     	% containing `Depth' elements.
     	%
     :- pred stack.depth(stack(T)::in, int::out) is det.
     :- func stack.depth(stack(T)) = int.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: std_util,  Next: store,  Prev: stack,  Up: Top

67 std_util
***********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1994-2006, 2008 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: std_util.m.
     % Main author: fjh.
     % Stability: high.
     %
     % This file contains higher-order programming constructs and other
     % useful standard utilities.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module std_util.
     :- interface.

     :- import_module maybe.

     %--------------------------------------------------%
     %
     % General purpose higher-order programming constructs
     %

         % compose(F, G, X) = F(G(X))
         %
         % Function composition.
         % XXX It would be nice to have infix `o' or somesuch for this.
         %
     :- func compose(func(T2) = T3, func(T1) = T2, T1) = T3.

         % converse(F, X, Y) = F(Y, X).
         %
     :- func converse(func(T1, T2) = T3, T2, T1) = T3.

         % pow(F, N, X) = F^N(X)
         %
         % Function exponentiation.
         %
     :- func pow(func(T) = T, int, T) = T.

         % The identity function.
         %
     :- func id(T) = T.

     %--------------------------------------------------%

         % maybe_pred(Pred, X, Y) takes a closure Pred which transforms an
         % input semideterministically. If calling the closure with the input
         % X succeeds, Y is bound to `yes(Z)' where Z is the output of the
         % call, or to `no' if the call fails.
         %
     :- pred maybe_pred(pred(T1, T2), T1, maybe(T2)).
     :- mode maybe_pred(pred(in, out) is semidet, in, out) is det.

     :- func maybe_func(func(T1) = T2, T1) = maybe(T2).
     :- mode maybe_func(func(in) = out is semidet, in) = out is det.

     %--------------------------------------------------%

         % isnt(Pred, X) <=> not Pred(X)
         %
         % This is useful in higher order programming, e.g.
         %   Odds  = list.filter(odd, Xs)
         %   Evens = list.filter(isnt(odd), Xs)
         %
     :- pred isnt(pred(T)::in(pred(in) is semidet), T::in) is semidet.

         % negate(Pred) <=> not Pred
         %
         % This is useful in higher order programming, e.g.
         %   expect(negate(Pred), ...)
         %
     :- pred negate((pred)::in((pred) is semidet)) is semidet.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: store,  Next: stream,  Prev: std_util,  Up: Top

68 store
********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1994-1997, 2000-2008, 2010-2011 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: store.m.
     % Main author: fjh.
     % Stability: low.
     %
     % This file provides facilities for manipulating mutable stores.
     % A store can be considered a mapping from abstract keys to their values.
     % A store holds a set of nodes, each of which may contain a value of any
     % type.
     %
     % Stores may be used to implement cyclic data structures such as circular
     % linked lists, etc.
     %
     % Stores can have two different sorts of keys:
     % mutable variables (mutvars) and references (refs).
     % The difference between mutvars and refs is that mutvars can only be updated
     % atomically, whereas it is possible to update individual fields of a
     % reference one at a time (presuming the reference refers to a structured
     % term).
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module store.
     :- interface.

     :- import_module io.

     %--------------------------------------------------%

         % Stores and keys are indexed by a type S of typeclass store(S) that
         % is used to distinguish between different stores.  By using an
         % existential type declaration for store.new (see below), we use the
         % type system to ensure at compile time that you never attempt to use
         % a key from one store to access a different store.
         %
     :- typeclass store(T) where [].
     :- type store(S).

     :- instance store(io.state).
     :- instance store(store(S)).

         % Initialize a new store.
         %
     :- some [S] pred store.init(store(S)::uo) is det.

     %--------------------------------------------------%
     %
     % Mutvars
     %

         % generic_mutvar(T, S):
         % A mutable variable holding a value of type T in store S.
         %
     :- type generic_mutvar(T, S).
     :- type io_mutvar(T) == generic_mutvar(T, io.state).
     :- type store_mutvar(T, S) == generic_mutvar(T, store(S)).

         % Create a new mutable variable, initialized with the specified value.
         %
     :- pred store.new_mutvar(T::in, generic_mutvar(T, S)::out, S::di, S::uo)
         is det <= store(S).

         % copy_mutvar(OldMutvar, NewMutvar, S0, S) is equivalent to the sequence
         %   get_mutvar(OldMutvar, Value, S0, S1),
         %   new_mutvar(NewMutvar, Value, S1, S )
         %
     :- pred store.copy_mutvar(generic_mutvar(T, S)::in, generic_mutvar(T, S)::out,
         S::di, S::uo) is det <= store(S).

         % Lookup the value stored in a given mutable variable.
         %
     :- pred store.get_mutvar(generic_mutvar(T, S)::in, T::out,
         S::di, S::uo) is det <= store(S).

         % Replace the value stored in a given mutable variable.
         %
     :- pred store.set_mutvar(generic_mutvar(T, S)::in, T::in,
         S::di, S::uo) is det <= store(S).

         % new_cyclic_mutvar(Func, Mutvar):
         %
         % Create a new mutable variable, whose value is initialized
         % with the value returned from the specified function `Func'.
         % The argument passed to the function is the mutvar itself,
         % whose value has not yet been initialized (this is safe
         % because the function does not get passed the store, so
         % it can't examine the uninitialized value).
         %
         % This predicate is useful for creating self-referential values
         % such as circular linked lists.
         % For example:
         %
         %   :- type clist(T, S) ---> node(T, mutvar(clist(T, S))).
         %
         %   :- pred init_cl(T::in, clist(T, S)::out,
         %       store(S)::di, store(S)::uo) is det.
         %
         %   init_cl(X, CList, !Store) :-
         %       store.new_cyclic_mutvar(func(CL) = node(X, CL), CList,
         %       !Store).
         %
     :- pred store.new_cyclic_mutvar((func(generic_mutvar(T, S)) = T)::in,
         generic_mutvar(T, S)::out, S::di, S::uo) is det <= store(S).

     %--------------------------------------------------%
     %
     % References
     %

         % generic_ref(T, S):
         %
         % A reference to value of type T in store S.
         %
     :- type generic_ref(T, S).
     :- type io_ref(T, S) == generic_ref(T, io.state).
     :- type store_ref(T, S) == generic_ref(T, store(S)).

         % new_ref(Val, Ref):
         %   /* In C: Ref = malloc(...); *Ref = Val; */
         %
         % Given a value of any type `T', insert a copy of the term
         % into the store and return a new reference to that term.
         % (This does not actually perform a copy, it just returns a view
         % of the representation of that value.
         % It does however allocate one cell to hold the reference;
         % you can use new_arg_ref to avoid that.)
         %
     :- pred store.new_ref(T::di, generic_ref(T, S)::out,
         S::di, S::uo) is det <= store(S).

         % ref_functor(Ref, Functor, Arity):
         %
         % Given a reference to a term, return the functor and arity
         % of that term.
         %
     :- pred store.ref_functor(generic_ref(T, S)::in, string::out, int::out,
         S::di, S::uo) is det <= store(S).

         % arg_ref(Ref, ArgNum, ArgRef):
         %   /* Pseudo-C code: ArgRef = &Ref[ArgNum]; */
         %
         % Given a reference to a term, return a reference to
         % the specified argument (field) of that term
         % (argument numbers start from zero).
         % It is an error if the argument number is out of range,
         % or if the argument reference has the wrong type.
         %
     :- pred store.arg_ref(generic_ref(T, S)::in, int::in,
         generic_ref(ArgT, S)::out, S::di, S::uo) is det <= store(S).

         % new_arg_ref(Val, ArgNum, ArgRef):
         %   /* Pseudo-C code: ArgRef = &Val[ArgNum]; */
         %
         % Equivalent to `new_ref(Val, Ref), arg_ref(Ref, ArgNum, ArgRef)',
         % except that it is more efficient.
         % It is an error if the argument number is out of range,
         % or if the argument reference has the wrong type.
         %
     :- pred store.new_arg_ref(T::di, int::in, generic_ref(ArgT, S)::out,
         S::di, S::uo) is det <= store(S).

         % set_ref(Ref, ValueRef):
         %   /* Pseudo-C code: *Ref = *ValueRef; */
         %
         % Given a reference to a term (Ref),
         % a reference to another term (ValueRef),
         % update the store so that the term referred to by Ref
         % is replaced with the term referenced by ValueRef.
         %
     :- pred store.set_ref(generic_ref(T, S)::in, generic_ref(T, S)::in,
         S::di, S::uo) is det <= store(S).

         % set_ref_value(Ref, Value):
         %   /* Pseudo-C code: *Ref = Value; */
         %
         % Given a reference to a term (Ref), and a value (Value),
         % update the store so that the term referred to by Ref
         % is replaced with Value.
         %
     :- pred store.set_ref_value(generic_ref(T, S)::in, T::di,
         S::di, S::uo) is det <= store(S).

         % Given a reference to a term, return that term.
         % Note that this requires making a copy, so this pred may
         % be inefficient if used to return large terms; it
         % is most efficient with atomic terms.
         % XXX current implementation buggy (does shallow copy)
         %
     :- pred store.copy_ref_value(generic_ref(T, S)::in, T::uo,
         S::di, S::uo) is det <= store(S).

         % Same as above, but without making a copy. Destroys the store.
         %
     :- pred store.extract_ref_value(S::di, generic_ref(T, S)::in, T::out)
         is det <= store(S).

     %--------------------------------------------------%
     %
     % Nasty performance hacks
     %
     % WARNING: use of these procedures is dangerous!
     % Use them only as a last resort, only if performance is critical, and only if
     % profiling shows that using the safe versions is a bottleneck.
     %
     % These procedures may vanish in some future version of Mercury.

         % `unsafe_arg_ref' is the same as `arg_ref',
         % and `unsafe_new_arg_ref' is the same as `new_arg_ref'
         % except that they doesn't check for errors,
         % and they don't work for `no_tag' types (types with
         % exactly one functor which has exactly one argument),
         % and they don't work for arguments which occupy a word with other
         % arguments,
         % and they don't work for types with >4 functors.
         % If the argument number is out of range,
         % or if the argument reference has the wrong type,
         % or if the argument is a `no_tag' type,
         % or if the argument uses a packed representation,
         % then the behaviour is undefined, and probably harmful.

     :- pred store.unsafe_arg_ref(generic_ref(T, S)::in, int::in,
         generic_ref(ArgT, S)::out, S::di, S::uo) is det <= store(S).

     :- pred store.unsafe_new_arg_ref(T::di, int::in, generic_ref(ArgT, S)::out,
         S::di, S::uo) is det <= store(S).

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: stream,  Next: stream.string_writer,  Prev: store,  Up: Top

69 stream
*********

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et
     %--------------------------------------------------%
     % Copyright (C) 2006-2007, 2010 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: stream.m.
     % Authors: juliensf, maclarty.
     % Stability: low
     %
     % This module provides a family of typeclasses for defining streams
     % in Mercury.  It also provides some generic predicates that operate
     % on instances of these typeclasses.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module stream.
     :- interface.

     :- import_module bool.
     :- import_module char.
     :- import_module list.

     :- include_module string_writer.

     %--------------------------------------------------%
     %
     % Types used by streams.
     %

     :- type stream.name == string.

     :- type stream.result(Error)
         --->    ok
         ;       eof
         ;       error(Error).

     :- type stream.result(T, Error)
         --->    ok(T)
         ;       eof
         ;       error(Error).

     :- type stream.res(Error)
         --->    ok
         ;       error(Error).

     :- type stream.res(T, Error)
         --->    ok(T)
         ;       error(Error).

         % stream.maybe_partial_res is used when it is possible to return
         % a partial result when an error occurs.
         %
     :- type stream.maybe_partial_res(T, Error)
         --->    ok(T)
         ;       error(T, Error).

     %--------------------------------------------------%
     %
     % Stream errors.
     %

     :- typeclass stream.error(Error) where
     [

         % Convert a stream error into a human-readable format.
         % e.g. for use in error messages.
         %
         func error_message(Error) = string
     ].

     %--------------------------------------------------%
     %
     % Streams.
     %

         % A stream consists of a handle type and a state type.
         % The state type is threaded through, and destructively updated by,
         % the stream operations.
         %
     :- typeclass stream.stream(Stream, State) <= (Stream -> State) where
     [
             % Returns a descriptive name for the stream.
             % Intended for use in error messages.
             %
             pred name(Stream::in, stream.name::out, State::di, State::uo) is det
     ].

     %--------------------------------------------------%
     %
     % Input streams.
     %

         % An input stream is a source of data.
         %
     :- typeclass stream.input(Stream, State) <= stream(Stream, State) where [].

         % A reader stream is a subclass of specific input stream that can be
         % used to read data of a specific type from that input stream.
         % A single input stream can support multiple reader subclasses.
         %
     :- typeclass stream.reader(Stream, Unit, State, Error)
         <= (stream.input(Stream, State), stream.error(Error),
             (Stream, Unit -> Error)) where
     [
         % Get the next unit from the given stream.
         %
         % The get operation should block until the next unit is available,
         % or the end of the stream or an error is detected.
         %
         % If a call to get/4 returns `eof', all further calls to get/4 or
         % bulk_get/9 for that stream return `eof'.  If a call to get/4
         % returns `error(...)', all further calls to get/4 or bulk_get/4 for
         % that stream return an error, although not necessarily the same one.
         %
         % XXX We should provide an interface to allow the user to reset the
         % error status to try again if an error is transient.
         %
         pred get(Stream::in, stream.result(Unit, Error)::out,
             State::di, State::uo) is det
     ].

         % A bulk_reader stream is a subclass of specific input stream that can
         % be used to read multiple items of data of a specific type from that
         % input stream into a specified container.  For example, binary input
         % streams may be able to efficiently read bytes into a bitmap.
         % A single input stream can support multiple bulk_reader subclasses.
         %
     :- typeclass stream.bulk_reader(Stream, Index, Store, State, Error)
         <= (stream.input(Stream, State), stream.error(Error),
             (Stream, Index, Store -> Error)) where
     [
         % bulk_get(Stream, Index, NumItems, !Store, NumItemsRead, Result, !State).
         %
         % Read at most NumItems items into the given Store starting at the
         % given index, returning the number of items read.
         %
         % If the read succeeds, Result is `ok' and NumItemsRead equals NumItems.
         %
         % On end-of-stream, bulk_get/9 puts as many items as it can into !Store.
         % NumItemsRead is less than NumItems, and Result is `ok'.
         %
         % If an error is detected, bulk_get/9 puts as many items as it can into
         % !Store.  NumItemsRead is less than NumItems, and Result is `error(Err)'.
         %
         % Blocks until NumItems items are available or the end of the stream
         % is reached or an error is detected.
         %
         % Throws an exception if Index given is out of range or NumItems units
         % starting at Index will not fit in !Store.
         %
         % If a call to bulk_get/4 returns less than NumItems items, all further
         % calls to get/4 or bulk_get/4 for that stream return no items.  If a
         % call to bulk_get/9 returns `error(...)', all further calls to get/4
         % or bulk_get/9 for that stream return an error, although not necessarily
         % the same one.
         %
         pred bulk_get(Stream::in, Index::in, int::in,
             Store::bulk_get_di, Store::bulk_get_uo,
             int::out, stream.res(Error)::out, State::di, State::uo) is det
     ].

         % XXX These should be di and uo, but with the current state of the mode
         % system an unsafe_promise_unique call would be required at each call
         % to bulk_get.
     :- mode bulk_get_di == in.
     :- mode bulk_get_uo == out.

     %--------------------------------------------------%
     %
     % Output streams.
     %

         % An output stream is a destination for data.
         % Note that unlike input streams, output streams do not include
         % an explicit error type.  They should handle errors by throwing
         % exceptions.
         %
     :- typeclass stream.output(Stream, State)
         <= stream(Stream, State) where
     [
         % For buffered output streams completely write out any data in the
         % buffer.  For unbuffered streams this operation is a no-op.
         %
         pred flush(Stream::in, State::di, State::uo) is det
     ].

         % A writer stream is a subclass of specific output stream that can be
         % used to write data of a specific type to that output stream.
         % A single output stream can support multiple writer subclasses.
         %
     :- typeclass stream.writer(Stream, Unit, State)
         <= stream.output(Stream, State) where
     [
         % Write the next unit to the given stream.
         % Blocks if the whole unit can't be written to the stream at the time
         % of the call (for example because a buffer is full).
         %
         pred put(Stream::in, Unit::in, State::di, State::uo) is det
     ].

     %--------------------------------------------------%
     %
     % Duplex streams.
     %

         % A duplex stream is a stream that can act as both a source
         % and destination of data, i.e. it is a both an input and
         % an output stream.
         %
     :- typeclass stream.duplex(Stream, State)
         <= (stream.input(Stream, State), stream.output(Stream, State))
             where [].

     %--------------------------------------------------%
     %
     % Putback streams.
     %

         % A putback stream is an input stream that allows data to be
         % pushed back onto the stream.  As with reader subclasses it is
         % possible to define multiple putback subclasses for a
         % single input stream.
         %
     :- typeclass stream.putback(Stream, Unit, State, Error)
         <= stream.reader(Stream, Unit, State, Error) where
     [
         % Un-gets a unit from the specified input stream.
         % Only one unit of putback is guaranteed to be successful.
         %
         pred unget(Stream::in, Unit::in, State::di, State::uo) is det
     ].

         % As above but guarantees that an unlimited number of units may
         % be pushed back onto the stream.
         %
     :- typeclass stream.unbounded_putback(Stream, Unit, State, Error)
         <= stream.putback(Stream, Unit, State, Error) where [].

     %--------------------------------------------------%
     %
     % Seekable streams.
     %

         % stream.whence denotes the base for a seek operation.
         %   set - seek relative to the start of the file
         %   cur - seek relative to the current position in the file
         %   end - seek relative to the end of the file.
         %
     :- type stream.whence
         --->    set
         ;       cur
         ;       end.

     :- typeclass stream.seekable(Stream, State) <= stream(Stream, State)
         where
     [
         % Seek to an offset relative to whence on the specified stream.
         % The offset is measured in bytes.
         %
         pred seek(Stream::in, stream.whence::in, int::in, State::di, State::uo)
             is det
     ].

     %--------------------------------------------------%
     %
     % Line oriented streams.
     %

         % A line oriented stream is a stream that keeps track of line numbers.
         %
     :- typeclass stream.line_oriented(Stream, State) <= stream(Stream, State)
         where
     [
         % Get the current line number for the specified stream.
         %
         pred get_line(Stream::in, int::out, State::di, State::uo) is det,

         % Set the current line number of the specified stream.
         %
         pred set_line(Stream::in, int::in,  State::di, State::uo) is det
     ].

     %--------------------------------------------------%
     %
     % Generic folds over input streams.
     %

         % Applies the given closure to each Unit read from the input stream
         % in turn, until eof or error.
         %
     :- pred stream.input_stream_fold(Stream, pred(Unit, T, T), T,
         stream.maybe_partial_res(T, Error), State, State)
         <= stream.reader(Stream, Unit, State, Error).
     :- mode stream.input_stream_fold(in, in(pred(in, in, out) is det),
         in, out, di, uo) is det.
     :- mode stream.input_stream_fold(in, in(pred(in, in, out) is cc_multi),
         in, out, di, uo) is cc_multi.

         % Applies the given closure to each Unit read from the input stream
         % in turn, until eof or error.
         %
     :- pred stream.input_stream_fold_state(Stream, pred(Unit, State, State),
         stream.res(Error), State, State)
         <= stream.reader(Stream, Unit, State, Error).
     :- mode stream.input_stream_fold_state(in, in(pred(in, di, uo) is det),
         out, di, uo) is det.
     :- mode stream.input_stream_fold_state(in, in(pred(in, di, uo) is cc_multi),
         out, di, uo) is cc_multi.

         % Applies the given closure to each Unit read from the input stream
         % in turn, until eof or error.
         %
     :- pred stream.input_stream_fold2_state(Stream,
         pred(Unit, T, T, State, State), T, stream.maybe_partial_res(T, Error),
         State, State) <= stream.reader(Stream, Unit, State, Error).
     :- mode stream.input_stream_fold2_state(in,
         in(pred(in, in, out, di, uo) is det),
         in, out, di, uo) is det.
     :- mode stream.input_stream_fold2_state(in,
         in(pred(in, in, out, di, uo) is cc_multi),
         in, out, di, uo) is cc_multi.

         % Applies the given closure to each Unit read from the input stream
         % in turn, until eof or error, or the closure returns `no' as its
         % second argument.
         %
     :- pred stream.input_stream_fold2_state_maybe_stop(Stream,
         pred(Unit, bool, T, T, State, State),
         T, stream.maybe_partial_res(T, Error), State, State)
         <= stream.reader(Stream, Unit, State, Error).
     :- mode stream.input_stream_fold2_state_maybe_stop(in,
         in(pred(in, out, in, out, di, uo) is det), in, out, di, uo) is det.
     :- mode stream.input_stream_fold2_state_maybe_stop(in,
         in(pred(in, out, in, out, di, uo) is cc_multi), in, out, di, uo)
         is cc_multi.

     %--------------------------------------------------%
     %
     % Misc. operations on input streams.
     %

         % Discard all the whitespace from the specified stream.
         %
     :- pred stream.ignore_whitespace(Stream::in, stream.result(Error)::out,
         State::di, State::uo)
         is det <= stream.putback(Stream, char, State, Error).

     %--------------------------------------------------%
     %
     % Misc. operations on output streams.
     %

         % put_list(Stream, Write, Sep, List, !State).
         %
         % Write all the elements List to Stream separated by Sep.
         %
     :- pred put_list(Stream, pred(Stream, T, State, State),
         pred(Stream, State, State), list(T), State, State)
         <= stream.output(Stream, State).
     :- mode put_list(in, pred(in, in, di, uo) is det, pred(in, di, uo) is det,
         in, di, uo) is det.
     :- mode put_list(in, pred(in, in, di, uo) is cc_multi,
         pred(in, di, uo) is cc_multi, in, di, uo) is cc_multi.
     :- mode put_list(in, pred(in, in, di, uo) is cc_multi,
         pred(in, di, uo) is det, in, di, uo) is cc_multi.

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: stream.string_writer,  Next: string.builder,  Prev: stream,  Up: Top

70 stream.string_writer
***********************

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et
     %--------------------------------------------------%
     % Copyright (C) 2006-2007, 2011 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: stream.string_writer.m.
     % Authors: trd, fjh, stayl
     %
     % Predicates to write to streams that accept strings.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%

     :- module stream.string_writer.
     :- interface.

     :- import_module char.
     :- import_module deconstruct.
     :- import_module io.
     :- import_module list.
     :- import_module string.
     :- import_module univ.

     %--------------------------------------------------%

     :- pred put_int(Stream::in, int::in, State::di, State::uo) is det
         <= stream.writer(Stream, string, State).

     :- pred put_float(Stream::in, float::in, State::di, State::uo) is det
         <= stream.writer(Stream, string, State).

     :- pred put_char(Stream::in, char::in, State::di, State::uo) is det
         <= stream.writer(Stream, string, State).

         % A version of io.format that works for arbitrary string writers.
         %
     :- pred format(Stream::in, string::in, list(string.poly_type)::in,
         State::di, State::uo) is det <= stream.writer(Stream, string, State).

     :- pred nl(Stream::in, State::di, State::uo) is det
         <= stream.writer(Stream, string, State).

         % print/4 writes its second argument to the string writer stream specified
         % in its first argument.  In all cases, the argument to output can be of
         % any type.  It is output in a format that is intended to be human
         % readable.
         %
         % If the argument is just a single string or character, it will be printed
         % out exactly as is (unquoted).  If the argument is of type univ, then it
         % will print out the value stored in the univ, but not the type.
         %
         % print/5 is the same as print/4 except that it allows the caller to
         % specify how non-canonical types should be handled.  print/4 implicitly
         % specifies `canonicalize' as the method for handling non-canonical types.
         % This means that for higher-order types, or types with user-defined
         % equality axioms, or types defined using the foreign language interface
         % (i.e. pragma foreign_type), the text output will only describe the type
         % that is being printed, not the value.
         %
         % print_cc/4 is the same as print/4 except that it specifies
         % `include_details_cc' rather than `canonicalize'.  This means that it will
         % print the details of non-canonical types.  However, it has determinism
         % `cc_multi'.
         %
         % Note that even if `include_details_cc' is specified, some implementations
         % may not be able to print all the details for higher-order types or types
         % defined using the foreign language interface.
         %
     :- pred print(Stream::in, T::in, State::di, State::uo) is det
         <= (stream.writer(Stream, string, State),
         stream.writer(Stream, char, State)).

     :- pred print(Stream, deconstruct.noncanon_handling, T, State, State)
         <= (stream.writer(Stream, string, State),
         stream.writer(Stream, char, State)).
     :- mode print(in, in(do_not_allow), in, di, uo) is det.
     :- mode print(in, in(canonicalize), in, di, uo) is det.
     :- mode print(in, in(include_details_cc), in, di, uo) is cc_multi.
     :- mode print(in, in, in, di, uo) is cc_multi.

     :- pred print_cc(Stream::in, T::in, State::di, State::uo) is cc_multi
         <= (stream.writer(Stream, string, State),
         stream.writer(Stream, char, State)).

         % write/4 writes its second argument to the string writer stream specified
         % in its first argument.  In all cases, the argument to output may be of
         % any type.  The argument is written in a format that is intended to be
         % valid Mercury syntax whenever possible.
         %
         % Strings and characters are always printed out in quotes, using backslash
         % escapes if necessary.  For higher-order types, or for types defined using
         % the foreign language interface (pragma foreign_type), the text output
         % will only describe the type that is being printed, not the value, and the
         % result may not be parsable by `read'.  For the types containing
         % existential quantifiers, the type `type_desc' and closure types, the
         % result may not be parsable by `read', either.  But in all other cases the
         % format used is standard Mercury syntax, and if you append a period and
         % newline (".\n"), then the results can be read in again using `read'.
         %
         % write/5 is the same as write/4 except that it allows the caller to
         % specify how non-canonical types should be handled.  write_cc/4 is the
         % same as write/4 except that it specifies `include_details_cc' rather than
         % `canonicalize'.
         %
     :- pred write(Stream::in, T::in, State::di, State::uo) is det
         <= (stream.writer(Stream, string, State),
         stream.writer(Stream, char, State)).

     :- pred write(Stream, deconstruct.noncanon_handling, T, State, State) is det
         <= (stream.writer(Stream, string, State),
         stream.writer(Stream, char, State)).
     :- mode write(in, in(do_not_allow), in, di, uo) is det.
     :- mode write(in, in(canonicalize), in, di, uo) is det.
     :- mode write(in, in(include_details_cc), in, di, uo) is cc_multi.
     :- mode write(in, in, in, di, uo) is cc_multi.

     :- pred write_cc(Stream::in, T::in, State::di, State::uo) is cc_multi
         <= (stream.writer(Stream, string, State),
         stream.writer(Stream, char, State)).

     %--------------------------------------------------%
     %--------------------------------------------------%


File: mercury_library.info,  Node: string.builder,  Next: string,  Prev: stream.string_writer,  Up: Top

71 string.builder
*****************

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et
     %--------------------------------------------------%
     % Copyright (C) 2006-2007 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: string.builder.m.
     % Main author: maclarty.
     %
     % This module implements a string builder stream.  It can be used to
     % build up a string using string or character writers.
     %
     % To build up a string using this module, you first construct an initial
     % string builder state by calling the init function.  You can then use
     % any instances of stream.writer that write strings or characters to update the
     % string builder state, using string.builder.handle as the stream argument.
     % Once you've finished writing to the string builder you can get the final
     % string by calling string.builder.to_string/1.
     %
     % For example:
     %
     %     State0 = string.builder.init,
     %     stream.string_writer.put_int(string.builder.handle, 5, State0, State),
     %     Str = string.builder.to_string(State),  % Str = "5".
     %
     %--------------------------------------------------%

     :- module string.builder.
     :- interface.

     :- import_module char.
     :- import_module stream.

     %--------------------------------------------------%

     :- type handle
         --->    handle.

     :- type state.

     :- func init = (string.builder.state::uo) is det.

     :- instance stream.stream(string.builder.handle, string.builder.state).

     :- instance stream.output(string.builder.handle, string.builder.state).

     :- instance stream.writer(string.builder.handle, string, string.builder.state).
     :- instance stream.writer(string.builder.handle, char, string.builder.state).

     :- func to_string(string.builder.state::di) = (string::uo) is det.

     %--------------------------------------------------%
     %--------------------------------------------------%

