Sunday, June 19, 2011

How to Support Property Chain Axiom Using Oracle's OWL Prime

In this article, we will show how to support Property Chain Axiom using OWLPrime rulebase in Oracle Semantic Technologies.
What Oracle Semantic Supports?
Oracle Semantic Technologies support the following rule set (but not limited to these):
  • OWLSIF (OWL with IF semantics)
    • Based on Dr. Horst's pD* vocabulary
  • OWLPrime
  • OWL2RL

If you are using 11.2.0.1, you can find OWl 2 RL support in the following patch on support.oracle.com:

  • Patch Number 9819833 - semantic technologies 11g r2 fix bundle 2

Note that Semantic 11.2.0.2 comes with OWl 2 RL support.

Property Chain Axiom[5]

Table 1 specifies the semantic conditions on property chain axiom:


If
Then
prp-spo2 T(?p, owl:propertyChainAxiom, ?x)
LIST[?x, ?p1, ..., ?pn]
T(?u1, ?p1, ?u2)
T(?u2, ?p2, ?u3)
...
T(?un, ?pn, ?un+1)
T(?u1, ?p, ?un+1)
Property chain axiom allows reasoner to infer the existence of a property from a chain of properties. For example, the following hasContained semantic using property chain axiom :
hasContained(x, "EOS 60D") ^ rdf:type("EOS 60D","Digital SLR Cameras")
-> hasContained(x,"Cameras")

<rdf:description about="hasContained">
<owl:propertychainaxiom parsetype="Collection"/>
<owl:objectproperty about="hasContained"/>
<owl:objectproperty about="&rdf;type">
</owl:propertychainaxiom>
</rdf:description>
to derive the fact that an article is related to the topic "Cameras" if it contains the key words "EOS 60D" because "EOS 60D" is a rdf:type of "Digital SLR Cameras" which is, in turn, a owl:subClassOf of "Cameras". Our camera ontology example looks like this:

Using Oracle's OWLPrime rule set, it doesn't support the above inference directly. What it can infer is just:
rdf:type("EOS 60D", "Digital SLR Cameras") ^
owl:subClassOf("Digital SLR Cameras","Cameras") -> rdf:type("EOS 60D","Cameras")
However, this is different from what we want. To enable Oracle Semantic to support what we want using OWLPrime rule set, we need to:
  • Specify chain definition RDF triples
  • Specify 'CHAIN' for the inf_components_in argument in SEM_APIS.CREATE_ENTAILMENT()
Note that OWL2RL has more rules than OWLPrime does and you can use it to achieve the above task directly. However, the more rules you include in the inference, the slower performance you get. That's the reason why we document the steps here to allow users to use OWLPrime instead of OWL2RL for property chain.

Chain Definition Triples

The first requirement is to insert the necessary chain definition triples for hasContained semantic into your ontology model:

prefix prop:, namespace URI: http://xmlns.oracle.com/rdfctx/property#
prefix owl:, namespace URI: http://www.w3.org/2002/07/owl#
prefix rdf:, namespace URI: http://www.w3.org/1999/02/22-rdf-syntax-ns#
prop:hasContained  owl:propertyChainAxiom _:jA1 .
_:jA1 rdf:first prop:hasContained .
_:jA1 rdf:rest _:jA2.
_:jA2 rdf:first rdf:type .
_:jA2 rdf:rest rdf:nil .
To insert the above chain definition triples, you can use the following INSERT statements:
INSERT INTO ontology_rdf_data VALUES(ONTOLOGY_S1.nextval,
sdo_rdf_triple_s('ontology_model',
'<http://xmlns.oracle.com/rdfctx/property#hasContained>',
'<http://www.w3.org/2002/07/owl#propertyChainAxiom>',
'_:jA1'));

INSERT INTO ontology_rdf_data VALUES(ONTOLOGY_S1.nextval,
sdo_rdf_triple_s('ontology_model','_:jA1',
'<http://www.w3.org/1999/02/22-rdf-syntax-ns#first>',
'<http://xmlns.oracle.com/rdfctx/property#hasContained>'));

INSERT INTO ontology_rdf_data VALUES(ONTOLOGY_S1.nextval,
sdo_rdf_triple_s('ontology_model',
'_:jA1', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#rest>',
'_:jA2'));

INSERT INTO ontology_rdf_data VALUES(ONTOLOGY_S1.nextval,
sdo_rdf_triple_s('ontology_model','_:jA2',
'<http://www.w3.org/1999/02/22-rdf-syntax-ns#first>',
'<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>'));

INSERT INTO ontology_rdf_data VALUES(ONTOLOGY_S1.nextval,
sdo_rdf_triple_s('ontology_model',
'_:jA2', '<http://www.w3.org/1999/02/22-rdf-syntax-ns#rest>',
'<http://www.w3.org/1999/02/22-rdf-syntax-ns#nil>'));
Note that our ontology_model is created as:
-- create application table
create table ontology_rdf_data (
triple_id NUMBER(18) NOT NULL,
triple SDO_RDF_TRIPLE_S,
CONSTRAINT ontology_rdf_data_pk PRIMARY KEY (triple_id)
);

-- create the RDF Model --
begin
sem_apis.create_rdf_model (model_name => 'ontology_model',
table_name => 'ontology_rdf_data',
column_name => 'triple');
end;
/

SEM_APIS.CREATE_ENTAILMENT

Before you use SEM_MATCH table function to query semantic data, it is required that you create a rules index using SEM_APIS.CREATE_ENTAILMENT. The rules index will contain precomputed triples inferred from RDF model(s) and rulebase(s).

Here we describe how to set up rules index correctly for supporting property chain. First, if you have already created the rules index, drop it first:
BEGIN
SEM_APIS.DROP_ENTAILMENT('rule_index_1');
END;
/

The second step is to run inference on default graph:

exec sem_apis.create_entailment('rule_index_1',sem_models('ontology_model','model_1'),sem_rulebases('owlprime'),inf_components_in => 'CHAIN', include_default_g => sem_models('ontology_model','model_1'));

Finally, you run NG-based (i.e., Name Graph) local inference:

exec sem_apis.create_entailment('rule_index_1',sem_models('ontology_model','model_1'),sem_rulebases('owlprime'), inf_components_in => 'CHAIN', options =>'ENTAIL_ANYWAY=T,LOCAL_NG_INF=T');
commit;

Unless you specify below argument
inf_components_in => 'CHAIN'
the reasoner won't support property chain using OWLPrime rulebase.

Note that there are two RDF models used in the above global and local inference(s):
  • ontology_model (i.e., TBox)
  • model_1 (i.e., ABox)

Global Inference vs. Local Inference
Global inference takes all asserted triples from all the source model(s) provided and applies semantic rules on top of all the asserted triples till an inference closure is reached. Even if the given source models contain one more multiple named graphs, it actually makes no difference to global inference because all assertions, whether part of a named graph or not, are treated the same as if they come from a single graph.

On the other hand, local inference is performed within the boundary of every single named graph combined with the common schema. See Oracle documentation for more details.

References
  1. OWL 2 Web Ontology Language Profiles
  2. Oracle's Support for a Subset of the Web Ontology Language (OWL)
  3. The Fragment of OWL Implemented in Oracle 11g
  4. rdf:type
  5. Property Chains
  6. SKOS (part 4): property chains

Wednesday, June 15, 2011

Reusable ADF Components—Application Modules

In the course of application development, certain components will often be reused. Creating and consuming reusable components should be included in the early design and architectural phases of software projects.

Whether the reuse happens within the same application, or across different applications, it is often advantageous to package these reusable components into a library that can be shared between different teams. These shared libraries can be added to a repository. Later if you need a component, you may look into the repository for something to be reused.

Multiple Oracle ADF components are reusable, which include[1]:
  • Application modules
  • Business Components
  • Data controls
  • Task flows
  • Page templates
  • Declarative components
These reusable components can be packaged into the ADF Library for reuse in applications (see [4] for how-to). Creating an ADF Library JAR involves compiling the project and validating the components, creating a resource service file, control files, an adflibREADME.txt, and adding the relevant project files into a JAR.

In this article, we will discuss a specific reusable component—Application Module. Application modules are associated with Business Components. When the reusable application module was packaged, the JAR includes the Business Components used to create the application module. These components will be available for reuse.

For packaging application modules, JDeveloper adds three control files to the JAR:
  1. oracle.adf.common.services.ResourceService.sva
  2. Manifest.mf
  3. adfm.xml
The service resource file for an application module includes entries for the Business Components associated with the application module, as well as an entry for the application module data control.

When you add an application module to a project, the application module appears in the Data Controls panel.

What's Application Module

Within a running BC4J application, one can think of the following containership of application objects:
  • Root Application Module contains nested Application Modules
  • An Application Module contains View Objects
  • A View Object contains Row Sets
  • A Row Set contain Row Set Iterators
Application Modules can be nested. That is, an Application Module can (logically) contain one or more other Application Modules (i.e., nested AMs) as well as View Objects. The outermost containing Application Module is referred to as the "root" Application Module.

What Do You Need to Know about Nested Application Module

In this Andrejus Baranovskis' article, it has two application modules which contain View Objects created from Employee and Job tables and are packaged into two ADF libraries
  1. adflibEmplooyeesApp.jar
  2. adflibJobsApp.jar
These two libraries can be imported into an ADF web application in two ways:
  1. Integrating ADF JAR's directly into the ViewController project (i.e., using Application Modules directly from ADF JAR's)
  2. Integrating ADF JAR's into the Model project with its own Application Module (i.e., Application Components from imported libraries are created as nested Application Modules)
Using either approach, you need to add both JAR's to the application first. When you add an ADF Library JAR to a project, either by using the Resource Palette or by manually adding the JAR, an ADF Library definition is created in the project. The ADF Library JAR file will be added to the class path of the project. The project will access and consume the components in the JAR by reference. See here for how to add an ADF Library JAR to a project using the Resource Palette.

In the first approach, two JAR's are added to the consuming project's (i.e., ViewController project) class path and so is available for reuse. See here on how to add them to the ViewController project manually. As shown below, adflibEmployeesApp.jar and adflibJobsApp.jar are added to the ViewController project's class path:
LinkIn the second approach, you first create a new Application Module (i.e., HrModule) in the Model project. See here on how-to. To specify a composite root application module that nests an instance of an existing application module, you use the overview editor for the application module. See here on how-to.

As shown below, EmpModule and JobsModule are nested under root Application Module HrModule in the second approach:
Important notes about nested application modules:
  • A nested Application Module design is useful for applications that define several functional
  • sub-applications that share the same transaction context and transaction caches.
  • With a nested Application Module design, it is easy to re-deploy nested Application Modules as standalone Application Modules in different client applications without having to modify the metadata for the other existing Application Module.
  • When a root application module contains other nested application modules, they all participate in the root application module's transaction and share the same database connection and a single set of entity caches.
    • This sharing is handled for you automatically by the root application module and its "Transaction" object.
  • A nested Application Module cannot see the instances of any other Application Modules that might be nested beneath the same root.
  • The API for application modules also supports nesting of application modules at runtime.
  • Nested Application Module can help performance by reducing database connection usage (i.e., sharing a single database connection instead of owning a separate connection per AM).

Further Considerations

  • You should consider how to organize and group the library JARs in a structure that fits your organizational needs. For example,
    • Usually you want to have two separate application modules to support UIs and define services because
      • UI application modules may contain additional view objects and context values
        that are only required for a particular UI, but not needed by a business service.
      • Application modules that define public services are versioned, but internal UI
        application modules are not.
  • You should also consider creating standardized naming conventions so that both creators and consumers of ADF Library JARs can readily identify the component functionality.
    • You want to try to have unique names to avoid naming conflicts with other projects, components, or connections in the application.
    • Naming conflicts could arise from components created in the consuming application and those loaded from other JAR files.
  • A project corresponds to one ADF Library JAR.
    • If you create multiple projects and want to reuse components from each of the projects, you may need to create an ADF Library JAR for each project.
  • You can package multiple components into one JAR file, or you can package a single component into a JAR file.
    • Oracle ADF and JDeveloper give you the option and flexibility to create reusable components that best suit you and your organization.
  • You should avoid metadata naming conflicts between projects that will be combined at runtime.
    • The basic package naming requirement is that ADF metadata registries (.dcx,.cpx, and so on) are generated based on the project's package name. So, make the package name unique.

References
  1. Reusing Application Components
  2. Defining Nested Application Modules
  3. What you may need to know about Nested Application Module
  4. How to Package a Component into an ADF Library JAR