# Rule Bases

Rule bases are collections of rules. Rule bases are created by writing a knowledge rule base (.krb) file with your favorite text editor.

A single rule base may contain both forward-chaining and backward-chaining rules.

The forward-chaining rules are run automatically when the rule base is activated to assert new statements of fact. Thus, forward-chaining rules are not directly used to determine whether any particular statement is true.

But backward-chaining rules are directly used to determine whether a particular statement is true. Thus, when a rule base name (or, more properly, a rule base category name, explained below) is used as the knowledge base name in a statement, it refers to the backward-chaining rules within that rule base.

Note

Pyke runs all forward-chaining rules before running any backward-chaining rules.

Thus, using rule base names as the knowledge base name in statements within a forward-chaining rule is prohibited, as this would cause backward-chaining rules to run in order to process the forward-chaining rule.

## Why Multiple Rule Bases?

There are two reasons to have more than one rule base (i.e., more than one .krb file):

1. To divide a large set of rules into human manageable units.

   In this case, you want Pyke to use all of the rule bases combined.

   For example, you may have rules governing the automatic generation of SQL statements, and other rules governing the generation of HTML documents. You want to keep these rules in different rule bases to make them more manageable.

2. To enable your Python program to choose between different rule bases that are tailored to different specific situations.

   For example, some of the rules governing the automatic generation of SQL statements may vary depending upon the target database (e.g., `mysql`, `postgresql`, `oracle`).

   In this case, you want to be able to tell Pyke which of several rule bases to use on each invocation, depending upon which target database you will be accessing. You would never use more than one of these rule bases at the same time, so these rule bases are mutually exclusive.

These two goals are met by three capabilities:

- Rule Base Categories
- Rule Base Inheritance
- Rule Base Activation

## Rule Base Categories

All rule bases are grouped into categories. Each rule base category only gets to have one active rule base.

Thus, you place rule bases that you want to have active simultaneously into different rule base categories; and place rule bases that are mutually exclusive with each other (e.g., the `mysql`, `postgresql` and `oracle` rule bases) into the same rule base category.

Each rule base category has a unique name. In the example above you would want two rule base categories: `database` and `html_generation`.

The rule base category name is used as the knowledge base name for statements within rules of one rule base category that want to refer to rules within another rule base category. For example, rule bases in the `html_generation` category would need to use `database.insert(...)` to refer to the `insert` rules in the `database` category.

## Rule Base Inheritance

The rule bases within the same category share rules amongst themselves through rule base inheritance.

Rule bases use single inheritance to inherit the rules from one other rule base. This can go on to any depth. Both forward-chaining and backward-chaining rules are inherited.

This allows mutually exclusive rule bases to share common rules in a parent rule base without having to duplicate these rules amongst themselves.

Here is the definition, then, of a rule base category:

> Each root rule base (through rule base inheritance) defines a unique rule base category. All rule bases derived (directly or indirectly) from that root rule base are in the same rule base category.

> The name of the rule base category is simply the name of its root rule base.

So, our `database` and `html_generation` example would look like this:

Rule Base Categories

We have one root rule base called `database` and it has derived rule bases called `mysql`, `postgresql` and `oracle`. And a second root rule base called `html_generation` with `firefox` and `internet_explorer`.

The two root rule bases define two rule base categories:

- database, which includes:
  - database
  - mysql
  - postgresql
  - oracle
- html_generation, which includes:
  - html_generation
  - firefox
  - internet_explorer

Note

The .krb files for these rule bases may be placed anywhere you want them within your Pyke source directory structure -- in other words, your directory structure is not required to match your rule base inheritance structure.

Only one rule base from each rule base category may be active at any point in time.

Within each of these rule bases, if the knowledge base name is omitted from a statement within a backward-chaining rule, it defaults to the rule base category of that rule base, not the rule base itself. Thus, `insert(...)` within `postgresql` would mean `database.insert(...)`, and `make_tag(...)` within `firefox` would mean `html_generation.make_tag(...)`.

Important

Note that referring to a rule base category (either explicitly or implicitly) always refers to the active rule base within that category. This may not be the rule base with that name (the root rule base), or even the rule base making implicit use of the rule base category. For example, `insert(...)` within `postgresql` will end up referring to `insert` rules within the `oracle` rule base when `oracle` is the active rule base.

All rules referring to foreign rule base categories must explicitly use the rule base category name. For example, to refer to the `insert` rule for databases, within the `html_generation` category, you would have to say `database.insert(...)`.

In this way, all of the rules will work no matter which rule base is active within each rule base category.

### Rule Inheritance

There is an important difference between how backward-chaining rule inheritance works within Pyke rule bases and how method inheritance works within Python classes:

- When a derived class in Python defines a method by the same name as a method in its parent class, the derived method overrides the parent method. I.e., only the derived method is used when a call is made to it.

- In contrast, when a derived rule base in Pyke defines backward-chaining rules for a goal that also has backward-chaining rules defined for it in the parent rule base, the derived rule extends the set of rules that may be used to try to prove this goal. All of the derived rules will be tried first. If all of these fail, then the parent rules are tried.

  If you don't want the parent rules to be used for a particular goal, you must list that goal name in the `without` clause of the extending statement at the beginning of the derived rule base.

Note

All forward-chaining rules in the parent rule base are always included in the derived rule base. The `without` clause only applies to backward-chaining rules.

## Rule Base Activation

Loading rule bases only makes them available for use. It does not automatically activate any of them. This must be done explicitly by your Python program. Your program may decide to activate different rule bases in different situations.

Additionally, forward-chaining rules may be used to activate more specific rule bases, based upon their inferencing. But once a rule base has been activated for a rule base category, only children of the currently active rule base may be activated from that point on. Because these children inherit the rules of the currently active rule base; activating child rule bases only adds new rules, and doesn't take any away. Thus, any forward-chaining rule run during the activation of the first rule base are not invalidated by activating the second rule base.

In our database example, your program could activate the root `database` rule base and let the forward-chaining rules within the `database` rule base figure out which derived rule base to activate depending on the particular database in use at the time the program is run.

Copyright © 2007-2009 Bruce Frederiksen

Page last modified Mon, Oct 27 2008.