Hi, Alexsandro <div><br></div><div>Here is how you can make it work:</div><div><br></div><div><div>:- module defs.</div><div>:- interface.   </div><div>:- import_module io.</div><div><br></div><div>:- pred main(io::di, io::uo) is det.</div>
<div><br></div><div>:- implementation.</div><div>:- import_module string.</div><div>:- import_module solutions, list.</div><div><br></div><div>:- type formula</div><div>    --->    and(formula, formula)</div><div>    ;       or(formula, formula)</div>
<div>    ;       not(formula)</div><div>    ;       literal(string).</div><div><br></div><div><br></div><div>:- type query</div><div>    --->    equiv(formula, formula)</div><div>    ;       formula(formula).</div><div>
<br></div><div>:- pred definition(query::out) is multi.</div><div><br></div><div>definition(equiv(literal("A"), and(literal("B"),  not(literal("C"))))).</div><div>definition(equiv(literal("C"), or(literal("D"), literal("E")))).</div>
<div>definition(equiv(literal("G"), or(literal("H"), literal("J")))).</div><div><br></div><div>:- pred definition_by_literal(string::in, formula::out) is semidet.</div><div>definition_by_literal(LitName, Formula) :-</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>solutions.solutions(pred(F::out) is nondet :-</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>definition(equiv(literal(LitName), F)), [Formula|_]).</div>
<div><br></div><div>:- func expand(formula) = formula.</div><div><br></div><div>expand(F) = ExF :-</div><div>   ( F = and(A,B),    ExF = and(expand(A), expand(B))</div><div>   ; F = or(A,B),       ExF = or(expand(A), expand(B))</div>
<div>   ; F = not(A),         ExF = not(expand(A))</div><div>   ; F = literal(X),</div><div>     ( if definition_by_literal(X,X1)</div><div>       then X1 = X2, ExF = expand(X2)</div><div>       else ExF = literal(X)</div>
<div>     )</div><div>   ).</div><div><br></div><div>main(!IO) :-</div><div>   X = and(literal("A"), literal("G")),</div><div>   io.print(expand(X),!IO),</div><div>   <a href="http://io.nl">io.nl</a>(!IO).</div>
</div><div><br></div><div><div>>defs</div><div>(literal("B") and (not literal("D") or literal("E"))) and (literal("H") or literal("J"))</div></div><div><br></div><div>Could someone propose better way doing this?</div>
<div><br></div><div><br><div class="gmail_quote">On Tue, Jul 19, 2011 at 6:23 PM, Alexsandro Soares <span dir="ltr"><<a href="mailto:prof.asoares@gmail.com">prof.asoares@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Hi,<br><br>   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 <br>

<br>     and(literal("A"), literal("G"))<br><br>into <br><br>   and(and(literal("B"),<br>                 not(or(literal("D"),<br>                           literal("E")))),<br>

          or(literal("H", literal("J"))))<br><br>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 <span lang="en"><span title="Clique para mostrar traduções alternativas">exactly </span></span>one expansion for each formula.<br>

<br>But when I try to compile the module defs.m (defined at end of this message) I get the following errors:<br>$ mmc --make defs<br>Making Mercury/int3s/defs.int3<br>Making Mercury/ints/<a href="http://defs.int" target="_blank">defs.int</a><br>

Making Mercury/cs/defs.c<br>defs.m:021: In `definition'(out):<br>defs.m:021:   error: determinism declaration not satisfied.<br>defs.m:021:   Declared `semidet', inferred `multi'.<br>defs.m:023:   Disjunction has multiple clauses with solutions.<br>

** Error making `Mercury/cs/defs.c'.<br><br>What am I doing wrong?<br><br>------------------------- defs.m -----------------------------------<br>:- module defs.<br>:- interface.   <br>:- import_module io.<br><br>:- pred main(io::di, io::uo) is det.<br>

<br>:- implementation.<br>:- import_module string.<br><br>:- type formula<br>    --->    and(formula, formula)<br>    ;       or(formula, formula)<br>    ;       not(formula)<br>    ;       literal(string).<br><br><br>

:- type query<br>    --->    equiv(formula, formula)<br>    ;       formula(formula).<br><br>:- pred definition(query::out) is semidet.<br><br>definition(equiv(literal("A"), and(literal("B"),  not(literal("C"))))).<br>

definition(equiv(literal("C"), or(literal("D"), literal("E")))).<br>definition(equiv(literal("G"), or(literal("H"), literal("J")))).<br><br><br>:- func expand(formula) = formula.<br>

<br>expand(F) = ExF :-<br>   ( F = and(A,B),    ExF = and(expand(A), expand(B))<br>   ; F = or(A,B),       ExF = or(expand(A), expand(B))<br>   ; F = not(A),         ExF = not(expand(A))<br>   ; F = literal(X),<br>     ( if definition(equiv(literal(X),X1))<br>

       then X1 = X2, ExF = expand(X2)<br>       else ExF = literal(X)<br>     )<br>   ).<br><br>main(!IO) :-<br>   X = and(literal("A"), literal("G")),<br>   io.print(expand(X),!IO),<br>   <a href="http://io.nl" target="_blank">io.nl</a>(!IO).<br>

     <br><br>-----------------------------------------------------------------------<br><br clear="all">    Thanks in advance for any answer.<br><br>Regards,<br>Alex<br>
</blockquote></div><br></div>