[mercury-users] Doing something with all solutions

Julien Fischer juliensf at csse.unimelb.edu.au
Thu Jul 19 11:41:04 AEST 2007


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
--------------------------------------------------------------------------



More information about the users mailing list