Question

I realize the title is crazy, but it really is the best I could think of. If anyone has better suggestions please leave them in the comments and I'll edit.

This question is a followup to the question asked here : Drools Constraint object other than P is found in collection

For those who don't want to click, that post describes the solution to the situation in which you want to know if there is a fact of CustomType which has a member field containing a value other than P. The Solution to this problem ended up being the following:

$c: CustomType()
exists Object(this != objectP) from $c.collection

The above code works great. My problem is that I want to know when there does not exist an object of type CustomType with this property. Now, since line 2 relies on a bound variable given in line 1, we cannot simply negate line 1 with a not operator. Doing so would throw a runtime exception. The following is how I intuitively want to write the code, but keep in mind it doesn't work:

not $c: CustomType()
exists Object(this != objectP) from $c.collection

I cannot simply negate line 2, because then the rule would require the existence of at least one object of CustomType. I want to know when the first code example is not the case.

My inner drooler tells me the original Solution might be flawed. Ideally we would want to express line 2 within the parentheses() of the CustomType. This would be expressing something more along the lines of "there is a CustomType with the property" rather than "There is a CustomType, and there is an Object with the property". The former we could negate with a not operator, but I'm not sure what to do with the latter.

Was it helpful?

Solution

When you need to work with constraints such as these, which need to be expressed in multiple lines, and negations of them, I think you're moving into the world of inference and truth maintenance:

http://blog.athico.com/2010/01/drools-inference-and-truth-maintenance.html

i.e. Your rules could be something like:

rule "Determine presence of non-P objects" when
    $c: CustomType()
    exists Object(this != objectP) from $c.collection
then
    insertLogical( new ContainsNonP($c) );
end

rule "There are some non-P objects" when
    $c: CustomType()
    exists ContainsNonP(customType == $c)
then
    ...
end

rule "There are no non-P objects" when
    $c: CustomType()
    not exists ContainsNonP(customType == $c)
then
    ...
end

Note that the final rule above may activate if the first rule has not yet activated. If the order of activations is important to your rules, you may wish to define some salience.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top