[mercury-users] Couple of questions about my program

Julien Fischer juliensf at csse.unimelb.edu.au
Wed Feb 16 11:52:01 AEDT 2011


Hi,

On Tue, 15 Feb 2011, Vladimir Gubarkov wrote:

> I have written brainfuck interpreter on mercury. You can see the source code
> here:
>
> http://www.xonix.info/2011/02/brainfuck-mercury.html (warning: text is in
> russian, but code is in mercury, however =) )
>
> google translated:
> http://translate.google.com/translate?js=n&prev=_t&hl=ru&ie=UTF-8&layout=2&eotf=1&sl=ru&tl=en&u=http://www.xonix.info/2011/02/brainfuck-mercury.html
>
> My questions are next:
>
> 1) I'm compiling the program with --infer-all option, so I believe compiler
> should infer all pred/mode declarations. However if I omit line

It will infer all non-exported pred and mode declarations.  Declarations
are required for predicates that are exported.

>
> :- mode ast(out, in, out) is multi.
>
> compilation gives me:
>
> D:\stuff\test\mercury\bf>..\mmc_.bat bf
> Making Mercury\int3s\bf.int3
> Making Mercury\ints\bf.int
> Making Mercury\cs\bf.c
> Uncaught Mercury exception:
> Software Error: unique_modes.m: Unexpected: call to implied mode?
> Stack dump not available in this grade.
> Error: system command received signal 1.
> ** Error making `Mercury\cs\bf.c'.

That looks like a bug -- at the very least it should be a proper error
message.  We will look into it.

> 2) Compilation gives me warning message:
>
> bf.m:261: In `opt_defaults'(out, out):
> bf.m:261:   warning: determinism declaration could be tighter.
> bf.m:261:   Declared `nondet', inferred `multi'.
>
> But if I change mode to multi it won't compile at all:
>
> bf.m:278: In clause for `main(di, uo)':
> bf.m:278:   in argument 1 of call to predicate `getopt.process_options'/4:
> bf.m:278:   mode error: variable `V_16' has instantiatedness
> bf.m:278:   `unique(getopt.option_ops(/* unique */(pred((ground >> ground),
> bf.m:278:   (free >> ground)) is semidet), /* unique */(pred((ground >>
> bf.m:278:   ground), (free >> ground)) is semidet), /* unique */(pred((free
>>>
> bf.m:278:   ground), (free >> ground)) is multi)))',
> bf.m:278:   expected instantiatedness was
> bf.m:278:   `bound(getopt.option_ops((pred((ground >> ground), (free >>
> bf.m:278:   ground)) is semidet), (pred((ground >> ground), (free >>
> ground))
> bf.m:278:   is semidet), (pred((free >> ground), (free >> ground)) is
> nondet))
> bf.m:278:   ; getopt.option_ops((pred((ground >> ground), (free >> ground))
> is
> bf.m:278:   semidet), (pred((ground >> ground), (free >> ground)) is
> semidet),
> bf.m:278:   (pred((free >> ground), (free >> ground)) is nondet),
> (pred((ground
> bf.m:278:   >> ground), (ground >> ground), (ground >> ground), (free >>
> bf.m:278:   ground)) is semidet)) ; getopt.option_ops_multi((pred((ground >>
> bf.m:278:   ground), (free >> ground)) is semidet), (pred((ground >>
> ground),
> bf.m:278:   (free >> ground)) is semidet), (pred((free >> ground), (free >>
> bf.m:278:   ground)) is multi)) ; getopt.option_ops_multi((pred((ground >>
> bf.m:278:   ground), (free >> ground)) is semidet), (pred((ground >>
> ground),
> bf.m:278:   (free >> ground)) is semidet), (pred((free >> ground), (free >>
> bf.m:278:   ground)) is multi), (pred((ground >> ground), (ground >>
> ground),
> bf.m:278:   (ground >> ground), (free >> ground)) is semidet)))'.
> For more information, recompile with `-E'.
> Error: system command received signal 1.
> ** Error making `Mercury\cs\bf.c'.
>
> I believe this behaviour is not correct.

It is correct, although the error message does require a little
decoding.  It is attempting to tell you that you are using the wrong
data constructor for the option_ops/1 type.  If the option_default
predicate is multi rather than nondet you have to use the
option_ops_multi/{3,4} constructors.

In your main/2 predicate you currently have:

     main(!IO) :-
         command_line_arguments(Args0, !IO),
         process_options(option_ops(opt_short,opt_long,opt_defaults),
             Args0, Args, MaybeOptions),

It should be:

     main(!IO) :-
         command_line_arguments(Args0, !IO),
         process_options(option_ops_multi(opt_short,opt_long,opt_defaults),
             Args0, Args, MaybeOptions),

if you change the mode to multi.

> 3) As you can see, I'm using
>
> one_solution(Pred, Solution) :-
> solutions(Pred, [Solution|_]).
>
> for finding the only solution for parsing by DCG. But I believe this is not
> optimal as it searches for ALL solutions, then SORTS them, and only after -
> returns the first one. My question is - how could I (and could I?) change my
> code to get first working solution?

You could use committed choice nondeterminism, e.g.

     one_solution(Pred, Solution) :-
       promise_equivalent_solutions [Solution] (
          Pred(Solution)
       ).

See the ``Interface nondeterministic code with the real world'' section
of the reference manual.

Julien.
--------------------------------------------------------------------------
mercury-users mailing list
Post messages to:       mercury-users at csse.unimelb.edu.au
Administrative Queries: owner-mercury-users at csse.unimelb.edu.au
Subscriptions:          mercury-users-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the users mailing list