Skip to content

Core

tuprolog.core

Logic terms and clauses: the data model of logic programming.

Every piece of data a logic program manipulates is a term (Term). Terms are immutable trees, whose kinds are:

  • variables (Var), placeholders for terms yet to be determined, e.g. X or _;
  • constants (Constant), carrying a value and no sub-terms:
    • atoms (Atom), symbolic names, e.g. bart, 'Hello World', []; true, false and fail are atoms too (Truth);
    • numbers (Numeric): arbitrary-precision integers (Integer, e.g. 42) and reals (Real, e.g. 3.14);
  • structures (Struct), a.k.a. compound terms: a functor (a name) applied to zero or more arguments (terms), e.g. parent(homer, bart), whose functor is parent and arity is 2; their indicator is parent/2. Some structures have a dedicated syntax and type:
    • lists (List): [a, b, c], i.e. chains of cells (Cons) ending in the empty list [] (EmptyList), or in another term for partial lists, e.g. [H | T];
    • tuples (Tuple): (a, b, c), i.e. conjunctions;
    • blocks (Block): {a, b, c};
    • clauses (Clause), the statements of logic programs: rules (Rule, Head :- Body, i.e. "Head holds if Body does"), facts (Fact, rules whose body is true, written Head.), and directives (Directive, :- Body, commands run when a program is loaded);
    • indicators (Indicator): name/arity, denoting predicates or functors.

A term is ground when it contains no variables. Variables are identified by more than their name: each var("X") call creates a new variable, printed as X_<n> (its complete name), so that equally named variables of different clauses never clash. Use the same Var object (or a Scope) wherever a variable must occur more than once.

A substitution (Substitution) maps variables to terms, e.g. {X = bart}: applying it to a term replaces the variables with their values. Successful substitutions are unifiers (Substitution.Unifier); the failed one (Substitution.Fail) means that no assignment exists, e.g. when unification fails (see tuprolog.unify).

This package offers:

  • the JVM types of terms and substitutions, whose methods are callable with Python names, e.g. term.is_ground, struct.functor, struct.args, term.apply(substitution);
  • Pythonic factories (atom, var, struct, integer, real, logic_list, rule, substitution, ...), converting Python values into terms where terms are expected;
  • the conversions between Python values and terms (to_term, to_python);
  • formatters, rendering terms as text (default_formatter, pretty_expressions_formatter, ...).

Sub-packages: tuprolog.core.operators (operators, e.g. + in 1 + 2) and tuprolog.core.parsing (terms from text).

Examples:

>>> from tuprolog.core import atom, logic_list, struct, to_python, var
>>> X = var("X")
>>> term = struct("parent", X, "bart")
>>> term
parent(X_..., bart)
>>> term.functor, term.arity, term.is_ground
('parent', 2, False)
>>> term[1]
bart
>>> to_python(logic_list(1, 2.5, "a"))
[1, 2.5, 'a']
See Also

2P-Kt's term hierarchy: https://tuprolog.github.io/2p-kt/reference/term-hierarchy/, and variables' scoping: https://tuprolog.github.io/2p-kt/explanation/variables-and-scoping/.

EMPTY_UNIFIER module-attribute

EMPTY_UNIFIER: Unifier = substitution()

The empty unifier {}, assigning no variables: applying it leaves terms unchanged.

FAILED_SUBSTITUTION module-attribute

FAILED_SUBSTITUTION: Fail = failed()

The failed substitution, meaning that no assignment of variables exists (see failed).

Applicable module-attribute

Applicable = _core.Applicable

Terms (and other objects) to which a substitution can be applied, i.e. Term and its sub-types.

apply(substitution) returns a copy of the object where the variables bound by the substitution are replaced by their values (in Python, also term[substitution]); fresh_copy() returns a copy where every variable is replaced by a brand-new one.

Note

2P-Kt's it.unibo.tuprolog.core.Applicable.

Atom module-attribute

Atom = _core.Atom

A constant symbolic name, e.g. bart, 'Hello World', [], +.

An atom is both a Constant, whose value is its name, and a structure with no arguments, whose functor is its name (and whose arity is 0). Atoms needing quotes in Prolog syntax (e.g. those starting with an uppercase letter or containing spaces) are printed quoted.

Some atoms have a dedicated type: [] is the EmptyList, {} the EmptyBlock, and true, false and fail are Truths.

Build atoms with tuprolog.core.atom (or Atom.of). Members: value (the name, a string).

Examples:

>>> from tuprolog.core import atom
>>> atom("bart"), atom("Hello World")
(bart, 'Hello World')
>>> atom("bart").value
'bart'
>>> atom("bart").is_atom, atom("bart").arity
(True, 0)

Block module-attribute

Block = _core.Block

A block, i.e. a curly-braced term: {a, b, c}, commonly used in grammar rules.

A block wrapping two or more terms folds them into a tuple, i.e. {a, b, c} is the structure {}((a, b, c)); the block wrapping no terms is the EmptyBlock {}. As other Recursive terms, blocks are iterable (and sized) over the terms they wrap.

Build blocks with tuprolog.core.block (or tuprolog.core.empty_block).

Examples:

>>> from tuprolog.core import atom, block
>>> b = block(atom("a"), atom("b"))
>>> b, len(b), list(b)
({a, b}, 2, [a, b])

Clause module-attribute

Clause = _core.Clause

A clause, i.e. a statement of a logic program: a structure with functor :-.

A clause is either a rule (Rule), Head :- Body, meaning that Head holds if Body does, or a directive (Directive), :- Body, a goal run when the program is loaded. Facts (Fact) are rules whose body is true, written Head.. A theory (see tuprolog.theory) is a sequence of clauses.

The body is a goal, i.e. a callable term, possibly a conjunction (a Tuple) of goals, as in grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

Build clauses with tuprolog.core.clause (or the more specific rule, fact, directive). Members: head (a Struct, or None for directives), body (a Term), body_items (the goals of the body), body_size, is_rule, is_fact, is_directive, is_well_formed, and methods returning modified copies, e.g. set_head(head), set_body(body), set_head_args(*args), insert_head_arg(index, arg), set_body_items(*goals).

Examples:

>>> from tuprolog.core import rule, struct, variables
>>> X, Y, Z = variables("X", "Y", "Z")
>>> r = rule(
...     struct("grandparent", X, Z), struct("parent", X, Y), struct("parent", Y, Z)
... )
>>> r.head, r.body_size
(grandparent(X_..., Z_...), 2)
>>> r.is_rule, r.is_fact, r.is_directive
(True, False, False)

Cons module-attribute

Cons = _core.Cons

A non-empty list cell: a structure with functor . and two arguments, its head (the first item) and its tail (the rest of the list).

[a, b] is '.'(a, '.'(b, [])), i.e. a chain of cells ending in the EmptyList. When a chain ends in another term (e.g. a variable), the list is partial, e.g. [a | T].

Build cells with tuprolog.core.cons (or logic_list, logic_list_from).

Examples:

>>> from tuprolog.core import atom, cons, logic_list
>>> cell = cons(atom("a"), logic_list("b", "c"))
>>> cell, cell.head, cell.tail
([a, b, c], a, [b, c])

Constant module-attribute

Constant = _core.Constant

A term carrying a single value and no sub-terms: an Atom (whose value is a string) or a Numeric (whose value is a number). Constants are always ground.

Members: value, is_constant.

Directive module-attribute

Directive = _core.Directive

A clause without head, :- Body, e.g. :- dynamic(counter/1).: a goal to run when the program including it is loaded, rather than knowledge to query.

Build directives with tuprolog.core.directive (or clause(None, ...)).

Examples:

>>> from tuprolog.core import directive, struct
>>> d = directive(struct("initialization", "main"))
>>> d, d.head, d.body
(:- initialization(main), None, initialization(main))

Empty module-attribute

Empty = _core.Empty

The type of the two "empty" atoms: the EmptyList [] and the EmptyBlock {}.

EmptyBlock module-attribute

EmptyBlock = _core.EmptyBlock

The empty block, i.e. the atom {}, a singleton (see tuprolog.core.empty_block).

EmptyList module-attribute

EmptyList = _core.EmptyList

The empty list, i.e. the atom [], a singleton (see tuprolog.core.empty_logic_list).

Every well-formed list ends with it.

Fact module-attribute

Fact = _core.Fact

A rule whose body is true, written Head., e.g. parent(homer, bart).: an unconditional truth.

Rule factories return a fact whenever the body is true. Build facts with tuprolog.core.fact.

Examples:

>>> from tuprolog.core import fact, struct
>>> f = fact(struct("parent", "homer", "bart"))
>>> f, f.head, f.body, f.is_fact
(parent(homer, bart) :- true, parent(homer, bart), true, True)

Formatter module-attribute

Formatter = _core.Formatter

An object turning other objects into strings, by its format(obj) method.

TermFormatter is the formatter of terms.

Indicator module-attribute

Indicator = _core.Indicator

A predicate (or functor) indicator, Name/Arity, e.g. parent/2: the term identifying a predicate (or a functor) by its name and its number of arguments.

Build indicators with tuprolog.core.indicator. Members: indicated_name (a string), indicated_arity (an int), name_term, arity_term, is_well_formed (whether the name is an atom and the arity a non-negative integer).

Examples:

>>> from tuprolog.core import indicator
>>> i = indicator("parent", 2)
>>> i, i.indicated_name, i.indicated_arity
(parent/2, 'parent', 2)

Integer module-attribute

Integer = _core.Integer

An integer number, e.g. 42, of arbitrary precision (never overflowing).

Build integers with tuprolog.core.integer (or numeric). Members: value and int_value (the value, a Python int), decimal_value (a decimal.Decimal), to_int(), to_float().

Examples:

>>> from tuprolog.core import integer
>>> n = integer("123456789012345678901234567890")
>>> n, n.value + 1
(123456789012345678901234567890, 123456789012345678901234567891)

List module-attribute

List = _core.List

A logic list: either the EmptyList [], or a Cons cell [Head | Tail].

[a, b, c] is a chain of cells ending in []: it is well-formed. A chain ending in another term, as [a, b | T], is a partial list. Lists are iterable (and sized) over their items, the last item of a partial list being its final tail.

Build lists with tuprolog.core.logic_list, logic_list_from, cons, or empty_logic_list. Members: is_well_formed, unfolded (all items, including the final [] of well-formed lists), to_iterable(), and those of Recursive terms.

Examples:

>>> from tuprolog.core import logic_list, logic_list_from, var
>>> logic_list(1, 2, 3), len(logic_list(1, 2, 3)), list(logic_list(1, 2, 3))
([1, 2, 3], 3, [1, 2, 3])
>>> partial = logic_list_from([1, 2], last=var("T"))
>>> partial, partial.is_well_formed
([1, 2 | T_...], False)

Numeric module-attribute

Numeric = _core.Numeric

A number: an Integer or a Real, both of arbitrary precision.

Integers and reals are distinct terms, even when their values are equal (1 and 1.0), as in Prolog. Build numbers with tuprolog.core.numeric (or integer, real). Members: int_value (a Python int), decimal_value (a decimal.Decimal), to_int(), to_float(), compare_value_to(other) (comparing values, regardless of the kind of number).

Examples:

>>> from tuprolog.core import integer, real
>>> integer(1) == real(1.0), integer(1).compare_value_to(real(1.0))
(False, 0)
>>> real(2.5).to_int(), integer(3).to_float()
(2, 3.0)

Real module-attribute

Real = _core.Real

A real number, e.g. 3.14, of arbitrary precision (a decimal, not a binary floating-point number).

Build reals with tuprolog.core.real (or numeric). Members: value and decimal_value (the value, a decimal.Decimal), int_value, to_int(), to_float().

Examples:

>>> from tuprolog.core import real
>>> real(0.1), real(0.1).value, real("3.14").to_float()
(0.1, Decimal('0.1'), 3.14)

Recursive module-attribute

Recursive = _core.Recursive

A structure representing a sequence of terms folded into nested binary structures: a List (functor .), a Tuple (functor ,) or a Block (functor {}).

Python protocols: len(term) is the number of items, and iter(term) iterates over them. Members: size, unfolded (the items, as a list), lazily_unfolded (the items, lazily), to_iterable().

Rule module-attribute

Rule = _core.Rule

A clause with a head, Head :- Body: "Head holds if Body does", e.g. grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

When the body is true the rule is a Fact. Build rules with tuprolog.core.rule. See Clause for the members.

Examples:

>>> from tuprolog.core import rule, struct, var
>>> X = var("X")
>>> r = rule(struct("mortal", X), struct("human", X))
>>> r, r.head, r.body
(mortal(X_...) :- human(X_...), mortal(X_...), human(X_...))

Scope module-attribute

Scope = _core.Scope

A factory of terms remembering the variables it creates, by name.

As var("X") creates a new variable at each call, building a term where a variable occurs more than once requires reusing the same Var object: a scope does it automatically, as asking it for a variable it already created returns that variable. Its factories mirror those of tuprolog.core (var, atom, struct, integer, real, numeric, truth, list, list_from, tuple, cons, block, clause, rule, fact, directive, indicator), without converting Python values: pass them terms.

Python protocols: name in scope tells whether the scope created a variable named name, and scope[name] returns it (or None). Members: variables (a map from names to variables), anonymous() (a new anonymous variable: var("_") returns the same variable at each call).

Build scopes with tuprolog.core.scope.

Examples:

>>> from tuprolog.core import scope
>>> s = scope()
>>> s.struct("member", s.var("H"), s.list_from([s.var("_")], s.var("T")))
member(H_..., [__... | T_...])
>>> s.var("H") == s["H"], "H" in s, "X" in s
(True, True, False)

Struct module-attribute

Struct = _core.Struct

A structure, a.k.a. compound term: a functor (a name) applied to zero or more arguments (terms), e.g. parent(homer, bart), whose functor is parent and arity is 2.

Most terms are structures under the hood: atoms (no arguments), lists, tuples, blocks, clauses and indicators, which have dedicated types. Structures are immutable: "modifying" methods return new structures.

Build structures with tuprolog.core.struct. Members: functor, arity, args (the arguments), indicator (functor/arity), get_arg_at(i), and methods returning modified copies, e.g. set_functor(name), set_args(*args), add_first(arg), add_last(arg), insert_at(i, arg).

Python protocols: struct[i] is the i-th argument, and struct[i, j, ...] is struct[i][j]....

Examples:

>>> from tuprolog.core import atom, struct
>>> s = struct("f", "a", struct("g", "b"))
>>> s.functor, s.arity, s.indicator
('f', 2, f/2)
>>> s[0], s[1, 0]
(a, b)
>>> s.set_functor("h"), s.add_last(atom("c"))
(h(a, g(b)), f(a, g(b), c))

Substitution module-attribute

Substitution = _core.Substitution

A substitution, i.e. an assignment of terms to variables, e.g. {X = bart, Y = 1}.

A substitution is either a unifier (Substitution.Unifier), a successful (possibly empty) assignment, or the failed substitution (Substitution.Fail), meaning that no assignment exists, e.g. because two terms do not unify (see tuprolog.unify). Applying a unifier to a term replaces the assigned variables with their values (term.apply(substitution), or term[substitution]).

Substitutions are immutable mappings from Vars to Terms: substitution[var], var in substitution, len(substitution) and iteration work as for dictionaries. Combining two substitutions with + merges them, failing when they assign different values to a variable; - removes variables. Members: is_success, is_failed, get_by_name(name), apply_to(term), filter(...).

Build substitutions with tuprolog.core.substitution, unifier, failed, or use the constants EMPTY_UNIFIER and FAILED_SUBSTITUTION.

Examples:

>>> from tuprolog.core import atom, struct, substitution, var
>>> X, Y = var("X"), var("Y")
>>> s = substitution({X: atom("a")})
>>> s[X], X in s, len(s), s.is_success
(a, True, 1, True)
>>> struct("f", X, Y)[s]
f(a, Y_...)
>>> (s + substitution({X: atom("b")})).is_failed
True

Term module-attribute

Term = _core.Term

The base type of all logic terms: variables (Var), constants (Atoms and Numerics), and structures (Struct, including lists, tuples, blocks and clauses).

Terms are immutable trees: methods "changing" a term return a new one. Terms are compared by == (variables being equal only to themselves) and ordered by the standard order of terms (variables, then numbers, then atoms, then structures), so < and sorted work.

Members, callable on any term:

  • type checks (properties): is_var, is_constant, is_atom, is_number, is_integer, is_real, is_struct, is_list, is_cons, is_empty_list, is_tuple, is_block, is_clause, is_rule, is_fact, is_directive, is_truth, is_true, is_ground, ...;
  • casts: cast_to_<type>() (e.g. cast_to_struct(), raising a Java ClassCastException on mismatch) and as_<type>() (e.g. as_var(), returning None on mismatch);
  • variables (the variables occurring in the term, lazily, repetitions included);
  • apply(substitution) (in Python, also term[substitution]), fresh_copy() (a copy with new variables);
  • structurally_equals(other) (equality up to variables' renaming), accept(visitor) (see TermVisitor);
  • tags (metadata attached to the term, see tuprolog.utils.Taggable).

str(term) and repr(term) render the term in Prolog syntax; see TermFormatter for other renderings.

Examples:

>>> from tuprolog.core import atom, integer, struct, var
>>> X = var("X")
>>> t = struct("f", X, "a")
>>> t.is_struct, t.is_ground, t.as_var()
(True, False, None)
>>> list(t.variables)
[X_...]
>>> sorted([atom("b"), integer(1), struct("f", "a"), atom("a")])
[1, a, b, f(a)]
>>> t.structurally_equals(struct("f", var("Y"), "a"))
True
See Also

2P-Kt's term hierarchy: https://tuprolog.github.io/2p-kt/reference/term-hierarchy/.

TermComparator module-attribute

TermComparator = _core.TermComparator

A comparator of terms (a JVM java.util.Comparator), following the standard order of terms: variables, then numbers, then atoms, then structures (by arity, then functor, then arguments).

Implement custom comparators in Python by subclassing AbstractTermComparator.

TermConvertible module-attribute

TermConvertible = _core.TermConvertible

Objects convertible into terms, by their to_term() method (e.g. operators, see tuprolog.core.operators.Operator).

Implement it in Python by subclassing AbstractTermConvertible.

TermFormatter module-attribute

TermFormatter = _core.TermFormatter

A formatter rendering terms as text, by its format(term) method.

Formatters differ in how they render variables (by complete name, e.g. X_0, by name, e.g. X, or as _<n>), operators (canonically, e.g. '+'(1, 2), or as expressions, e.g. 1 + 2), and whether they quote atoms when needed. Build formatters with tuprolog.core.default_formatter, canonical_formatter, readable_formatter, pretty_variables_formatter, or pretty_expressions_formatter.

Examples:

>>> from tuprolog.core import pretty_expressions_formatter, struct, var
>>> pretty_expressions_formatter().format(struct("+", var("X"), 1))
'X + 1'

TagsFormattingOptions module-attribute

TagsFormattingOptions = TermFormatter.TagsFormattingOptions

Options for rendering the tags of terms (see Term.tags), used by formatters.

Its constructor takes (all optional): showTags (whether to render tags, default false), delimiters (a Kotlin pair of strings, default < and >), separator (default ", "), showKeys (default true), showDelimitersIfEmpty (default false), keyFilter (a predicate over tag names), tagFormatter (a Formatter of tag values). Its copy(...) method takes them all, positionally.

DEFAULT_TAGS_FORMATTING_OPTIONS module-attribute

DEFAULT_TAGS_FORMATTING_OPTIONS: TagsFormattingOptions = (
    TagsFormattingOptions()
)

The default TagsFormattingOptions, not rendering tags.

Terms module-attribute

Terms = _core.Terms

Constants shared by the term types, e.g. reserved functors and the patterns of well-formed names.

TermVisitor module-attribute

TermVisitor = _core.TermVisitor

A visitor of terms (the Visitor pattern): term.accept(visitor) calls the visitX method matching the term's type (visitVar, visitAtom, visitStruct, visitList, ...).

Each visitX method defaults to the method of the parent type (e.g. visitAtom to visitStruct, and finally visitTerm to defaultValue), so implementations override just the methods they need, plus defaultValue. Implement visitors in Python by subclassing AbstractTermVisitor.

Truth module-attribute

Truth = _core.Truth

A truth value: one of the atoms true, false and fail (the constants TRUE, FALSE, FAIL).

Build them with tuprolog.core.truth, or atom("true") etc. Members: is_true, is_fail.

Tuple module-attribute

Tuple = _core.Tuple

A tuple, i.e. a conjunction: (a, b, c), a structure with functor , and two arguments, left and right, where tuples of more items nest on the right ((a, (b, c)) is (a, b, c)).

The bodies of clauses with many goals are tuples. As other Recursive terms, tuples are iterable (and sized) over their items.

Build tuples with tuprolog.core.logic_tuple.

Examples:

>>> from tuprolog.core import logic_tuple
>>> t = logic_tuple(1, 2, 3)
>>> t, t.left, t.right, list(t)
((1, 2, 3), 1, (2, 3), [1, 2, 3])

Var module-attribute

Var = _core.Var

A logic variable: a placeholder for a term yet to be determined, e.g. X.

A variable has a name (e.g. X), but its identity is its complete_name (e.g. X_0), pairing the name with a unique number: each var("X") call creates a new variable, different from other variables named X, so that variables of different clauses never clash. Reuse the same Var object (or a Scope) wherever a variable must occur more than once. Variables named _ are anonymous: each occurrence is a different variable.

Build variables with tuprolog.core.var or variables. Members: name, complete_name, is_anonymous.

Examples:

>>> from tuprolog.core import var
>>> X = var("X")
>>> X.name, X == X, X == var("X")
('X', True, False)
>>> var("_").is_anonymous
True

Variabled module-attribute

Variabled = _core.Variabled

Objects containing variables, i.e. terms: their variables member lists the variables occurring in them.

TRUE module-attribute

TRUE = Truth.TRUE

The atom true, i.e. the goal that always succeeds.

FALSE module-attribute

FALSE = Truth.FALSE

The atom false, i.e. a goal that always fails.

FAIL module-attribute

FAIL = Truth.FAIL

The atom fail, i.e. a goal that always fails.

AbstractTermComparator

A base class for term comparators implemented in Python.

Override compare(first, second), returning a negative int, zero, or a positive int when first precedes, equals, or follows second. Instances are TermComparators, usable wherever 2P-Kt expects one.

Examples:

>>> from tuprolog.core import AbstractTermComparator, atom
>>> class ByLength(AbstractTermComparator):
...     def compare(self, first, second):
...         return len(str(first)) - len(str(second))
>>> ByLength().compare(atom("abc"), atom("z")) > 0
True

AbstractTermConvertible

A base class for Python objects convertible into terms: override toTerm().

Instances are TermConvertibles, usable wherever 2P-Kt expects one.

AbstractTermVisitor

A base class for term visitors implemented in Python (see TermVisitor).

Override defaultValue(term), the result for the terms whose visitX method is not overridden, and any visitX(term) method (visitVar, visitAtom, visitStruct, visitList, ...): the ones not overridden delegate to the method of the parent type, as in 2P-Kt. Then call term.accept(visitor).

Examples:

>>> from tuprolog.core import AbstractTermVisitor, atom, integer, var
>>> class Kind(AbstractTermVisitor):
...     def defaultValue(self, term):
...         return "other"
...     def visitAtom(self, term):
...         return "atom"
...     def visitVar(self, term):
...         return "variable"
>>> [t.accept(Kind()) for t in (atom("a"), var("X"), integer(1))]
['atom', 'variable', 'other']

atom

atom(string: str) -> Atom

Creates an atom, i.e. a constant symbolic name.

Parameters:

Name Type Description Default
string str

the name of the atom, e.g. "bart". The names "[]", "{}", "true", "false" and "fail" give the corresponding special atoms (tuprolog.core.EmptyList, tuprolog.core.EmptyBlock, tuprolog.core.Truth).

required

Returns:

Type Description
Atom

The atom.

Examples:

>>> atom("bart"), atom("Hello World"), atom("[]").is_empty_list
(bart, 'Hello World', True)
Note

Wraps 2P-Kt's Atom.of.

block

block(*terms: Term | Iterable[Term]) -> Block

Creates a block, i.e. a curly-braced term such as {a, b}.

Parameters:

Name Type Description Default
*terms Term | Iterable[Term]

the terms in the block (terms, not Python values), either as many arguments or as a single iterable. No terms give the empty block {}.

()

Returns:

Type Description
Block

The block.

Examples:

>>> block(atom("a"), atom("b")), block([atom("a")]), block()
({a, b}, {a}, {})
Note

Wraps 2P-Kt's Block.of.

clause

clause(
    head: Term | None = None, *body: Term | Iterable[Term]
) -> Clause

Creates a clause: a rule (head :- body), a fact, or a directive (:- body).

Parameters:

Name Type Description Default
head Term | None

the head of the clause (a structure or an atom), or None for a directive.

None
*body Term | Iterable[Term]

the goals of the body (terms), either as many arguments or as a single iterable; many goals are joined in a conjunction. No goals give a fact (with a head) or an error (without a head).

()

Returns:

Type Description
Clause

The clause: a tuprolog.core.Rule (a tuprolog.core.Fact when the body is empty or

Clause

true), or a tuprolog.core.Directive when head is None.

Raises:

Type Description
IllegalArgumentException

if both the head and the body are missing.

Examples:

>>> clause(struct("p"), atom("q"), atom("r"))
p :- (q, r)
>>> clause(struct("p")), clause(None, atom("q"))
(p :- true, :- q)
Note

Wraps 2P-Kt's Clause.of.

empty_logic_list

empty_logic_list() -> EmptyList

Returns the empty list [].

Returns:

Type Description
EmptyList

The empty list, a singleton.

Examples:

>>> empty_logic_list(), empty_logic_list().is_empty_list
([], True)

cons

cons(head: Term, tail: Term | None = None) -> Cons

Creates a list cell, i.e. the list [head | tail].

Parameters:

Name Type Description Default
head Term

the first item (a term).

required
tail Term | None

the rest of the list (a term, usually a list or a variable). If None, the list [head].

None

Returns:

Type Description
Cons

The list cell.

Examples:

>>> cons(atom("a")), cons(atom("a"), logic_list("b")), cons(atom("a"), var("T"))
([a], [a, b], [a | T_...])
Note

Wraps 2P-Kt's Cons.of and Cons.singleton.

directive

directive(*goals: Term | Iterable[Term]) -> Directive

Creates a directive, i.e. a clause without head, :- goal1, ..., goalN.

Parameters:

Name Type Description Default
*goals Term | Iterable[Term]

the goals (terms), either as many arguments or as a single iterable: at least one.

()

Returns:

Type Description
Directive

The directive.

Examples:

>>> directive(struct("dynamic", indicator("counter", 1)))
:- dynamic(counter/1)
Note

Wraps 2P-Kt's Directive.of.

empty_block

empty_block() -> Block

Returns the empty block {}.

Returns:

Type Description
Block

The empty block, a singleton.

Examples:

>>> empty_block(), empty_block().is_empty_block
({}, True)

fact

fact(struct: Term) -> Fact

Creates a fact, i.e. a clause head :- true, stating that head holds unconditionally.

Parameters:

Name Type Description Default
struct Term

the head of the fact (a structure or an atom).

required

Returns:

Type Description
Fact

The fact.

Examples:

>>> fact(struct("parent", "homer", "bart"))
parent(homer, bart) :- true
Note

Wraps 2P-Kt's Fact.of.

indicator

indicator(name: str | Term, arity: int | Term) -> Indicator

Creates an indicator, name/arity, identifying a predicate or a functor.

Parameters:

Name Type Description Default
name str | Term

the name, as a string or a term (usually an atom; a variable for patterns).

required
arity int | Term

the number of arguments, as an int or a term (usually an integer; a variable for patterns).

required

Returns:

Type Description
Indicator

The indicator.

Examples:

>>> indicator("parent", 2), indicator(atom("parent"), integer(2))
(parent/2, parent/2)
Note

Wraps 2P-Kt's Indicator.of.

integer

integer(value: int | BigInteger | str) -> Integer

Creates an integer number, of arbitrary precision.

Parameters:

Name Type Description Default
value int | BigInteger | str

the value, as a Python int (booleans count as 0 and 1), a tuprolog.math.BigInteger, or a string of digits (e.g. "42", or "0x1F" in hexadecimal).

required

Returns:

Type Description
Integer

The integer.

Raises:

Type Description
TypeError

if value has another type (e.g. a float).

Examples:

>>> integer(42), integer("123456789012345678901234567890"), integer("0x1F")
(42, 123456789012345678901234567890, 31)
Note

Wraps 2P-Kt's Integer.of.

real

real(value: float | BigDecimal | str | Decimal) -> Real

Creates a real number, of arbitrary precision.

Parameters:

Name Type Description Default
value float | BigDecimal | str | Decimal

the value, as a Python float (its shortest representation is kept, e.g. 0.1 stays 0.1), a decimal.Decimal, a string (e.g. "3.14", "1e3"), a Python int, or a tuprolog.math.BigDecimal.

required

Returns:

Type Description
Real

The real.

Examples:

>>> real(0.1), real("3.14"), real(1), real(Decimal("2.50"))
(0.1, 3.14, 1.0, 2.5)
Note

Wraps 2P-Kt's Real.of; see tuprolog.math.big_decimal for the conversion.

numeric

numeric(
    value: BigInteger | BigDecimal | str | float | Decimal,
) -> Numeric

Creates a number, integer or real depending on value.

Parameters:

Name Type Description Default
value BigInteger | BigDecimal | str | float | Decimal

the value. Python ints (and tuprolog.math.BigIntegers) give integers; floats, decimal.Decimals (and tuprolog.math.BigDecimals) give reals; strings are parsed, giving an integer or a real by their syntax.

required

Returns:

Type Description
Numeric

The number, a tuprolog.core.Integer or a tuprolog.core.Real.

Raises:

Type Description
NumberFormatException

if value is a string not representing a number.

Examples:

>>> numeric(3), numeric(1.5), numeric("2"), numeric("2.5")
(3, 1.5, 2, 2.5)
>>> numeric("2").is_integer, numeric("2.5").is_real
(True, True)
>>> numeric("1e3")  # reals are normalized as by `real`
1000.0
Note

Wraps 2P-Kt's Numeric.of.

to_term

to_term(
    value: Term
    | str
    | bool
    | float
    | Decimal
    | list
    | tuple,
) -> Term

Converts a Python value into a term.

Strings become atoms, booleans truths (true/false), ints integers, floats and decimal.Decimals reals, lists logic lists, and tuples logic tuples (i.e. conjunctions (a, b), where a trailing nested tuple flattens, as (a, (b, c)) is (a, b, c); a 1-tuple gives its item). The items of lists and tuples are converted as well; terms are returned as they are. to_python is its inverse.

Parameters:

Name Type Description Default
value Term | str | bool | float | Decimal | list | tuple

the value to convert.

required

Returns:

Type Description
Term

The term.

Raises:

Type Description
TypeError

if value cannot be converted (e.g. None, a dict, or the empty tuple).

Examples:

>>> to_term("bart"), to_term(True), to_term(42), to_term(2.5)
(bart, true, 42, 2.5)
>>> to_term([1, "a", (2, 3)])
[1, a, (2, 3)]

to_python

to_python(term: Term) -> Any

Converts a term into a Python value, as the inverse of to_term.

Truths become booleans (fail too becomes False), integers ints, reals floats (possibly losing precision), atoms strings ([] gives the empty list, being a list), well-formed lists lists, and tuples tuples, converting their items as well. Other terms (e.g. variables, compound terms, partial lists) are returned as they are.

Parameters:

Name Type Description Default
term Term

the term to convert.

required

Returns:

Type Description
Any

The Python value, or term itself when it has no Python counterpart.

Examples:

>>> to_python(logic_list(1, 2.5, "a", truth(True)))
[1, 2.5, 'a', True]
>>> to_python(logic_tuple(1, 2)), to_python(struct("f", "a"))
((1, 2), f(a))

rule

rule(head: Struct, *body: Term | Iterable[Term]) -> Rule

Creates a rule, head :- body, i.e. "head holds if body does".

Parameters:

Name Type Description Default
head Struct

the head (a structure or an atom).

required
*body Term | Iterable[Term]

the goals of the body (terms), either as many arguments or as a single iterable; many goals are joined in a conjunction. No goals, or just true, give a fact.

()

Returns:

Type Description
Rule

The rule (a tuprolog.core.Fact when the body is empty or true).

Examples:

>>> X, Y, Z = variables("X", "Y", "Z")
>>> rule(struct("grandparent", X, Z), struct("parent", X, Y), struct("parent", Y, Z))
grandparent(X_..., Z_...) :- (parent(X_..., Y_...), parent(Y_..., Z_...))
>>> rule(struct("p")).is_fact
True
Note

Wraps 2P-Kt's Rule.of.

struct

struct(
    functor: str, *args: Term | Iterable[Term]
) -> Struct

Creates a structure, i.e. a compound term functor(arg1, ..., argN).

The arguments are converted with to_term, so Python values are accepted. Structures with a dedicated type come out with that type, e.g. struct(",", "a", "b") is a tuprolog.core.Tuple and struct("f") is the atom f.

Parameters:

Name Type Description Default
functor str

the name of the structure.

required
*args Term | Iterable[Term]

the arguments, either as many arguments or as a single iterable (a list is unpacked: wrap it, as in struct("f", [[1, 2]]), to pass a logic list as the only argument).

()

Returns:

Type Description
Struct

The structure.

Examples:

>>> struct("parent", "homer", "bart"), struct("f", 1, 2.5, var("X"))
(parent(homer, bart), f(1, 2.5, X_...))
>>> struct("f", ["a", "b"]), struct("f", [["a", "b"]])
(f(a, b), f([a, b]))
Note

Wraps 2P-Kt's Struct.of.

truth

truth(boolean: bool) -> Truth

Creates a truth value, i.e. the atom true or false.

Parameters:

Name Type Description Default
boolean bool

the truth value (any truthy or falsy value).

required

Returns:

Type Description
Truth

tuprolog.core.TRUE or tuprolog.core.FALSE.

Examples:

>>> truth(True), truth(False)
(true, false)
Note

Wraps 2P-Kt's Truth.of.

logic_list

logic_list(*items: Term | Iterable[Term]) -> List

Creates a well-formed logic list, e.g. [1, 2, 3].

The items are converted with to_term, so Python values are accepted.

Parameters:

Name Type Description Default
*items Term | Iterable[Term]

the items, either as many arguments or as a single iterable. No items give [].

()

Returns:

Type Description
List

The list.

Examples:

>>> logic_list(1, 2, 3), logic_list(["a", "b"]), logic_list()
([1, 2, 3], [a, b], [])
Note

Wraps 2P-Kt's List.of.

logic_list_from

logic_list_from(
    items: Iterable[Term], last: Term | None = None
) -> List

Creates a logic list from an iterable, ending with a given tail rather than [].

The items (and last) are converted with to_term, so Python values are accepted. Use logic_list for well-formed lists.

Parameters:

Name Type Description Default
items Iterable[Term]

the items.

required
last Term | None

the final tail, giving the list [item1, ..., itemN | last] (e.g. a partial list, when last is a variable, or a well-formed list, when last is []). If None, the last item is the final tail, i.e. the list is [item1, ..., itemN-1 | itemN].

None

Returns:

Type Description
List

The list.

Examples:

>>> logic_list_from([1, 2], last=var("T")), logic_list_from([1, 2], last=empty_logic_list())
([1, 2 | T_...], [1, 2])
>>> logic_list_from([1, logic_list(2, 3)])
[1, 2, 3]
Note

Wraps 2P-Kt's List.from.

logic_tuple

logic_tuple(
    first: Term,
    second: Term,
    *others: Term | Iterable[Term],
) -> Tuple

Creates a logic tuple, i.e. a conjunction (first, second, ...).

The items are converted with to_term, so Python values are accepted. A last item that is a tuple flattens, as (a, (b, c)) is (a, b, c).

Parameters:

Name Type Description Default
first Term

the first item.

required
second Term

the second item.

required
*others Term | Iterable[Term]

the other items, either as many arguments or as a single iterable.

()

Returns:

Type Description
Tuple

The tuple.

Examples:

>>> logic_tuple(1, 2, 3), logic_tuple("a", "b", ["c", "d"])
((1, 2, 3), (a, b, c, d))
Note

Wraps 2P-Kt's Tuple.of.

var

var(name: str) -> Var

Creates a new logic variable.

Each call creates a different variable, even with the same name: its complete name (e.g. X_0) adds a unique number to name. Reuse the returned object (or a scope) wherever the variable must occur more than once.

Parameters:

Name Type Description Default
name str

the name of the variable, e.g. "X"; "_" gives an anonymous variable. Names that are not valid Prolog variable names (e.g. lowercase) are printed between backticks.

required

Returns:

Type Description
Var

The variable.

Examples:

>>> X = var("X")
>>> X.name, X == X, X == var("X")
('X', True, False)
Note

Wraps 2P-Kt's Var.of.

unifier

unifier(
    assignments: Mapping[Var, Any] | None = None,
) -> Unifier

Creates a unifier, i.e. a successful substitution, from variable-term assignments.

Parameters:

Name Type Description Default
assignments Mapping[Var, Any] | None

a mapping from variables to terms (or Python values, converted by to_term). If None, the empty unifier.

None

Returns:

Type Description
Unifier

The unifier.

Examples:

>>> X = var("X")
>>> unifier({X: atom("a")})[X], unifier({X: 1})[X], unifier()
(a, 1, {})
Note

Wraps 2P-Kt's Substitution.unifier.

substitution

substitution(
    assignments: Mapping[Var, Any] | None = None,
) -> Substitution

Creates a substitution from variable-term assignments.

Unlike unifier, the assignments are checked: variables assigned to other assigned variables are resolved, and contradicting assignments give the failed substitution.

Parameters:

Name Type Description Default
assignments Mapping[Var, Any] | None

a mapping from variables to terms (or Python values, converted by to_term). If None, the empty substitution.

None

Returns:

Type Description
Substitution

The substitution: a tuprolog.core.Substitution.Unifier, or a

Substitution

tuprolog.core.Substitution.Fail.

Examples:

>>> X, Y = var("X"), var("Y")
>>> s = substitution({X: atom("a"), Y: X})
>>> s[Y], s.is_success
(a, True)
Note

Wraps 2P-Kt's Substitution.of.

failed

failed() -> Fail

Returns the failed substitution, meaning that no assignment of variables exists.

Returns:

Type Description
Fail

The failed substitution, a singleton (also tuprolog.core.FAILED_SUBSTITUTION).

Examples:

>>> failed(), failed().is_failed
({Failed Substitution}, True)
Note

Wraps 2P-Kt's Substitution.failed.

scope

scope(*variables: Var | str) -> Scope

Creates a scope, i.e. a factory of terms remembering the variables it creates by name.

See tuprolog.core.Scope.

Parameters:

Name Type Description Default
*variables Var | str

the variables the scope starts with, as Vars or names (creating new variables).

()

Returns:

Type Description
Scope

The scope.

Examples:

>>> s = scope("X")
>>> s.struct("f", s.var("X"), s.var("X"))
f(X_..., X_...)
Note

Wraps 2P-Kt's Scope.of and Scope.empty.

variables

variables(*names: str) -> tuple[Var]

Creates many new logic variables at once (see var).

Parameters:

Name Type Description Default
*names str

the names of the variables: at least one.

()

Returns:

Type Description
tuple[Var]

A tuple of the variables, in the order of names.

Raises:

Type Description
ValueError

if no names are given.

Examples:

>>> X, Y = variables("X", "Y")
>>> X.name, Y.name
('X', 'Y')

canonical_formatter

canonical_formatter() -> TermFormatter

Creates a formatter rendering terms in canonical form, ignoring operators.

Structures are rendered as functor(arg1, ..., argN) (lists too, as '.'(head, tail)), atoms are quoted when needed, and variables are rendered as _<n>.

Returns:

Type Description
TermFormatter

The formatter.

Examples:

>>> str(canonical_formatter().format(struct("+", "a", logic_list(1))))
"'+'(a, '.'(1, []))"
Note

Wraps 2P-Kt's TermFormatter.canonical.

default_formatter

default_formatter(
    operators: Any = None,
    tags: TagsFormattingOptions | None = None,
) -> TermFormatter

Creates the default formatter: operators as expressions, variables as _<n>, atoms never quoted, and tags shown.

Parameters:

Name Type Description Default
operators Any

the operators to render as expressions (a tuprolog.core.operators.OperatorSet). If None, tuprolog.core.operators.DEFAULT_OPERATORS.

None
tags TagsFormattingOptions | None

how to render the tags of terms. If None, the default options, but showing the tags.

None

Returns:

Type Description
TermFormatter

The formatter.

Examples:

>>> default_formatter().format(struct("+", var("X"), 1))
'_... + 1'
Note

Wraps 2P-Kt's TermFormatter.default.

readable_formatter

readable_formatter(
    operators: Any = None,
    tags: TagsFormattingOptions = DEFAULT_TAGS_FORMATTING_OPTIONS,
) -> TermFormatter

Creates a formatter for humans: operators as expressions, variables by their name (numbered when names clash, _ for anonymous ones), atoms quoted when needed.

Parameters:

Name Type Description Default
operators Any

the operators to render as expressions (a tuprolog.core.operators.OperatorSet). If None, tuprolog.core.operators.DEFAULT_OPERATORS.

None
tags TagsFormattingOptions

how to render the tags of terms (by default, not rendering them).

DEFAULT_TAGS_FORMATTING_OPTIONS

Returns:

Type Description
TermFormatter

The formatter.

Examples:

>>> readable_formatter().format(struct("is", var("X"), struct("+", 1, 2)))
'X is 1 + 2'
Note

Wraps 2P-Kt's TermFormatter.readable.

pretty_variables_formatter

pretty_variables_formatter(
    tags: TagsFormattingOptions = DEFAULT_TAGS_FORMATTING_OPTIONS,
) -> TermFormatter

Creates a formatter rendering variables by their name (numbered when names clash), operators canonically, and lists, tuples and blocks with their syntax.

Parameters:

Name Type Description Default
tags TagsFormattingOptions

how to render the tags of terms (by default, not rendering them).

DEFAULT_TAGS_FORMATTING_OPTIONS

Returns:

Type Description
TermFormatter

The formatter.

Examples:

>>> str(pretty_variables_formatter().format(struct("+", var("X"), logic_list(1))))
"'+'(X, [1])"
Note

Wraps 2P-Kt's TermFormatter.prettyVariables.

pretty_expressions_formatter

pretty_expressions_formatter(
    pretty_variables: bool = True,
    operators: Any = None,
    tags: TagsFormattingOptions = DEFAULT_TAGS_FORMATTING_OPTIONS,
) -> TermFormatter

Creates a formatter rendering operators as expressions, e.g. 1 + 2 rather than '+'(1, 2).

Parameters:

Name Type Description Default
pretty_variables bool

whether to render variables by their name (e.g. X), rather than by their complete name (e.g. X_0).

True
operators Any

the operators to render as expressions (a tuprolog.core.operators.OperatorSet). If None, tuprolog.core.operators.DEFAULT_OPERATORS.

None
tags TagsFormattingOptions

how to render the tags of terms (by default, not rendering them).

DEFAULT_TAGS_FORMATTING_OPTIONS

Returns:

Type Description
TermFormatter

The formatter.

Examples:

>>> term = struct("+", var("X"), struct("*", 2, 3))
>>> pretty_expressions_formatter().format(term)
'X + 2 * 3'
>>> pretty_expressions_formatter(pretty_variables=False).format(term)
'X_... + 2 * 3'
Note

Wraps 2P-Kt's TermFormatter.prettyExpressions.