“In this post I will describe an alternative solution where the database is replaced by a rule engine and object serialization.”
While working with my master thesis, I’ve come across several many-to-many dependencies between concepts in a domain model I’m currently studying which focuses on calculation of pollutive emissions from ships. A common way of implementing this type of dependency between concepts is by using a relational database. This solution typically involves three tables, two of them describing the two concepts and a mapping table taking care of the relation between them.

In addition, you need a bunch of code to take care of the connection to the database, CRUD operations, and not at least to ensure consistency between the object model and the database tables. Setting up all this is time consuming and boring work, and the result has has weaknesses (e.g. what if relational characteristics of concepts in the model changes?).
The following tables shows some test data.



It’s not a pleasant job to maintain table data like the above directly, without using SQL calls with a syntax you never remember properly. In this post I will describe an alternative solution where the database is replaced by a rule engine and object serialization.
By using a rule engine such as BRIX Rules, relations are mde by freely combining object attributes in a separate graphical interface. A clear advantage of this approach is that the relations are made by using the object attributes directly – not by querying a separate mapping table.
The EngineType class may look something like this, a pretty basic XML-serializable class. The EmissionType class is implemented in the same way.
public class EngineType : IFindable
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("description")]
public string Description { get; set; }
public EngineType()
{
}
}
Instances of EngineType are serialized to XML, and retrieved by deserialization (reading the XML-file). This is done in a generic XMlSerialization class.
...
public static void Main()
{
EngineType engineType = XMLSerialization<EngineType>.Find("Slow Speed");
EmissionType emissionType = XMLSerialization<EmissionType>.Find("CO2");
Console.WriteLine("KgPerMetricTon=" + Emission.GetKgPerMetricTon(engineType, emissionType))
}
A WorkingMemory class sets up the connection to the rule engine, much in the same manner as connecting to a database. The rulebase is maintained through the rule system interface, possibly by an external domain expert.
'
public class Emission
{
...
public static double GetKgPerMetricTon(EngineType EngineType, EmissionType EmissionType)
{
double kgPerMetricTon = 0.0;
object[] inArgs = new object[] { EngineType, EmissionType, kgPerMetricTon };
object[] outArgs = (object[])WorkingMemory.Instance.FireRule(inArgs, "EngineTypeToEmissionType");
kgPerMetricTon = (double)outArgs[2];
return kgPerMetricTon;
}
}
The relation between engine types and emission types are set up as a graphical matrix in BRIX Rules. Each axis cell holds premises like
If EngineType.Name=="Slow Speed" or If EmissionType.Name=="CO2" and each result cell is performing a result action like assigning a value to a return variable ?kgPerMetricTonFct:=3170

The table above is invoked by the consequent (look at it as a function), taking the EngineType and EmissionType objects as in-parameter and returns the value of ?KgPerMetricTonFct.

Setting a single attribute value based on attribute values from to classes is a simple case – yet I think it already reveals potential for incorporating externally maintained rules into the business logic of software applications working on domain knowledge like this. I’m working to get more advanced examples up and running, involving rule chaining (rules invoking rules) and more ambitious relations between domain model concepts.

The figure above tries to depict the abstraction levels in the two solutions. Gray represents data storage, while yellow represents business logic. The size of the ellipsis, is not accidental – it should give and indication of the amount of code involved.
I’m actually a bit surprised that rule-based approach such as this is not more common practice already. The answer might be that as the good old relational database still is needed anyway, why bother to have more dependent components (the rule engine) and to learn a new and unfamiliar computational regime?