Language::Prolog::Yaswi - Yet another interface to SWI-Prolog
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]);
Language::Prolog::Yaswi implements a bidirectional interface to the SWI-Prolog system (http://www.swi-prolog.org/).
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.
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_set_query(...)
swi_var($var)
Returns the value binded to $var in the current query/solution combination.
$var
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
(1, 3, 7, 21)
swi_find_all(member(X, [1, 3, 7, 21]), [X])
returns the array ([1], [3], [7], [21]).
([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_find_all
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!!!
local
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.
pl
Defaults arguments are -q to stop the SWI-Prolog welcome banner for being printed to the console.
-q
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.
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.
Code
perl5_call(+Sub, +Args, -Result)
calls a perl sub.
perl5_method(+Object, +Method, +Args, -Result)
calls the method Method from the perl object Object.
Method
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.
UNIVERSAL
This module doesn't export anything by default. Subroutines should be explicitely imported.
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.
Under Unix, it's not possible to load prolog shared libraries (i.e. xpce).
SWI-Prolog documentation http://www.swi-prolog.org/, pl(1), Languages::Prolog::Types and Language::Prolog::Sugar.
Salvador Fandiño, <sfandino@yahoo.com>
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:
You forgot a '=back' before '=head2'
Non-ASCII character seen before =encoding in 'Fandiño,'. Assuming CP1252
To install Language::Prolog::Yaswi, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Language::Prolog::Yaswi
CPAN shell
perl -MCPAN -e shell install Language::Prolog::Yaswi
For more information on module installation, please visit the detailed CPAN module installation guide.