NAME

Language::Prolog::Yaswi - Yet another interface to SWI-Prolog

SYNOPSIS

use Language::Prolog::Yaswi ':query';
use Language::Prolog::Types::overload;
use Language::Prolog::Sugar functors => { equal => '='
                                          is    => 'is' },
                            chains => { orn => ';',
                                        andn => ',',
                                        add => '+' },
                            vars => [qw (X Y Z)];

swi_set_query( equal(X, Y),
               orn( equal(X, 27),
                    equal(Y, 'hello')));

while (swi_next) {
    printf "Query=".swi_query()."\n";
    printf "  X=%_, Y=%_\n\n", swi_var(X), swi_var(Y);
}

print join("\n",
           xsb_findall(andn(equal(X, 2),
                            orn(equal(Y, 1),
                                equal(Y, 3.1416))
                            is(Z, plus(X,Y,Y))),
                       [X, Y, Z]);

ABSTRACT

Language::Prolog::Yaswi implements a bidirectional interface to the SWI-Prolog system (http://www.swi-prolog.org/).

DESCRIPTION

This package provides a bidirectional interface to SWI-Prolog. That means that Prolog code can be called from Perl that can call Perl code again and so on:

Perl -> Prolog -> Perl -> Prolog -> ...

(unfortunately, by now, the cicle has to be started from Perl, although it is very easy to circunvent this limitation with the help of a dummy Perl script that just calls Prolog the first time).

The interface is based on the set of classes defined in Language::Prolog::Types. Package Language::Prolog::Sugar can also be used to improve the look and readability of scripts mixing Perl and Prolog code.

The interface to call Prolog from Perl is very simple, at least if you are used to Prolog non deterministic nature.

SUBROUTINES

Grouped by export tag:

:query
swi_set_query($query1, $query2, $query3, ...)

Compose a query with all its parameters and sets it. Return the set of free variables found in the query.

swi_set_query_module($query, $module, $ctx_module)

Allows to set a query in a different module than the default.

swi_result()

Return the values binded to the variables in the query.

swi_next()

Iterates over the query solutions.

If a new solution is available returns true, if not, closes the query and returns false.

It should be called after swi_set_query(...) to obtain the first solution.

swi_var($var)

Returns the value binded to $var in the current query/solution combination.

swi_query

Returns the current query with the variables binded to its values in the current solution (or unbinded if swi_next has not been called yet).

swi_cut

Closes the current query even if not all of its solutions have been retrieved. Similar to prolog !.

swi_find_all($query, @pattern)

iterates over $query and returns and array with @pattern binded to every solution. i.e:

swi_find_all(member(X, [1, 3, 7, 21]), X)

returns the array (1, 3, 7, 21) and

swi_find_all(member(X, [1, 3, 7, 21]), [X])

returns the array ([1], [3], [7], [21]).

More elaborate constructions can be used:

%mothers=swi_find_all(mother(X,Y), X, Y)

There is also an example of its usage in the SYNOPSIS.

swi_find_one($query, @pattern

as swi_find_all but only for the first solution.

swi_call

runs the query once and return true if a solution was found or false otherwise.

:interactive
swi_toplevel

mostly for debugging pourposes, runs SWI-Prolog shell.

:assert
swi_assert($head => @body)
swi_assertz($head => @body)

add new definitions at the botton of the database

swi_asserta($head => @body)

adds new definitions at the top of the database

swi_facts(@facts)

commodity subroutine to add several facts (facts, doesn't have body) to the database in one call.

i.e.:

use Language::Prolog::Sugar functors=>[qw(man woman)];

swi_facts( man('teodoro'),
           man('socrates'),
           woman('teresa'),
           woman('mary') );
:context
$swi_module
$swi_ctx_module

allow to change the module and the context module for the upcoming queries.

use ALWAYS the local operator when changing their values!!!

i.e.:

local $swi_module='mymodule'
swi_set_query($query_from_mymodule);
$swi_converter

allows to change the way data is converter from Perl to Prolog.

You should not use it for any other thing that to configure perl classes as opaque, i.e.:

$swi_converter->pass_as_opaque(qw(LWP::UserAgent
                                  HTTP::Request
                                  HTTP::Result))
:run
swi_init(@args)

lets init the prolog engine with a different set of arguments (identical to the command line arguments for the pl SWI-Prolog executable.

Defaults arguments are -q to stop the SWI-Prolog welcome banner for being printed to the console.

Language::Prolog::Yaswi will automatically create a new engine with the default arguments (or with the last passed via swi_init), when needed.

swi_cleanup()

releases the prolog engine.

Language::Prolog::Yaswi will release the engine when the script finish, this function is usefull to release the engine to free resources or to be able to init it again with a different set of arguments.

CALLBACKS

Yaswi adds to SWI-Prolog three new predicates to call perl back.

All the calls are make in array contest and the Result value is always a list. There is not way to make a call in scalar context yet.

perl5_eval(+Code, -Result)

makes perl evaluate the string Code (really a Prolog atom) and returns the results.

perl5_call(+Sub, +Args, -Result)

calls a perl sub.

perl5_method(+Object, +Method, +Args, -Result)

calls the method Method from the perl object Object.

To get objects passed to prolog as opaques instead of marshaled to prolog types, its class (or one of its parent classes) has to be previously register as opaque with the $swi_converter object. i.e.:

perl5_eval('$swi_converter->pass_as_opaque("HTTP::Request")',_),
perl5_eval('use HTTP::Request',_),
perl5_method('HTTP::Request', new, [], [Request]),
perl5_method(Request, as_string, [], [Text]);

Registering class UNIVERSAL makes all objects to be passed to prolog as opaques.

EXPORT

This module doesn't export anything by default. Subroutines should be explicitely imported.

THREADS

To get thread support in this module both Perl and SWI-Prolog have to be previously compiled with threads (Perl needs the ithread model available from Perl version 5.8.0, the 5.005 threads model is not supported).

When Perl is called back from a thread created from Prolog a new fresh Perl engine is constructed. That means there will be no modules preloaded on it, no access to Perl data from other threads (not even data marked as shared!), etc. Threads created from Perl do not suffer from this limitation.

KNOWN BUGS

Under Unix, it's not possible to load prolog shared libraries (i.e. xpce).

SEE ALSO

SWI-Prolog documentation http://www.swi-prolog.org/, pl(1), Languages::Prolog::Types and Language::Prolog::Sugar.

AUTHOR

Salvador Fandiño, <sfandino@yahoo.com>

COPYRIGHT AND LICENSE

Copyright 2003 by Salvador Fandiño

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

2 POD Errors

The following errors were encountered while parsing the POD:

Around line 393:

You forgot a '=back' before '=head2'

Around line 463:

Non-ASCII character seen before =encoding in 'Fandiño,'. Assuming CP1252