The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

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.

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

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

use ALWAYS the local operator when changing its value!!!

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))

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.

SEE ALSO

SWI-Prolog documentation http://www.swi-prolog.org/, Languages::Prolog::Types, 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.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 419:

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