Usage

Installation

To install ruly, call:

pip install ruly

Quickstart

Ruly’s main use case can be summed up with the following code block:

import ruly

knowledge_base = ruly.KnowledgeBase(
    'IF sound="croak" AND behavior="eats flies" THEN animal="frog"',
    'IF sound="chirp" AND behavior="sings" THEN animal="canary"',
    'IF animal="frog" THEN color="green"',
    'IF animal="canary" THEN color="yellow"')
state = ruly.backward_chain(knowledge_base, 'color',
                            sound='croak',
                            behavior='eats flies')
print(state['color'])
# prints green
print(state['animal'])
# prints frog

We can see that there are two distinct separate steps taken in the usage - knowledge base creation and backward chaining evaluation. Optionally, additional arguments can be passed to evaluation functions, allowing caller to further modify its behavior.

Knowledge base

The central point of the ruly’s rule engine is a knowledge base. It serves as a rule aggregator that evaluators use to derive other variable values. The knowledge base is implemented in the following class:

class ruly.KnowledgeBase(*args, parse=<function parse>)

Class representing a knowledge base, stores known rules

Parameters:
  • *args (Tuple[Union[ruly.Rule, ruly.KnowledgeBase, str]]) – initial rules of which the knowledge base consists, can be rule objects, knowledge bases or string representations

  • parser (Callable[[str], ruly.Rule]) – parser used to turn string representations into ruly.Rule objects, default is ruly.parse()

property derived_variables

Names of variables contained within at least one rule’s antecedent

Type:

Set[str]

property input_variables

Names of variables that are never contained within a rule’s antecedent

Type:

Set[str]

property rules

Stored rules

Type:

List[ruly.Rule]

Rule declaration

Knowledge base requires a list of initial rules for creation and can add additional rules after it’s instantiated. Knowledge base’s interface is such that it accepts, strings, other knowledge bases or ruly.Rule objects. If strings are received, they are parsed into ruly.Rule objects, more on that in its separate section. The object that represents the rule itself has the following signature:

class ruly.Rule(antecedent: Condition | Expression, consequent: Dict[str, Any])

Knowledge base rule

antecedent

expression or a condition that, if evaluated to True, fires assignment defined by the consequent.

Type:

Union[ruly.Condition, ruly.Expression]

consequent

keys are variable names, values are values assigned if rule fires

Type:

Dict[str, Any]

Rule’s antecedent is a logical expression that, if evaluated to true, signifies that rule should fire during evaluation. The consequent represents which value will be added to a variable if the rule fires, represented as a standard dictionary. The dictionary can be interpreted as the key-value pairs as the part of the state affected by the firing rule.

Conditions

class ruly.Condition(name: str)

Abstract class representing a condition that needs to be satisfied when evaluating an expression.

name

variable name

Type:

str

abstract satisfied(value)

Checks whether the condition is satisfied for the given value

Parameters:

value (Any) – checked value

Returns:

true if condition is satisfied, false otherwise

Return type:

bool

class ruly.conditions.Equals(name: str, value: Any)

Condition that checks whether variable value is equal to what is written under the value attribute

value

value against which the variable is compared to

Type:

Any

satisfied(value)

Checks whether the condition is satisfied for the given value

Parameters:

value (Any) – checked value

Returns:

true if condition is satisfied, false otherwise

Return type:

bool

class ruly.conditions.Greater(name: str, value: Any)

Condition that checks whether variable value is greater than what is written under the value attribute

value

value against which the variable is compared to

Type:

Any

satisfied(value)

Checks whether the condition is satisfied for the given value

Parameters:

value (Any) – checked value

Returns:

true if condition is satisfied, false otherwise

Return type:

bool

class ruly.conditions.GreaterOrEqual(name: str, value: Any)

Condition that checks whether variable value is greater or equal to what is written under the value attribute

value

value against which the variable is compared to

Type:

Any

satisfied(value)

Checks whether the condition is satisfied for the given value

Parameters:

value (Any) – checked value

Returns:

true if condition is satisfied, false otherwise

Return type:

bool

class ruly.conditions.Less(name: str, value: Any)

Condition that checks whether variable value is less than what is written under the value attribute

value

value against which the variable is compared to

Type:

Any

satisfied(value)

Checks whether the condition is satisfied for the given value

Parameters:

value (Any) – checked value

Returns:

true if condition is satisfied, false otherwise

Return type:

bool

class ruly.conditions.LessOrEqual(name: str, value: Any)

Condition that checks whether variable value is less or equal to what is written under the value attribute

value

value against which the variable is compared to

Type:

Any

satisfied(value)

Checks whether the condition is satisfied for the given value

Parameters:

value (Any) – checked value

Returns:

true if condition is satisfied, false otherwise

Return type:

bool

Expressions

class ruly.Expression(operator: Operator, children: Sequence[Condition | Expression])

Logical expression, aggregation of conditions and sub-expressions

operator

operator applied to all children when evaluated

Type:

ruly.Operator

children

list of conditions or other expressions

Type:

List[Union[ruly.Condition, ruly.Expression]]

Parsing

Rules can also be generated by parsing strings. For this, a parser function needs to be defined. Ruly offers a default parser function at:

ruly.parse(rule)

Parses a string representation of a rule and returns it. Uses JSON to deserialize values.

Parameters:

rule (str) – string representation of a rule

Returns:

ruly.Rule

Evaluation

Ruly offers evaluation functions for individual rules and knowledge bases.

ruly.backward_chain(knowledge_base, output_name, post_eval_cb=None, **kwargs)

Evaluates the output using backward chaining

The algorithm is depth-first-search, if goal variable assignment is contained within a rule that has a depending on a derived variable, this variable is solved for using the same function call.

Parameters:
  • knowledge_base (ruly.KnowledgeBase) – knowledge base

  • output_name (str) – name of the goal variable

  • post_eval_cb (ruly.PostEvalCb) – callback called after determining which rules fired. Return value is changed state. If None, state is changed by using assignment of first fired rule’s consequent (or not changed if no rules fired)

  • **kwargs (Any) – names and values of input variables

Returns:

state containing calculated values

Return type:

Dict[str, Any]

ruly.PostEvalCb(*args, **kwargs)

Callable type of the post evaluation callback function.

Parameters:
  • state (Dict[str, Any]) – state calculated during evaluation

  • output_name (str) – name of the goal variable

  • fired_rules (List[ruly.Rule]) – rules whose antecedents were satisfied

  • evaluation (during the)

Returns:

updated state

Return type:

Dict[str, Any]

ruly.evaluate(inputs, antecedent)

Evaluates truthiness of an antecedent

Parameters:
Returns:

bool