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]
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]
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.
- 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
- 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
- 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
- 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
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:
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.
- ruly.evaluate(inputs, antecedent)¶
Evaluates truthiness of an antecedent
- Parameters:
inputs (Dict[str, Any]) – variable values
antecedent (Union[ruly.Expression, ruly.Condition]) – rule antecedent
- Returns:
bool