<!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>