[rules-users] Capturing condition/constraint evaluation results

Davide Sottara dsotty at gmail.com
Mon Jan 28 18:31:01 EST 2013


There was a similar discussion going on some time ago
http://drools.46999.n3.nabble.com/Anyway-to-get-Failed-Reason-for-Failed-Rule-td4019070.html#a4019078

This said, what you are asking is not possible using the current APIs
because constraints are
not observable. There are ways to hack the problem, but all require a deeper
understanding of 
the internal structure of the engine.

Moreover, it would make a big difference if your use case is the general
"detect whenever a constraint 
is not satisfied" as opposed to "find facts which can't possibly lead to ANY
rule activation to
be allowed to retract them". Your last message seems to point in the latter
direction, is this
the case?

Good news is, the next version of Drools might be based on a different
algorithm which will make
it much easier to trace rule execution. Mark Proctor might be able to
provide more details.
Best
Davide

WARNING: Code hacks below:






Just to give you an idea of the code hacks:
*WARNING : not being public, these methods are subject to changes.*

In the latter case, you can possibly do this:

FactHandle h = ksession.insert( foo );
        boolean inLeft = ((DefaultFactHandle) h).getFirstLeftTuple() !=
null;
        boolean inRight = ((DefaultFactHandle) h).getFirstRightTuple() !=
null;
if ( ! inLeft && ! inRight ) ksession.retract( h );
 
if an object, after being insert, has blocked along ALL possible paths in
the RETE network, 
it means that it won't lead to any activation (unless rules are changed) so
I guess they 
could be safely retracted. In this case, both get methods above would return
null.



The more general case is much more complicated, and requires hacking either
the constraints
or the nodes, making them signal whenever they block an object or tuple.
The code is MUCH messier, for example this is what you could do to customize
the alpha nodes:

RuleBaseConfiguration rbc = (RuleBaseConfiguration)
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
        rbc.getComponentFactory().setNodeFactoryProvider( new
DefaultNodeFactory() {
            @Override
            public AlphaNode buildAlphaNode( int id,
AlphaNodeFieldConstraint constraint, ObjectSource objectSource, BuildContext
context ) {
                // Option 1: Wrap the constraint to add the behavior :
                // AlphaNodeFieldConstraint wrappedConstraint = new
NotifyingAlphaNodeFieldConstraint( constraint );
                // return super.buildAlphaNode( id, wrappedConstraint,
objectSource, context );

                // Option 2 : override the node behavior
                return new AlphaNode( id, constraint, objectSource, context
) {
                    @Override
                    public void assertObject( InternalFactHandle factHandle,
PropagationContext context, InternalWorkingMemory workingMemory ) {
                        final AlphaMemory memory = (AlphaMemory)
workingMemory.getNodeMemory( this );
                        if ( getConstraint().isAllowed( factHandle,
                                workingMemory,
                                memory.context ) ) {

                            this.sink.propagateAssertObject( factHandle,
                                    context,
                                    workingMemory );
                        } else {
                            // Signal here
                            System.err.println( "Constraint evaluation
failed for " + factHandle );
                        }
                    }
                };
            }
        });
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase( rbc );





--
View this message in context: http://drools.46999.n3.nabble.com/Capturing-condition-constraint-evaluation-results-tp4021831p4021895.html
Sent from the Drools: User forum mailing list archive at Nabble.com.


More information about the rules-users mailing list