I. Rule-based systems The Oska player that you're constructing has a lot of knowledge about how to play Oska, but it's not exactly obvious by looking at the program just what that knowledge is, as it's represented in some fairly obscure ways. Some functions return numbers, other functions propagate numbers...it's not easy to follow. This kind of knowledge is often called "how-to" or "procedural" knowledge---knowledge about how to perform some task. This is different from "what-is-it" or "declarative" knowledge, like that encoded in an inheritance hierarchy for dogs and birds. Procedural knowledge doesn't necessarily have to be encoded as cryptically as it is in your Oska program. Another way to represent this kind of knowledge is as a set of "if-then expressions" or "rules". These rules take the form: IF some condition(s) exist THEN perform some action(s) A set of test-action or if-then rules is often called a "production system"---if the left side holds true, the right side is produced. We see production systems used a lot in computer science. If you should take a compiler course, for example, you'll see production systems used to describe programming languages: [expression] := [expression] [arithmetic-op] [expression] This is the stuff that compilers and compiler generators are made of. It's also the backbone of natural language understanding system. In the world of artificial intelligence, production systems are often called "rule-based systems", and are used not only for building flexible intelligent systems, but also for modelling human cognition. II. Components of a rule-based system A computational implementation of a rule-based system needs three parts: 1. The rule base (also known as the knowledge base or production memory). This is the place where the rules are stored (the procedural knowledge). 2. The rule interpreter (a.k.a. the control mechanism or the inference engine). This is a means of determining which rules have tests that are satisfied, and then selecting one of those rules to have its associated action performed. 3. The data base (a.k.a. working memory, short term memory, the world model, or context). This is an abstracted representation of the world that this system "cares" about. It represents the current state of the world. The left-hand sides of the rules look at this to see if they're satisfied; the right-hand sides act operate on this information. This is where the facts or declarative knowledge is stored. If you put enough knowledge into the rule base so that it can perform some interesting, complex task at the same performance level as a human, we could call this an "expert system". III. Designing a simple rule-based system for tic-tac-toe You might get a better feel for rule-based systems if you actually go through the design of one. Here's a half-baked attempt at a rule-based system for playing tic-tac-toe. We won't worry much about implementation details; we'll just do some handwaving and describe the knowledge in English. Here are some rules which might be useful, but these aren't necessarily all the rules. Oh, and assume "row" means any adjacent squares, whether horizontal, vertical, or diagonal: IF I have three tokens in a row THEN I win; quit IF the opponent has three tokens THEN I lose; quit in a row IF I have two tokens in a row and THEN put my token in the third square in the row is the third square empty IF the opponent has two tokens in THEN put my token in a row and the third square in the third square the row is empty IF the center square is empty THEN put my token in the center square IF a corner square is empty THEN put my token in that corner square IF a side square is empty THEN put my token in that side square And so on, and so on. The first thing to note is that more than one of these rules may have tests that are satisfied at the same time. We'll talk about how to select which rule to use later on. The second thing to note is that these rules are described at a very high level. There aren't many details, and certainly none that a computer could understand without a lot of help. Nevertheless, we want to maintain that high-level description, as one of the things we want to accomplish with a rule-based system is to make the procedural knowledge more accessible, or more easily understandable, to us. That is we want our rules to look more like something that people read as opposed to rules that Scheme or Prolog interpreters read. To make this happen, we must construct a rule interpreter, which interprets the language of if-then rules that describes the procedural knowledge for playing tic-tac-toe. In other words, these if-then rules are yet another way of building a language on top of a language. IV. The rule interpreter The rule interpreter is just a simple loop: do until no left-hand-side is satisfied begin find all the rules whose tests (or preconditions or antecedents or left-hand-sides) are satisfied from that group, use a conflict resolution strategy (hang on, we'll get there) to select the most appropriate rule to be used execute that rule's actions (or postconditions or consequents or right-hand-sides) and update the data base accordingly end In addition to all this, you'll need a data base, so... V. The data base In the case of our tic-tac-toe game player, the data base is going to be really simple. We just need to represent the current state of a game, so a board that looks like this: | |o -+-+- |x| -+-+- | | might be represented like this: [[e,e,o],[e,x,e],[e,e,e]] or one of any of a number of other possible representations. But of course, you'd employ such nice data abstraction techniques that only some simple accessor and constructor functions would have to know the details of the representation, right?
Last revised: December 7, 2004