Déduction project

Java Swing application generator from OWL model and N3 logic rules

Jean-Marc Vanel, 2009-08-26 - a version possibly older, in sync. with EulerGUI release

TOC

Introduction

On one side, you have the "traditional" expert systems and rule engines. On the other side there are the usual applications that are done entirely or for the most part by hand. And even MDA engines and other application generators are themselves hand coded. The Deductions project wants to apply logical rules and engines for software engineering tasks: generating applications or sub-sytems, enabling seamless integration of libraries and components, and more. See here the Deductions vision .

The first tool that the Deduction project develops, because it is the most conspicuous functionality, is an application generator centered around a form generator and a N3 file persistence. The Déductions application generator's main part is a set of contructives rules in N3 logic; they are hosted in the Déductions Sourceforge project. Then to execute the rules, and run the generated application, the EulerGUI IDE is used.

Due to the logic and declarative nature of the architecture, this enables further features:

See a companion presentation (in OpenOffice format) architecture.odp ; in PDF architecture.pdf.

Features

Missing Features

Here is a formal (N3) feature list . See here Runtime behavior specification and IHM principles .

If you want to see a log view of the latest changes in source, go to: http://deductions.svn.sourceforge.net/viewvc/deductions/?view=log

How to

First you need to install EulerGUI; the Euler GUI Manual covers all aspects : install, usage, links, development, architecture .

Then, facultatively, you download the N3 sources for Deductions in their latest version.

If you go on this Web repository page, you can see what are the latest developments:

http://deductions.svn.sourceforge.net/viewvc/deductions/n3/

The good news for testers is that all projects examples are now working entirely from a URL ending with .n3p .

Running a ready-made example (Person)

Then:

  1. launch EulerGUI
  2. open the person_test2.n3p project, directly from the Web: click on File / Open project From URL, then paste: http://deductions.svn.sourceforge.net/viewvc/deductions/n3/person_test2.n3p . You can also give this URL as command line argument.

    Alternativel you can also open it from the zip you just downloaded from Deductions SourceForge depot) .

  3. press on the "Run Drools" button with Drools logo on the right (that takes a few seconds)
  4. select Tools / Launch generated app. ; and then a small Swing window appears.

The EulerGUI IDE at step 3:

The EulerGUI IDE at step 3

The generated GUI at step 4:

Here this setting is activated, that expands recursively forms following properties :

app:globalSettings app:expandForms true .

gui_person

You can enter values in fields,; numeric types are enforced ("age" is a positice integer and "size" is a floating point number) .

When quitting the Agents application, the data are saved in an N3 file named user_data.n3

in home directory (or current.n3 in current directory for old architecture).

If you re-open the generated application, you can modify data already entered.

You can further constraint values entered by the user by adding rules like this (see person-events.n3 ) :

{ ?P a :Person .
  ?P :name "Bush" .
} => {
  ded:exception :throw " is already retired!" .
} .

Rules need not be that simple, you have all the power of N3 logic at runtime.

Another (larger) example, from the NRI relational database :

Deduction GUI - NRI 2

Running a project with Déductions rules hidden and imported

We will now open another version of the same project, where the generic Déductions rules are hidden and provided through an imported project.

Open the test_person_import.n3p project ( directly from the Sourceforce site, or in the zip you downloaded from Deductions SourceForge depot ) .

You see that the Déductions rules are hidden and provided through the imported project swing-rules2.n3p .

You just see three project specific sources:

You can generate the GUI just like before ( press on the "Run Drools" button , and select Tools / Launch generated app. ).

You can also open the imported project, by clicking on the light blue button, if you want to see what is inside.

eulergui_ide_import

Running your own project (FOAF)

We will make a new project for an application based on a model downloaded from Internet.

We use this classical vocabulary, FOAF (Friend Of a Friend), about people, organizations and the Internet :

http://xmlns.com/foaf/spec/index.rdf

This project is also available as a ready-made project named foaf_import.n3p . Following is the step-by-step procedure to create the project.

  1. in the "File" pull-down menu, click on "New Project"
  2. in the "File" pull-down menu, click on "Import Project from URL ..." ; then choose http://deductions.svn.sourceforge.net/viewvc/deductions/n3/swing-rules2.n3p
  3. drag-and-drop from the search engine the above URL of the OWL model; this adds it to the project. You could also click on the second button "Add N3 or RDF source from URL" and paste or type the URL. It is downloaded and translated into N3 on the fly, and you can open it with the N3 editor (or go direct to step 4 below) :

n3_editor_gvim

If the N3 view of the ontology is not enough for you, you can open it with Protégé 4. You can also drag-and-drop the URL on Protégé. I tend to prefer writing N3 to create an ontology, and using Protégé to visualize it.

foaf_protege

If you want still another way to visualize an N3 file (including the N3 rules), there is the Graphviz feature; just click on the "GRAPH" button nearby each document. Here is the result on subform.n3 :

subform_graphviz

Step 4:

Now remains to define the desired application: add a new N3 source to the project (using the first button in the toolbar), say foaf-app-spec.n3, with this content:

@prefix : <http://purl.org/zen/foaf-DL.owl#> .
@prefix app: <http://jmvanel.free.fr/ontology/software_applications.owl#> .
:FOAF_GUI a app:SoftwareApplication .
:FOAF_GUI app:editedClass :Agent .
:FOAF_GUI app:platform app:Java .
:FOAF_GUI app:name "FOAF GUI" .

Now you can again press on the "Run Drools" button (no need to re-choose "Launch generated app." ). And here is your new application:

foaf_agent

Note that datatype properties "birthday" and "gender" have no type (that is, no rdfs:range) specified in the model. The generator applied type xsd:string.

The "holdsAccount" object property has type (range) "OnlineAccount", which has three sub-classes; so three button appear to choose the type of "OnlineAccount".

Similarly, the class "Agent" has three sub-classes: "Person", "Group", "Organization". So three button appear to choose the type of the current object (the object associated to the current form). This set of three button has a white background.

>>>> TODO When the user clicks to choose among subclasses, the fields for chosen subclass are added at once.

Also in the case of "holdsAccount" of type owl:Thing, not a FunctionalProperty nor InverseFunctionalProperty, it is possible that an account is shared by two or more Agents; so the GUI has to propose either a shared or a new object.

>>>> TODO The shared object will be searched by a text field matching any property of that object, and also its Id.

When object property have no explicit type, the generator applies rdfs:range owl:Thing . But in turn type owl:Thing poses problems as to which behavior to hold. Cardinalities, FunctionalProperty and InverseFunctionalProperty character must also be taken in account.

Multi-instances forms

However this is just a form to enter one Agent. If we want to enter a series of Agents, we need to add a new class being just that, a series of Agents. Here is the modified application specification:

@prefix : <http://purl.org/zen/foaf-DL.owl#> .
@prefix app: <http://jmvanel.free.fr/ontology/software_applications.owl#> .
:AgentList a owl:Class .
:agents a owl:ObjectProperty ;
        rdfs:domain :AgentList ;
        rdfs:range  :Agent .
:FOAF_GUI a app:SoftwareApplication .
:FOAF_GUI app:editedClass :AgentList .
:FOAF_GUI app:platform app:Java .
:FOAF_GUI app:name "FOAF Agent" .

And now the new application has just one button labelled "agents". Upon clicking, it pops up a window just like the preceding, allowing to enter a new Agent.

If you're happy with your work, you can save your project and exit ( EulerGUI will not let you quit if you don't save in some file ) . Note that saving the project just means saving the list of files comprised in this project; the editors for the files can stay opened and there is no communication (for now) between the editors and the IDE.

Start from an RDFS model (CV)

We will again make a new project for an application based on a model downloaded from Internet.

Again on Swoogle, we found a human resources example:

http://captsolo.net/semweb/resume/cv.rdfs

For RDFS models, there one complication (we should add more intelligence here :) ).

Infering GUI's from RDFS is indirectly supported. One must use our RDFS to OWL converter, rdfs_owl-rules.n3 .

The example is cv.n3p. The fist step converts RDFS to OWL, the second step, cv.post.n3p, applies the GUI rules. They are chained automatically; this is a pipeline of N3 projects. The second step takes as input the output of the first step (plus its own inputs). The second step, imports the GUI rules swing-rules2.n3p just like preceding project. From the point of view of the application designer, the data flow is thus (actually an UML Activity Diagram) :

user --cv.rdfs--> main_Project --OWL_model--> post_Project --Java_objects--> Instantiator
                  cv.n3p                      cv.post.n3p    in_N3
                                                  ^
user --cv_app-spec.n3-----------------------------|

The relation between projects corresponds this UML class diagram:

                         1                           *
cv.n3p <>----------------- cv.post.n3p <>------------- swing-rules2.n3p
            postProcessing                 subProjects

The steps to create the project from scratch are the following :

  1. in the "File" pull-down menu, click on "New Project"
  2. drag-and-drop from the search engine the URL of the RDFS model; this adds it to the project. It is downloaded and translated into N3 on the fly, and you can open it with the N3 editor.

    You could also click on the second button "Add N3 or RDF source from URL" and paste or type the URL.

  3. add a new N3 source to the project (using the first button in the toolbar) , rdfs_owl-rules.n3
  4. add a N3 query to the project (using the button with the orange question mark) , rdfs-query.n3
  5. in the "File" pull-down menu, click on "Add Project as Post-processing ..." ; choose cv.post.n3p
  6. click on the turquoise button for Post-processing Project cv.post.n3p , and add to it cv_app-spec.n3 and query.n3 as a query (orange button)
  7. in the "File" pull-down menu, click on "Import Project ..." ; then choose swing-rules2.n3p

Then after running the N3 Drools engine and the Application generator as usual, one gets this form:

CV form

If you want to see the OWL model produced at intermediate step, you can uncheck the "active" checkbox near the post-processing project, and re-run the inference engine.

TODO >>>>> minor bug : the imported project is not active for run when just added; you have to close and re-open the project.

Another RDFS model (Food)

Suppose we want to deal with food, maybe to manage grocery orders. After some trials and errors, like with every search engine, we come up with this swoogle search : "food vegetable fruit cheese dish" . Among the results, we find several large (5Mb) OWL documents, that include larger vocabulary than just food. We find several not too large (~ 200 kb) RDF Schema documents, like this one:

http://spypixel.com/2006/tap/tap.xmlns.com/tap-food-schema.rdf

CAUTION !!!!!!! today (2009-08-04) the original remote site for this RDF Schema is down. So we made a copy here :

http://deductions.svn.sourceforge.net/viewvc/deductions/examples/models/tap-food-schema.rdf

The N3 project is available as rdfs_food_gui.n3p ; like the preceding, it has two steps, one to convert RDFS to OWL, and one to generate the aplication.

From the point of view of the application designer, the two ingredients are:

Since the edited Class PreparedFood has no properties at all, the initial GUI produced has no text fields. PreparedFood, however, has many subclasses. The GUI gives a choice to create and edit one of these subclasses. This reuses what is done for object properties.

food example

TODO >>>>> After the use chooses one of the subclasses, the generated window should be updated with the fields of the chosen subclass. In the present example, this would not change anything, since few classes have properties in this model.

Start from an UML model (Employee)

Alas, there is no public repository for reusable UML or eCore models.

Much like for RDFS models, generating GUI's from UML models involves two steps. The first steps converts UML to OWL, while the second step generates the GUI from OWL.

The relation between projects corresponds this UML class diagram:

                          1                            *
uml.n3p <>----------------- uml.post.n3p <>------------- swing-rules2.n3p
             postProcessing                  subProjects

The N3 project is available as uml.n3p.

FIGURE: The EulerGUI windows corresponding to the three projects :

ulergui_ide_uml1

eulergui_ide_uml 2

eulergui_ide_uml3

PENDING: !!!!!!!!!!!! the subform "subordonate" does not popup.

Start from an eCore model (Library)

Here is a project opening the classic library example of eCore : ecore.n3p .

A convertion rule base from eCore to OWL has been writen, ecore_owl-rules.n3,

The builtin log:dtlit in Drools engine or Euler is used to change string datypes from eCore to plain strings.

Here is the form obtained for the edited class "Book":

form obtained for the edited class "Book"

Development

Development plan and feature list , generated (by N3 logic!) from status.n3 and a formal (N3) task list plan.n3.

Architecture : overall data flow

Designer              Rule             JVM         Runtime     End       GUI
  |                   Engine           Runtime     Storage     User
  |                   |                |            |          .         .
  ---add bizz class-->|                |            |          .         .
  ---add property  -->|                |            |          .         .
  |                   |--new object -->|            |          .         .
  |                   |--assign prop-->|            |          .         .
  |                   |--method call-->|            |          .         .
  |                   |                |// GUI      |          .         .
  |                   |                |// running  |          |         |
  ---add bizz rule -------------------------------->|          |         |
  |                   |                |            |          --event-->|
  |                   |                |            |<---storage event---|
  |                   |                |            |--invalid exceptio->|

Notes:

Architecture : rules

Rules architecture:

rules_architecture

The meaning of the above diagram is that blue rectangles are ontologies (classes and properties), and arrow are N3 rules files transforming one ontology into another.

Rules data flow:

rules_data_flow.

This completes the preceding diagram by showing the generated Swing application with its Drools WorkingMemory used as data store and also to infer forms at runtime.

Rules example 1

# add a field in the form for each property of a class:
{  ?CLASS gui:hasForm ?FORM .
   ?PROP rdfs:domain ?CLASS .
} => {
  ?FORM gui:hasField ?FIELD .
  ?FIELD gui:inputWidgetSpecification ?PROP .
} .

A verbose translation (that could generated automatically) is :

If a class CLASS has a form FORM, and this class is the domain of a property PROP, then there exists a field FIELD belonging to the form; and moreover the input Widget Specification of FIELD is PROP.

Rules example 2

The preceding rule just entails the existence of a field satisfying 2 conditions. This rule sets a type for the field. We see here the extreme modularity of rules.

# the type of the field depends on the type of the property: ObjectProperty or DatatypeProperty
{
  ?FIELD gui:inputWidgetSpecification ?PROP .
  ?PROP a owl:DatatypeProperty .
} => {
  ?FIELD a gui:DatatypeInputWidget .
} .

A verbose translation is :

If the input Widget Specification of FIELD is PROP, and PROP is a OWL Datatype Property, then ?FIELD is a Datatype Input Widget.

These rules are in app_gui-rules.n3 .

Architecture : runtime

See runtime-architecture.html

References

A Practical Guide To Building OWL Ontologies Using The Protege-OWL

http://owl.cs.manchester.ac.uk/tutorials/protegeowltutorial/ ( latest version for Protege 4 )