[mercury-users] Doing something with all solutions

Nikolas Everett nik9000 at gmail.com
Thu Jul 26 21:58:40 AEST 2007


Thanks to both Paul and Julien.  I ended up using most of Julien's solution
but wrote main this way:
main(!IO) :-
    io.format("DOG + ANT = CAT\n", [], !IO),
    solutions(
        (pred({DOG, ANT, CAT}::out) is nondet :- dogAntCat(DOG, ANT, CAT)),
        Solutions
    ),
    ( if
        Solutions = []
    then
        io.format("No Result.", [], !IO)
    else
        io.write_list(Solutions, "\n", writeDogAntCat, !IO),
        io.nl(!IO)
    ).

So I could keep my old dogAntCat definition.  It just felt better to have
the option of flipping one of the arguments to an in argument at some point.

I have a question about reordering predicates.  The example had this to do
that dogAntCat predicate:
    D0 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], C0 = 0,
    list.delete(D0, G, D1),
    list.delete(D1, T, D2),
    T = (G + T + C0) mod 10, C1 = (G + T + C0) / 10,
    list.delete(D2, O, D3),
    list.delete(D3, N, D4),
    A = (O + N + C1) mod 10, A\=0, C2 = (O + N + C1) / 10,
    list.delete(D4, D, D5),
    list.delete(D5, A, D6),
    C = (D + A + C2), D \= 0, 0  = (D + A + C2) / 10,
    list.delete(D6, C, _),
    DOG = 100 * D + 10 * O + G,
    ANT = 100 * A + 10 * N + T,
    CAT = 100 * C + 10 * A + T.

is it equivalent to do:
    D0 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], C0 = 0,
    list.delete(D0, G, D1),
    list.delete(D1, T, D2),
    list.delete(D2, O, D3),
    list.delete(D3, N, D4),
    list.delete(D4, D, D5),
    list.delete(D5, A, D6),
    list.delete(D6, C, _),
    A = (O + N + C1) mod 10, A\=0, C2 = (O + N + C1) / 10,
    T = (G + T + C0) mod 10, C1 = (G + T + C0) / 10,
    C = (D + A + C2), D \= 0, 0  = (D + A + C2) / 10,
    DOG = 100 * D + 10 * O + G,
    ANT = 100 * A + 10 * N + T,
    CAT = 100 * C + 10 * A + T.

It feels like it would be, but I'm not sure if the compiler does infer that
kind of thing.

On 18/07/07, Julien Fischer <juliensf at csse.unimelb.edu.au> wrote:
>
>
> Hi,
>
> On Wed, 18 Jul 2007, Nikolas Everett wrote:
>
> > I'm sure you get this a lot, but how can I ask Mercury to do something
> with
> > all the solutions that it finds for some predicate?  At this point I'd
> just
> > like to print out all of my solutions, but I'm sure there are better
> things
> > to do then that.
> >
> > I've started with one of the programs in the Ralph Becket's tutorial and
> > produced the below.  I've messed around a little with the solutions
> module,
> > but haven't gotten any where.
>
> The directory samples/solutions in the Mercury distribution contains
> exaqmple of how to use the predicates in the solutions module.
>
> There is also a brief discussion of the predicates in this module in the
> Prolog-to-Mercury transition guide, which is available here.
>
> <
> http://www.cs.mu.oz.au/research/mercury/information/doc-latest/mercury_trans_guide/All_002dsolutions.html#All_002dsolutions
> >
>
>
> > :- module first.
> > :- interface.
> > :- import_module io.
> >
> > :- pred main(io::di, io::uo) is cc_multi.
> >
> > :- implementation.
> > :- import_module int, list, string.
> >
> > main(!IO) :-
> >   io.format("DOG + ANT = CAT\n", [], !IO),
> >   ( if
> >       dogAntCat(DOG, ANT, CAT)
> >   then
> >       io.format("%d + %d = %d\n", [i(DOG), i(ANT), i(CAT)], !IO)
> >   else
> >       io.format("No result.", [], !IO)
> >   ).
> >
> > :- pred dogAntCat(int::out, int::out, int::out) is nondet.
> > dogAntCat(DOG, ANT, CAT) :-
> >   ( if
> >       D0 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], C0 = 0,
> >       pick(D0, G, D1),
> >       pick(D1, T, D2),
> >       T = (G + T + C0) mod 10, C1 = (G + T + C0) / 10,
> >       pick(D2, O, D3),
> >       pick(D3, N, D4),
> >       A = (O + N + C1) mod 10, A\=0, C2 = (O + N + C1) / 10,
> >       pick(D4, D, D5),
> >       pick(D5, A, D6),
> >       C = (D + A + C2), D \= 0, 0  = (D + A + C2) / 10,
> >       pick(D6, C, _)
> >   then
> >       DOG = 100 * D + 10 * O + G,
> >       ANT = 100 * A + 10 * N + T,
> >       CAT = 100 * C + 10 * A + T
> >   else
> >       fail
> >   ).
>
> The if-then-else in the body of this clause is redundant.
>
> > :- pred pick(list(int)::in, int::out, list(int)::out) is nondet.
> > pick([X | Xs], X, Xs).
> > pick([X | Xs], Y, [X | Zs]) :- pick(Xs, Y, Zs).
>
> This predicate is available in the standard library in the list module
> under the name list.delete/3.
>
> A version of the above program that writes out all solutions using
> the predicate solutions/2 is:
>
> :- module first.
> :- interface.
> :- import_module io.
>
> :- pred main(io::di, io::uo) is det.
>
> :- implementation.
> :- import_module int.
> :- import_module list.
> :- import_module solutions.
> :- import_module string.
>
> main(!IO) :-
>      io.format("DOG + ANT = CAT\n", [], !IO),
>      solutions(dogAntCat, Solutions),
>      (
>          Solutions = [],
>          io.format("No result.", [], !IO)
>      ;
>          Solutions = [_ | _],
>          io.write_list(Solutions, "\n", write_solution, !IO),
>          io.nl(!IO)
>      ).
>
> :- pred dogAntCat({int, int, int}::out) is nondet.
>
> dogAntCat({DOG, ANT, CAT}) :-
>      D0 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], C0 = 0,
>      list.delete(D0, G, D1),
>      list.delete(D1, T, D2),
>      T = (G + T + C0) mod 10, C1 = (G + T + C0) / 10,
>      list.delete(D2, O, D3),
>      list.delete(D3, N, D4),
>      A = (O + N + C1) mod 10, A \= 0, C2 = (O + N + C1) / 10,
>      list.delete(D4, D, D5),
>      list.delete(D5, A, D6),
>      C = (D + A + C2), D \= 0, 0 = (D + A + C2) / 10,
>      list.delete(D6, C, _),
>      DOG = 100 * D + 10 * O + G,
>      ANT = 100 * A + 10 * N + T,
>      CAT = 100 * C + 10 * A + T.
>
> :- pred write_solution({int, int, int}::in, io::di, io::uo) is det.
>
> write_solution({DOG, ANT, CAT}, !IO) :-
>      io.format("%d + %d = %d", [i(DOG), i(ANT), i(CAT)], !IO).
>
> Cheers,
> 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
> --------------------------------------------------------------------------
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/users/attachments/20070726/94b80e6d/attachment.html>


More information about the users mailing list