<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  </head>
  <body text="#000000" bgcolor="#ffffff">
    <h3 class="post-title entry-title"><a class="moz-txt-link-freetext" href="http://blog.athico.com/2011/06/truth-maintenance-over-directed-graphs.html">http://blog.athico.com/2011/06/truth-maintenance-over-directed-graphs.html</a></h3>
    -------<br>
    <h3 class="post-title entry-title"><a
href="http://blog.athico.com/2011/06/truth-maintenance-over-directed-graphs.html">Truth
        Maintenance over Directed Graphs using Reactive Derivation
        Queries</a>
    </h3>
    <div class="post-header">
      <div class="post-header-line-1"><span class="post-author vcard">
          Posted by
          <span class="fn">Mark Proctor</span>
        </span>
      </div>
    </div>
    Drools 5.2 is almost done and we have something very cool added. As
    previous blogs have mentioned, we recently added <a
href="http://blog.athico.com/2011/04/backward-chaining-emerges-in-drools.html">positoinal
      syntax and prolog like derivation query based backward chaining</a>.
    However those queries were pull only and didn't support the recently
    added live <a
      href="http://blog.athico.com/2010/05/live-querries.html">"open
      queries"</a>. It also had the problem that it was method recursion
    based, so could blow the method stack if it was too deep.<br>
    <br>
    5.2 is now stack based and supports "open queries", you just miss of
    the '?'. So what this means is you can have TMS over reactive
    derivation queries. If I have a key in an envelop on a desk in an
    office I can add a TMS justifcation that will only exist while the
    key remains in the office.<br>
    <br>
    This should have some very interesting use cases and I look forward
    to seeing what people come up with. For instance you could create a
    rule to monitor a project's maven dependencies and transititive
    depdencies and receive an alert if ASL/MIT/BSD project has a GPL
    dependency added via a transititive dependency.<br>
    <br>
    It's a bit abstract, but here is the unit test showing it working:
    <pre class="brush:drl">package org.drools.test  
import java.util.List
import java.util.ArrayList
import org.drools.Person
global List list
dialect "mvel"
declare Location
    thing : String 
    location : String 
end
query isContainedIn( String x, String y ) 
    Location(x, y;)
    or 
    ( Location(z, y;) and isContainedIn(x, z;) )
end

rule look when 
    Person( $l : likes ) 
    isContainedIn( $l, 'office'; )
then
   insertLogical( 'blah' );end
rule existsBlah when 
    exists String( this == 'blah') 
then
   list.add( 'exists blah' );end

rule notBlah when 
    not String( this == 'blah') 
then
   list.add( 'not blah' );end

rule init when
then
    insert( new Location("apple", "kitchen") );
    insert( new Location("desk", "office") );
    insert( new Location("flashlight", "desk") );
    insert( new Location("envelope", "desk") );
    insert( new Location("key", "envelope") );
    insert( new Location("washing machine", "cellar") );
    insert( new Location("nani", "washing machine") );
    insert( new Location("broccoli", "kitchen") );
    insert( new Location("crackers", "kitchen") );
    insert( new Location("computer", "office") );
end

rule go1 when 
    String( this == 'go1') 
then
 list.add( rule.getName() ); 
 insert( new Location('lamp', 'desk') );
end

rule go2 when 
    String( this == 'go2') 
    $l : Location('lamp', 'desk'; )
then
    list.add( rule.getName() ); 
    retract( $l );
end

rule go3 when 
    String( this == 'go3') 
then
 list.add( rule.getName() ); 
 insert( new Location('lamp', 'desk') );
end

rule go4 when 
    String( this == 'go4') 
    $l : Location('lamp', 'desk'; )
then
 list.add( rule.getName() ); 
    modify( $l ) { thing = 'book' };
end

rule go5 when 
    String( this == 'go5') 
    $l : Location('book', 'desk'; )
then
    list.add( rule.getName() ); 
    modify( $l ) { thing = 'lamp' };
end

rule go6 when 
    String( this == 'go6') 
    $l : Location( 'lamp', 'desk'; )
then
    list.add( rule.getName() ); 
    modify( $l ) { thing = 'book' };
end

rule go7 when 
    String( this == 'go7') 
    $p : Person( likes == 'lamp' ) 
then
    list.add( rule.getName() ); 
    modify( $p ) { likes = 'key' };
end

-----

[go1, exists blah, go2, not blah, go3, exists blah, go4, not blah, go5, exists blah, go6, not blah, go7, exists blah]

-----

Person p = new Person();
p.setLikes( "lamp" );
FactHandle handle = ksession.insert(  p  );
ksession.fireAllRules();

list.clear();

FactHandle fh = ksession.insert( "go1" );
ksession.fireAllRules();
ksession.retract( fh );        
assertEquals( "go1", list.get(0));
assertEquals( "exists blah", list.get(1));

fh = ksession.insert( "go2" );
ksession.fireAllRules();
ksession.retract( fh );
assertEquals( "go2", list.get(2));
assertEquals( "not blah", list.get(3));

fh = ksession.insert( "go3" );
ksession.fireAllRules();
ksession.retract( fh );
assertEquals( "go3", list.get(4));
assertEquals( "exists blah", list.get(5));        

fh = ksession.insert( "go4" );
ksession.fireAllRules();
ksession.retract( fh );
assertEquals( "go4", list.get(6));
assertEquals( "not blah", list.get(7));          

fh = ksession.insert( "go5" );
ksession.fireAllRules();
ksession.retract( fh );
assertEquals( "go5", list.get(8));
assertEquals( "exists blah", list.get(9));

// This simulates a modify of the root DroolsQuery object, but first we break it
fh = ksession.insert( "go6" );
ksession.fireAllRules();
ksession.retract( fh );
assertEquals( "go6", list.get(10));
assertEquals( "not blah", list.get(11));  

// now fix it
fh = ksession.insert( "go7" );
ksession.fireAllRules();
ksession.retract( fh );
assertEquals( "go7", list.get(12));
assertEquals( "exists blah", list.get(13));          

System.out.println( list );</pre>
  </body>
</html>