[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