|
RiverSoftAVG
Newsletter #4
April/May 2001
Hello and welcome to the fourth edition of
RiverSoftAVG's newsletter! It is amazing how the year is flying by.
This latest newsletter may be a little late but it is the best one yet!
In this issue, we reveal exciting details about the database support that
will be in the upcoming Inference Engine Component Suite (IECS) version 2.
Also, we have two tips for writing your expert systems, one from the
coding side and one from the expert system side. Finally, we thought
you should know about a new free component to download (in case you
haven't been to the web site lately)!
A reminder, this newsletter and all previous
ones are available for download from the web site at http://www.riversoftavg.com/articles_&_tips.htm
Contents
Note: You received this newsletter because
you are an owner of a RiverSoftAVG product. If you received this
newsletter by mistake or if for any reason you wish to not receive any
future mailings from RiverSoftAVG, just reply to this message informing us
so. We apologize for any intrusion.
This Fall, the Inference Engine Component Suite (IECS) is going to receive
a major upgrade, bringing it up to version 2.0. While this will not
be a free upgrade (pricing to be determined), we think that this upgrade
will be well worth it. This month, we will discuss one of the great
new features coming in version 2.0, database support.
In later newsletters, we will have more about other great features to
come.
One of the major new features for the IECS will be database support (for
Delphi Pro and above users, of course). The new database
features of the IECS are incredibly integrated and transparent.
Basically, if you have used the Delphi database components before, you
will know how to use these. For version 2, we
are making a data-aware inference engine descendant,
TDBInferenceEngine, which is much more powerful than standard data-aware
controls. The TDBInferenceEngine component provides two powerful
database features for your expert systems:
Let's talk about the first feature. The
TDBInferenceEngine component accepts multiple datasources
and multiple fields from each datasource. Unlike traditional
data-aware controls (TDBEdit, TDBMemo) which accept one dataset and
usually only one field in the dataset, the TDBInferenceEngine component
can read from and write to multiple datasources. Each data source
defines a different fact template in the inference engine, and each field
of the data source can be mapped to a slot in the fact template. At
run-time, each record in the data source defines, or relates to, a
fact. As the user or program scrolls around the dataset, new facts
are automatically asserted to and retracted from the inference engine.
For example, the BioLife table in the DBDEMOS database defines 8 fields:
Species No, Category, Common_Name, Species Name, Length (cm), Length_In,
Notes, and Graphic. The TDBInferenceEngine component supports fields
with primitive types: integer, float, etc (sorry, no blobs).
The IECS architecture automatically maps this table as a fact template in
the expert system; each allowable field maps to one slot in the fact
template (you can specify which ones). Each record,
as the dataset moves to it, is asserted onto the fact list of the
inference engine. By default, when the dataset leaves the record,
the equivalent fact is retracted from the inference engine. Note
that retractions, again by default, will not delete records in the dataset
(deleting records when retractions occur could be a disastrous side
effect, for example, when you clear the inference engine).
Now let's go through the steps so you can see how really easy it truly is:
(deftemplate Table1 "Dataset facts"
(slot SpeciesNo (type INTEGER FLOAT) (default "90020") ) (slot Category (type ATOM STRING) (default "Triggerfish") ) (slot Common_Name (type ATOM STRING) (default "Clown Triggerfish") ) (slot SpeciesName (type ATOM STRING) (default "Ballistoides conspicillum") ) (slot Length_In (type INTEGER FLOAT) (default "19.6850393700787") ) (slot Lengthcm (type INTEGER FLOAT) (default "50") ) )
f-0 (Initial-Fact)
f-1 (Table1 (SpeciesNo 90110) (Category "Shark") (Common_Name "Swell Shark") (SpeciesName "Cephaloscyllium ventriosum") (Length_In 40.1574803149606) (Lengthcm 102)) For a total of 2 facts.
Table1.First;
while not Table1.Eof do begin DBInferenceEngine1.Run; Table1.Next; end;
Table1.First;
while not Table1.Eof do Table1.Next;
Now, what does it mean "it can act like a database, where
every fact template can be a dataset, for other data-aware
controls?" The TDBInferenceEngine
component can also make the connection the other way. The
inference engine acts as a virtual database. Using a special
TIEDataSet component, you can connect to the TDBInferenceEngine
component. From there, a TDataSource component can link to the
dataset, and data-aware controls can link to the data source. But
what does this feature mean to you? Well, now you can use standard
Delphi data-aware controls, such as TDBGrid, to edit, assert, and
retract facts from the engine. Your user (or you) need not know
any CLIPS! As a bonus, by making the IE data-aware and act
like a database at the same time, you can chain IEs together.
IE1->TIEDataset->TDataSource->IE2!
The database support is rounded out in the IECS by supplying functions
so that you can work with these new features from within your expert
system. For example, an 'assert-record' function is now
available that will not only assert your fact into the inference engine,
but if the fact template is mapped to a dataset, will also post a
record.
This is only a quick explanation of the new database features in the
IECS. Hopefully, it has whetted your appetite for version 2.0.
In the coming months, we will discuss other features of this major
upgrade.
Many times, you may want to write an expert system where only certain
rules should be considered at certain time. For example, you may
want to write rules that only fire during some initialization phase,
other rules to fire when an expert system is "reasoning",
and finally, some rules at the end to clean up. What you are
looking for is some way to control the flow of execution in
the expert system, to partition your rule set.
To partition your rule sets is very easy. You define a special
phase, or flow-of-control, fact type, which is used as a pattern on
the left-hand-side of your rules to control their activations.
For example, say you wanted to have three periods in your expert
system: init, reason, and cleanup. To write rules that would
only execute in the reason period, you would include the (phase
reason) fact in your rule:
(deftemplate citizen (slot name) (slot status))
(defrule MyRule
(phase reason) (citizen (name ?name) (status good)) => (printout t ?name " is a good citizen"))
To implement your flow of control automatically, e.g., to change
phases, you need a fact set (or deffacts in CLIPS terminology) and a
"phase change" rule. The fact set specifies the phase
fact and enumerates all the phases using some
"next-phase" facts. The phase change rule is a rule with
a really low priority so that it only fires if no other rule can
fire. If the phase change rule fires, it automatically
advances the phase to the next phase in the enumeration.
For example, ; ************************* ; Fact Sets (deffacts phase-factset "" (phase init) (next-phase init reason) (next-phase reason cleanup) ) (defrule phase-change "Change phases if no other rules can fire" (declare (salience -10)) ?p <- (phase ?phase) (next-phase ?phase ?next-phase) => (retract ?p) (assert (phase ?next-phase)))
Often in expert systems, you will find yourself writing rules which
have variables. Variables match facts against a certain pattern
and then work with that specific fact's information in the right hand
side of the rule. For example,
(defrule MyRule
(phase reason) (citizen (name ?name) (status good)) => (printout t ?name " is a good citizen"))
?name is a variable. When the inference engine finds a citizen
fact that matches to "status equals good", this rule will be
activated. Using the ?name variable, you can access the fact's
name slot value on the right-hand-side of the rule, such as with the
printout function above.
Well, that is all well and good when you are writing rules in CLIPS,
but how do you access variables from within a rule's OnFire event, using a
TRule component at design-time? When the OnFire event is
called, your event handler gets two parameters: Sender (which is the
rule) and Context. It turns out Context is the key to getting
rules from your code. The TIEContext object is how the inference
engine library defines scope within an expert system. Just like
in Object Pascal, where you can have global variables which can be
hidden by local variables within a function or method, so too does the
inference engine have global and local variables. The scoping is
controlled through TIEContext objects. There is a global context
(GlobalContext property) for the inference engine. Every rule
firing also gets a local context which will contains the variables
defined only for that rule (such as the ?name variable above).
You use the Variable property of the TIEContext class to access
variables. The Variable property accepts the name of variable
(without the question mark) and returns its value (IIEValue
interface).
So, to write the above rule as a design-time rule, we would use the
following steps:
procedure TMainForm.Rule1Fire(Sender: TObject; Context: TIEContext);
begin InferenceEngine1.PrintOut( Context.Variable['name'].AsString + ' is a good citizen.' ); end;
In January, we made available for download from our web site a free
Flocking component. Last month, we extended the flocking
components to implement group formations! These new components
move your little boids into squares, wedges, etc like they are on a
parade ground! :) If you haven't already downloaded it, you
should get it as it really is an amazing display of emergent behavior.
The demo comes with source and executable for testing the flocking
code. It demonstrates how to implement formations using flocking
behavior. The formation flocking code is based on the four rules of
flocking: separation, alignment, cohesion, and avoidance. The
Formation Flocking code however modifies the standard cohesion and
separation rules to provide formations. The cohesion rule now
moves the boid towards its position in the formation rather
than toward the flock's center point. The separation rule has
been modified so that it doesn't interfere when the boid is in its
place in formation. In addition, the separation strength has been
turned way down to avoid the boids from pushing away from each other
in the formation.
You can find the Formation Flocking component at http://www.riversoftavg.com/formation_flocking.htm |
Send mail to
webmasterNO@SPAMRiverSoftAVG.com with questions or comments about this web
site.
|