Next: , Previous: counter, Up: Top


19 deconstruct

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et
     %--------------------------------------------------%
     % Copyright (C) 2002-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: deconstruct.m.
     % Main author: zs.
     % Stability: low.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%
     
     :- module deconstruct.
     :- interface.
     
     :- import_module construct.
     :- import_module list.
     :- import_module maybe.
     :- import_module univ.
     
     %--------------------------------------------------%
     
         % Values of type noncanon_handling are intended to control how
         % predicates that deconstruct terms behave when they find that
         % the term they are about to deconstruct is of a noncanonical type,
         % i.e. of a type in which a single logical value may have more than one
         % concrete representation.
         %
         % The value `do_not_allow' means that in such circumstances the
         % predicate should abort.
         %
         % The value `canonicalize' means that in such circumstances the
         % predicate should return a constant giving the identity of the type,
         % regardless of the actual value of the term.
         %
         % The value `include_details_cc' means that in such circumstances
         % the predicate should proceed as if the term were of a canonical type.
         % Use of this option requires a committed choice context.
     
     :- type noncanon_handling
         --->    do_not_allow
         ;       canonicalize
         ;       include_details_cc.
     
     :- inst do_not_allow ---> do_not_allow.
     :- inst canonicalize ---> canonicalize.
     :- inst include_details_cc ---> include_details_cc.
     :- inst canonicalize_or_do_not_allow
         --->    do_not_allow
         ;       canonicalize.
     :- inst do_not_allow_or_include_details_cc
         --->    do_not_allow
         ;       include_details_cc.
     
         % functor, argument and deconstruct and their variants take any type
         % (including univ), and return representation information for that type.
         %
         % The string representation of the functor that these predicates
         % return is:
         %
         %   - for user defined types with standard equality, the functor
         %     that is given in the type definition. For lists, this means
         %     the functors [|]/2 and []/0 are used, even if the list uses
         %     the [....] shorthand.
         %   - for user-defined types with user-defined equality, the
         %     functor will be of the form <<module.type/arity>>, except
         %     with include_details_cc, in which case the type will be
         %     handled as if it had standard equality.
         %   - for integers, the string is a base 10 number;
         %     positive integers have no sign.
         %   - for floats, the string is a floating point, base 10 number;
         %     positive floating point numbers have no sign.
         %   - for strings, the string, inside double quotation marks
         %   - for characters, the character inside single quotation marks
         %   - for predicates, the string <<predicate>>, and for functions,
         %     the string <<function>>, except with include_details_cc,
         %     in which case it will be the predicate or function name.
         %     (The predicate or function name will be artificial for
         %     predicate and function values created by lambda expressions.)
         %   - for tuples, the string {}.
         %   - for arrays, the string <<array>>.
         %   - for c_pointers, the string ptr(0xXXXX) where XXXX is the
         %     hexadecimal representation of the pointer.
         %   - for bitmaps, the bitmap converted to a a length and a
         %     hexadecimal string inside angle brackets and quotes of the
         %     form """<[0-9]:[0-9A-F]*>""".
         %
         % The arity that these predicates return is:
         %
         %   - for user defined types with standard equality, the arity
         %     of the functor.
         %   - for user defined types with user-defined equality, zero,
         %     except with include_details_cc, in which case the type
         %     will be handled as if it had standard equality.
         %   - for integers, zero.
         %   - for floats, zero.
         %   - for strings, zero.
         %   - for characters, zero.
         %   - for predicates and functions, zero, except with
         %     include_details_cc, in which case it will be the number of
         %     arguments hidden in the closure.
         %   - for tuples, the number of elements in the tuple.
         %   - for arrays, the number of elements in the array.
         %   - for c_pointers, zero.
         %   - for bitmaps, zero.
         %
         % Note that in the current University of Melbourne implementation,
         % the implementations of these predicates depart from the above
         % specification in that with --high-level-code, they do not
         % deconstruct predicate- and function-valued terms even with
         % include_details_cc; instead, they return <<predicate>> or
         % <<function>> (in both cases with arity zero) as appropriate.
     
         % functor(Data, NonCanon, Functor, Arity)
         %
         % Given a data item (Data), binds Functor to a string representation
         % of the functor and Arity to the arity of this data item.
         %
     :- pred functor(T, noncanon_handling, string, int).
     :- mode functor(in, in(do_not_allow), out, out) is det.
     :- mode functor(in, in(canonicalize), out, out) is det.
     :- mode functor(in, in(include_details_cc), out, out) is cc_multi.
     :- mode functor(in, in, out, out) is cc_multi.
     
         % functor_number(Data, FunctorNumber, Arity)
         %
         % Given a data item, return the number of the functor,
         % suitable for use by construct.construct, and the arity.
         % Fail if the item does not have a discriminated union type.
         % Abort if the type has user-defined equality.
         %
     :- pred functor_number(T::in, functor_number_lex::out, int::out) is semidet.
     
         % functor_number_cc(Data, FunctorNumber, Arity)
         %
         % Given a data item, return the number of the functor,
         % suitable for use by construct.construct, and the arity.
         % Fail if the item does not have a discriminated union type.
         % Don't abort if the type has user-defined equality.
         %
     :- pred functor_number_cc(T::in, functor_number_lex::out,
         int::out) is cc_nondet.
     
         % arg(Data, NonCanon, Index, Argument)
         %
         % Given a data item (Data) and an argument index (Index), starting
         % at 0 for the first argument, binds Argument to that argument of
         % the functor of the data item. If the argument index is out of range
         % -- that is, greater than or equal to the arity of the functor or
         % lower than 0 -- then the call fails.
         %
         % Note that this predicate only returns an answer when NonCanon is
         % do_not_allow or canonicalize.  If you need the include_details_cc
         % behaviour use deconstruct.arg_cc/3.
         %
     :- some [ArgT] pred arg(T, noncanon_handling, int, ArgT).
     :- mode arg(in, in(do_not_allow), in, out) is semidet.
     :- mode arg(in, in(canonicalize), in, out) is semidet.
     :- mode arg(in, in(canonicalize_or_do_not_allow), in, out) is semidet.
     
     :- type maybe_arg
         --->    some [T] arg(T)
         ;       no_arg.
     
         % arg_cc/3 is similar to arg/4, except that it handles arguments with
         % non-canonical types.  The possible non-existence of an argument is
         % encoded using a maybe type.
         %
     :- pred arg_cc(T::in, int::in, maybe_arg::out) is cc_multi.
     
         % named_arg(Data, NonCanon, Name, Argument)
         %
         % Same as arg/4, except the chosen argument is specified by giving
         % its name rather than its position. If Data has no argument with that
         % name, named_arg fails.
         %
     :- some [ArgT] pred named_arg(T, noncanon_handling, string, ArgT).
     :- mode named_arg(in, in(do_not_allow), in, out) is semidet.
     :- mode named_arg(in, in(canonicalize), in, out) is semidet.
     :- mode named_arg(in, in(canonicalize_or_do_not_allow), in, out) is semidet.
     
         % named_arg_cc/3 is similar to named_arg/4, except that it handles
         % arguments with non-canonical types.
         %
     :- pred named_arg_cc(T::in, string::in, maybe_arg::out) is cc_multi.
     
         % det_arg(Data, NonCanon, Index, Argument)
         %
         % Same as arg/4, except that for cases where arg/4 would fail,
         % det_arg/4 will abort.
         %
     :- some [ArgT] pred det_arg(T, noncanon_handling, int, ArgT).
     :- mode det_arg(in, in(do_not_allow), in, out) is det.
     :- mode det_arg(in, in(canonicalize), in, out) is det.
     :- mode det_arg(in, in(include_details_cc), in, out) is cc_multi.
     :- mode det_arg(in, in, in, out) is cc_multi.
     
         % det_named_arg(Data, NonCanon, Name, Argument)
         %
         % Same as named_arg/4, except that for cases where named_arg/4 would fail,
         % det_named_arg/4 will abort.
         %
     :- some [ArgT] pred det_named_arg(T, noncanon_handling, string, ArgT).
     :- mode det_named_arg(in, in(do_not_allow), in, out) is det.
     :- mode det_named_arg(in, in(canonicalize), in, out) is det.
     :- mode det_named_arg(in, in(include_details_cc), in, out) is cc_multi.
     :- mode det_named_arg(in, in, in, out) is cc_multi.
     
         % deconstruct(Data, NonCanon, Functor, Arity, Arguments)
         %
         % Given a data item (Data), binds Functor to a string representation
         % of the functor, Arity to the arity of this data item, and Arguments
         % to a list of arguments of the functor. The arguments in the list
         % are each of type univ.
         %
         % The cost of calling deconstruct depends greatly on how many arguments
         % Data has. If Data is an array, then each element of the array is
         % considered one of its arguments. Therefore calling deconstruct
         % on large arrays can take a very large amount of memory and a very
         % long time. If you call deconstruct in a situation in which you may
         % pass it a large array, you should probably use limited_deconstruct
         % instead.
         %
     :- pred deconstruct(T, noncanon_handling, string, int, list(univ)).
     :- mode deconstruct(in, in(do_not_allow), out, out, out) is det.
     :- mode deconstruct(in, in(canonicalize), out, out, out) is det.
     :- mode deconstruct(in, in(include_details_cc), out, out, out) is cc_multi.
     :- mode deconstruct(in, in, out, out, out) is cc_multi.
     
         % deconstruct_du(Data, NonCanon, FunctorNumber, Arity, Arguments)
         %
         % Given a data item (Data) which has a discriminated union type, binds
         % FunctorNumber to the number of the functor in lexicographic order,
         % Arity to the arity of this data item, and Arguments to a list of
         % arguments of the functor. The arguments in the list are each of type
         % univ.
         %
         % Fails if Data does not have discriminated union type.
         %
     :- pred deconstruct_du(T, noncanon_handling, functor_number_lex,
         int, list(univ)).
     :- mode deconstruct_du(in, in(do_not_allow), out, out, out) is semidet.
     :- mode deconstruct_du(in, in(include_details_cc), out, out, out) is cc_nondet.
     :- mode deconstruct_du(in, in, out, out, out) is cc_nondet.
     
         % limited_deconstruct(Data, NonCanon, MaxArity,
         %   Functor, Arity, Arguments)
         %
         % limited_deconstruct works like deconstruct, but if the arity of T is
         % greater than MaxArity, limited_deconstruct fails. This is useful in
         % avoiding bad performance in cases where Data may be a large array.
         %
         % Note that this predicate only returns an answer when NonCanon is
         % do_not_allow or canonicalize.  If you need the include_details_cc
         % behaviour use deconstruct.limited_deconstruct_cc/3.
         %
     :- pred limited_deconstruct(T, noncanon_handling, int, string, int,
         list(univ)).
     :- mode limited_deconstruct(in, in(do_not_allow), in, out, out, out)
         is semidet.
     :- mode limited_deconstruct(in, in(canonicalize), in, out, out, out)
         is semidet.
     
     :- pred limited_deconstruct_cc(T::in, int::in,
         maybe({string, int, list(univ)})::out) is cc_multi.
     
     %--------------------------------------------------%
     %--------------------------------------------------%