Before diving straight down into the low-level details of the implementation, we need to consider the previous research or design decisions to determine how it all fits together.
Rule-Based System or Not?
The main concern during development is a trade-off between work and results. How much time are we willing to invest in developing an RBS? A fully fledged system might take weeks to develop and may be overkill for this relatively simple problem. On the other hand, a simpler alternative (such as steering behaviors) will be much quicker to implement but might not be suited to other problems.
In this chapter, we will actually design a modular RBS. However, efficiency remains of prime importance because of the nature of the application; when targeting other problems than fundamental behaviors (such as motion), flexibility and extensibility are often the main requirements.
Type of Chaining
As far as the type of RBS is concerned, we'll stick to a forward-chaining system (explained in Chapter 11, "Rule-Based Systems") for two main reasons:
The intention is to allow direct support for hard-coded effectors (which perform actions in the environment), but also allow declarative conditions (loaded from a file). We'll support sensor indirectly by using preprocessing to gather information from the surroundings.
Precautions to Simplify Rules
Even though rules are conceptually simple, ideally we want to keep their complexity down to a minimum (both head and body). We also want to reduce the number of rules as much as possible. This will undoubtedly simplify the knowledge acquisition greatly.
Each of the rules is implicitly ranked, which hints to the interpreter which rules to pick first. When the processing starts with the higher priorities, latter rules can assume that the conditions of previous rules are true. This simplifies the conditions of rules lower down the ranks.
In addition, symbols are often set to the same values in the body of rules. For example, all but one rule may set symbol A to true. Explicitly including this action in every rule is highly redundant. Instead, we can use default values to set A to true unless it's overridden.
To reduce the number of rules, we'll allow for multiple actions in the rule body. This avoids the duplication of rules, and supports atomic operation; in some cases, we must set two symbols at the same time, instead of waiting for the next cycle of the interpreter to do so.