[mercury-users] Doubt about determinism checking

Alexsandro Soares prof.asoares at gmail.com
Wed Jul 20 00:23:51 AEST 2011


Hi,

   I'm trying to make a predicate that converts a formula with complex
literals into a formula with primitive literals.  For example, using the
facts informed in predicate "definition" (in module defs.m), I could convert
the complex formula

     and(literal("A"), literal("G"))

into

   and(and(literal("B"),
                 not(or(literal("D"),
                           literal("E")))),
          or(literal("H", literal("J"))))

Each complex literal can only be defined one time, so the predicate
"definition" can provide, at most, one answer. Similarly, the predicate
"expand" can only provide exactly one expansion for each formula.

But when I try to compile the module defs.m (defined at end of this message)
I get the following errors:
$ mmc --make defs
Making Mercury/int3s/defs.int3
Making Mercury/ints/defs.int
Making Mercury/cs/defs.c
defs.m:021: In `definition'(out):
defs.m:021:   error: determinism declaration not satisfied.
defs.m:021:   Declared `semidet', inferred `multi'.
defs.m:023:   Disjunction has multiple clauses with solutions.
** Error making `Mercury/cs/defs.c'.

What am I doing wrong?

------------------------- defs.m -----------------------------------
:- module defs.
:- interface.
:- import_module io.

:- pred main(io::di, io::uo) is det.

:- implementation.
:- import_module string.

:- type formula
    --->    and(formula, formula)
    ;       or(formula, formula)
    ;       not(formula)
    ;       literal(string).


:- type query
    --->    equiv(formula, formula)
    ;       formula(formula).

:- pred definition(query::out) is semidet.

definition(equiv(literal("A"), and(literal("B"),  not(literal("C"))))).
definition(equiv(literal("C"), or(literal("D"), literal("E")))).
definition(equiv(literal("G"), or(literal("H"), literal("J")))).


:- func expand(formula) = formula.

expand(F) = ExF :-
   ( F = and(A,B),    ExF = and(expand(A), expand(B))
   ; F = or(A,B),       ExF = or(expand(A), expand(B))
   ; F = not(A),         ExF = not(expand(A))
   ; F = literal(X),
     ( if definition(equiv(literal(X),X1))
       then X1 = X2, ExF = expand(X2)
       else ExF = literal(X)
     )
   ).

main(!IO) :-
   X = and(literal("A"), literal("G")),
   io.print(expand(X),!IO),
   io.nl(!IO).


-----------------------------------------------------------------------

    Thanks in advance for any answer.

Regards,
Alex
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20110719/1ce56fe9/attachment.html>


More information about the users mailing list