Forward Chaining in Python
Forward Chaining in Python
Contents
1 Introduction 1
2 Approach 2
2.1 Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.1.1 Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.1.2 Program representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Knowledge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.4 Bonus: conclusion hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3 Sample runs 4
3.1 Input rules from rules.txt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.2 Graph of rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3 Animals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3.1 Tiger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3.2 Penguin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3.3 Zebra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.3.4 Nightmare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
A Source code 7
References 7
1 Introduction
This system is for forward-chaining rule-based systems written in Python. It takes a plain-text file
of rules as input and outputs a graph, generated using dotty [1], of the relationships between facts
and conclusions, as well as how it reached them for a given set of base knowledge. All examples in
this report use the Zookeeper rules presented in [2], but the system will work with similar rules in
any problem domain.
1
2 Approach
There are three main sections to the implementation: the rules, knowledge representation, and the
algorithm for doing the actual forward chaining.
2.1 Rules
2.1.1 Encoding
Rules are stored as lines in a file. They consist of two parts: an if expression and a then conclusion
and are written like if part expression -> then conclusion. The if expression is the set of
facts which must be true for the then conclusion to be true. For example, Rule Z14 from the
textbook [2, page 124], is:
If ?x is a bird
?x does not fly
?x has long legs
?x has a long neck
?x is black and white
then ?x is an ostrich
1. There are no spaces in any of the terms: “has long neck” becomes has long neck.
2. Negation is explicitly specified: “does not fly” was represented as not flies.
3. The original rule contained implicit ands; these are explicitly placed in the if part of the
rule.
4. There is one rule per line; the \ is only present in this document.
5. One-line comments are allowed and are set off with # as the first character.
6. There are parentheses in the rule, although they serve no functional purpose in this specific
rule.
The rules in rules.txt are verified to make sure they are valid: properly parenthesized with
one and only one conclusion.
2
2.1.2 Program representation
The rules are stored in memory as a list1 of two-item tuples2 . The first item is the if expression
and the second part is the then conclusion:
[ (’has_hair’, ’is_mammal’),
(’gives_milk’, ’is_mammal’),
(’has_feathers’, ’is_bird’),
(’flies and lays_eggs’, ’is_bird’),
(’is_mammal and eats_meat’, ’is_carnivore’),
...
]
2.2 Knowledge
Now that we have our rules processed, we want to create some baseline knowledge about a concept.
This breaks down into two things: things we know to be true and things we know to be false.
For example, we know that Tux has feathers, swims, and has black and white color. Also, Tux
does not fly. We represent this with a map3 from a condition to a true (1) or false (0) value:
{
’flies’: 0,
’has_black_and_white_color’: 1,
’has_feathers’: 1,
’swims’: 1
}
2.3 Algorithm
Now that we have our base knowledge and our rules, we follow the algorithm presented on [2, page
128].
3
∗ Replace every occurance of the item in the antecedant with the known value for
that item5
4. If the antecedant is a valid logical expression6 and the antecedant evaluates to 1:
∗ Indicate that rule r has been fired
∗ Draw links from the antecedants to the conclusion, possibly with a box for the
rule
∗ Indicate that we made a new conclusion
∗ Add the conclusion to our base knowledge with a value of 1 so we can use it for
remaining rules
3 Sample runs
The sample runs are for the Zookeeper system.
4
is_carnivore and has_tawny_color and has_black_stripes -> is_tiger
# bird rules
is_bird and not flies and has_long_legs and has_long_neck
and has_black_and_white_color -> is_ostrich
is_bird and swims
and (not flies and has_black_and_white_color) -> is_penguin
is_bird and flies -> is_albatross
3.3 Animals
3.3.1 Tiger
This is the base knowledge for Tiger. (Note that it does not fly; this was just extra information to
see how the system would respond.)
{ ’eats_meat’: 1,
’flies’: 0,
’gives_milk’: 1,
’has_black_stripes’: 1,
’has_tawny_color’: 1}
Figures 3 on page 10 shows with rule boxes, and Figure 4 on page 10 shows it without rule
boxes. It came to the appropriate conclusions: is mammal, is carnivore, is tiger. (Any oval
that is not in the base knowledge box is an inferred conclusion.)
3.3.2 Penguin
Tux the Penguin has the following base knowledge:
{ ’flies’: 0,
’has_black_and_white_color’: 1,
’has_feathers’: 1,
’swims’: 1}
Figures 5 on page 11 shows with rule boxes, and Figure 6 on page 11 shows it without rule
boxes. It came to the appropriate conclusions: is bird, is penguin
5
3.3.3 Zebra
The Zebra has the following base knowledge:
{ ’gives_milk’: 1,
’has_black_stripes’: 1,
’has_hair’: 1,
’has_hoofs’: 1}
Figures 7 on page 12 shows with rule boxes, and Figure 8 on page 13 shows it without rule
boxes. It came to the appropriate conclusions: is mammal, is ungulate, is zebra
3.3.4 Nightmare
I remembered one of my cousins attempting to describe a creature in one of his dreams. Obviously,
this doesn’t exist, but it’s interesting to see the conclusions drawn.
{ ’eats_meat’: 1,
’flies’: 1,
’gives_milk’: 1,
’has_black_stripes’: 1,
’has_dark_spots’: 1,
’has_feathers’: 1,
’has_hoofs’: 1,
’has_long_legs’: 1,
’has_long_neck’: 1}
Figures 9 on page 14 shows with rule boxes, and Figure 10 on page 15 shows it without rule
boxes. It came to several conclusions: is albatross, is bird, is carnivore, is giraffe,
is mammal, is ungulate, is zebra. These are neither correct nor incorrect; it’s a fictional ani-
mal.
Improvements If I was going to improve it, I would add better input/output. There’s no input
now since it’s forward chaining: the user knows everything ahead of time and they can just input it
in the function call. I’m not quite happy with the handling of not: the formatting is sub-optimal
and I’d like it to be able to draw “negative conclusions” (animal products -> not vegan), which
opens a whole host of issues. It would be neat to “overlay” a specific instance of the system on
top of the full rule graph so you can see what paths were taken versus what paths were possible;
this is just an input/output issue, though. Also, or clauses and and clauses show up the same and
parentheses aren’t indicated on the graph at all.
6
Implementation Python’s eval function made things easy: I could just pass in some arbitrary
boolean expression and have it figure it out; I’d probably have to write a parser if I did this in
C++. Getting the output to be both correct and useful was difficult, and I had some termination
problems to start with.
Lessons learned I learned that the general solution was somewhat easier (and definately more
fun) to implement than the specific solution. Also, the choice of language can help speed up
implementation time. Backward chaining is good for testing specific hypotheses, especially if no
data has been collected: “Was that a tiger?” “Well, did it have a tawny color?” Forward chaining
is good when there is already data and the goal is to find out as much about it as possible: “It had
feathers, and it was swimming; what was it?”
A Source code
Source code is attached.
References
[1] Stephen C. North and Eleftherios Koutsofios. Application of graph visualization. In
Proceedings of Graphics Interface ’94, pages 235–245, Banff, Alberta, Canada, 1994.
http://www.research.att.com/sw/tools/graphviz/download.html. 1
[2] Patrick Henry Winston. Artificial Intelligence. Addison Wesley, 3rd edition, 1992. 1, 2.1.1, 2.3
7
8
9
Figure 3: Tiger with rule boxes
10
Figure 4: Tiger without rule boxes
11
Figure 5: Tux (Penguin) with rule boxes
12
Figure 6: Tux (Penguin) without rule boxes
13
Figure 7: Zebra with rule boxes
14
Figure 8: Zebra without rule boxes
15
16