TypeDB Fundamentals Lecture Series: from Nov 16 to Jan 9

Define rules

Rules are defined independently of types in the same schema. However, any types used in a rule must be defined in the schema.

They are executed only as a part of Get queries when the inference option is enabled in a read transaction.

The results inferred by rules are virtual because they exist only within the transaction. They are not persisted in a database, and any data inferred in a query ceases to exist when the transaction is closed.

Read more on rules in the Rule validation section below.

Syntax

Rules are defined in TypeQL with the following syntax:

rule <label>:
when {
    <pattern>
} then {
    <pattern>
};

Use the rule, when, and then keywords for a rule definition.

Unlike other define statements for schema definitions, the rule syntax uses patterns consisting of variables and constraints for data instances. For more information, see the Pattern syntax section.

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:

  1. A new relation.

  2. Ownership of an attribute defined by its value.

  3. 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).

Rule processing (inference)

The approach TypeDB uses is a backward-chaining execution on top of Horn-clause logic.

Negation functionality follows the set-difference semantics. It corresponds to the negation-as-failure model under the following conditions:

  • We have stratified negation.

  • The results are grounded.

  • We ensure all variables occurring both inside and outside the negation are bound by the time the negation is evaluated.

Infinite recursion and non-termination are prevented with a tabling mechanism.

Examples

Basic

define

rule test:
    when {
        $p isa person;
    } then {
        $p has full-name "Dude";
    };

The example above demonstrates a simple rule. All person entities matched by a read query with the inference option enabled will have a full-name attribute with the value Dude, even if they have other full-name attributes with different values.

Using value variables

define

size-mb sub attribute, value double;

file owns size-mb;

rule size-covert:
    when {
        $f isa file, has size-kb $s;
        ?mb = $s/1024;
    } then {
        $f has size-mb ?mb;
    };

The above query defines an additional attribute subtype size-mb, defines that it can be owned by the file entity subtype, and creates a rule size-convert to create ownership of size-mb with the value 1024 times lower than size-kb to any file instance that has size-kb. The rule uses a value variable for arithmetics.

With this rule defined and the inference option enabled, we can try the following query:

match
    $f isa file, has size-kb $s, has size-mb $mb;
    $mb > 1;

With the default IAM dataset sample, this query shall return only one result (because all others will have size-mb lower than 1), similar to this:

{
    $f iid 0x826e80078000000000000000 isa file;
    $mb 1.6650390625 isa size-mb;
    $s 1705 isa size-kb;
}

The value of size-mb is not persisted in the database but instead — inferred by the size-covert rule every time we do a read transaction with the inference option enabled and query for size-mb.

Transitive rule

define

rule transitive-reachability:
    when {
        (from: $x, to: $y) isa rel;
        (from: $y, to: $z) isa rel;
    } then {
        (from: $x, to: $z) isa rel;
    };

The example above allows for the transitivity of relations. We can interpret this rule as joining two relations together. It creates a relation x to z, given that there are relations of x to y and y to z.

Advanced transitivity usage

When inferring relations, it is possible to variablize any part of the then clause of the rule. For example, if we want a rule to infer many types of relations, we could propose a rule such as:

define

rule all-relation-types-are-transitive:
    when {
        ($role1: $x, $role2: $y) isa! $relation;
        ($role1: $y, $role2: $z) isa! $relation;
    } then {
        ($role1: $x, $role2: $z) isa $relation;
    };

Complex rule

define

rule add-view-permission:
    when {
        $modify isa action, has name "modify_file";
        $view isa action, has name "view_file";
        $ac_modify (object: $obj, action: $modify) isa access;
        $ac_view (object: $obj, action: $view) isa access;
        (subject: $subj, access: $ac_modify) isa permission;
    } then {
        (subject: $subj, access: $ac_view) isa permission;
    };

The example above illustrates a more complex rule using the IAM schema.

In short, the permission to access some file with the action that has name of view_file can be inferred by the rule from the permission to modify_file the same file.

The Example section of Inferring data page gives a full explanation of how this rule works.

Provide Feedback