ibm-odmrete

How to update state of list so that Rete picks up the objects added therein for rules re-evaluation


I am using IBM 8.9.2 and we have a scenario where I need to create a list X based on values from the list Y while grouping on those values.
For example, lets say I have a list of cities and every City object (in cityList list) has an attribute - country. Now I want to invert the relationship and create a countries list which consists of Country objects having a containedCities list.

My rule is

definitions
    set 'cities' to all cities in cityList;
    set 'a city' to a city in 'cities'
    set 'countries' to all countries in countryList;
    set 'a country' to a country in 'countries'

if 
    the country code of 'a city' is the country code of 'a country'
then
     add 'a city' to the contained cities of 'a country' ; (** Assume B2X/XOM has method for adding the city to the country list)
else
      create country for 'a city' and add it to countryList ; (** Assume appropriate B2X/XOM)

Adding a country to countryList will not update it's object state and hence will not reintroduce it on the agenda for a re-evaluation of rules after the rules run for the first city of cityList.
The result hence is a list of countries with a new Country object created for each city rather than the grouping that was planned.
The goal I am aiming for is that I insert both cityList and countryList in the memory and turn Rete on so that the pattern matching can happen on the fly in memory.

Looking for pointers on how I can achieve this.


Solution

  • I would write two separate rules. One to add the country of every city to the list of countries. Another to add every city to the appropriate country. Both BOM 'add' methods should have 'Update object state' checked. Note: I've added comments to the rules where ODM does not allow such.

    First Rule

    definitions
        set 'the city' to a city in cityList ;
    
    if 
        the country code of 'the city' is not one of the country codes of countryList // Assume BOM method exists
    then
         add the country code of 'the city' to the country codes of countryList ; // Assume BOM method exists
    

    Second Rule

    definitions
        set 'the city' to a city in cityList ;
        set 'the country' to a country in countryList 
            where the country code of this country is the country code of 'the city';
    
    if 
        'the city' is not one of the cities of 'the country' // Requires City.equals method
    then
         add 'the city' to the cities of 'the country' ; // Assume BOM method exists