AI-Prolog

 view release on metacpan or  search on metacpan

lib/AI/Prolog/Introduction.pod  view on Meta::CPAN


The second line is where the bulk of the work gets done. In Prolog, to identify
the head (first element) of a list and its tail (all elements except the
first), we use the syntax [head|tail]. Since ":-" is read as "if" in Prolog,
what this says if we want to concatenate (a,b,c) and (d,e,f):

=over 4

=item * Given a list with a head of W and a tail of X:

 @list1 = qw/a b c/; (qw/a/ is W, the head, and qw/b c/ is X, the tail)

=item * If it's appended to list Y:

 @Y = qw/d e f/;

=item * We get a list with a head of W and a tail of Z:

 @list2 = qw/a b c d e f/;

=item * Only if X appended to Y forms Z:

 X is qw/b c/. Y is qw/d e f/. Z is qw/b c d e f/.

=back

But how do we know if X appended to Y forms Z? Well, it's recursive. You see,
the head of X is 'b' and it's tail is 'c'. Let's follow the transformations:

 append([a,b,c],[d,e,f],[a,b,c,d,e,f])
  if append([b,c],[d,e,f],[b,c,d,e,f])
  if append([c],[d,e,f],[c,d,e,f])
  if append([],[d,e,f],[d,e,f])

As you can see, the last line matches our boundary condition, so the program
can determine what the concatenation is.

Now that may seem confusing at first, but so was the Schwartzian transform when
many of us encountered it. After a while, it becomes natural. Sit down and work
it out and you'll see what's going one.

So what does this give us? Well, we can now append lists X and Y to form Z:

 append([a], [b,c,d], Z).

Given Y and Z, we can infer X.

 append(X, [b,c,d], [a,b,c,d]).

And finally, given Z, we can infer all X and Y that combine to form Z.

 append(X,Y,[a,b,c,d]).

Note that you get all of that from one definition of how to append two lists.
You also don't have to tell the program how to do it. It just figures it out
for you.

Translating all of this into C<AI::Prolog> looks like this:

 use AI::Prolog;
 use Data::Dumper;

 my $prolog = AI::Prolog->new(append_prog());
 $prolog->raw_results(0) # Disable raw results
 $prolog->query("append(X,Y,[a,b,c,d])");
 while (my $result = $prolog->results) {
     print Dumper($result->X); # array references
     print Dumper($result->Y);
 }

 sub append_prog {
     return <<'    END_PROLOG';
     append([], X, X).
     append([W|X],Y,[W|Z]) :- append(X,Y,Z).
     END_PROLOG
 }

=head1 SEE ALSO

W-Prolog:  L<http://goanna.cs.rmit.edu.au/~winikoff/wp/>

X-Prolog:  L<http://www.iro.umontreal.ca/~vaucher/XProlog/>

Roman BartE<225>k's online guide to programming Prolog:
L<http://kti.ms.mff.cuni.cz/~bartak/prolog/index.html>

=head1 AUTHOR

Curtis "Ovid" Poe, E<lt>moc tod oohay ta eop_divo_sitrucE<gt>

Reverse the name to email me.

This work is based on W-Prolog, http://goanna.cs.rmit.edu.au/~winikoff/wp/,
by Dr. Michael Winikoff.  Many thanks to Dr. Winikoff for granting me
permission to port this.

=head1 COPYRIGHT AND LICENSE

Copyright 2005 by Curtis "Ovid" Poe

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself. 

=cut

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.462 second using v1.00-cache-2.02-grep-82fe00e-cpan-2c419f77a38b )