I have been using CLIPS (C Language Integrated Production System) for quite sometime and very much appreciated its beauty of minimalism and inherent parallelism in using declarative rules as "knowledge" to perform "reasoning".
It is the most elementary form of artificial intelligence but proven to be the most widely used, especially in handling business logic, decision-making type of "if-then" rules, however, not using the conventional procedural progrmamming.
From
here you should be able to find a good introduction to CLIPS.
Here I will try to sum up my understanding of CLIPS. This is the preparation to the ultimate exploring of bridging CLIPS with C#, in much the same way as JESS with Java. I found out the ability to directly reason with and manupliate C# business entity objects in a CLIPS alike archtecture could prove very attactive.
Why the simplicity? A rule based architecture such as CLIPS is based on the many-to-many matching philosophy (or problem).
The current state of the world is usually described by the working memory containing descriptions of objects.
A rule consists of the condition part and the action part. The condition part of a rule is matched against the description of the objects in the working memory. If the patterns are matched, such a rule would be included into a resulting set. This loops until the patterns in the working memory no longer match the condition part of any rule. The resulting set is now constructed and called the conflict set. Such a step is also called rule activation. During the matching, if you match LHS of the rule (the condition) with the fact, it is called forward chaining. This is used in CLIPS. If you match RHS of the rule (the action) with hypothesis, it is backward chaining.
By means of conflict resolution, ONLY one rule of the conflict set is selected and fired, which means the action part of the rule is executed and the current state of the world or the working memory is updated.
Such a cycle continues until the conflict set would be empty.
From the above description, it can be seen that a rule based system invovles a lot of search (and pattern match), and the conflict resolution strategy is essential in reducing the search. The conflict resolution strategy of CLIPS would be described in details sometime later, but for now, let us see an example of a rule.
A fact could be simply as:
(ModuleOwner SQL_Sp Bob) // Meaning Bob owns the module called SQL_Sp
More facts are as follows:
(ModuleOwner DataAccess Bob)
(ModuleOwner DataAccess Shirley)
(ModuleOwner ASPNET_Forms Shirley)
(ModuleOwner Workflow Ivan)
Imagine you want to find out the person who owns only a single module:
(defrule single_module
(ModuleOwner ?a_module ?a_person) ; [1]
(not (ModuleOwner ~?another_module ?a_person)) ; [2]
=>
(assert (single_module ?a_person))
)
The above rule would be activated for Ivan because if ?a_person is instantiated in [1] as Ivan, ?a_module is instantiated as Workflow during the pattern matching, you would not be able to instantiate ?another_module which is not Workflow in [2]. Simple and effective, isn't it?
After (single_module Ivan) is being asserted into the working memory, the state of the whole world is changed and you could write rules that pattern-match (single_module ?someone) and you can have the reasoning continues.
The best part is that the order of the rules is not important at all, you can write whichever rule you think of first - this is the simplicity and aiding the separation of concerns - as long as you do not forget one - of course, who fires first and the efficiency depends much on the conflict resolution strategy. A selected rule would also be fired for all objects with matched patterns and this is implicit parallelism.
So much for Part 1. The next one should write about conflict resolution strategy in CLIPS.