PSOA RuleML API

From RuleML Wiki
Jump to: navigation, search

Authors: Mohammad Sadnan Al Manir, Harold Boley


PSOA RuleML is a language introducing generalized rules over positional-slotted, object-applicative terms that permit the application of a predicate (acting as a relation) to be without or with an Object IDentifier (OID) -- typed by the predicate (acting as a class) -- and the predicate’s arguments to be positional, slotted, or combined. This page describes the status and various stages of the development of an open-source PSOA RuleML API in Java. Its availability will benefit PSOA-based research and applications. The API supports creating and manipulating abstract syntax objects (ASOs) using factory-based Java methods. These are used to parse the XML-based concrete syntax (serialization) of PSOA RuleML into ASOs, and render ASOs as PSOA RuleML's RIF-like presentation syntax. This parse-render composition, developed with the API, amounts to a translator from PSOA RuleML's XML syntax to the presentation syntax. The PSOA RuleML API is wrapped into an online demo Web application, which shows a list of PSOA RuleML/XML rulebases and generates their equivalent forms in the presentation syntax.

1 Introduction

PSOA RuleML API is a Java open-source tool which aims to facilitate experimental research and development in Semantic Web technologies. It allows the creation of ASOs corresponding to PSOA constructs, such as constants, variables, tuples, slots, atoms, formulas, rules, etc., by parsing XML-based PSOA documents using the JAXB library, and by employing factory-based method calls. It also allows generation of presentation syntax from ASOs, by recursive traversal of the ASOs. Thus, the API can be employed for PSOA rule processing, including rule authoring, rule translation into other languages, rule-based applications, and rule engines.

2 Structure of the API

The API is divided into two main components:

  1. Creation and traversal of ASOs
  2. Parsing and rendering of ASOs

The AbstractSyntax is the top-level class for factories and contains all Java interfaces for different types of ASOs. The DefaultAbstractSyntax class implements AbstractSyntax interfaces, which is suitable for most purposes. However, more demanding uses may require custom implementations of the interfaces.

The package also contains a Parser class, which provides PSOA RuleML/XML parsing and translation into presentation syntax. Parsing is implemented using the Java Architecture for XML Binding (JAXB) [6], which creates equivalent Java objects based on XML schema files. The schema is a straight-forward encoding of the syntactic construct hierarchy:

PSOA RuleML API Structure


The above figure presents the most important classes and interfaces implementing different types of syntactic constructs. Each of the names in a rectangular box represents a Java interface, and is kept as close as possible to the presentation syntax construct names. The corresponding implementations of these interfaces use Java inheritance, shown by the solid arrows.

The interface Construct sits at the top of the hierarchy. Group can be populated with more Groups and Rules. Both universal facts and universal rules are represented by the Rule class, which encapsulates a Clause. The interface Clause represents either an implication or an atomic formula. Implication is represented by the interface Implies whereas Atomic represents atomic formulas.

The generalized interface Atomic is implemented either by Atom or by Subclass or by Equal. Implementations of the generalized Formula interface represent either disjunction, conjunction, or existential formulas by implementing Formula_Or, Formula_And, and Formula_Exists, respectively. In addition to atomic formulas, external formulas can be represented using the Formula_External interface. The generalized interface Term is represented by implementing Const for different kinds of constants, Var for variables, Expr for expressions denoting psoa terms, and External for external expressions. Constants can be either Const_Literal or Const_Constshort. The interface Psoa is implemented to represent both objectified and non-objectified functions or predicates with membership symbol ‘#’ for the objectified version and tuples and slots as arguments, e.g., inst#family(Homer Merge child->Bart). The non-objectified version omits the membership e.g. family(Homer Merge child->Bart). The internal nodes Sentence, Formula, Atomic, Term, Const, and Expr, are generalized classes and implemented by more specific classes.

3 EBNF Grammar for the Presentation Syntax of PSOA RuleML

Rule Language

Document  ::= 'Document' '(' Base? Prefix* Import* Group? ')'
Base      ::= 'Base' '(' ANGLEBRACKIRI ')'
Prefix    ::= 'Prefix' '(' Name ANGLEBRACKIRI ')'
Import    ::= 'Import' '(' ANGLEBRACKIRI PROFILE? ')'
Group     ::= 'Group' '(' (RULE | Group)* ')'
RULE      ::= ('Forall' Var+ '(' CLAUSE ')') | CLAUSE
CLAUSE    ::= Implies | ATOMIC
Implies   ::= (HEAD | 'And' '(' HEAD* ')') ':-' FORMULA
HEAD      ::= ATOMIC | 'Exists' Var+ '(' ATOMIC ')'
PROFILE   ::= ANGLEBRACKIRI

Condition Language

FORMULA        ::= 'And' '(' FORMULA* ')' | 
                   'Or' '(' FORMULA* ')' | 
                   'Exists' Var+ '(' FORMULA ')' | 
                   ATOMIC | 
                   'External' '(' Atom ')'
ATOMIC         ::= Atom | Equal | Subclass
Atom           ::= PSOA
PSOA           ::= (oid '#')? op '(' (TUPLEARGS | Tuple*)  slot* ')'
Equal          ::= left '=' right
Subclass       ::= sub '##' super
oid            ::= INDTERM
op             ::= OPTERM
Tuple          ::= TUPLEARGS
TUPLEARGS      ::= INDTERM*
slot           ::= INDTERM '->' INDTERM
left           ::= INDTERM
right          ::= INDTERM
sub            ::= op
super          ::= op
INDTERM        ::= Ind | Var | Expr | 'External' '(' Expr ')'
OPTERM         ::= Rel | Fun | Var | Expr | 'External' '(' Expr ')'
Expr           ::= PSOA
Ind            ::= '"' UNICODESTRING '"^^' SYMSPACE | CONSTSHORT
Rel            ::= '"' UNICODESTRING '"^^' SYMSPACE | CONSTSHORT
Fun            ::= '"' UNICODESTRING '"^^' SYMSPACE | CONSTSHORT
Var            ::= '?' UNICODESTRING?
SYMSPACE       ::= ANGLEBRACKIRI | CURIE

4 Status of PSOA RuleML API

4.1 Current Status

The PSOARuleML-API project is written in Java and is currently hosted on Github.

Web Service to Convert PSOA RuleML/XML into the Presentation Syntax based on the API

4.2 Deprecated

Version-1.0 of the API is not outdated. It was first released to the Maven Central Repository on January 15, 2015.

  • To use the API-v-1.0 in your Maven project add the following dependency
<dependency>
    <groupId>org.ruleml.psoa</groupId>
    <artifactId>psoaruleml-api</artifactId>
    <version>1.0</version>
</dependency>

5 Revision History

Various features of the API have been revised and actions have been performed to accommodate the recommended changes. These revisions can be found in the following documents:

  • Presentation Slides on Initial Implementation: See [5]
  • Recommended modification steps of the API: Click Here

6 How to Use the API

6.1 Using the Library

The artifact of the API is available as psoaruleml-api-version.jar and it can be used in any of the following ways:

6.1.1 Maven Dependency

  • To use the API in your Maven project add the following dependency in your pom.xml
<dependency>
    <groupId>org.ruleml.psoa</groupId>
    <artifactId>psoaruleml-api</artifactId>
    <version>1.1</version>
</dependency>

6.1.2 Downloadable psoaruleml-api.jar

6.1.3 Build the library from Source

The API is available as a Maven Java project. Maven must be installed on the machine to compile the Java source files and create the jar library. The instructions for installing Maven can be found here. Once Maven is installed, follow the instructions below to create the library:

  • Download the compressed project source.
  • Alternatively, use $ git clone https://github.com/sadnanalmanir/PSOARuleML-API.git to clone from the Github repository if you are using git.
  • Access the project root directory $ cd PSOARuleML-API.
  • To compile the sources issue the command $ mvn compile
  • Issue the command $ mvn package to create the jar.
  • The jar library will be created as psoaruleml-api-version.jar inside the target directory.

6.2 How to Convert from PSOA RuleML/XML to PSOA Presentation Syntax

The API can be used for conversion in two different modes:

  • By using an existing rulebase: A valid PSOARuleML/XML rulebase in the form of a *.psoa file (e.g. single_tuple_psoa_term.psoa) can be converted into PSOA presentation syntax. A list of sample rulebases is available on the Web demo page which can be reused for this purpose. In this mode, the ASOs are created automatically and then pretty-printed as presentation syntax.
  • By authoring a rulebase: This approach fully utilizes the power of the API by creating the rulebases from scratch. A list of createX(...) methods is used to create instances of the constructs shown in the figure above. A few examples are added to demonstrate the utility of the API.

6.2.1 Conversion from an Existing Rulebase

The following rulebase represents an atomic formula. It contains a psoa term which consists of a class membership with the OID f3 being an instance of the class family, multi-tuple terms Mike, Jessie and 1951, and two name-value pairs as slots. The first slot pairs child with Fred while the second slot pairs child with Jane.

<?xml version="1.0" encoding="UTF-8"?>

<!-- 
  http://wiki.ruleml.org/index.php/PSOA_RuleML#Psoa_terms_with_slots_and_tuples
-->

<!DOCTYPE Document [
<!ENTITY psoa  "http://psoa.ruleml.org/lang/spec#">
<!ENTITY xs   "http://www.w3.org/2001/XMLSchema#">
<!ENTITY rdf  "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
]>

<Document xmlns="&psoa;">
  <payload>
    <Group>
      <sentence>
        <Atom xmlns="&psoa;">
          <oid>
            <Ind type="&psoa;local">f3</Ind>
          </oid>
          <op>
            <Rel type="&psoa;local">family</Rel>
          </op>
          <Tuple>
            <Ind type="&psoa;local">Mike</Ind>
            <Ind type="&psoa;local">Jessie</Ind>
          </Tuple>
          <Tuple>
            <Ind type="&xs;integer">1951</Ind>
          </Tuple>
          <slot>
            <Ind type="&psoa;local">child</Ind>
            <Ind type="&psoa;local">Fred</Ind>
          </slot>
          <slot>
            <Ind type="&psoa;local">child</Ind>
            <Ind type="&psoa;local">Jane</Ind>
          </slot>
        </Atom>
      </sentence>
    </Group>
  </payload>
</Document>

Assuming that the PSOA RuleML/XML rulebase is stored in the file named psoa_term_with_tuple_slot.psoa and instantiated as psoaRuleMLKB, it is parsed and then instantiated as a document called psoaPSKB. Finally, the rulebase is rendered in presentation syntax by the overridden toString(...) method as shown below (cf. PSOARuleMLXML2PSSyntax.java, currently lines 38-58):

DefaultAbstractSyntax factory = new DefaultAbstractSyntax();        

try {

      Parser parser = new Parser();
      File psoaRuleMLKB = new File("psoa_term_with_tuple_slot.psoa");          
      Document psoaPSKB = (Document) parser.parse(psoaRuleMLKB, factory);            
      System.out.println(psoaPSKB);            
} 
catch (Exception e) {     

      e.printStackTrace();
}

The equivalent presentation syntax is pretty-printed as follows:

Document (

  Group (

    _f3#_family([_Mike _Jessie] ["1951"^^http://www.w3.org/2001/XMLSchema#integer] _child->_Fred _child->_Jane)

  )

)

6.2.2 Conversion by Authoring a Rulebase

In this section, we demonstrate how to use the API methods to create PSOA RuleML/XML rulebases consisting of atomic formulas built from psoa terms with OIDs, classes, slots as name value pairs, and single-tuple terms or multi-tuple terms. The creation of a rulebase consisting of both the rule head and rule body consisting of conjunctive formula where the variables are universally and existentially quantified is demonstrated next. In each case, the rulebase is pretty-printed in its equivalent presentation syntax.

6.2.2.1 Rulebase with a Single-tuple Psoa Term

The Java code below demonstrates how to create a PSOA RuleML/XML rulebase with a single-tuple psoa term and render as its equivalent presentation syntax. The term consists of a class membership with the OID o1 being an instance of the class p, two tuple terms a1 and a2, and no slots. The source code can be found here.

// factory object reference for creating the Abstract Syntax Objects
DefaultAbstractSyntax factory = new DefaultAbstractSyntax();

// create the oid term
Term ind = factory.createConst_Constshort("o1");
// create op term
Term op = factory.createConst_Constshort("p");
// create two tuple terms
Term tupleTerm1 = factory.createConst_Constshort("a1");
Term tupleTerm2 = factory.createConst_Constshort("a2");
// store the tuple terms together in a list
List<Term> tupleTermsList = new ArrayList<Term>();
tupleTermsList.add(tupleTerm1);
tupleTermsList.add(tupleTerm2);
// wrap the tuple terms in a tuple
Tuple tuple = factory.createTuple(tupleTermsList);
// store the tuple as a list item
List<Tuple> listOfTuples = new ArrayList<Tuple>();
listOfTuples.add(tuple);
// create the psoa term without any slot
Psoa psoaTerm = factory.createPsoa(ind, op, listOfTuples, null);
// create the atomic formula
Atom atom = factory.createAtom(psoaTerm);
// create a clause
Clause clause = factory.createClause(atom);
// create a rule consisting of only head but no body
Rule rule = factory.createRule(null, clause);
// the rule is an item of a list of sentences
List<Sentence> sentence = new ArrayList<Sentence>();
sentence.add(rule);
// create a group with only one sentence
Group group = factory.createGroup(sentence);
// create the PSOA RuleML document
Document doc = factory.createDocument(null, group);
// render the single-tuple psoa term in presentation syntax
System.out.println("PSOA RuleML/XML document rendered in Presentation Syntax: \n" + doc);


The equivalent presentation syntax is displayed below:

Document (
  
  Group (
  
    _o1#_p(_a1 _a2)

  )
  
)
6.2.2.2 Rulebase with a Psoa Term with Slots and Tuples

The Java code below demonstrates how to create the rulebase described in the section above utilizing the API. The complete source code can be found here.

// factory object reference for creating the Abstract Syntax Objects
DefaultAbstractSyntax factory = new DefaultAbstractSyntax();

// create the oid term
Term f3_Oid = factory.createConst_Constshort("f3");
// create the op term
Term f3_Op = factory.createConst_Constshort("family");

// create the first two terms
Term f3_multiTupleTerm1 = factory.createConst_Constshort("Mike");
Term f3_multiTupleTerm2 = factory.createConst_Constshort("Jessie");

// create the integer typed literal term
Symspace f3_multiTupleTerm3_Type = factory.createSymspace(XMLSchemaDatatype.INTEGER.toString());
Term f3_multiTupleTerm3 = factory.createConst_Literal("1951", f3_multiTupleTerm3_Type);

// keep the first two terms together in a list
List<Term> f3_multiTupleList1 = new ArrayList<Term>();
f3_multiTupleList1.add(f3_multiTupleTerm1);
f3_multiTupleList1.add(f3_multiTupleTerm2);

// keep the third term in a separate list
List<Term> f3_multiTupleList2 = new ArrayList<Term>();
f3_multiTupleList2.add(f3_multiTupleTerm3);

// wrap the first two terms inside a Tuple and the third term into a separate tuple
Tuple f3_multiTuple1 = factory.createTuple(f3_multiTupleList1);
Tuple f3_multiTuple2 = factory.createTuple(f3_multiTupleList2);

// express tuples as multi-tuple
List<Tuple> f3_allTuples = new ArrayList<Tuple>();
f3_allTuples.add(f3_multiTuple1);
f3_allTuples.add(f3_multiTuple2);

// create the first slot
Term name1 = factory.createConst_Constshort("child");
Term value1 = factory.createConst_Constshort("Fred");
Slot slot1 = factory.createSlot(name1, value1);

// create the second slot
Term name2 = factory.createConst_Constshort("child");
Term value2 = factory.createConst_Constshort("Jane");
Slot slot2 = factory.createSlot(name2, value2);
// store the slots as a list items
List<Slot> f3_allSlots = new ArrayList<Slot>();
f3_allSlots.add(slot1);
f3_allSlots.add(slot2);

// create the psoa term
Psoa psoaTerm = factory.createPsoa(f3_Oid, f3_Op, f3_allTuples, f3_allSlots);
// create an atom from the psoa term
Atom atom = factory.createAtom(psoaTerm);
// create a clause containing an atomic formula
Clause clause = factory.createClause(atom);
// create the rule
Rule rule = factory.createRule(null, clause);
// the rule is an item of a list of sentences
List<Sentence> sentence = new ArrayList<Sentence>();
sentence.add(rule);
// create a group with only one sentence
Group group = factory.createGroup(sentence);
// create the document
Document doc = factory.createDocument(null, group);
// render the psoa term with slots and tuples in presentation syntax
System.out.println("PSOA RuleML/XML document rendered in Presentation Syntax: \n" + doc);

The equivalent presentation syntax is similar to the one we have seen in the section above.

6.2.2.3 Rulebase with a Universally and Existentially Quantified Formula

Now that we know how to create a psoa term with class membership, tuples, and slots, we move on to rule authoring. The following piece of code creates a rule where the rule body contains the conjunction of two formulas. The conjunctive formula consists of an atomic formula and an existentially quantified atomic formula. The complete source code is available here.

// factory object reference for creating the Abstract Syntax Objects
DefaultAbstractSyntax factory = new DefaultAbstractSyntax();

/**
* create an atomic formula in rule head
*/
// holds the universally quantified quantified variables
List<Var> varsUniversal = new ArrayList<Var>();
// holds the universally quantified quantified variables
List<Var> varsExistential = new ArrayList<Var>();

/* creating atomic formula ?o#_family(_child->?Ch) in rule head */

// create oid term
Var f1_v1 = factory.createVar("o");
varsUniversal.add(f1_v1);
Term f1_Oid = f1_v1;

// create op term
Term f1_Op = factory.createConst_Constshort("family");

// slot name
Term f1_name = factory.createConst_Constshort("child");
// slot value
Var f1_v2 = factory.createVar("Ch");
varsUniversal.add(f1_v2);
Term f1_value = f1_v2;
// create slot _child->?Ch
Slot f1_slot = factory.createSlot(f1_name, f1_value);
// add the slot as a list item
List<Slot> f1_slots = new ArrayList<Slot>();
f1_slots.add(f1_slot);

// create psoa term
Psoa f1_psoaTerm = factory.createPsoa(f1_Oid, f1_Op, null, f1_slots);
// create an atom
Atom f1_atom = factory.createAtom(f1_psoaTerm);
// create the head
Head f1_head = factory.createHead(null, f1_atom);
// add the head atomic formula as a list item
List<Head> headList = new ArrayList<Head>();
headList.add(f1_head);

/**
 * creating rule body
 */
// create oid term
// create oid term
Var f2_v1 = f1_v1;
Term f2_Oid = f2_v1;
// create op term
Term f2_Op = f1_Op;
// create slot name
Term f2_name1 = factory.createConst_Constshort("husb");
// create slot value
Var f2_v2 = factory.createVar("Hu");
Term f2_value1 = f2_v2;

// create the slot _husb->?Hu
Slot f2_slot1 = factory.createSlot(f2_name1, f2_value1);

Term f2_name2 = factory.createConst_Constshort("wife");
Var f2_v3 = factory.createVar("Wi");
Term f2_value2 = f2_v3;

// create the slot _wife->?Wi
Slot f2_slot2 = factory.createSlot(f2_name2, f2_value2);

// add the slots as list items
List<Slot> f2_slots = new ArrayList<Slot>();
f2_slots.add(f2_slot1);
f2_slots.add(f2_slot2);
// create a psoa term ?o#_family( _husb->?Hu _wife->?Wi)
Psoa f2_psoaTerm = factory.createPsoa(f2_Oid, f2_Op, null, f2_slots);
// create the atom from the psoa term
Atom f2_atom = factory.createAtom(f2_psoaTerm);

/* creating the existentially quantified formula */
// create oid
Var f3_v1 = factory.createVar("obj3");
varsExistential.add(f3_v1);
Term f3_Oid = f3_v1;
// create op
Term f3_Op = factory.createConst_Constshort("kid");
// create 2 tuples
Var f3_v2 = factory.createVar("Hu");
varsUniversal.add(f3_v2);
Term f3_TupleTerm1 = f3_v2;
Var f3_v3 = factory.createVar("Ch");
varsUniversal.add(f3_v3);
Term f3_TupleTerm2 = f3_v3;
// add two tuple terms to the list of term
List<Term> f3_TupleList = new ArrayList<Term>();
f3_TupleList.add(f3_TupleTerm1);
f3_TupleList.add(f3_TupleTerm2);
// wrap the tuple terms in a tuple
Tuple f3_Tuple = factory.createTuple(f3_TupleList);
// store the tuple as a list item
List<Tuple> f3_All_Tuples = new ArrayList<Tuple>();
f3_All_Tuples.add(f3_Tuple);

// create the psoa term ?obj3#_kid(?Hu ?Ch)
Psoa f3_psoaTerm = factory.createPsoa(f3_Oid, f3_Op, f3_All_Tuples, null);
// create an atom from the psoa term
Atom f3_atom = factory.createAtom(f3_psoaTerm);
// create the existential formula Exists ?obj3 ( ?obj3#_kid(?Hu ?Ch) )
Formula_Exists formula2 = factory.createFormula_Exists(varsExistential, f3_atom);
// add both the atomic formulas and the existentially quantified formula to the list of formulas
List<Formula> formulas = new ArrayList<Formula>();
formulas.add(f2_atom);
formulas.add(formula2);
// express these two formulas as a conjunctive formula
Formula_And body = factory.createFormula_And(formulas);
// create the implication
Implies implication = factory.createImplies(headList, body);
// create the clause
Clause clause = factory.createClause(implication);
// create the rule
Rule rule = factory.createRule(varsUniversal, clause);
// the rule is an item of a list of sentences
List<Sentence> sentences = new ArrayList<Sentence>();
sentences.add(rule);
// create a group with only one sentence
Group group = factory.createGroup(sentences);
// create the document
Document doc = factory.createDocument(null, group);
// render the rule in presentation syntax
System.out.println("PSOA RuleML/XML document rendered in Presentation Syntax: \n" + doc);

The equivalent presentation syntax for the rule is displayed below:

Document (

  Group (

    Forall ?Hu ?Ch ?o ?Ch 
    (
       ?o#_family(_child->?Ch)
        :-
          And
          (
            ?o#_family(_husb->?Hu _wife->?Wi)
            Exists ?obj3 
            (
              ?obj3#_kid(?Hu ?Ch)          
            )
          )
    )

  )

)

7 References

1. Boley, H.: PSOA RuleML: Integrated Object-Relational Data and Rules. In Wolfgang Faber and Adrian Paschke, editors, Reasoning Web. Web Logic Rules (RW2015) - 11th International Summer School 2015, Berlin, Germany, July 31-August 4, 2015, Tutorial Lectures, volume 9203 of Lecture Notes in Computer Science, pp. 114-150. Springer, 2015. SpringerLink: Abstract. Postprint: http://www.cs.unb.ca/~boley/papers/PSOAObjRelDataRules.pdf. Presented in the Computational Logic Seminar – MUGS, 27 May 2015, the SRI AIC Seminar Series, 9 June 2015, plus RW2015, 31 July - 4 August 2015. Slides for RW2015: http://www.cs.unb.ca/~boley/talks/PSOAObjRelDataRules-talk-RW2015.pdf. Slides with maximum details from paper: http://www.cs.unb.ca/~boley/talks/PSOAObjRelDataRules-talk.pdf. PSOARuleMLSQLSPARQL (pdf, docx) subset of slides for AWoSS 2015: http://www.cs.unb.ca/~boley/talks/PSOAObjRelDataRules-AWoSS2015-talk.pdf

2. Harold Boley, A RIF-Style Semantics for RuleML-Integrated Positional-Slotted, Object-Applicative Rules. In Nick Bassiliades, Guido Governatori, and Adrian Paschke, editors, RuleML Europe, volume 6826 of LNCS, pp. 94–211. Springer, 2011. Preprint: http://www.cs.unb.ca/~boley/papers/SemanticsPsoaRules.pdf. Slides for IJCAI 2011 Best Papers from Sister Conferences Track: http://www.cs.unb.ca/~boley/talks/SemanticsPsoaRules-talk-IJCAI2011.pdf. Slides with maximum details from paper: http://www.cs.unb.ca/~boley/talks/SemanticsPsoaRules-talk-UNB2011.pdf

3. Al Manir, M.S., Riazanov, A., Boley, H., Baker, C.J.O.: PSOA RuleML API: A Tool for Processing Abstract and Concrete Syntaxes. In: Bikakis, A., Giurca, A. (eds.) RuleML 2012. LNCS, vol. 7438, pp. 280–288. Springer, Heidelberg (2012). Preprint: http://www.cs.unb.ca/~boley/papers/PSOA_RuleML_API.pdf. Slides: http://www.cs.unb.ca/~boley/talks/PSOA_RuleML_API-talk.pdf

4. Sadnan Al Manir, Harold Boley, Alexander Riazanov. PSOA RuleML API : An Open-source JAVA Based Tool for Rendering PSOA RuleML/XML to Presentation Syntax. Research Exposition, UNB Faculty of Computer Science, April 10, 2012. Poster: http://www.cs.unb.ca/research-expo/archive/2012/submissions/Sadnan%20Al%20Manir_sadnan.almanir@unb.ca_Poster.pdf

5. Mohammad Sadnan Al Manir. PSOA RuleML API, An informal talk on the progress of the API, January 25, 2011. Slides: https://dl.dropboxusercontent.com/u/64656644/PSOARuleMLParser.pdf

6. Joe Fialli and Sekhar Vajjhala. Java Architecture for XML Binding (JAXB) 2.0. Java Specification Request (JSR) 222, October 2005.

8 Appendix: XML Schema for PSOA RuleML

8.1 Condition Language

Copied from : https://github.com/sadnanalmanir/PSOARuleML-API/blob/master/src/main/resources/PSOACond.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://psoa.ruleml.org/lang/spec#" targetNamespace="http://psoa.ruleml.org/lang/spec#" elementFormDefault="qualified" version="Id: PSOACond.xsd, v. 1.0, 2011-10-19, ">
  <!--the xml.xsd is imported from web address, to load faster load it locally

  <xs:import namespace='http://www.w3.org/XML/1998/namespace'
  schemaLocation='http://www.w3.org/2001/03/xml.xsd'/>
-->
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="https://www.w3.org/2009/01/xml.xsd"/>
<xs:annotation>
  <xs:documentation>

    Last updated: 2016-01-24

    This is the tentative XML schema for the Rule Language as defined by
    the PSOA RuleML Published at http://www.cs.unb.ca/~boley/papers/SemanticsPsoaRules.pdf


    The schema is based on the following EBNF for the PSOA RuleML Condition Language:

    FORMULA        ::= 'And' '(' FORMULA* ')' | 
                       'Or' '(' FORMULA* ')' | 
                       'Exists' Var+ '(' FORMULA ')' | 
                       ATOMIC | 
			     'External' '(' Atom ')'
    ATOMIC         ::= Atom | Equal | Subclass
    Atom           ::= PSOA
    PSOA           ::= (oid '#')? op '(' (TUPLEARGS | Tuple*)  slot* ')'
    Equal          ::= left '=' right
    Subclass       ::= sub '##' super
    oid            ::= INDTERM
    op             ::= OPTERM
    Tuple          ::= TUPLEARGS
    TUPLEARGS      ::= INDTERM*
    slot           ::= INDTERM '-&gt;' INDTERM
    left           ::= INDTERM
    right          ::= INDTERM
    sub            ::= op
    super          ::= op
    INDTERM        ::= Ind | Var | Expr | 'External' '(' Expr ')'
    OPTERM         ::= Rel | Fun | Var | Expr | 'External' '(' Expr ')'
    Expr           ::= PSOA
    Ind            ::= '"' UNICODESTRING '"^^' SYMSPACE | CONSTSHORT
    Rel            ::= '"' UNICODESTRING '"^^' SYMSPACE | CONSTSHORT
    Fun            ::= '"' UNICODESTRING '"^^' SYMSPACE | CONSTSHORT
    Var            ::= '?' UNICODESTRING?
    SYMSPACE       ::= ANGLEBRACKIRI | CURIE

    Currently string (http://www.w3.org/2001/XMLSchema#string), integer (http://www.w3.org/2001/XMLSchema#integer),
    local (http://psoa.ruleml.org/lang/spec#local), and global (http://psoa.ruleml.org/lang/spec#global) datatype are supported
    Only Top uses global (see Slide 21 of http://www.cs.unb.ca/~boley/talks/SemanticsPsoaRules-talk-AWoSS3.pdf)

  </xs:documentation>
</xs:annotation>

<xs:element name="formula">
  <xs:complexType>
    <xs:sequence>
      <xs:group ref="FORMULA"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

<xs:group name="FORMULA">
  <!--
  FORMULA        ::= 'And' '(' FORMULA* ')' |
  'Or' '(' FORMULA* ')' |
  'Exists' Var+ '(' FORMULA ')' |
  ATOMIC |
  'External' '(' Atom ')'
-->
<xs:choice>
  <xs:element ref="And"/>
  <xs:element ref="Or"/>
  <xs:element ref="Exists"/>
  <xs:group ref="ATOMIC"/>
  <xs:element name="External" type="External-FORMULA.type"/>
</xs:choice>
</xs:group>

<!--
FORMULA        ::= 'And' '(' FORMULA* ')'
-->
<xs:element name="And">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="formula" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
FORMULA       ::= 'Or' '(' FORMULA* ')'
-->
<xs:element name="Or">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="formula" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
FORMULA       ::= 'Exists' Var+ '(' FORMULA ')'
-->
<xs:element name="Exists">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="declare" minOccurs="1" maxOccurs="unbounded"/>
      <xs:element ref="formula"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
FORMULA       ::= 'External' '(' Atom ')'
-->
<xs:complexType name="External-FORMULA.type">
  <xs:sequence>
    <xs:element name="content" type="content-FORMULA.type"/>
  </xs:sequence>
</xs:complexType>
<!-- sensitive to FORMULA (Atom) context
FORMULA       ::= 'External' '(' Atom ')'
-->
<xs:complexType name="content-FORMULA.type">
  <xs:sequence>
    <xs:element ref="Atom"/>
  </xs:sequence>
</xs:complexType>
<xs:element name="declare">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="Var"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
ATOMIC         ::= Atom | Equal | Subclass
-->
<xs:group name="ATOMIC">
  <xs:choice>
    <xs:element ref="Atom"/>
    <xs:element ref="Equal"/>
    <xs:element ref="Subclass"/>
  </xs:choice>
</xs:group>
<!--
Atom           ::= PSOA
-->
<xs:element name="Atom">
  <xs:complexType>
    <xs:sequence>
      <xs:group ref="PSOA"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
PSOA           ::= (oid '#')? op '(' (TUPLEARGS | Tuple*)  slot* ')'
-->
<xs:group name="PSOA">
  <xs:sequence>
    <xs:element ref="oid" minOccurs="0" maxOccurs="1"/>
    <xs:element ref="op"/>
    <xs:choice>                
        <xs:group ref="TUPLEARGS"/>
        <xs:element ref="Tuple" minOccurs="0" maxOccurs="unbounded"/>
    </xs:choice>    
    <xs:element name="slot" type="slot-PSOA.type" minOccurs="0" maxOccurs="unbounded"/>
  </xs:sequence>
</xs:group>       
<!--
Tuple          ::= TUPLEARGS
-->
<xs:element name="Tuple">
  <xs:complexType>
    <xs:sequence>
      <!--xs:group ref="INDTERM" minOccurs="1" maxOccurs="unbounded"/-->
      <xs:group ref="TUPLEARGS"/>
    </xs:sequence>
    <xs:attribute name="ordered" type="xs:string" fixed="yes"/>
  </xs:complexType>
</xs:element>
<!--
TUPLEARGS          ::= INDTERM*
-->
<xs:group name="TUPLEARGS">      
    <xs:sequence>
      <xs:group ref="INDTERM" minOccurs="0" maxOccurs="unbounded"/>        
    </xs:sequence>
</xs:group>
<!--
slot           ::= INDTERM '-&gt;' INDTERM
-->
<xs:complexType name="slot-PSOA.type">
  <xs:sequence>
    <xs:group ref="INDTERM"/>
    <xs:group ref="INDTERM"/>
  </xs:sequence>
  <xs:attribute name="ordered" type="xs:string" fixed="yes"/>
</xs:complexType>
<!--
oid            ::= INDTERM
-->
<xs:element name="oid">
  <xs:complexType>
    <xs:sequence>
      <xs:group ref="INDTERM"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
op             ::= OPTERM
-->
<xs:element name="op">
  <xs:complexType>
    <xs:sequence>
      <xs:group ref="OPTERM"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
Equal          ::= left '=' right
-->
<xs:element name="Equal">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="left"/>
      <xs:element ref="right"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
left           ::= INDTERM
-->
<xs:element name="left">
  <xs:complexType>
    <xs:choice>
      <xs:group ref="INDTERM"/>
    </xs:choice>
  </xs:complexType>
</xs:element>
<!--
right          ::= INDTERM
-->
<xs:element name="right">
  <xs:complexType>
    <xs:choice>
      <xs:group ref="INDTERM"/>
    </xs:choice>
  </xs:complexType>
</xs:element>
<!--
Subclass       ::= sub '##' super
-->
<xs:element name="Subclass">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="sub"/>
      <xs:element ref="super"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
sub            ::= op
-->
<xs:element name="sub">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="op"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
super          ::= op
-->
<xs:element name="super">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="op"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
INDTERM        ::= Ind | Var | Expr | 'External' '(' Expr ')'
-->
<xs:group name="INDTERM">
  <xs:choice>
    <xs:element ref="Ind"/>
    <xs:element ref="Rel"/>
    <xs:element ref="Var"/>
    <xs:element ref="Expr"/>
    <xs:element name="External" type="External-TERM.type"/>
  </xs:choice>
</xs:group>
<!--
OPTERM         ::= Rel | Fun | Var | Expr | 'External' '(' Expr ')'
-->
<xs:group name="OPTERM">
  <xs:choice>
    <xs:element ref="Rel"/>
    <xs:element ref="Fun"/>
    <xs:element ref="Var"/>
    <xs:element ref="Expr"/>
    <xs:element name="External" type="External-TERM.type"/>
  </xs:choice>
</xs:group>
<xs:complexType name="External-TERM.type">
  <!-- sensitive to TERM (Expr) context-->
  <xs:sequence>
    <xs:element name="content" type="content-TERM.type"/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="content-TERM.type">
  <!-- sensitive to TERM (Expr) context-->
  <xs:sequence>
    <xs:element ref="Expr"/>
  </xs:sequence>
</xs:complexType>
<!--
Expr           ::= PSOA
-->
<xs:element name="Expr">
  <xs:complexType>
    <xs:sequence>
      <xs:group ref="PSOA"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<!--
Ind           ::= typed individual constant
-->
<xs:element name="Ind">
  <xs:complexType mixed="true">
    <xs:sequence>
      <xs:group ref="IRIMETA" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="type" type="xs:anyURI" use="required"/>
    <!--xs:attribute ref="xml:lang"/-->
  </xs:complexType>
</xs:element>
<!--
Rel           ::= typed relational constant
-->
<xs:element name="Rel">
  <xs:complexType mixed="true">
    <xs:sequence>
      <xs:group ref="IRIMETA" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="type" type="xs:anyURI" use="required"/>
    <!--xs:attribute ref="xml:lang"/-->
  </xs:complexType>
</xs:element>
<!--
Fun           ::= typed functional constant
-->
<xs:element name="Fun">
  <xs:complexType mixed="true">
    <xs:sequence>
      <xs:group ref="IRIMETA" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
    <xs:attribute name="type" type="xs:anyURI" use="required"/>
    <!--xs:attribute ref="xml:lang"/-->
  </xs:complexType>
</xs:element>
<xs:element name="Var">
<!--
  Var            ::= '?' UNICODESTRING
-->
<xs:complexType mixed="true">
  <xs:sequence>
    <xs:group ref="IRIMETA" minOccurs="0" maxOccurs="1"/>
  </xs:sequence>
</xs:complexType>
</xs:element>
<xs:group name="IRIMETA">
<!--
  IRIMETA   ::= '(*' IRICONST? (Frame | 'And' '(' Frame* ')')? '*)'
-->
<xs:sequence>
  <xs:element ref="id" minOccurs="0" maxOccurs="1"/>
  <xs:element ref="meta" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:group>
<xs:element name="id">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Ind" type="IRICONST.type"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<xs:element name="meta">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="And" type="And-meta.type"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
<xs:complexType name="And-meta.type">
  <!-- sensitive to meta (Frame) context-->
  <xs:sequence>
    <xs:element name="formula" minOccurs="0" maxOccurs="unbounded"/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="IRICONST.type" mixed="true">
  <!-- sensitive to location/id context-->
  <xs:sequence/>
  <xs:attribute name="type" type="xs:anyURI" use="required" fixed="http://psoa.ruleml.org/lang/spec#iri"/>
</xs:complexType>
</xs:schema>

8.2 Rule Language

Copied from : https://github.com/sadnanalmanir/PSOARuleML-API/blob/master/src/main/resources/PSOARule.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns="http://psoa.ruleml.org/lang/spec#" 
  targetNamespace="http://psoa.ruleml.org/lang/spec#" 
  elementFormDefault="qualified" 
  version="Id: PSOARule.xsd, v. 1.0, 2011-10-19">
  <xs:annotation>
    <xs:documentation>
      
      Last updated: 2014-12-29

    This is the tentative XML schema for the Rule Language as defined by
    the PSOA RuleML Published at http://www.cs.unb.ca/~boley/papers/SemanticsPsoaRules.pdf

    The schema is based on the following EBNF for the PSOA Rule Language:
  
  Document  ::= 'Document' '(' Base? Prefix* Import* Group? ')'
  Base      ::= 'Base' '(' ANGLEBRACKIRI ')'
  Prefix    ::= 'Prefix' '(' Name ANGLEBRACKIRI ')'
  Import    ::= 'Import' '(' ANGLEBRACKIRI PROFILE? ')'
  Group     ::= 'Group' '(' (RULE | Group)* ')'
  RULE      ::= ('Forall' Var+ '(' CLAUSE ')') | CLAUSE
  CLAUSE    ::= Implies | ATOMIC
  Implies   ::= (HEAD | 'And' '(' HEAD* ')') ':-' FORMULA
  HEAD      ::= ATOMIC | 'Exists' Var+ '(' ATOMIC ')'
  PROFILE   ::= ANGLEBRACKIRI
      
    </xs:documentation>
  </xs:annotation>
  <!-- The Rule Language includes the Condition Language from the same directory -->
  <xs:include schemaLocation="https://dl.dropboxusercontent.com/u/64656644/PSOACond.xsd"/>
  <xs:element name="Document">
    <!--
  Document  ::= 'Document' '(' Base? Prefix* Import* Group? ')'
    -->
    <xs:complexType>
      <xs:sequence>
	  <xs:group ref="IRIMETA" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="directive" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="payload" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="directive">
    <!--
  Base and Prefix represented directly in XML
    -->
    <xs:complexType>
      <xs:sequence>        
        <xs:element ref="Import"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="payload">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Group"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="Import">
    <!--
  Import    ::= IRIMETA? 'Import' '(' LOCATOR PROFILE? ')'
  LOCATOR   ::= ANGLEBRACKIRI
  PROFILE   ::= ANGLEBRACKIRI
    -->
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="location"/>
        <xs:element ref="profile" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="location" type="xs:anyURI"/>

  <xs:element name="profile" type="xs:anyURI"/>

  <xs:element name="Group">
    <!--
  Group     ::= 'Group' '(' (RULE | Group)* ')'
    -->
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="sentence" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="sentence">
    <xs:complexType>
      <xs:choice>
        <xs:group ref="RULE"/>
        <xs:element ref="Group"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:group name="RULE">
    <!--
  RULE      ::= ('Forall' Var+ '(' CLAUSE ')') | CLAUSE
    -->
    <xs:choice>
      <xs:element ref="Forall"/>
      <xs:group ref="CLAUSE"/>
    </xs:choice>
  </xs:group>
  <xs:element name="Forall">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="declare" minOccurs="1" maxOccurs="unbounded"/>
        <!-- different from formula in And, Or and Exists -->
        <xs:element name="formula">
          <xs:complexType>
            <xs:group ref="CLAUSE"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:group name="CLAUSE">
    <!--
  CLAUSE   ::= Implies | ATOMIC
    -->
    <xs:choice>
      <xs:element ref="Implies"/>
      <!--xs:group ref="ATOMIC"/-->
      <xs:group ref="HEAD"/>
    </xs:choice>
  </xs:group>
  <xs:element name="Implies">
    <!--
  Implies   ::= (HEAD | 'And' '(' HEAD* ')') ':-' FORMULA
    -->
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="if"/>
        <xs:element ref="then"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!--
   FORMULA
  -->
  <xs:element name="if">
    <xs:complexType>
      <xs:sequence>
        <xs:group ref="FORMULA"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <!--
   (HEAD | 'And' '(' HEAD* ')')
    -->
  <xs:element name="then">
    <xs:complexType>
      <xs:choice>
        <xs:group ref="HEAD"/>
        <xs:element name="And" type="And-then.type"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <!--
   'And' '(' HEAD* ')'
    -->
  <xs:complexType name="And-then.type">
    <xs:sequence>
      <xs:element name="formula" type="formula-and-then.type" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="formula-and-then.type">
    <xs:sequence>
      <xs:group ref="HEAD"/>
    </xs:sequence>
  </xs:complexType>
  <!--
   HEAD
    -->
  <xs:group name="HEAD">
    <!--
  HEAD      ::= ('Exists' Var+ '(' ATOMIC ')') | ATOMIC   
    -->
    <xs:choice>
      <xs:group ref="ATOMIC"/>
      <xs:element name="Exists" type="Exists-then.type"/>
    </xs:choice>
  </xs:group>
  <!--
  ('Exists' Var+ '(' ATOMIC ')')
    -->
  <xs:complexType name="Exists-then.type">
    <xs:sequence>
      <xs:element ref="declare" minOccurs="1" maxOccurs="unbounded"/>
      <xs:element name="formula" type="formula-exists-then.type"/>
    </xs:sequence>
  </xs:complexType>
  <!--
  ATOMIC   
    -->
  <xs:complexType name="formula-exists-then.type">
    <xs:sequence>
      <xs:group ref="ATOMIC"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>