Inference
TypeDB is capable of reasoning over data via rules defined in the schema.
The reasoning engine uses rules as a set of logic to infer new data, based on the existence of patterns in data of a TypeDB database.
Reasoning, or inference, is performed at a query time. Only The results are transaction-bound and are not persisted. As soon as transaction is closed — all inference results perish. |
When executing a get
query with the infer
transaction option enabled
(True
), TypeDB inspects and triggers rules that may lead to new answers to the query.
It returns data that answers the query taking into account inference results. Reasoning can proceed from one rule to another, including recursion, leading to complex behaviors emerging from a few simple rules.
During a single transaction, inferred facts will be retained and reused (with corresponding performance gains). These inferred data will be lost as soon as we close the transaction. A new transactions will re-compute inferred facts again.
Limitations
Inference works by rules defined in a schema of a database.
What’s possible to infer is limited by what can be defined in a rule. See the Rule validation section for more information.
Rules
Rules are a part of schema and define embedded logic.
The reasoning engine uses rules as a set of logic to infer new data.
Rules can dramatically shorten complex queries, perform explainable knowledge discovery, and implement business logic at the database level.
A rule consists of a condition and a conclusion.
A condition is a pattern to look for in data.
A conclusion is a pattern to insert virtual (inferred) data for every result matched with a pattern from the condition.
Inference can only be used in a read transaction. Rules can’t change persisted data in a database. All reasoning is done within a dataset of a transaction. |
The rules syntax uses when
and then
keywords for condition and conclusion, respectively.
rule rule-label:
when {
## The condition
} then {
## The conclusion
};
The conclusion can be used to create a single virtual instance of data: a relation or ownership of an attribute.
Queries use rules for Inferring new data only in read transactions and only if the inference option is enabled.
It is possible to create a recursive logic in the line of |
Read more on how to create rules in a schema in the Define rules section of the Defining schema page.
We can use computation operations and functions in the condition pattern. And we can use value variables in the conclusion of a rule.
Rule validation
A rule’s when
clause (condition) can be a pattern with multiple statements, including disjunctions and negations.
A then
clause (conclusion) describes a single relation or a constraint of ownership of
an attribute (due to Horn-clause logic).
When using a disjunction in a rule, the disjunctive parts must be bound by variables outside the or
statement.
These variables are the only ones permitted in the then
clause.
Since version 2.18.0
, we can use abstract types in a rule
as long as all the type variables that define which instances to create during materialization are concrete
(non-abstract).
See the example with abstract types
define
abstract-person sub entity, abstract, plays friendship:friend; #abstract
friendship sub relation, relates friend; #non-abstract
rule concrete-relation-over-abstract-players:
when {
$x isa abstract-person;
} then {
(friend: $x) isa friendship;
};
The then
clause of a rule can’t use variables (either concept variables or value variables) that aren’t defined in
the when
clause.
The then
clause of a rule must not insert any instance which occurs negated in its when
clause or in the when
clause of any rule it may trigger. Attempting to define such a rule will throw an error.
Rules will not create duplicates of instances that are already in the database or have already been inferred. There is no need to check if it already exists in a rule.
There are exactly three distinct conclusions permitted:
-
A new relation.
-
Ownership of an attribute defined by its value.
-
Ownership of an attribute defined by a variable.
The then
clause must be insertable according to the schema (e.g., we can’t give an attribute to an instance
that can’t own that attribute type).