Prolog

Provides the basic Prolog interface.

exception pyswip.prolog.PrologError
exception pyswip.prolog.NestedQueryError

SWI-Prolog does not accept nested queries, that is, opening a query while the previous one was not closed. As this error may be somewhat difficult to debug in foreign code, it is automatically treated inside PySwip

class pyswip.prolog.Prolog

Provides the entry point for the Prolog interface

classmethod asserta(format, *args, catcherrors=False)

Assert a clause (fact or rule) into the database.

asserta asserts the clause as the first clause of the predicate.

See asserta/1 in SWI-Prolog documentation.

Parameters:
  • format (str) – The format to be used to generate the clause. The placeholders (%p) are replaced by the args if one ore more arguments are given.

  • args – Arguments to replace the placeholders in the format string

  • catcherrors (bool) – Catches the exception raised during goal execution

Return type:

None

Note

Currently, If no arguments given, the format string is used as the raw clause, even if it contains a placeholder. This behavior is kept for for compatibility reasons. It may be removed in future versions.

>>> Prolog.asserta("big(airplane)")
>>> Prolog.asserta("small(mouse)")
>>> Prolog.asserta('''bigger(A, B) :-
...    big(A),
...    small(B)''')
>>> nums = list(range(5))
>>> Prolog.asserta("numbers(%p)", nums)
classmethod assertz(format, *args, catcherrors=False)

Assert a clause (fact or rule) into the database.

assertz asserts the clause as the last clause of the predicate.

See assertz/1 in SWI-Prolog documentation.

Parameters:
  • format (str) – The format to be used to generate the clause. The placeholders (%p) are replaced by the args if one ore more arguments are given.

  • catcherrors (bool) – Catches the exception raised during goal execution

Return type:

None

Note

Currently, If no arguments given, the format string is used as the raw clause, even if it contains a placeholder. This behavior is kept for for compatibility reasons. It may be removed in future versions.

>>> Prolog.assertz("big(airplane)")
>>> Prolog.assertz("small(mouse)")
>>> Prolog.assertz('''bigger(A, B) :-
...    big(A),
...    small(B)''')
>>> nums = list(range(5))
>>> Prolog.assertz("numbers(%p)", nums)
classmethod dynamic(*terms, catcherrors=False)

Informs the interpreter that the definition of the predicate(s) may change during execution

See dynamic/1 in SWI-Prolog documentation.

Parameters:
  • terms (str) – One or more predicate indicators

  • catcherrors (bool) – Catches the exception raised during goal execution

Raises:

ValueError – if no terms was given.

Return type:

None

>>> Prolog.dynamic("person/1")
>>> Prolog.asserta("person(jane)")
>>> list(Prolog.query("person(X)"))
[{'X': 'jane'}]
>>> Prolog.retractall("person(_)")
>>> list(Prolog.query("person(X)"))
[]
classmethod retract(format, *args, catcherrors=False)

Removes the fact or clause from the database

See retract/1 in SWI-Prolog documentation.

Parameters:
  • format (str) – The format to be used to generate the term. The placeholders (%p) are replaced by the args if one ore more arguments are given.

  • catcherrors (bool) – Catches the exception raised during goal execution

Return type:

None

Note

Currently, If no arguments given, the format string is used as the raw term, even if it contains a placeholder. This behavior is kept for for compatibility reasons. It may be removed in future versions.

>>> Prolog.dynamic("person/1")
>>> Prolog.asserta("person(jane)")
>>> list(Prolog.query("person(X)"))
[{'X': 'jane'}]
>>> Prolog.retract("person(jane)")
>>> list(Prolog.query("person(X)"))
[]
>>> Prolog.dynamic("numbers/1")
>>> nums = list(range(5))
>>> Prolog.asserta("numbers(10)")
>>> Prolog.asserta("numbers(%p)", nums)
>>> list(Prolog.query("numbers(X)"))
[{'X': [0, 1, 2, 3, 4]}, {'X': 10}]
>>> Prolog.retract("numbers(%p)", nums)
>>> list(Prolog.query("numbers(X)"))
[{'X': 10}]
classmethod retractall(format, *args, catcherrors=False)

Removes all facts or clauses in the database where the head unifies.

See retractall/1 in SWI-Prolog documentation.

Parameters:
  • format (str) – The term to unify with the facts or clauses in the database

  • catcherrors (bool) – Catches the exception raised during goal execution

Return type:

None

>>> Prolog.dynamic("person/1")
>>> Prolog.asserta("person(jane)")
>>> Prolog.asserta("person(joe)")
>>> list(Prolog.query("person(X)"))
[{'X': 'joe'}, {'X': 'jane'}]
>>> Prolog.retractall("person(_)")
>>> list(Prolog.query("person(X)"))
[]
classmethod consult(path, *, catcherrors=False, relative_to='')

Reads the given Prolog source file

The file is always reloaded when called.

See consult/1 in SWI-Prolog documentation.

Tilde character (~) in paths are expanded to the user home directory

>>> Prolog.consult("~/my_files/hanoi.pl")
>>> # consults file /home/me/my_files/hanoi.pl

relative_to keyword argument makes it easier to construct the consult path. This keyword is no-op, if the consult path is absolute. If the given relative_to path is a file, then the consult path is updated to become a sibling of that path.

Assume you have the /home/me/project/facts.pl that you want to consult from the run.py file which exists in the same directory /home/me/project. Using the built-in __file__ constant which contains the path of the current Python file , it becomes very easy to do that:

>>> Prolog.consult("facts.pl", relative_to=__file__)

If the given relative_path is a directory, then the consult path is updated to become a child of that path.

>>> project_dir = "~/projects"
>>> Prolog.consult("facts1.pl", relative_to=project_dir)
Parameters:
  • path (Union[str, Path]) – The path to the Prolog source file

  • catcherrors (bool) – Catches the exception raised during goal execution

  • relative_to (Union[str, Path]) – The path where the consulted file is relative to

Return type:

None

classmethod query(format, *args, maxresult=-1, catcherrors=True, normalize=True)

Run a prolog query and return a generator

If the query is a yes/no question, returns {} for yes, and nothing for no. Otherwise returns a generator of dicts with variables as keys.

Parameters:
  • format (str) – The format to be used to generate the query. The placeholders (%p) are replaced by the args if one ore more arguments are given.

  • args – Arguments to replace the placeholders in the format string

  • maxresult (int) – Maximum number of results to return

  • catcherrors (bool) – Catches the exception raised during goal execution

  • normalize (bool) – Return normalized values

Return type:

Generator

Note

Currently, If no arguments given, the format string is used as the raw query, even if it contains a placeholder. This behavior is kept for for compatibility reasons. It may be removed in future versions.

>>> Prolog.assertz("father(michael,john)")
>>> Prolog.assertz("father(michael,gina)")
>>> bool(list(Prolog.query("father(michael,john)")))
True
>>> bool(list(Prolog.query("father(michael,olivia)")))
False
>>> print(sorted(Prolog.query("father(michael,X)")))
[{'X': 'gina'}, {'X': 'john'}]
classmethod register_foreign(func, /, name='', arity=None, *, module='', nondeterministic=False)

Registers a Python callable as a Prolog predicate

Parameters:
  • func (Callable) – Callable to be registered. The callable should return a value in foreign_t, True or False or None. Returning None is equivalent to returning True.

  • name (str) – Name of the callable. If the name is not specified, it is derived from func.__name__.

  • arity (Optional[int]) – Number of parameters of the callable. If not specified, it is derived from the callable signature.

  • module (str) – Name of the module to register the predicate. By default, the current module.

  • nondeterministic (bool) – Set the foreign callable as nondeterministic