Pergunta

I have an object graph that I am trying to generate Fulfillment object from in Drools. Specifically, Fulfillment objects represent a rule that is either satisfied, or unsatisfied. My object graph looks like the following:

Users ---> many Requirements --> Event
      `--> many Records      ----^

Records can fulfill Requirements if they both point at the same Event. This produces a Fulfillment object in Drools.

A reduce down rule to produce Fulfillments is the following:

rule "fulfils"
when
    $u : User()
    $rec : Record() from $u.records
    $r : Requirement(event contains $rec.event) from $u.requirements
then
    insertLogical( new Fulfillment($u, $rec, $r, true));
    System.out.println("Inserting logical");
end

rule "unfulfils"
when
    $u : User()
    $rec : Record() from $u.records
    $r : Requirement(event not contains $rec.event) from $u.requirements
then
    insertLogical( new Fulfillment($u, $rec, $r, false));
    System.out.println("Inserting logical");
end

query "fulfillment"
    $fulfillment : Fulfillment()
end

The problem I run into here is if the user has no records, there is no Fulfillment inserted for the requirement. I believe this is because there is no Record() to search on to satisfy my graph.

Is there a way to use the records without requiring more than zero to exist?

Also, do I need two rules here to insert both true and false Fulfillments or is there a better way to do this?

Edit

Another problem I am facing with these rules is the Requirement(event contains $rec.event) does not accomplish the task of finding if any records satisfy the given collection of events. Is there a better way to find if there exists an overlap between the many record's single events, and the single requirements multiple events?

Another Edit

Here's another approach I thought up. Instead of inserting Fulfillments if a requirement/record pair is not found, why not just insertLogical Fullfillments for all Requirements that have no matching positive Fullfillment:

rule "unfulfils"
when
    $u : User()
    $r : Requirement() from $u.requirements
    not(Fulfillment(user == $u, requirement == $r, fulfilled == true))
then
    insertLogical( new Fulfillment($u, null, $r, false));
    System.out.println("Inserting logical");
end

query "fulfillment"
    $fulfillment : Fulfillment()
end

This takes care of the issue of comparing the overlap of two collections, and the case where a user has no records. (Would appreciate some validation on this).

Foi útil?

Solução

Using 2 different rules for your situation is a common pattern. It makes your rule base easier to read (and in a way to maintain too). Regarding your question about no Record(), I think you could write something like this (If I understood your question correctly):

rule "unfulfils because of no Record"
when
    $u : User(records == null || records.empty == true) //A user without records
    $r : Requirement() from $u.requirements // but with Requirements
then
    //You don't have a record to set in your Fulfillment object
    insertLogical( new Fulfillment($u, $rec, null, false));
    System.out.println("Inserting logical");
end
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top