Newsletter #3: February/March 2001 Edition
Home Up Feedback Search

Articles & Tips
Recommended Links



RiverSoftAVG Newsletter #3
February/March 2001
Hello and welcome to the third edition of RiverSoftAVG's newsletter!  It is hard to believe that it is already time for the third one.  We hope you have been finding these newsletters useful.  We try to give you a mix of news, tips, and downloads so that these newsletters are useful to everyone, even those who check our web site regularly.  If you have any ideas or comments, please don't hesitate to let us know how we are doing. 
This newsletter took longer than usual because we have been hard at work developing the second version of the Inference Engine Component Suite.  Unfortunately, please don't expect the second version before late Summer/Fall 2001.  The feature set of the second version is starting to settle down and we are excited about it.  It will be the next major version of the inference engine adding some great features.  We are sorry but the next version will not be a free upgrade, as yet, pricing has not been determined.  In upcoming newsletters, we will reveal more about the second version.  Stay tuned!  In the meantime, be sure to read the results of the Inference Engine Component Suite Survey Results as well as answer our Query to Users: How should RiverSoftAVG handle interfaces?  Now on to the newsletter!
A reminder, this newsletter and all previous ones are available for download from the web site at
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.
The Inference Engine Component Suite has been updated!  February 5th, RiverSoftAVG posted a bug fix update to the suite upping the version from 1.1 to 1.11.  The major "feature" of the update was the elimination of a bug in the rule editor dialog.  Rules could not be added or replaced because of embedded spaces in Salience edit box. This bug was introduced in
in v1.1 when salience became a TMaskEdit instead of TSpinEdit.  If you don't already have it, hurry to the web site at to download the update. The complete version history is available at
Last issue, we included a IECS survey, to get valuable feedback on how we are doing and in what direction we should be going.  First, thanks to all who responded.  Every answer was carefully read and noted.  The response rate was lower than we had hoped, approximately 25% of users responded.  Perhaps this was because it was the holiday season or perhaps it's just typical return rates for these types of survey.  However, we did get some great feedback, and it is never too late to fill out the survey (just use the last newsletter available at or from your mailbox). 
Now onto the results so far.  In general, we seem to have been doing a good job and people were pleased with the IECS, though everyone admitted that making expert systems is hard :)  We sincerely wish that this was easier too.  Expert systems are a powerful and great AI technique but are not a silver bullet.  For version 2, we plan to address this, at least in part.  There will be a new wizard to make the initial setup of an expert system problem easier.  The other major thing we learned you wanted is database support.  We are happy to say that database support will also definitely be in version 2.  We took all your answers to heart and are trying to address them, at least partially, in version 2.  We will reveal more about version 2 in upcoming newsletters.
As you know, the Inference Engine Component Suite relies heavily on interfaces to decouple objects from each other and to make it easier for you to insert your own objects into the hierarchy.  Version 2 is going to possibly require extensions to some interfaces.  Usually, conventional programming wisdom states that a new interface should be defined that extends the old one, such as an IFactTemplate2 interface which descends from the IFactTemplate interface.  This ensures no old code is broken by the changes.  For example, Microsoft's DirectX interfaces have gone through multiple versions of IDirectDraw, IDirectDraw2, etc.  However, while this makes undeniable sense for Microsoft with their thousands, if not millions of developers, the IECS family is a LOT more modest and is just starting out.  Making multiple interfaces makes the code a lot less cleaner AND can slow the code down by forcing the Inference Engine to have extra logic for each new interface.
So, our question to you:
Given that changing any interfaces is transparent to you, unless you have implemented them yourself within your code, will it impact and bother you if we change interfaces rather than descend from them?
Since the number of users is very small, it is unlikely that anyone has implemented our interfaces yet, and it keeps the code base cleaner, RiverSoftAVG is planning to change interfaces rather than descend from them unless we hear a firestorm of protest.  Note that we are not planning to change IUserFunction, which is the one interface which it could be expected that you have implemented it in your code. 
Please let us know what you think!
Many of you are aware of the power of functions within the Inference Engine Component Suite.  Functions and IUserFunctions, such as assert, printout, cos, etc., can be called from the console and on the right-hand side of a rule.  However, were you aware that functions can be called from the left-hand side of a rule?
A typical rule is made up of a series of patterns on the left-hand side (antecedents) of a rule and a series of actions (consequents) on the right-hand side of a rule.  The patterns must be matched to facts in the fact base in order to activate a rule for firing.  A typical rule looks like this:
(defrule test-question
(stack a)
(printout t "Rule Fired!"))
If there are facts with the pattern, (stack a), the rule gets activated and placed on the agenda.  And when the inference engine gets to that activation on the agenda, the rule fires.
In addition to patterns, you can also evaluate functions that must be TRUE in order to activate a rule.  There is a "test" predicate in CLIPS that can be used to call a function in the left-hand side of a rule.  When you add a rule to CLIPS, if ALL the preceding antecedents are TRUE, the test predicate will immediately execute the function to determine if it is true and the rule can be put on the Agenda.  The function is executed when the rule is created or some new fact causes the preceding antecedents to be TRUE, NOT when the rule is put on the agenda.  Some later antecedent could FAIL, preventing the rule from being put on the agenda, but the test will still have executed.
So for example, you can create a TUserFunction (FunctionName='ask-question'; MaxArgumentCount = 1; MinArgumentCount = 1; Engine = InferenceEngine1; and OnCall event equal to:
procedure TMainForm.UserFunction1Call(Sender: TObject; FunCall: IFunCall;
  Context: TIEContext; var Result: IIEValue);
     if MessageDlg( FunCall.Argument[0].Resolve(Context).AsString,
                    mtInformation, [mbYes, mbNo], 0) = mrYes then
        result := FCTrue
         result := FCFalse;
Then, you can define a rule:
(defrule test-question
(stack a)
(test (ask-question "say yes"))
(printout t "Rule Fired!"))
When you assert facts, if you (assert (stack a)), the test predicate will fire and ask you the question "say yes".  If you click "Yes", the ask-question function returns TRUE and the rule is put on the agenda.  When it fires, it will print out "Rule Fired!".  However, if you click "No", the function returns FALSE and the rule is not put on the agenda for that fact.
Note that there are no restrictions on the functions that may be called, they just must evaluate to TRUE for the rule to be activated.  If a function never returns TRUE (for example, Assert), the rule can never be activated though the function may be executed many times (every time a new fact is added to the fact list which matches preceding patterns).
Currently, there is a restriction at design-time that the test predicate cannot call a TUserFunction component design-time function, though it can at run-time.  This is not a concern unless you don't have any preceding antecedents/patterns or that they are already matched by facts you have inserted at design-time.  This restriction will be removed in Version 2.
In January, we made available for download from our web site a free Flocking component.  The demo comes with source and executable for testing the flocking code.  It demonstrates how to implement flocking behavior. Flocking is an artificial intelligence technique for simulating "natural" behaviors for a group of entities, such as a herd of sheep, a school of fish, etc. Flocking uses four simple rules (separation, alignment, cohesion, and avoidance) to control each member, or boid, of a flock to create an emergent behavior which mimics real-life behavior.
You can find more information and download the Flocking component at
Send mail to with questions or comments about this web site.
Copyright 2002-2010 RiverSoftAVG
Last modified: September 20, 2010