N3 rules triggering Java actions

© Jean-Marc Vanel - $Date: 2012-05-01$ - under Creative Commons License by-nc-nd 3.0

Posted on forum deductions-user and eulergui-user .

TOC

Popping an alert message

I'm having fun with N3 rules triggering Java actions; look at examples/BloodPressure.n3p . This works nicely, because a triple

?L :alert "true" 

has been asserted by the N3 source BloodPressure.n3 .

popup-java.n3
{       ?L :alert "true"
        ; log:uri ?LL .
} => {  ?F a java:javax-swing-JFrame
        ; javap:title ?LL
        ; javam:setSize ( 200 200 )
        ; javap:visible true .
}.

However from a software engineering point of view, this is mixing too much N3 and Java. On the right handside, one has to know too much of Java. And EulerGUI does not have the facilities of eclipse for Java code completion.

For EulerGUI framework, the recommended practice is to encapsulate the Java action in a class . Then this class itself will be encapulated in a pure N3 action:

popup-java2.n3
{       ?L :alert "true"
        ; log:uri ?LL .
} => {  :application :displayAlert ?LL . }.
#------------------------------------------
{ :application :displayAlert ?LL .
} => { 
  ?F a java:eulergui-gui-TemporaryFrame
  ; javap:localizedMessage ?LL .
}.

And, of course, in a real project these two rules should be in separate files, so that no java* prefixes are in the business rules.

To sum up, we have in this small example 3 kinds of rules:

  1. pure business rule (i.e. no Java stuff involved) : BloodPressure.n3
  2. behavioral rule (also no Java stuff involved) ) : first rule in popup-java2.n3
  3. implementation rule : mixed Java and N3) ) : second rule in popup-java2.n3

Leverage on Drools to automatically retract GUI components

This demonstration shows how to leverage on Drools to automatically retract GUI components and content when some domain fact triple is retracted from the Knowledge Base.

We leverage on Drools thruth maintenance (alias logical insert) .

How to test

  1. Open test/n3JavaMapping-GUI.n3p

    http://eulergui.svn.sourceforge.net/viewvc/eulergui/trunk/eulergui/

  2. run Drools engine

    ==> a new Window with "data" appears

  3. Open N3 shell
  4. paste this in N3 shell:
    x :p "new data" .

    ==> in new window , "new data" appears

  5. paste this in N3 shell:
    @prefix kb: <http://deductions.sf.net/ontology/knowledge_base.owl#> . _:d kb:retract ( :x :p "data" ) .

    ==> in new window , "data" disappears

How it works

There is a Swing DefaultListModel associated to the URI :listModel .

Then the rule says: whenever there is a triple :x :p ?V , add ?V to the ListModel .

:listModel a java:javax-swing-DefaultListModel.
{
  :x :p ?V .
} => {
  :listModel javam:addElement ( ?V ).
} .

The DefaultListModel is added in a JList object itself added to a JFrame ( standard Swing technology, just wrapped in N3 ) :

:JFRAME a java:javax-swing-JFrame .
:JLIST a java:javax-swing-JList .
:JLIST javam:setModel ( :listModel ) . 

:JFRAME javam:add :JLIST .
:JFRAME javam:setSize ( 200 200 ) .
:JFRAME java:visible true .

So the scene is set at step 2.

As a by-product, this has added to the KB an object DeferredMethodCall that represents the addElement() method call in the consequent of the rule. This is N3 + Drools engine machinery ( BTW it allows to make calls deferred until both subject and arguments are bound ) .

Now, when the triple :x :p "data" is retracted, Drools automatically retracts the DeferredMethodCall object representing the addElement() method call:

We added a class JavaObjectsRetractionListener implementing WorkingMemoryEventListener which is called when the DeferredMethodCall object is retracted. The listener calls removeElement when the method was addElement (also another common pattern : remove and add methods names).

So the element "data" is removed from DefaultListModel, which removes the list item in the window by standard Swing Model - View design pattern.

Conclusion

In this article, I showed how one can add features to the current project, which becomes thus a kind of application.

For a comprehensive account, see : EulerGUI application building Framework .

In the next article, configure EulerGUI in N3, I show how one can add features to EulerGUI itself, expressed by rules, Java classes, or a mixture of both.

About in Java + N3 mixing, to know exactly what is implemented and works, look at the test class BasicRuntimeTest .