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.Xor_; - constants (
Constant), carrying a value and no sub-terms:- atoms (
Atom), symbolic names, e.g.bart,'Hello World',[];true,falseandfailare atoms too (Truth); - numbers (
Numeric): arbitrary-precision integers (Integer, e.g.42) and reals (Real, e.g.3.14);
- atoms (
- 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 isparentand arity is 2; their indicator isparent/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. "Headholds ifBodydoes"), facts (Fact, rules whose body istrue, writtenHead.), and directives (Directive,:- Body, commands run when a program is loaded); - indicators (
Indicator):name/arity, denoting predicates or functors.
- lists (
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 JavaClassCastExceptionon mismatch) andas_<type>()(e.g.as_var(), returningNoneon mismatch); variables(the variables occurring in the term, lazily, repetitions included);apply(substitution)(in Python, alsoterm[substitution]),fresh_copy()(a copy with new variables);structurally_equals(other)(equality up to variables' renaming),accept(visitor)(seeTermVisitor);tags(metadata attached to the term, seetuprolog.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.
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
¶
Creates an atom, i.e. a constant symbolic name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
string
|
str
|
the name of the atom, e.g. |
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
¶
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
¶
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
|
*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 |
Clause
|
|
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
¶
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
|
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
¶
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
¶
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
¶
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 |
required |
Returns:
| Type | Description |
|---|---|
Integer
|
The integer. |
Raises:
| Type | Description |
|---|---|
TypeError
|
if |
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 |
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 |
required |
Returns:
| Type | Description |
|---|---|
Numeric
|
The number, a |
Raises:
| Type | Description |
|---|---|
NumberFormatException
|
if |
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
¶
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 |
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
¶
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 |
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
¶
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 |
()
|
Returns:
| Type | Description |
|---|---|
Rule
|
The rule (a |
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
¶
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 |
()
|
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
¶
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
|
|
Examples:
>>> truth(True), truth(False)
(true, false)
Note
Wraps 2P-Kt's Truth.of.
logic_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
¶
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 |
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
¶
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
¶
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. |
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
¶
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 |
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 |
None
|
Returns:
| Type | Description |
|---|---|
Substitution
|
The substitution: a |
Substitution
|
|
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 |
Examples:
>>> failed(), failed().is_failed
({Failed Substitution}, True)
Note
Wraps 2P-Kt's Substitution.failed.
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 |
()
|
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
¶
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 |
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 |
None
|
tags
|
TagsFormattingOptions | None
|
how to render the tags of terms. If |
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 |
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. |
True
|
operators
|
Any
|
the operators to render as expressions (a |
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.