Rule Grammar Persistence

Here is a very high-level diagram of the grammar for storing rules in the logic games project.

RuleBase is the top-level class that stores the collection of Rules and the collection of known Facts. A Rule consists of an Antecedent (the "if" portion of the rule) and a Consequent (the "then" portion of the rule). The consequent is a simple Clause, which consists of an Entity / Property pair a comparator and a value for the property. So to represent a car being painted blue, we would have an Entity of "car", a property of "color", a comparator of "equals" and a value of "blue". The antecedent is a ClauseCluster, which represents one or more Clauses joined by the Boolean operators AND, OR and NOT. To represent this, a ClauseCluster has a left-hand side (lhs) and a right-hand side (rhs), each of which can either be a Clause, or another ClauseCluster. So you get a tree of ClauseClusters, where the leaves of the tree are Clauses, and the depth of the tree represents different levels of parenthesization.

I want to be able to persist RuleBases. It's not really necessary for this project, but it will help with testing, and since this is all just a way for me to learn more about knowledge representation, I wanted to make sure I could persist that knowledge as well.

I started working with DataMapper as the persistence layer. I've done a bunch of work with ActiveRecord, and I wanted to try something new. DataMapper has several features that make it really interesting to me. I like the query syntax, and I love that it only keeps one instance of each object in memory at a time. However, one thing it is lacking that I need in this project is polymorphic associations. Since the lhs and rhs of a ClauseCluster can either be a Clause or another ClauseCluster, I need a way to define a relationship based on both id and type. I only need to ever walk the tree from top to bottom, so only need one side of the polymorphic relationship (i.e. a ClauseCluster has one lhs and has one rhs, but I don't care if the lhs and rhs know who their parent ClauseCluster is). So I'm putting together a very simple implementation of polymorphic associations for DataMapper. It's too simple to be of much use to anyone outside of this project, but I'll post the code when it's ready.