Skip to content

Repl

tuprolog.repl

Interactive Prolog shells, i.e. read-eval-print loops (REPLs).

A REPL reads what the user types, evaluates it, prints the result, and loops. A Prolog REPL lets users write a program clause by clause and query it, as in the shells of most Prolog systems:

  • typing a clause (e.g. parent(abe, homer).) adds it to the solver's dynamic knowledge base;
  • typing ?- and a query (e.g. ?- parent(X, homer).) prints all its solutions;
  • typing :- and a goal (e.g. :- op(700, xfx, likes).) runs it as a directive;
  • typing : and a command runs it: :help lists the commands, :exit leaves the REPL.

Input ends with a full stop (.): lines without one are joined to the next ones.

Run a REPL from the command line with python -m tuprolog.repl.prolog (for Prolog) or python -m tuprolog.repl.problog (for ProbLog, i.e. probabilistic logic programming, whose solutions also show their probability), or create a PrologREPL for any solver.

Examples:

>>> import io
>>> from tuprolog.solve.prolog import prolog_solver
>>> user_input = io.StringIO("parent(abe, homer).\n?- parent(abe, Who).\n:exit\n")
>>> output = io.StringIO()
>>> repl = PrologREPL(prolog_solver(mutable=True), "prolog", stdin=user_input, stdout=output)
>>> repl.cmdloop(intro="")
>>> print(output.getvalue())
prolog>prolog>yes: parent(abe, homer)
    Who = homer
prolog>
See Also

tuprolog.solve, for solving queries from Python.

PrologREPL

PrologREPL(
    solver: Solver,
    name: str,
    completekey: str = "tab",
    stdin: IO[str] | None = None,
    stdout: IO[str] | None = None,
    probabilistic: bool | None = None,
)

Bases: Cmd

A read-eval-print loop (REPL) for a logic solver.

It is a cmd.Cmd shell: cmdloop() runs it, reading lines from its input until :exit, the end of the input, or a query halting the solver (e.g. halt.). Each input is:

  • a query, if it starts with ?-: all its solutions are printed (see do_query);
  • a directive, if it starts with :-: it is run, printing its outcome only if it does not succeed (see do_directive);
  • a command, if it starts with : (e.g. :help, :exit);
  • a sequence of clauses, otherwise: they are added to the end of the solver's dynamic knowledge base (see do_assert).

Queries, directives and clauses end with a full stop: until one is typed, lines are accumulated, and the prompt becomes ...>. Parsing follows the solver's current operators, so operators defined by directives (e.g. :- op(700, xfx, likes).) are recognized afterward.

Attributes:

Name Type Description
solver

The solver answering queries; it should have a mutable knowledge base, for clauses to be added.

name

The name of the language, shown in the prompt (e.g. prolog>) and introduction.

probabilistic

Whether queries are solved probabilistically, showing the probability of each successful solution.

multi_line_command

The input accumulated so far, while waiting for a full stop.

Examples:

>>> import io
>>> from tuprolog.solve.prolog import prolog_solver
>>> user_input = io.StringIO("p(1). p(2).\n?- p(\n  X).\n")
>>> output = io.StringIO()
>>> solver = prolog_solver(mutable=True)
>>> repl = PrologREPL(solver, "prolog", stdin=user_input, stdout=output)
>>> repl.cmdloop(intro="")
>>> print(output.getvalue())
prolog>prolog>...>yes: p(1)
    X = 1
yes: p(2)
    X = 2
prolog>

Creates a REPL for a solver.

Parameters:

Name Type Description Default
solver Solver

The solver answering queries (see tuprolog.solve), preferably with a mutable knowledge base.

required
name str

The name of the language, shown in the prompt and introduction.

required
completekey str

The key completing commands (see cmd.Cmd).

'tab'
stdin IO[str] | None

The input to read from (sys.stdin, unless given).

None
stdout IO[str] | None

The output to write to (sys.stdout, unless given).

None
probabilistic bool | None

Whether queries show the probability of their solutions; if None (the default), they do for ProbLog solvers (see tuprolog.solve.problog).

None

clauses_parser property

clauses_parser: ClausesParser

The parser of clauses, knowing the solver's current operators.

query_parser property

query_parser: TermParser

The parser of queries and directives, knowing the solver's current operators.

solution_formatter property

solution_formatter: SolutionFormatter

The formatter of solutions, writing terms with the solver's current operators.

prompt property

prompt: str

The prompt: the language name (e.g. prolog>), or ...> while input is incomplete.

emptyline

emptyline() -> bool

Does nothing on empty lines (cmd.Cmd would repeat the last command).

precmd

precmd(line: str) -> str

Accumulates lines until a full stop ends the input.

Parameters:

Name Type Description Default
line str

The line read.

required

Returns:

Type Description
str

The whole input, once it ends with a full stop, or the line itself, if it is a

str

command; an empty string while input is incomplete. The end of the input becomes

str

:exit.

do_exit

do_exit(arg: str) -> bool

Exit the REPL.

parseline

parseline(line: str) -> tuple[str | None, str | None, str]

Splits the input into the command to run (query, directive, assert, or the one following :), its argument, and the input itself.

do_query

do_query(arg: str) -> bool

Query the theory.

Prints every solution of the query, with its variable bindings (and probability, if probabilistic), or no. if there is none; type ?- query. to run it.

Returns:

Type Description
bool

True (ending the REPL) if the query halted the solver, False otherwise.

do_directive

do_directive(arg: str) -> bool

Runs a directive (:- goal.), reporting only its failures.

Returns:

Type Description
bool

True (ending the REPL) if the directive halted the solver, False otherwise.

do_assert

do_assert(arg: str) -> bool

Asserts a clause, appending to the theory.

All the clauses in the input are added to the end of the solver's dynamic knowledge base; clauses which cannot be parsed or added are reported as errors.

Returns:

Type Description
bool

False, as asserting never ends the REPL.

on_parsing_error

on_parsing_error(err: ParseException) -> None

Reports input which is not valid Prolog, writing the parser's message.