function
tuprolog.solve.function
¶
Logic functions: functions evaluated in arithmetic expressions, e.g. by is/2.
Prolog evaluates arithmetic expressions only in some predicates, e.g. X is 1 + 2 or X > 2:
elsewhere, 1 + 2 is just a term. Each operation in an expression (e.g. +/2, sqrt/1) is a
logic function, receiving the (evaluated) arguments, and returning a term. The standard ones
are in tuprolog.solve.stdlib.function; libraries add others (see tuprolog.solve.library).
Functions receive a compute request (ComputeRequest: the function's signature, its
arguments, and the solver's context), and return a compute response (ComputeResponse,
holding the result).
Main types and functions:
function: creates a logic function from a Python function on Python values;logic_function: creates a logic function from a Python function on requests;LogicFunction,ComputeRequest,ComputeResponse,AbstractLogicFunction;eval_as_expressionandeval_as_arithmetic_expression: evaluate expressions in primitives.
Examples:
>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.prolog import prolog_solver
>>> hypot = function(lambda x, y: (x**2 + y**2) ** 0.5)
>>> solver = prolog_solver(libraries=library("my.math", functions={"hypot/2": hypot}))
>>> solver.solve_once("X is hypot(3, 4) + 1")["X"]
6.0
See Also
- 2P-Kt's primitives and functions.
LogicFunction
module-attribute
¶
LogicFunction = _function.LogicFunction
A logic function: computes the result of an operation in arithmetic expressions.
Its only method is compute(request), taking a ComputeRequest and returning a
ComputeResponse. Create logic functions with function or logic_function, or by subclassing
AbstractLogicFunction.
Compute
module-attribute
¶
Compute = _function.Compute
The JVM base class of compute requests and responses.
It nests them as Compute.Request (ComputeRequest) and Compute.Response (ComputeResponse).
ArithmeticUtilsKt
module-attribute
¶
ArithmeticUtilsKt = _function.ArithmeticUtilsKt
The JVM class of 2P-Kt's expression evaluation functions.
Its static methods are wrapped by eval_as_expression and eval_as_arithmetic_expression.
ComputeRequest
module-attribute
¶
ComputeRequest = Compute.Request
A request to compute a logic function.
Members: signature, arguments (the evaluated arguments, a list of terms), context (the
tuprolog.solve.ExecutionContext of the solver), query (the expression, i.e. the struct of the
signature and arguments), request_issuing_instant, execution_max_duration (in
milliseconds), and reply_with(result), returning the ComputeResponse with result. Create
requests with compute_request.
ComputeResponse
module-attribute
¶
ComputeResponse = Compute.Response
The response of a logic function, holding its result, a term.
Create responses with compute_response, or ComputeRequest.reply_with.
AbstractLogicFunction
¶
A base class for logic functions written in Python: subclasses implement compute.
Examples:
>>> from tuprolog.core import integer
>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.prolog import prolog_solver
>>> class Arity(AbstractLogicFunction):
... def compute(self, request):
... return request.reply_with(integer(len(request.arguments)))
>>> solver = prolog_solver(libraries=library("my.lib", functions={"arity/3": Arity()}))
>>> solver.solve_once("X is arity(1, 2, 3)")["X"] # arguments are evaluated: numbers
3
compute
¶
compute(request: ComputeRequest) -> ComputeResponse
Computes the result of the function for request.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ComputeRequest
|
The compute request, with the evaluated arguments. |
required |
Returns:
| Type | Description |
|---|---|
ComputeResponse
|
The compute response, holding the result. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
Unless overridden by subclasses. |
logic_function
¶
logic_function(
callable: Callable[[ComputeRequest], ComputeResponse],
) -> LogicFunction
Creates a logic function from a Python function on compute requests.
Unlike function, the Python function sees the whole request, including the solver's
context, and works on terms. The exceptions it raises become logic errors (see
tuprolog.solve.primitive.python_error): 2P-Kt's are kept, any other one becomes a
system_error, which catch/3 can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callable
|
Callable[[ComputeRequest], ComputeResponse]
|
A function taking a |
required |
Returns:
| Type | Description |
|---|---|
LogicFunction
|
The logic function. |
Examples:
>>> from tuprolog.core import integer
>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.prolog import prolog_solver
>>> def count_arguments(request):
... return request.reply_with(integer(len(request.arguments)))
>>> count = logic_function(count_arguments)
>>> solver = prolog_solver(libraries=library("my.lib", functions={"count/2": count}))
>>> solver.solve_once("X is count(1, 2) * 10")["X"]
20
function
¶
function(callable: Callable) -> LogicFunction
Creates a logic function from a Python function on Python values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callable
|
Callable
|
A function taking the evaluated arguments, converted to Python values (see
|
required |
Returns:
| Type | Description |
|---|---|
LogicFunction
|
The logic function. |
Note
Exceptions raised by callable become logic errors, as in logic_function.
Examples:
>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.prolog import prolog_solver
>>> solver = prolog_solver(
... libraries=library("my.lib", functions={"twice/1": function(lambda x: 2 * x)})
... )
>>> solver.solve_once("X is twice(21)")["X"]
42
compute_request
¶
compute_request(
signature: Signature,
arguments: Iterable[Term],
context: ExecutionContext,
issuing_instant: int | None = None,
max_duration: int = MAX_TIMEOUT,
) -> ComputeRequest
Creates a compute request, e.g. to test logic functions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signature
|
Signature
|
The signature of the function. |
required |
arguments
|
Iterable[Term]
|
The arguments, as many as the arity of |
required |
context
|
ExecutionContext
|
The execution context of the solver. |
required |
issuing_instant
|
int | None
|
When the request is issued, in milliseconds (see
|
None
|
max_duration
|
int
|
The maximum duration of the computation, in milliseconds; none by default. |
MAX_TIMEOUT
|
Returns:
| Type | Description |
|---|---|
ComputeRequest
|
The compute request. |
Raises:
| Type | Description |
|---|---|
IllegalArgumentException
|
If the number of arguments does not match the arity. |
compute_response
¶
compute_response(result: Term) -> ComputeResponse
Creates a compute response, holding the result of a logic function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
result
|
Term
|
The result. |
required |
Returns:
| Type | Description |
|---|---|
ComputeResponse
|
The compute response. |
Examples:
>>> from tuprolog.core import integer
>>> compute_response(integer(1)).result
1
eval_as_expression
¶
eval_as_expression(
term: Term,
request: SolveRequest,
index: int | None = None,
) -> Term
Evaluates a term as an expression, with the functions of the solver, in a primitive.
Variables are left as they are; any other non-evaluable term raises an error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
term
|
Term
|
The term to evaluate, e.g. an argument of the request. |
required |
request
|
SolveRequest
|
The request of the primitive (see |
required |
index
|
int | None
|
The (0-based) index of the argument |
None
|
Returns:
| Type | Description |
|---|---|
Term
|
The value of the expression. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If a sub-term is not evaluable. |
eval_as_arithmetic_expression
¶
eval_as_arithmetic_expression(
term: Term,
request: SolveRequest,
index: int | None = None,
) -> Term
Evaluates a term as an arithmetic expression, as is/2 does, in a primitive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
term
|
Term
|
The term to evaluate, e.g. an argument of the request. |
required |
request
|
SolveRequest
|
The request of the primitive (see |
required |
index
|
int | None
|
The (0-based) index of the argument |
None
|
Returns:
| Type | Description |
|---|---|
Term
|
The number the expression evaluates to (a |
Raises:
| Type | Description |
|---|---|
LogicError
|
If the expression is not instantiated or not evaluable, or does not evaluate to a number. |
Examples:
>>> from tuprolog.core import integer, substitution
>>> from tuprolog.solve.library import library
>>> from tuprolog.solve.primitive import primitive
>>> from tuprolog.solve.prolog import prolog_solver
>>> @primitive
... def double(request):
... value = eval_as_arithmetic_expression(request.arguments[0], request, 0)
... result = integer(value.int_value * 2)
... yield request.reply_success(substitution({request.arguments[1]: result}))
>>> solver = prolog_solver(libraries=library("my.lib", primitives={"double/2": double}))
>>> solver.solve_once("double(1 + 2, X)")["X"]
6