Skip to content

primitive

tuprolog.solve.primitive

Primitives: predicates implemented in Python (or Kotlin) rather than in Prolog.

A logic solver proves a goal such as upper(abc, U) by looking for clauses whose head matches it. Some predicates cannot be (conveniently) written as clauses, e.g. those doing arithmetic, I/O, or calling external code: they are implemented as primitives, i.e. functions the solver calls whenever a goal invokes them.

A primitive receives a solve request (SolveRequest) describing the goal being proven: its signature (name and arity, e.g. upper/2), its arguments (terms, possibly containing unbound variables), and the execution context (tuprolog.solve.ExecutionContext) of the solver at that moment (its knowledge base, flags, operators, libraries, I/O channels...). It replies with zero or more solve responses (SolveResponse), one per solution, lazily: each response carries a solution (success with a substitution binding the goal's variables, failure, or an error), and optionally side effects on the solver's state (see tuprolog.solve.sideffects). Replying with no response at all, or with a failure, means the goal has no (more) solutions.

Primitives are packed into libraries (see tuprolog.solve.library), which are then given to solvers. The easiest way to write one is predicate, turning a plain Python function into a primitive; primitive gives full control over requests and responses. The ensuring_* functions check the arguments of a request, raising the standard ISO Prolog error (see tuprolog.solve.exception.error) when they are not as expected.

Examples:

A predicate from a Python function, yielding one tuple of argument values per solution:

>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.prolog import prolog_solver
>>> between = predicate(lambda low, high, x: ((low, high, i) for i in range(low, high + 1)))
>>> solver = prolog_solver(libraries=library("demo", primitives={"between/3": between}))
>>> list(solver.query("between(1, 3, X)"))
[{'X': 1}, {'X': 2}, {'X': 3}]

A primitive handling the request directly, checking its first argument:

>>> from tuprolog.core import integer
>>> def double(request):
...     ensuring_argument_is_integer(request, 0)
...     n, result = request.arguments
...     doubled = integer(n.to_int() * 2)
...     yield request.reply_with(request.context.unificator.mgu(result, doubled))
>>> lib = library("demo", primitives={"double/2": primitive(double)})
>>> solver = prolog_solver(libraries=lib)
>>> list(solver.query("double(21, X)"))
[{'X': 42}]
>>> solver.solve_once("catch(double(a, X), error(E, _), true)")["E"]
type_error(integer, a)
See Also

tuprolog.solve.function, for Python-defined arithmetic functions; tuprolog.solve.library, to bundle primitives into libraries; 2P-Kt's documentation on primitives.

Primitive module-attribute

Primitive = _primitive.Primitive

A predicate implemented by code: a function from a SolveRequest to responses.

The JVM interface every primitive implements: its single method, solve(request), returns the (lazy) sequence of SolveResponses answering the request, one per solution. Primitives are registered in libraries under a signature (see tuprolog.solve.library.library).

Build primitives with primitive (from a callable handling requests) or predicate (from a plain Python function), or by subclassing AbstractPrimitive; Primitive.of(callable) is 2P-Kt's own factory, and Primitive.enforcingSignature(signature, primitive) restricts a primitive to one signature.

Solve module-attribute

Solve = _primitive.Solve

The base type of SolveRequest (Solve.Request) and SolveResponse (Solve.Response).

PrimitiveWrapper module-attribute

PrimitiveWrapper = _primitive.PrimitiveWrapper

2P-Kt's base class of the primitives it implements, wrapping a function under a signature.

Its static methods back the argument checks of this package (e.g. ensuring_argument_is_atom calls PrimitiveWrapper.ensuringArgumentIsAtom); PrimitiveWrapper.wrap(signature, primitive) builds a wrapper from a signature and a Primitive, and wrapper.implementation (also wrapper.signature, wrapper.description_pair) gives back the checked primitive.

SolveRequest module-attribute

SolveRequest = Solve.Request

A request, issued by a solver, to prove a goal by means of a primitive.

Members (snake_case aliases as well):

  • signature: the tuprolog.solve.Signature (name and arity) of the goal, e.g. upper/2;
  • arguments: the goal's arguments (a JVM list of tuprolog.core.Terms, possibly containing unbound variables), indexable and iterable;
  • query: the goal itself, as a tuprolog.core.Struct (e.g. upper(abc, U));
  • context: the solver's tuprolog.solve.ExecutionContext when the request was issued (its knowledge bases, flags, operators, libraries, channels, and unificator);
  • start_time and max_duration: when the request was issued, and how long (in milliseconds) it may take before timing out;
  • unificator: the context's unification algorithm (see tuprolog.unify), e.g. request.unificator.mgu(a, b) gives the substitution unifying a and b.

Reply to it with responses built by its methods, each optionally taking side effects (tuprolog.solve.sideffects) as further arguments:

  • reply_with(outcome): a success or a failure from a substitution (failed substitutions mean failure), a tuprolog.solve.Solution, or a boolean;
  • reply_success(substitution=None): a success, binding the goal's variables as substitution says (nothing, by default);
  • reply_fail(): a failure;
  • reply_exception(exception): an error, i.e. a tuprolog.solve.exception.ResolutionException (raising it from the primitive has the same effect).

solve(goal, max_duration=None) proves another goal in a sub-solver sharing this request's context (by default within the time left to this request), giving back its solutions.

Build requests (e.g. for testing primitives) with solve_request.

Examples:

>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.prolog import prolog_solver
>>> from tuprolog.solve.primitive import primitive
>>> requests = []
>>> def spy(request):
...     requests.append(request)
...     yield request.reply_success()
>>> solver = prolog_solver(libraries=library("spy", primitives={"spy/2": primitive(spy)}))
>>> solver.solve_once("spy(a, f(X))").is_yes
True
>>> request = requests[0]
>>> request.signature.name, request.signature.arity
('spy', 2)
>>> [str(argument) for argument in request.arguments]
['a', 'f(X_...)']
>>> request.reply_fail().solution.is_no
True

SolveResponse module-attribute

SolveResponse = Solve.Response

A response to a SolveRequest: one solution of the goal, plus side effects.

Members (snake_case aliases as well): solution, the tuprolog.solve.Solution (a success with its substitution, a failure, or an error); side_effects, the (possibly empty) list of tuprolog.solve.sideffects.SideEffects to apply to the solver's state (e.g. asserting clauses, setting flags); side_effect_manager, solver-specific state for control-flow primitives (None unless changed).

Build responses with the reply_* methods of requests, or with solve_response.

AbstractPrimitive

A base class for primitives implemented in Python, as subclasses overriding solve.

Instances implement the JVM interface Primitive; primitive is the shortcut building one from a callable, also turning the Python exceptions solve raises into logic errors.

Examples:

>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.prolog import prolog_solver
>>> from tuprolog.solve.primitive import AbstractPrimitive
>>> class Hello(AbstractPrimitive):
...     def solve(self, request):
...         yield request.reply_success()
>>> hello = Hello()
>>> solver = prolog_solver(libraries=library("demo", primitives={"hello/0": hello}))
>>> solver.solve_once("hello").is_yes
True

solve

solve(request: SolveRequest) -> Iterable[SolveResponse]

Answers a request with its responses, one per solution (lazily, e.g. as a generator).

Parameters:

Name Type Description Default
request SolveRequest

the request to prove a goal invoking this primitive.

required

Returns:

Type Description
Iterable[SolveResponse]

The responses to request; none, or a failure, if the goal has no (more) solutions.

Raises:

Type Description
NotImplementedError

unless overridden.

python_error

python_error(
    context: ExecutionContext, error: BaseException
) -> ResolutionException

The logic error for an exception raised by Python code run by a solver.

Errors of 2P-Kt (tuprolog.solve.exception.ResolutionExceptions) are kept as they are; any other exception becomes a system_error, whose culprit is the JVM exception, or the term python_error(Type, Message) for Python exceptions (e.g. python_error('ValueError', 'oops')). This is how primitive (and so predicate) turns the exceptions of Python code into logic errors, which Prolog code can handle with catch/3.

Parameters:

Name Type Description Default
context ExecutionContext

the execution context in which the error occurred (e.g. request.context).

required
error BaseException

the exception raised.

required

Returns:

Type Description
ResolutionException

The logic error to reply with (e.g. by request.reply_exception).

Examples:

>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.primitive import predicate
>>> from tuprolog.solve.prolog import prolog_solver
>>> def fail_loudly():
...     raise ValueError("oops")
>>> lib = library("demo", primitives={"oops/0": predicate(fail_loudly)})
>>> solver = prolog_solver(libraries=lib)
>>> solver.solve_once("catch(oops, error(E, _), true)")["E"]
system_error
>>> solver.solve_once("oops").get_exception().message
"Uncaught exception `python_error('ValueError', oops)`"

primitive

primitive(
    callable: Callable[
        [SolveRequest], Iterable[SolveResponse]
    ],
) -> Primitive

Makes a primitive from a callable mapping requests to responses.

The callable receives each SolveRequest issued for the goals invoking the primitive, and returns (or yields, being a generator) its SolveResponses, built by the reply_* methods of the request: one per solution, none if there are no solutions. Exceptions it raises (even after some responses) become logic errors, as python_error says, ending the solutions.

Parameters:

Name Type Description Default
callable Callable[[SolveRequest], Iterable[SolveResponse]]

the implementation, from a request to an iterable of responses.

required

Returns:

Type Description
Primitive

A primitive, to be registered in a library (see tuprolog.solve.library.library).

Examples:

>>> from tuprolog.core import atom
>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.primitive import primitive
>>> from tuprolog.solve.prolog import prolog_solver
>>> def colour(request):
...     [argument] = request.arguments
...     for name in ("red", "green"):
...         yield request.reply_with(request.unificator.mgu(argument, atom(name)))
>>> lib = library("demo", primitives={"colour/1": primitive(colour)})
>>> list(prolog_solver(libraries=lib).query("colour(C)"))
[{'C': 'red'}, {'C': 'green'}]
See Also

predicate, to write primitives as plain Python functions.

predicate

predicate(
    function: Callable[..., bool | None | Iterable],
) -> Primitive

Makes a primitive from a Python function taking the goal's arguments as Python values.

The arguments of the goal are converted by tuprolog.core.to_python (e.g. atoms become strings, integers ints, lists lists); unbound variables, and terms without a Python counterpart, are passed as they are (as tuprolog.core.Terms). The function then either:

  • returns a boolean: True (or None) means success, without binding any variable, and False failure;
  • returns or yields tuples of values, one per solution, as long as the goal's arguments: each tuple is converted by tuprolog.core.to_term and unified with the arguments, binding the goal's variables; tuples not unifying are skipped. For predicates of arity 1, plain values may be returned instead of 1-tuples.

Exceptions it raises become logic errors (see python_error).

Parameters:

Name Type Description Default
function Callable[..., bool | None | Iterable]

the implementation, called with as many arguments as the goal's arity.

required

Returns:

Type Description
Primitive

A primitive, to be registered in a library (see tuprolog.solve.library.library).

Raises:

Type Description
ValueError

(as a logic system_error) if a tuple of values is not as long as the goal's arguments.

Examples:

>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.primitive import predicate
>>> from tuprolog.solve.prolog import prolog_solver
>>> lib = library(
...     "demo",
...     primitives={
...         "even/1": predicate(lambda n: n % 2 == 0),
...         "upper/2": predicate(lambda s, _: [(s, s.upper())]),
...         "digit/1": predicate(lambda _: range(3)),
...     },
... )
>>> solver = prolog_solver(libraries=lib)
>>> solver.solve_once("even(4)").is_yes, solver.solve_once("even(3)").is_yes
(True, False)
>>> list(solver.query("upper(abc, U)"))
[{'U': 'ABC'}]
>>> list(solver.query("digit(D)"))
[{'D': 0}, {'D': 1}, {'D': 2}]

solve_request

solve_request(
    signature: Signature,
    arguments: Iterable[Term],
    context: ExecutionContext,
    issuing_instant: int | None = None,
    max_duration: int = MAX_TIMEOUT,
) -> SolveRequest

Creates a request to prove a goal by means of a primitive.

Solvers issue requests by themselves: build them only to call primitives directly (e.g. when testing them).

Parameters:

Name Type Description Default
signature Signature

the signature of the goal (see tuprolog.solve.signature).

required
arguments Iterable[Term]

the arguments of the goal, as many as signature's arity.

required
context ExecutionContext

the execution context of the request (e.g. another request's context).

required
issuing_instant int | None

when the request is issued, in milliseconds since the epoch; now, by default (see tuprolog.solve.current_time_instant).

None
max_duration int

how long (in milliseconds) the request may take; unlimited by default.

MAX_TIMEOUT

Returns:

Type Description
SolveRequest

The request, whose query is the goal.

Examples:

>>> from tuprolog.core import atom, var
>>> from tuprolog.solve import signature
>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.primitive import predicate, primitive, solve_request
>>> from tuprolog.solve.prolog import prolog_solver
>>> contexts = []
>>> def capture(request):
...     contexts.append(request.context)
...     yield request.reply_success()
>>> lib = library("demo", primitives={"capture/0": primitive(capture)})
>>> _ = prolog_solver(libraries=lib).solve_once("capture")
>>> upper = predicate(lambda s, _: [(s, s.upper())])
>>> request = solve_request(signature("upper", 2), [atom("abc"), var("U")], contexts[0])
>>> request.query
upper(abc, U_...)
>>> [str(response.solution.substitution) for response in upper.solve(request)]
["{U_...='ABC'}"]

solve_response

solve_response(
    solution: Solution, *side_effects: Any
) -> SolveResponse

Creates a response with a solution and some side effects.

Requests' reply_* methods are the handier way of building responses.

Parameters:

Name Type Description Default
solution Solution

the solution (see tuprolog.solve.yes_solution, no_solution, halt_solution).

required
*side_effects Any

the side effects on the solver's state (see tuprolog.solve.sideffects), or a single iterable of them.

()

Returns:

Type Description
SolveResponse

The response.

check_term_is_recursively_callable

check_term_is_recursively_callable(
    request: SolveRequest, term: Term
) -> Any

Checks whether a term can be called as a goal, its sub-goals included.

A term is callable if it is a structure (e.g. an atom or a compound term) or a variable; conjunctions, disjunctions and implications (,, ;, ->) are callable if their sub-goals are.

Parameters:

Name Type Description Default
request SolveRequest

the request on whose behalf the check is made (giving the error's context).

required
term Term

the term to check.

required

Returns:

Type Description
Any

None, if term is callable, or the type_error(callable, Culprit) to raise otherwise

Any

(a tuprolog.solve.exception.error.type.TypeError, not raised by this function).

ensuring_all_arguments_are_instantiated

ensuring_all_arguments_are_instantiated(
    request: SolveRequest,
) -> SolveRequest

Checks that no argument of a request is an unbound variable.

Parameters:

Name Type Description Default
request SolveRequest

the request whose arguments are checked.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
InstantiationError

instantiation_error, for the first unbound argument.

ensuring_procedure_has_permission

ensuring_procedure_has_permission(
    request: SolveRequest,
    signature: Signature,
    operation: Any,
) -> SolveRequest

Checks that a procedure can be modified, i.e. that it is neither a library one nor static.

Used by primitives altering the knowledge base (e.g. assert/1, retract/1).

Parameters:

Name Type Description Default
request SolveRequest

the request on whose behalf the check is made.

required
signature Signature

the signature of the procedure to modify (None passes the check).

required
operation Any

the attempted operation (e.g. OPERATION_MODIFY, see tuprolog.solve.exception.error.permission).

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
PermissionError

permission_error(Operation, private_procedure, Name/Arity) if a library defines the procedure, or permission_error(Operation, static_procedure, Name/Arity) if the static knowledge base does.

ensuring_clause_procedure_has_permission

ensuring_clause_procedure_has_permission(
    request: SolveRequest, clause: Clause, operation: Any
) -> SolveRequest

Checks that the procedure of a clause (i.e. its head's) can be modified.

As ensuring_procedure_has_permission, for the signature of clause's head.

Parameters:

Name Type Description Default
request SolveRequest

the request on whose behalf the check is made.

required
clause Clause

the clause whose procedure is checked.

required
operation Any

the attempted operation (e.g. OPERATION_MODIFY).

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
PermissionError

if the procedure is a library or static one.

ensuring_argument_is_well_formed_indicator

ensuring_argument_is_well_formed_indicator(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a well-formed predicate indicator.

A predicate indicator is a Name/Arity term, with an atom Name and an integer Arity.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
InstantiationError

if the argument, its name, or its arity are unbound.

TypeError

type_error(predicate_indicator, Culprit) if the argument is not _/_, type_error(atom, Name) or type_error(integer, Arity) if its parts are not.

DomainError

domain_error(not_less_than_zero, Arity) for negative arities.

RepresentationError

representation_error(max_arity) if the arity exceeds the max_arity flag.

not_implemented

not_implemented(
    request: SolveRequest, message: str
) -> SolveResponse

Raises the error reporting that a primitive is not implemented yet.

Parameters:

Name Type Description Default
request SolveRequest

the request answered.

required
message str

the error message.

required

Returns:

Type Description
SolveResponse

Never returns: it raises.

Raises:

Type Description
SystemError

always, with message.

not_supported

not_supported(
    request: SolveRequest, message: str
) -> SolveResponse

Raises the error reporting that a primitive does not support an operation.

Parameters:

Name Type Description Default
request SolveRequest

the request answered.

required
message str

the error message.

required

Returns:

Type Description
SolveResponse

Never returns: it raises.

Raises:

Type Description
SystemError

always, with message.

ensuring_argument_is_well_formed_clause

ensuring_argument_is_well_formed_clause(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a well-formed clause.

Well-formed clauses are callable terms, or Head :- Body ones with a callable head and body.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
InstantiationError

if the argument is unbound.

TypeError

type_error(callable, Culprit) if the argument is not a structure.

DomainError

domain_error(clause, Culprit) for ill-formed :-/2 terms.

ensuring_argument_is_instantiated

ensuring_argument_is_instantiated(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is not an unbound variable.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
InstantiationError

instantiation_error, if the argument is unbound.

ensuring_argument_is_numeric

ensuring_argument_is_numeric(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a number (an integer or a real).

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(number, Culprit), otherwise.

ensuring_argument_is_struct

ensuring_argument_is_struct(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a structure (an atom or a compound term).

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(callable, Culprit), otherwise.

ensuring_argument_is_callable

ensuring_argument_is_callable(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is callable, i.e. a structure.

The same as ensuring_argument_is_struct.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(callable, Culprit), otherwise.

ensuring_argument_is_variable

ensuring_argument_is_variable(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is an unbound variable.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(variable, Culprit), otherwise.

ensuring_argument_is_compound

ensuring_argument_is_compound(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a compound term (not an atom).

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(compound, Culprit), otherwise.

ensuring_argument_is_atom

ensuring_argument_is_atom(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is an atom.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(atom, Culprit), otherwise.

ensuring_argument_is_constant

ensuring_argument_is_constant(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is atomic, i.e. an atom or a number.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(atomic, Culprit), otherwise.

ensuring_argument_is_ground

ensuring_argument_is_ground(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is ground (contains no unbound variable).

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
InstantiationError

instantiation_error, for its first variable, otherwise.

ensuring_argument_is_char

ensuring_argument_is_char(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a character, i.e. an atom of length 1.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(character, Culprit), otherwise.

ensuring_argument_is_specifier

ensuring_argument_is_specifier(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is an operator specifier.

Operator specifiers are atoms such as xfx or fy (see tuprolog.core.operators).

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
DomainError

domain_error(operator_specifier, Culprit), otherwise.

ensuring_argument_is_integer

ensuring_argument_is_integer(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is an integer.

Examples:

>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.primitive import ensuring_argument_is_integer, primitive
>>> from tuprolog.solve.prolog import prolog_solver
>>> def check(request):
...     yield ensuring_argument_is_integer(request, 0).reply_success()
>>> lib = library("demo", primitives={"check/1": primitive(check)})
>>> solver = prolog_solver(libraries=lib)
>>> solver.solve_once("check(1)").is_yes
True
>>> solver.solve_once("catch(check(a), error(E, _), true)")["E"]
type_error(integer, a)

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(integer, Culprit), otherwise.

ensuring_argument_is_list

ensuring_argument_is_list(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a list (possibly a partial one).

Partial lists end with a variable, e.g. [a | T].

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(list, Culprit), otherwise.

ensuring_argument_is_well_formed_list

ensuring_argument_is_well_formed_list(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a well-formed list (ending with []).

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(list, Culprit) if the argument is not a list.

DomainError

domain_error(well_formed_list, Culprit) for partial lists.

ensuring_argument_is_arity

ensuring_argument_is_arity(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a valid arity.

Valid arities are non-negative integers not exceeding the max_arity flag.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(integer, Culprit) if the argument is not an integer.

DomainError

domain_error(not_less_than_zero, Culprit) if it is negative.

RepresentationError

representation_error(max_arity) if it exceeds the flag.

ensuring_argument_is_non_negative_integer

ensuring_argument_is_non_negative_integer(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a non-negative integer.

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(integer, Culprit) if the argument is not an integer.

DomainError

domain_error(not_less_than_zero, Culprit) if it is negative.

is_character_code

is_character_code(integer: Integer) -> bool

Checks whether an integer is not a valid character code.

Note

Despite its name, this wraps 2P-Kt's PrimitiveWrapper.isCharacterCode, which returns True for integers outside the range of character codes (0 to 65535).

Parameters:

Name Type Description Default
integer Integer

the logic integer to check.

required

Returns:

Type Description
bool

True if integer is not a character code, False if it is one.

Examples:

>>> from tuprolog.core import integer
>>> from tuprolog.solve.primitive import is_character_code
>>> is_character_code(integer(65)), is_character_code(integer(-1))
(False, True)

ensuring_term_is_char_code

ensuring_term_is_char_code(
    request: SolveRequest, term: Term
) -> SolveRequest

Checks that a term is a character code, i.e. an integer from 0 to 65535.

Parameters:

Name Type Description Default
request SolveRequest

the request on whose behalf the check is made.

required
term Term

the term to check.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
RepresentationError

representation_error(character_code), otherwise.

ensuring_term_is_well_formed_list

ensuring_term_is_well_formed_list(
    request: SolveRequest, term: Term
) -> SolveRequest

Checks that a term is a well-formed list, i.e. one ending with [].

Parameters:

Name Type Description Default
request SolveRequest

the request on whose behalf the check is made.

required
term Term

the term to check.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
DomainError

domain_error(well_formed_list, Culprit), otherwise.

ensuring_argument_is_char_code

ensuring_argument_is_char_code(
    request: SolveRequest, index: int
) -> SolveRequest

Checks that the index-th argument of a request is a character code (0 to 65535).

Parameters:

Name Type Description Default
request SolveRequest

the request whose argument is checked.

required
index int

the (0-based) position of the argument.

required

Returns:

Type Description
SolveRequest

request itself, if the check passes, so that checks can be chained.

Raises:

Type Description
TypeError

type_error(integer, Culprit) if the argument is not an integer.

RepresentationError

representation_error(character_code) if it is out of range.