To be fair, my example is a bit more verbose than regular Prolog due to some parser limitations that I am currently working through. For example, the member/2 predicate is usually built in and doesn't need to be specified and the last line normally reads like this:

100 is A + B + C + D + E.

There are a few other things that would also clarify this code, but again, the parser is not yet where it should be. However, if you look at the code, you'll notice that I never told it how to find the answer. I just defined logically what the answer was and Prolog figured out how to arrive at it. If you read the code, it actually sounds fairly natural (particularly if you read my example below). It's easy to understand. Your's, on the other hand, is much less clear for me to understand from simply reading it.

I'm also willing to bet that someone with more Prolog-fu than myself would be able to come up with a more concise solution. I just typed in what occurred to me.

Update: And I could just put all of the numbers in one list. That makes the code simpler and faster:

#!/usr/local/bin/perl use strict; use warnings; use AI::Prolog 0.65; my @numbers = grep { ! ($_ % 2) || ! ($_ % 5) } 1 .. 100; my $numbers = AI::Prolog->make_list(@numbers); my $prolog = AI::Prolog->new(<<"END_PROLOG"); member(X,[X|Tail]). member(X,[Head|Tail]) :- member(X, Tail). one_hundred(A,B,C,D,E) :- member(A, [$numbers]), member(B, [$numbers]), member(C, [$numbers]), member(D, [$numbers]), member(E, [$numbers]), is(100, plus(A, plus(B, plus(C, plus(D, E))))). END_PROLOG $prolog->query('one_hundred(A,B,C,D,E).'); while (my $results = $prolog->results) { print join(',' =>@{$results}[1 .. 5]), $/; }

It's also worth noting what my solution can do that your solution cannot do. Tomorrow, your boss comes to you and says "yeah, great, but we just found out that the first and fourth numbers are always 4 and 45, respectively." So I change my query:

$prolog->query('one_hundred(4,B,C,45,E).'); while (my $results = $prolog->results) { print join(',' =>@{$results}[1 .. 5]), $/; }

I still get the right answers, but I didn't have to change my code (note that this still requires that the numbers be multiples of 2 or 5, because of the definition. It's trivial to alter, though.)

Cheers,
Ovid

New address of my CGI Course.


In reply to Re^3: How to determine & record all possible variations (AI::Prolog) by Ovid
in thread How to determine & record all possible variations for 5 items? by Stenyj

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.