All Downloads are FREE. Search and download functionalities are using the official Maven repository.

openllet.examples.BnodeQueryExample Maven / Gradle / Ivy

There is a newer version: 2.6.5
Show newest version
// Portions Copyright (c) 2006 - 2008, Clark & Parsia, LLC. 
// Clark & Parsia, LLC parts of this source code are available under the terms of the Affero General Public License v3.
//
// Please see LICENSE.txt for full license terms, including the availability of proprietary exceptions.
// Questions, comments, or requests for clarification: [email protected]

package openllet.examples;

import openllet.core.OpenlletOptions;
import openllet.jena.PelletReasonerFactory;
import openllet.query.sparqldl.jena.SparqlDLExecutionFactory;
import org.apache.jena.ontology.OntModel;
import org.apache.jena.query.Query;
import org.apache.jena.query.QueryExecution;
import org.apache.jena.query.QueryExecutionFactory;
import org.apache.jena.query.QueryFactory;
import org.apache.jena.query.ResultSet;
import org.apache.jena.query.ResultSetFormatter;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Resource;

/**
 * Bnodes used in a SPARQL query are treated as variables but different from ordinary SPARQL variables they are not required to be bound to existing
 * individuals. This means a bnode in the query can be matched with an _individual whose existence is inferred from a someValues or a minCardinality
 * restriction.
 *
 * @author Evren Sirin
 */
public class BnodeQueryExample
{
	public static void main(final String[] args)
	{
		OpenlletOptions.TREAT_ALL_VARS_DISTINGUISHED = false;
		final String ns = "http://www.w3.org/TR/2003/PR-owl-guide-20031209/food#";

		// create an empty ontology model using Pellet spec
		final OntModel model = ModelFactory.createOntologyModel(PelletReasonerFactory.THE_SPEC);

		// read the file
		model.read("file:examples/data/wine.owl");

		// getOntClass is not used because of the same reason mentioned above
		// (i.e. avoid unnecessary classifications)
		final Resource RedMeatCourse = model.getResource(ns + "RedMeatCourse");
		final Resource PastaWithLightCreamCourse = model.getResource(ns + "PastaWithLightCreamCourse");

		// create two individuals Lunch and dinner that are instances of  
		// PastaWithLightCreamCourse and RedMeatCourse, respectively
		model.createIndividual(ns + "MyLunch", PastaWithLightCreamCourse);
		model.createIndividual(ns + "MyDinner", RedMeatCourse);

		final String queryBegin = "PREFIX rdf:  \r\n" + "PREFIX food: \r\n" + "PREFIX wine: \r\n" + "\r\n" + "SELECT ?Meal ?WineColor\r\n" + "WHERE {\r\n";
		final String queryEnd = "}";

		// create a query that asks for the color of the wine that
		// would go with each meal course
		final String queryStr1 = queryBegin + "   ?Meal rdf:type food:MealCourse .\r\n" + "   ?Meal food:hasDrink _:Wine .\r\n" + "   _:Wine wine:hasColor ?WineColor" + queryEnd;

		// same query as above but uses a variable instead of a bnode        
		final String queryStr2 = queryBegin + "   ?Meal rdf:type food:MealCourse .\r\n" + "   ?Meal food:hasDrink ?Wine .\r\n" + "   ?Wine wine:hasColor ?WineColor" + queryEnd;

		final Query query1 = QueryFactory.create(queryStr1);
		final Query query2 = QueryFactory.create(queryStr2);

		// The following definitions from food ontology dictates that 
		// PastaWithLightCreamCourse has white wine and RedMeatCourse 
		// has red wine.
		//  Class(PastaWithLightCreamCourse partial
		//        restriction(hasDrink allValuesFrom(restriction(hasColor value (White)))))
		//  Class(RedMeatCourse partial
		//        restriction(hasDrink allValuesFrom(restriction(hasColor value (Red)))))
		//
		// PelletQueryEngine will successfully find the answer for the first query
		printQueryResults("Running first query with PelletQueryEngine...", SparqlDLExecutionFactory.create(query1, model), query1);

		// The same query (with variables instead of bnodes) will not return same answers!
		// The reason is this: In the second query we are using a variable that needs to be 
		// bound to a specific wine instance. The reasoner knows that there is a wine (due
		// to the cardinality restriction in the ontology) but does not know the URI for  
		// that _individual. Therefore, query fails because no binding can be found. 
		//
		// Note that this behavior is similar to what you get with "must-bind", "don't-bind" 
		// variables in OWL-QL. In this case, variables in the query are "must-bind" variables 
		// and bnodes are "don't-bind" variables.
		printQueryResults("Running second query with PelletQueryEngine...", SparqlDLExecutionFactory.create(query2, model), query2);

		// When the standard QueryEngine of Jena is used we don't get the results even 
		// for the first query. The reason is Jena QueryEngine evaluates the query one triple 
		// at a time and thus fails when the wine _individual is not found. PelletQueryEngine
		// evaluates the query as a whole and succeeds. (If the above feature, creating bnodes
		// automatically, is added to Pellet then you would get the same results here) 
		printQueryResults("Running first query with standard Jena QueryEngine...", QueryExecutionFactory.create(query1, model), query1);
	}

	public static void printQueryResults(final String header, final QueryExecution qe, final Query query)
	{
		System.out.println(header);

		final ResultSet results = qe.execSelect();

		ResultSetFormatter.out(System.out, results, query);

		System.out.println();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy