[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