PRODUCT   :  R:BASE                  VERSION      :  3.1
   Most computer programs use an algorithm to solve a specific problem,
   but an expert system solves problems in a narrow problem area by using
   high-quality, specific knowledge rather than an algorithm.
   Although expert systems are predominantly developed in expert system
   shells (programming languages especially designed for expert system
   development) you can use R:BASE to develop a simple expert system.
   Algorithms Versus Expert Systems
   In an algorithmic program, you get to the end result by evaluating
   statements (commands) sequentially. The program sets the sequential
   order of evaluation at compile time.
   In an expert system, you get to the end result by searching and
   evaluating stored knowledge in an order that's determined during the
   actual execution of the program.
   Expert System Tasks
   An expert system has three tasks:
     o  Store rules (heuristic knowledge).
     o  Save the facts (knowledge that is known without requiring a rule
        to infer it).
     o  Match the facts with the rules in an effort to solve the problem
        by using what's called an inference engine.
   In R:BASE, you can store rules and facts in tables and create a
   command file to act as the inference engine.
   Identification Example
   This article presents an interpretive expert system that infers what
   an animal is by asking for observations.
   OBJECTS Table
   The table OBJECTS has one column named OBJECT (TEXT 20) that holds the
   names of the objects (animals). For example, it might include this
             cheetah    tiger     giraffe     zebra
             ostrich    penguin   albatross
   RULE_BASE Table
   The table RULE_BASE holds the rules (heuristic knowledge) about the
   various animals. It has four columns:
     o  OBJECT (TEXT 20) holds the objects of the inference (animal names
        in this case).
     o  HAS_IT (INTEGER) equals one if the object (animal) has the
        quality, zero if it doesn't.
     o  QUALITY (TEXT 60) holds the object (animal) quality. The animal
        either has the quality or it doesn't.
     o  ASK_ORDER (INTEGER) holds the order the expert system is to use
        when asking you questions about the unidentified animal.
   Object         Has_it   Quality                       Ask_order
   ------------   ------   ---------------------------   ---------
   cheetah          1      Does it have hair?                 1
   cheetah          1      Does it eat meat?                  2
   cheetah          1      Does it have tawny color?          3
   cheetah          1      Does it have dark spots?           4
   tiger            1      Does it have hair?                 1
   tiger            1      Does it eat meat?                  2
   tiger            1      Does it have tawny color?          3
   tiger            1      Does it have black stripes?        4
   giraffe          1      Does it have hair?                 1
   giraffe          0      Does it eat meat?                  2
   giraffe          1      Does it have hooves?               3
   giraffe          1      Does it have a long neck?          5
   giraffe          1      Does it have long legs?            6
   giraffe          1      Does it have dark spots?           4
   zebra            1      Does it have hair?                 1
   zebra            0      Does it eat meat?                  2
   zebra            1      Does it have hooves?               3
   zebra            1      Does it have black stripes?        6
   zebra            0      Does it have a long neck?          4
   zebra            0      Does it have long legs?            5
   ostrich          0      Does it have hair?                 1
   ostrich          1      Does it have feathers?             2
   ostrich          0      Does it fly?                       3
   ostrich          0      Does it swim?                      4
   penguin          0      Does it have hair?                 1
   penguin          1      Does it have feathers?             2
   penguin          0      Does it fly?                       3
   penguin          1      Does it swim?                      4
   albatross        0      Does it have hair?                 1
   albatross        1      Does it have feathers?             2
   albatross        1      Does it fly?                       3
   This is an interpretive system, so there are no existing facts about
   an unidentified animal. These facts will be determined from user
   observations when the inference engine determines that a quality has
   not been previously established by the user.
   INF_ENG.CMD acts as the inference engine, storing the facts in two
   tables (POS_FACTS and NEG_FACTS) as they are uncovered during a query
   Both POS_FACTS and NEG_FACTS have only one column (QUALITY TEXT 60).
   If an unidentified animal possesses a quality, INF_ENG stores that
   quality in POS_FACTS. If it doesn't possess a quality, INF_ENG stores
   that quality in NEG_FACTS.
   Look at the DECLARE CURSOR structure used in INF_ENG.CMD. By having
   all DECLARE CURSOR commands at the top and opening and closing cursors
   as needed in the WHILE loops, you achieve the best performance.
   Structure your R:BASE code like this. That is, avoid putting DECLARE
   CURSOR and DROP commands in WHILE loops--use OPEN and CLOSE in loops.
   An Example Run
   Here's an example. Say the first FETCH in INF_ENG.CMD fetches one of
   the fur animals from the OBJECTS table. The first rule segment
   evaluated for a fur animal is whether it has hair, so INF_ENG.CMD
   queries the POS_FACTS and NEG_FACTS tables. If the fur information
   isn't in either table, which is the case at the beginning of a
   session, INF_ENG.CMD asks you if the animal has hair. If you answer
   yes, INF_ENG inserts the quality (Does it have hair?) into POS_FACTS.
   If you answer no, INF_ENG.CMD inserts the quality into NEG_FACTS.
   If you answer "no," INF_ENG.CMD continues row by row through RULE_BASE
   until it finds an animal (OBJECT) that has a zero HAS_IT value
   associated with the quality "Does it have hair?" This occurs when the
   FETCH command in the outer WHILE loop fetches a bird as the object.
   Next, the inner WHILE loop fetches the next bird quality--does it have
   feathers? INF_ENG.CMD doesn't find a match in either POS_FACTS or
   NEG_FACTS so it asks you if the animal has feathers. This continues
   until INF_ENG.CMD matches all the rules for an animal (object). Then
   it either displays the answer or tells you the system can't identify
   the animal.
   Adding Animals to RULE_BASE
   You can add animals to RULE_BASE. For example, say you want to add an
   eagle as a type of bird. It has all of the same qualities as an
   albatross, so you need to add an identifying quality. Do this by
   adding a rule to distinguish between the two birds. For example, you
   might add this rule: "Is it the U.S. national symbol?" for the eagle
   and the albatross in RULE_BASE. Then eagle will have a one in HAS_IT
   for that quality, and albatross will have a zero.
   Develop Your Own Expert System
   This implementation is a simple expert system shell. You can apply the
   same design to implement other simple expert systems by forming rules
   and putting them in RULE_BASE.
   The inference engine is generic. You need only modify the WRITE
   statements that refer to animals to comply with your situation. For
   example, you can develop an expert system for diagnosing automobile
   trouble. An OBJECT could be a dead battery with one QUALITY "Do the
   lights turn on?" and a no qualifier in the HAS_IT column.
   This simple expert system implementation demonstrates the flexibility
   of R:BASE. You can add to such a system by adding another command file
   that acts as a learning facility to allow the user to add objects and