ObjectiveCLIPS Updated

ObjectiveCLIPS, a programming environment specifically designed for Cocoa, the native Mac OS X object system, has been updated to version 1.7. The new release includes a number of significant performance improvements along with a new execution trace feature that provides extensive logging of trace information during development.

ObjectiveCLIPS integrates the popular NASA-developed CLIPS expert system shell with Apple's Core Data technology and F-Script, allowing the creation of intelligent Cocoa applications with persistent object models and complex business rules. Developers can easily embed ObjectiveCLIPS in their application and take advantage of its powerful inference engine and associated tools to implement their application logic.

ObjectiveCLIPS unifies CLIPS facts with Core Data Objective-C objects, and allows for the manipulation of these objects with the Cocoa-based F-Script language in rules. By bringing the latest innovations in Mac OS X and object-oriented scripting together with the power of the CLIPS artificial intelligence environment, ObjectiveCLIPS provides a unique foundation for building smart Mac OS X applications.

ObjectiveCLIPS is open source software. It can be downloaded from http://www.ObjectiveCLIPS.com

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Clips?

Hey Todd, after all these years of you referring to CLIPS, I'm still not sure I understand what it actually does. Part object database; part query language; part automation tool; part rules based language? And I gather you're experience with FScript has been pleasant?

CLIPS is an inference engine

C Language Integrated Production System.

Split the world into facts (data) and rules (pattern=>action pairs).

Apple's Cocoa lets you create a UI using Interface Builder, and a persistent object model using CoreData. With bindings you bind entities in the object model to UI elements through configurable Controllers. All of this can be done without a line of code an you have a dumb MVC application that can save its data to a file. But there is no behavior.

In Apple's view, you would subclass the data objects and write code to implement constraints. This is a typically fragile process. Example:

PurchaseItem of Quantity, UnitPrice, Tax, Amount.
Constraint: Amount must equal Quantity*UnitPrice + Tax.
Constraint: Tax must equal Quantity*UnitPrice*TaxRate.


I can write this in code - or I can use CLIPS rules to express the constraints.
Sample rule would go here but the system keeps eating it.


Whenever this constraint is violated, the rule is "activated" and eventually "fired" (the RHS is performed). This keeps the amount up to date with the quantity, price, and tax.

CLIPS is way better at business rule constraints because patterns can span many objects using joins (just like relational joins in a db) and you don't have to do the messy navigation to see if that value in the object over there has changed.

Good OO design works against business rule implementation because "Objects Are Intentionally Myopic". I integrated FScript into the CLIPS language by installing custom parsers. FScript is surrounded by Smalltalk block syntax [FScript is in here]. This lets you script the ObjectiveC objects directly from the rules. Its all very seamless. If you have a Mac, download the package - it comes with a sample application with half a dozen rules. FScript, BTW, rocks.

see also materialized views

The RETE algorithm can be thought of as a way of maintaining materialized views on a database, for limited kinds of queries.

The trouble with rule-based-programming is that the chains of causality arent explicity stated, but are implicit based on the queries and the data.

In addition, because the rule/action pairs both observe the database as well as modifying it, as a chain of rule/action pairs succesively cause the next to activate, it becomes rapidly very difficult to characterise the emergent behavior of the system.

In this way, its a bit like a spreadsheet in that the logic is distributed throughout the application, and its hard to get an overall picture of its operation from a high level.

I think that's a feature

"The trouble with rule-based-programming is that the chains of causality arent explicity stated, but are implicit based on the queries and the data."

I don't see that as trouble. Its not at all hard to include an "explain" feature that illustrates the chains. In fact, its a feature I'm considering adding to ObjectiveCLIPS. I've been meaning to improve undo record aggregation so that undoing a single user edit will also undo all the consequent edits performed by rules to accurately roll back the system. Since I have to log the changes, I can also log the rules making the changes and use this to explain causality.

"In addition, because the rule/action pairs both observe the database as well as modifying it, as a chain of rule/action pairs succesively cause the next to activate, it becomes rapidly very difficult to characterise the emergent behavior of the system."

Again this is a feature. You don't have to specify all permutation to get reasonably intelligent behavior and the independent nature of the rules makes the system much more reliable in the face of changes. Ladder logic is fragile and hard to modify.

Additionally, with rules you sort of "program by induction" where you end up with a sequence of rules firing in logical succession because altogether they form a chain of reason. This chain may not be clear to you at the time you are representing your knowledge.

OTOH, if you can characterize the behavior of the system accurately, then you have an algorithm on your hands and you don't need to be relying on heuristics.

When to use rules

The RETE algorithm can be thought of as a way of maintaining materialized views on a database, for limited kinds of queries.

IIRC, RETE does the equivalent of SELECT/PROJECT (pattern matching) at alpha nodes, and natural JOINs at beta nodes. Negation complicates things, and I can't remember how it is handled (been a while since I implemented a RETE). There are other algorithms too: TREAT does away with beta nodes and claims to be more efficient; LEAPS is a lazy algorithm that, IIRC, combines the matching and conflict resolution stages for efficiency (but loses flexibility?); RETE* is a more modern development, which allows limiting the number of beta nodes, thus allowing TREAT and RETE at each extreme (no betas vs full betas resp.).

The trouble with rule-based-programming is that the chains of causality arent explicity stated, but are implicit based on the queries and the data.

As tblanchard pointed out, this is the whole point of rules; that you don't explicitly state the flow of control. Ideally rules could be given a logical semantics, similar to Prolog etc. In practice, there is often a reliance on non-local side-effects and imperative actions in rule based programs that scuppers this. (Retractions are hard to avoid in rule-based programming, which implies a non-monotonic semantics, but there are ways for making this less of an issue).

In this way, its a bit like a spreadsheet in that the logic is distributed throughout the application, and its hard to get an overall picture of its operation from a high level.

Rules are supposed to allow you to reason locally, without having to have a global view. A rule should be able to be considered independently: it says under what conditions it may fire, and what effect it will have. If you need to know the precise chain of rules that will cause it to fire, then quite likely this is an inappropriate use of rules, and you might be better off using some other paradigm (e.g. functional programming). There are difficulties with rules though. The use of the phrase "may fire" above illustrates one of them. It can be a fine art picking a good conflict resolution strategy that ensures that rules do actually fire when you expect them to. The presence of retractions and other non-local effects make this more important, as they are bringers of causality. The best rule based programs I've seen separate out a main set of rules which only assert new facts from those which cause retractions. Run the former set first allowing all rules in the conflict set to fire, and then run the separate house-keeping rules that cause retractions.

Conflict Resolution

"It can be a fine art picking a good conflict resolution strategy that ensures that rules do actually fire when you expect them to."

CLIPS has several conflict resolution strategies you can choose from. In the end if I need something other than random I usually end up with the complexity one. The rule with the most complex match pattern goes first. As it happens, this is usually right since the wacky "exception that proves the rule" rule will usually have a fairly elaborate match pattern.

You point about having two sets of rules is on as well. I don't always need it, but its good to have.