Path: utzoo!utgpu!water!watmath!clyde!rutgers!ames!pasteur!ucbvax!chorus.fr!will From: will@chorus.fr (Will Neuhauser) Newsgroups: comp.ai.digest Subject: Re: Software Development and Expert Systems Summary: Additional commentary on "modularizing" expert systems. Message-ID: <843@chorus.fr> Date: 31 Jan 88 14:40:41 GMT References: <8801270004.AA12634@nrl-rjkj.arpa> Sender: daemon@ucbvax.BERKELEY.EDU Organization: Chorus, 6 av. Gustave Eiffel, 78180 Montigny-le-Btx, France Lines: 64 Approved: ailist@kl.sri.com In article <8801270004.AA12634@nrl-rjkj.arpa>, jacob@NRL-CSS.ARPA (Rob Jacob) writes: > Saw your message about software engineering techniques for expert > systems on the AIList. [...] Our basic solution is to divide > the set of rules up into pieces and limit the connectivity of the > pieces. [...] This would appear to be the basic definition of "modularity", and the usual hints should apply given a little thought. To achieve greater modularity in a prototype expert system, in C++, I created classes for "expert systems" (inference engines), for rule-bases, and for fact-bases. Inference Engines. ----------------- Separate engines allows the user to select an appropriate inference engine for the tasks at hand. It would have been nice to add a language construct for defaulting engines; as it was you had to code these. The expert sytems could be organized hierarchically. Each system had a pointer to its parent(s) and vice versa. In truth, I only ever used one engine because I was really more interested in modularizing the rule-base, but the potential was there, right? Fact-bases. ---------- Separate fact-bases allowed for the use of the same rule-base in different situations: when a rule-base appeared more that once, it was given a new fact-base, and the rule-base was re-used. Hypothetically, the separate fact-bases could have been useful in "trial and error" situations: one could create new fact-base instances (objects) and then throw them away when they didn't pan out. I never had a chance to try it out. Rule-bases. ---------- Separate rule-bases were the important factor in this current discussion, and my main interest. I used a very simple default, that could obviously be extended to provide finer control. The separate rule-bases were very useful for modularizing the total rule-base. Each "coherent set of rules" was located in a different file, and when read in, was read into a separate rule-base instance (it was a prototype so don't give me too much grief!). The default rule for connection was that terminal goals, those which never appeared on the left-hand side of a rule, were automatically exported to the calling expert system(s) (via the parent-pointers). This was sort of nice in that when a sub-expert-system had new goals added, they were automatically made a part of the callers name space. (Of course there could be conflicts, but in the prototype I just lived with the problem and the new meanings suddenly given to existing names, but, again, I was just trying out some modularization concepts in a prototype.) Aside from the obvious advantages of modularization to reduce the size of the name space and thus the difficulty of understanding a single giant set of rules (actually, it seemed that 100 rules was hard for one person to remember for long), I had another reason for wanting modularization: I wanted to clearly separate the experts, facts, and rules into different computational tasks (coherent systems of sub rules) so that one could divide the rule-base up onto separate processors in a multi-processor computer. (Again, never tried.)