Package org.drools.reteoo

Source Code of org.drools.reteoo.LogicalAssertionTest

package org.drools.reteoo;

import org.drools.DroolsTestCase;
import org.drools.FactException;
import org.drools.FactHandle;
import org.drools.RuleBase;
import org.drools.rule.Rule;
import org.drools.spi.Activation;
import org.drools.spi.ClassObjectType;
import org.drools.spi.Consequence;
import org.drools.spi.PropagationContext;

public class LogicalAssertionTest extends DroolsTestCase
{

    public void testSingleLogicalRelationship() throws Exception
    {
        /*
         * create a RuleBase with a single ObjectTypeNode we attach a MockObjectSink so we can detect assertions and retractions
         */
        Rete rete = new Rete();
        ObjectTypeNode objectTypeNode = rete.getOrCreateObjectTypeNode( new ClassObjectType( String.class ) );
        MockObjectSink sink = new MockObjectSink();
        objectTypeNode.addObjectSink( sink );
        RuleBase ruleBase = new RuleBaseImpl( rete );
        WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase.newWorkingMemory();

        final Agenda agenda = workingMemory.getAgenda();

        Consequence consequence = new Consequence() {
            public void invoke(Activation activation)
            {
                // do nothing
            }
        };
        final Rule rule1 = new Rule( "test-rule1" );
        rule1.setConsequence( consequence );

        FactHandleImpl handle1 = new FactHandleImpl( 1 );
        ReteTuple tuple1 = new ReteTuple( 0,
                                          handle1,
                                          workingMemory );

        final PropagationContext context1 = new PropagationContextImpl( PropagationContext.ASSERTION,
                                                                    null,
                                                                    null );

        /* Test single activation for a single logical assertions */
        agenda.addToAgenda( tuple1,
                            context1,
                            rule1 );
        ModuleImpl main = (ModuleImpl) agenda.getFocus();
        Activation activation1 = (Activation) main.getActivationQueue().get();

        String logicalString = new String ( "logical" );
        FactHandle logicalHandle = workingMemory.assertObject( logicalString,
                                                               false,
                                                               true,
                                                               rule1,
                                                               activation1 );
        agenda.removeFromAgenda( tuple1.getKey(),
                                 context1,
                                 rule1 );

        assertLength( 1,
                      sink.getRetracted() );

        Object[] values = (Object[]) sink.getRetracted().get( 0 );

        assertSame( logicalHandle,
                    values[0] );

        /*
         * Test single activation for a single logical assertions. This also tests that logical assertions live on after the related Activation has fired.
         */
        agenda.addToAgenda( tuple1,
                            context1,
                            rule1 );
        activation1 = (Activation) main.getActivationQueue().get();

        logicalHandle = workingMemory.assertObject( logicalString,
                                                    false,
                                                    true,
                                                    rule1,
                                                    activation1 );

        agenda.fireNextItem( null );

        agenda.removeFromAgenda( tuple1.getKey(),
                                 context1,
                                 rule1 );

        assertLength( 2,
                      sink.getRetracted() );

        values = (Object[]) sink.getRetracted().get( 1 );

        assertSame( logicalHandle,
                    values[0] );
    }

    public void testEqualsMap() throws Exception
    {
        /*
         * create a RuleBase with a single ObjectTypeNode we attach a MockObjectSink so we can detect assertions and retractions
         */
        Rete rete = new Rete();
        ObjectTypeNode objectTypeNode = rete.getOrCreateObjectTypeNode( new ClassObjectType( String.class ) );
        MockObjectSink sink = new MockObjectSink();
        objectTypeNode.addObjectSink( sink );
        RuleBase ruleBase = new RuleBaseImpl( rete );
        WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase.newWorkingMemory();

        final Agenda agenda = workingMemory.getAgenda();

        Consequence consequence = new Consequence() {
            public void invoke(Activation activation)
            {
                // do nothing
            }
        };
        final Rule rule1 = new Rule( "test-rule1" );
        rule1.setConsequence( consequence );

        FactHandleImpl handle1 = new FactHandleImpl( 1 );
        ReteTuple tuple1 = new ReteTuple( 0,
                                          handle1,
                                          workingMemory );

        final PropagationContext context1 = new PropagationContextImpl( PropagationContext.ASSERTION,
                                                                    null,
                                                                    null );

        /* Test single activation for a single logical assertions */
        agenda.addToAgenda( tuple1,
                            context1,
                            rule1 );
        ModuleImpl main = (ModuleImpl) agenda.getFocus();
        Activation activation1 = (Activation) main.getActivationQueue().get();

        String logicalString1 = new String( "logical" );
        FactHandle logicalHandle1 = workingMemory.assertObject( logicalString1,
                                                                false,
                                                                true,
                                                                rule1,
                                                                activation1 );

        String logicalString2 = new String( "logical" );
        FactHandle logicalHandle2 = workingMemory.assertObject( logicalString2,
                                                                false,
                                                                true,
                                                                rule1,
                                                                activation1 );

        assertSame( logicalHandle1,
                    logicalHandle2 );
       
        /* little sanity check using normal assert */
        logicalHandle1 = workingMemory.assertObject( logicalString1 );
        logicalHandle2 = workingMemory.assertObject( logicalString2 );
        assertNotSame( logicalHandle1,
                       logicalHandle2 );       
    }
   
    /**
     * This tests that Stated asserts always take precedent
     * @throws Exception
     */
    public void testStatedOverride() throws Exception
    {
        /*
         * create a RuleBase with a single ObjectTypeNode we attach a MockObjectSink so we can detect assertions and retractions
         */
        Rete rete = new Rete();
        ObjectTypeNode objectTypeNode = rete.getOrCreateObjectTypeNode( new ClassObjectType( String.class ) );
        MockObjectSink sink = new MockObjectSink();
        objectTypeNode.addObjectSink( sink );
        RuleBase ruleBase = new RuleBaseImpl( rete );
        WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase.newWorkingMemory();

        final Agenda agenda = workingMemory.getAgenda();

        Consequence consequence = new Consequence() {
            public void invoke(Activation activation)
            {
                // do nothing
            }
        };
        final Rule rule1 = new Rule( "test-rule1" );
        rule1.setConsequence( consequence );

        FactHandleImpl handle1 = new FactHandleImpl( 1 );
        ReteTuple tuple1 = new ReteTuple( 0,
                                          handle1,
                                          workingMemory );

        final PropagationContext context1 = new PropagationContextImpl( PropagationContext.ASSERTION,
                                                                    null,
                                                                    null );

        /* Test that a STATED assertion overrides a logical assertion */
        agenda.addToAgenda( tuple1,
                            context1,
                            rule1 );
        ModuleImpl main = (ModuleImpl) agenda.getFocus();
        Activation activation1 = (Activation) main.getActivationQueue().get();

        String logicalString1 = new String( "logical" );
        FactHandle logicalHandle1 = workingMemory.assertObject( logicalString1,
                                                               false,
                                                               true,
                                                               rule1,
                                                               activation1 );
       
        /* This assertion is stated and should override any previous justified
         * "equals" objects.
         */
        String logicalString2 = new String( "logical" );
        FactHandle logicalHandle2 = workingMemory.assertObject( logicalString2 );
       
        agenda.removeFromAgenda( tuple1.getKey(),
                                 context1,
                                 rule1 );
       
        assertLength( 0,
                      sink.getRetracted() )
       
        /* Should keep the same handle when overriding */
        assertSame( logicalHandle1,
                    logicalHandle2 );              
       
        /* so while new STATED assertion is equal */
        assertEquals( logicalString1,
                      workingMemory.getObject( logicalHandle2 ) );
        /* they are not identity same */
        assertNotSame( logicalString1,
                       workingMemory.getObject( logicalHandle2 ) );
       
       
        /* Test that a logical assertion cannot override a STATED assertion */
        agenda.addToAgenda( tuple1,
                            context1,
                            rule1 );
        activation1 = (Activation) main.getActivationQueue().get();
       
        logicalString2 = new String( "logical" );
        logicalHandle2 = workingMemory.assertObject( logicalString2 );       

        /* This logical assertion will be ignored as there is already
         * an equals STATED assertion.
         */
        logicalString1 = new String( "logical" );
        logicalHandle1 = workingMemory.assertObject( logicalString1,
                                                     false,
                                                     true,
                                                     rule1,
                                                     activation1 );      
        /* already an equals object but not identity same, so will do nothing and return null */
        assertNull( logicalHandle1 );   

        logicalHandle1 = workingMemory.assertObject( logicalString2,
                                                     false,
                                                     true,
                                                     rule1,
                                                     activation1 );
        /* already an equals object and identity same, so will do nothing and return the matched handle */       
        assertSame( logicalHandle2,
                    logicalHandle1 );          
       
        agenda.removeFromAgenda( tuple1.getKey(),
                                 context1,
                                 rule1 );
       
        assertLength( 0,
                      sink.getRetracted() )
       
        /* Should keep the same handle when overriding */
        assertSame( logicalHandle1,
                    logicalHandle2 );              
       
        /* so while new STATED assertion is equal */
        assertEquals( logicalString1,
                      workingMemory.getObject( logicalHandle2 ) );
        /* they are not identity same */
        assertNotSame( logicalString1,
                       workingMemory.getObject( logicalHandle2 ) );      
                      
    }   
   
    public void testRetract() throws Exception
    {
        /*
         * create a RuleBase with a single ObjectTypeNode we attach a MockObjectSink so we can detect assertions and retractions
         */
        Rete rete = new Rete();
        ObjectTypeNode objectTypeNode = rete.getOrCreateObjectTypeNode( new ClassObjectType( String.class ) );
        MockObjectSink sink = new MockObjectSink();
        objectTypeNode.addObjectSink( sink );
        RuleBase ruleBase = new RuleBaseImpl( rete );
        WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase.newWorkingMemory();

        Consequence consequence = new Consequence() {
            public void invoke(Activation activation)
            {
                // do nothing
            }
        };
       
        /* create the first activation which will justify the fact "logical" */
        final Rule rule1 = new Rule( "test-rule1" );
        rule1.setConsequence( consequence );            

        FactHandleImpl handle1 = new FactHandleImpl( 1 );
        ReteTuple tuple1 = new ReteTuple( 0,
                                          handle1,
                                          workingMemory );

        PropagationContext context =  new PropagationContextImpl( PropagationContext.ASSERTION,
                                                              null,
                                                              null );
       
        Activation activation1 = new AgendaItem( tuple1,
                                                 context,
                                                 rule1 );
           
        /* Assert the logical "logical" fact */
        String logicalString1 = new String ( "logical" );
        FactHandle logicalHandle1 = workingMemory.assertObject( logicalString1,
                                                                false,
                                                                true,
                                                                rule1,
                                                                activation1 );
       
        /* create the second activation to justify the "logical" fact */
        final Rule rule2 = new Rule( "test-rule2" );
        rule2.setConsequence( consequence );         
       
        FactHandleImpl handle2 = new FactHandleImpl( 2 );
        ReteTuple tuple2 = new ReteTuple( 0,
                                          handle2,
                                          workingMemory );

        Activation activation2 = new AgendaItem( tuple2,
                                                 context,
                                                 rule2 );

       
        /* Assert the logical "logical" fact */
        String logicalString2 = new String ( "logical" );
        FactHandle logicalHandle2 = workingMemory.assertObject( logicalString2,
                                                                false,
                                                                true,
                                                                rule2,
                                                                activation2 );
       
        /* "logical" should only appear once */
        assertLength( 1,
                      workingMemory.getJustified().values() );

        /* but has two justifications */
        assertLength( 2,
                      workingMemory.getJustifiers().values() );   
       
        /* retract the logical object */
        workingMemory.retractObject( logicalHandle2 );
       
        /* The logical object should never appear */
        assertLength( 0,
                      workingMemory.getJustified().values() );

        /* And its justifers should also be removed */
        assertLength( 0,
                      workingMemory.getJustifiers().values() );         
       
       
    }
   
    public void testMultipleLogicalRelationships() throws FactException
    {
        /*
         * create a RuleBase with a single ObjectTypeNode we attach a MockObjectSink so we can detect assertions and retractions
         */
        Rete rete = new Rete();
        ObjectTypeNode objectTypeNode = rete.getOrCreateObjectTypeNode( new ClassObjectType( String.class ) );
        MockObjectSink sink = new MockObjectSink();
        objectTypeNode.addObjectSink( sink );
        RuleBase ruleBase = new RuleBaseImpl( rete );
        WorkingMemoryImpl workingMemory = (WorkingMemoryImpl) ruleBase.newWorkingMemory();

        final Agenda agenda = workingMemory.getAgenda();

        Consequence consequence = new Consequence() {
            public void invoke(Activation activation)
            {
                // do nothing
            }
        };
       
        /* Create first justifier */
        final Rule rule1 = new Rule( "test-rule1" );
        rule1.setConsequence( consequence );

        FactHandleImpl handle1 = new FactHandleImpl( 1 );
        ReteTuple tuple1 = new ReteTuple( 0,
                                          handle1,
                                          workingMemory );

        final PropagationContext context1 = new PropagationContextImpl( PropagationContext.ASSERTION,
                                                                    null,
                                                                    null );

        /* get the activation onto the agenda*/
        agenda.addToAgenda( tuple1,
                            context1,
                            rule1 );

        /* Create the second justifer */
        final Rule rule2 = new Rule( "test-rule2" );
        rule2.setConsequence( consequence );
       
        FactHandleImpl handle2 = new FactHandleImpl( 2 );
        ReteTuple tuple2 = new ReteTuple( 0,
                                          handle2,
                                          workingMemory );

        final PropagationContext context2 = new PropagationContextImpl( PropagationContext.ASSERTION,
                                                                    null,
                                                                    null );

        /* get the activations onto the agenda */
        agenda.addToAgenda( tuple2,
                            context2,
                            rule2 );
       
        /* We have two activations on the Agenda, so use toArray to get them out */
        ModuleImpl main = (ModuleImpl) agenda.getFocus();
        Activation[] activations = ( Activation[] ) main.getActivationQueue().toArray( new Activation[] {} );              
       
        /* Create the first justifieable relationship */
        String logicalString1 = new String ( "logical" );
        Activation activation1 = activations[0];
        FactHandle logicalHandle1 = workingMemory.assertObject( logicalString1,
                                                               false,
                                                               true,
                                                               activation1.getRule(),
                                                               activation1 );
       
        /* Create the second justifieable relationship */
        String logicalString2 = new String ( "logical" );
        Activation activation2 = activations[1];       
        FactHandle logicalHandle2 = workingMemory.assertObject( logicalString2,
                                                               false,
                                                               true,
                                                               activation2.getRule(),
                                                               activation2 );
       
        /* "logical" should only appear once */
        assertLength( 1,
                      workingMemory.getJustified().values() );
        /* but has two justifications */
        assertLength( 2,
                      workingMemory.getJustifiers().values() )
       
        /* Now lets cancel the first activation */
        agenda.removeFromAgenda( ( (ReteTuple) activation2.getTuple() ).getKey(),
                                 context2,
                                 activation2.getRule() );
       
        /* because this logical fact has two relationships it shouldn't retract yet */
        assertLength( 0,
                      sink.getRetracted() );       
       
        /* check "logical" is still in the system */
        assertLength( 1,
                      workingMemory.getJustified().values() );
        /* but now it only has one justifier */
        assertLength( 1,
                      workingMemory.getJustifiers().values() );   
       
        /* now remove that final justification */
        agenda.removeFromAgenda( ( (ReteTuple) activation1.getTuple() ).getKey(),
                                 context1,
                                 activation1.getRule() );
       
        /* Should cause the logical fact to be retracted */
        assertLength( 1,
                      sink.getRetracted() );        
       
        /* "logical" fact should no longer be in the system */
        assertLength( 0,
                      workingMemory.getJustified().values() );
        /* all justifiers should be removed */
        assertLength( 0,
                      workingMemory.getJustifiers().values() );         
    }
   
   

}
TOP

Related Classes of org.drools.reteoo.LogicalAssertionTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.