From: <lor...@us...> - 2013-01-22 09:47:32
|
Revision: 3884 http://dl-learner.svn.sourceforge.net/dl-learner/?rev=3884&view=rev Author: lorenz_b Date: 2013-01-22 09:47:20 +0000 (Tue, 22 Jan 2013) Log Message: ----------- Moving QTL algorithm to core module. Modified Paths: -------------- trunk/components-core/pom.xml trunk/components-core/src/main/java/org/dllearner/algorithms/DisjointClassesLearner.java trunk/components-core/src/main/java/org/dllearner/algorithms/properties/FunctionalObjectPropertyAxiomLearner.java trunk/components-core/src/main/java/org/dllearner/algorithms/properties/ObjectPropertyDomainAxiomLearner.java trunk/components-core/src/main/java/org/dllearner/core/AbstractAxiomLearningAlgorithm.java trunk/components-core/src/main/java/org/dllearner/reasoning/SPARQLReasoner.java Added Paths: ----------- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QueryTreeFactory.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/cache/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/cache/QueryTreeCache.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/NodeRenderer.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/QueryTree.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/GeneralisedQueryTree.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeChange.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeImpl.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/examples/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/examples/DBpediaExample.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/examples/LinkedGeoDataExample.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/exception/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/exception/EmptyLGGException.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/exception/NBRException.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/exception/NegativeTreeCoverageExecption.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/exception/QTLException.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/exception/TimeOutException.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/ExactMatchFilter.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/Filter.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/Filters.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/I_Sub.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/QueryTreeFilter.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/QuestionBasedQueryTreeFilter.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/QuestionBasedQueryTreeFilterAggressive.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/QuestionBasedStatementFilter.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/QuestionBasedStatementFilter2.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/QuestionBasedStatementSelector.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/filters/ZeroFilter.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/impl/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/impl/QueryTreeFactoryImpl.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/impl/QueryTreeFactoryImpl2.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/FilterVisitor.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/Generalisation.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/NBR.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/PostLGG.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/lgg/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/lgg/LGGGenerator.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/lgg/LGGGeneratorImpl.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/nbr/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/nbr/NBRGenerator.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/nbr/NBRGeneratorImpl.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/nbr/strategy/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/nbr/strategy/BruteForceNBRStrategy.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/nbr/strategy/GreedyNBRStrategy.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/nbr/strategy/NBRStrategy.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/operations/nbr/strategy/TagNonSubsumingPartsNBRStrategy.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/util/ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/util/Prefixes.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/util/SPARQLEndpointEx.java trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/util/TreeHelper.java trunk/components-core/src/test/java/org/dllearner/algorithms/ trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/ trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/GeneralisationTest.java trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/LGGTest.java trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/NBRTest.java trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/QTLTest.java trunk/components-core/src/test/java/org/dllearner/algorithms/qtl/TreeSubsumptionTest.java Property Changed: ---------------- trunk/components-core/ Property changes on: trunk/components-core ___________________________________________________________________ Modified: svn:ignore - components-core.iml target log .classpath .project .settings + components-core.iml target log .classpath .project .settings cache Modified: trunk/components-core/pom.xml =================================================================== --- trunk/components-core/pom.xml 2013-01-22 09:43:25 UTC (rev 3883) +++ trunk/components-core/pom.xml 2013-01-22 09:47:20 UTC (rev 3884) @@ -113,11 +113,18 @@ </exclusions> </dependency> - <!-- THIS IS FROM THE UNIBAS REPO --> <dependency> <groupId>net.sourceforge.owlapi</groupId> - <artifactId>owlapi</artifactId> + <artifactId>owlapi-distribution</artifactId> </dependency> + <dependency> + <groupId>net.sourceforge.owlapi</groupId> + <artifactId>owlapi-reasoner</artifactId> +</dependency> +<dependency> + <groupId>net.sourceforge.owlapi</groupId> + <artifactId>owlapi-util</artifactId> + </dependency> <!-- THIS IS FROM THE UNIBAS REPO --> <dependency> @@ -253,6 +260,12 @@ <artifactId>xercesImpl</artifactId> <version>2.8.0</version> </dependency> + + <dependency> + <groupId>uk.ac.shef.wit</groupId> + <artifactId>simmetrics</artifactId> + <version>1.6.2</version> + </dependency> </dependencies> <dependencyManagement> <dependencies> Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/DisjointClassesLearner.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/DisjointClassesLearner.java 2013-01-22 09:43:25 UTC (rev 3883) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/DisjointClassesLearner.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -178,12 +178,12 @@ class2Overlap.put(cls, cnt); } //for each property in knowledge base - for(NamedClass cls : allClasses){ + for(NamedClass cls : allClasses){if(!cls.toString().equals("http://dbpedia.org/ontology/MotorcycleRider"))continue; //get the popularity int otherPopularity = reasoner.getPopularity(cls); if(otherPopularity == 0){//skip empty properties continue; - } + }System.out.println(cls); //get the overlap int overlap = class2Overlap.containsKey(cls) ? class2Overlap.get(cls) : 0; //compute the estimated precision @@ -455,7 +455,8 @@ ks = new LocalModelBasedSparqlEndpointKS(new URL("http://dl-learner.svn.sourceforge.net/viewvc/dl-learner/trunk/examples/swore/swore.rdf?revision=2217")); ks = new SparqlEndpointKS(SparqlEndpoint.getEndpointDBpediaLiveAKSW()); DisjointClassesLearner l = new DisjointClassesLearner(ks); - l.setClassToDescribe(new NamedClass("http://dbpedia.org/ontology/Book")); + l.setClassToDescribe(new NamedClass("http://dbpedia.org/ontology/Agent")); + l.setMaxExecutionTimeInSeconds(60); l.init(); l.getReasoner().prepareSubsumptionHierarchy(); l.getReasoner().precomputeClassPopularity(); Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/properties/FunctionalObjectPropertyAxiomLearner.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/properties/FunctionalObjectPropertyAxiomLearner.java 2013-01-22 09:43:25 UTC (rev 3883) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/properties/FunctionalObjectPropertyAxiomLearner.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -164,7 +164,7 @@ public static void main(String[] args) throws Exception{ FunctionalObjectPropertyAxiomLearner l = new FunctionalObjectPropertyAxiomLearner(new SparqlEndpointKS(SparqlEndpoint.getEndpointDBpedia())); - l.setPropertyToDescribe(new ObjectProperty("http://dbpedia.org/ontology/league")); + l.setPropertyToDescribe(new ObjectProperty("http://dbpedia.org/ontology/currency")); l.setMaxExecutionTimeInSeconds(20); l.setForceSPARQL_1_0_Mode(true); l.init(); Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/properties/ObjectPropertyDomainAxiomLearner.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/properties/ObjectPropertyDomainAxiomLearner.java 2013-01-22 09:43:25 UTC (rev 3883) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/properties/ObjectPropertyDomainAxiomLearner.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -206,14 +206,14 @@ ObjectPropertyDomainAxiomLearner l = new ObjectPropertyDomainAxiomLearner(ks); l.setReasoner(reasoner); - l.setPropertyToDescribe(new ObjectProperty("http://dbpedia.org/ontology/grammyAward")); + l.setPropertyToDescribe(new ObjectProperty("http://dbpedia.org/ontology/anthem")); l.setMaxExecutionTimeInSeconds(40); - l.addFilterNamespace("http://dbpedia.org/ontology/"); +// l.addFilterNamespace("http://dbpedia.org/ontology/"); // l.setReturnOnlyNewAxioms(true); l.init(); l.start(); - System.out.println(l.getCurrentlyBestEvaluatedAxioms(10, 0.3)); + System.out.println(l.getCurrentlyBestEvaluatedAxioms()); } } Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QTL.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -0,0 +1,387 @@ +/** + * Copyright (C) 2007-2011, Jens Lehmann + * + * This file is part of DL-Learner. + * + * DL-Learner is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DL-Learner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +package org.dllearner.algorithms.qtl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.apache.commons.collections15.ListUtils; +import org.apache.log4j.Logger; +import org.dllearner.algorithms.qtl.cache.QueryTreeCache; +import org.dllearner.algorithms.qtl.datastructures.QueryTree; +import org.dllearner.algorithms.qtl.datastructures.impl.QueryTreeImpl; +import org.dllearner.algorithms.qtl.exception.EmptyLGGException; +import org.dllearner.algorithms.qtl.exception.NegativeTreeCoverageExecption; +import org.dllearner.algorithms.qtl.exception.TimeOutException; +import org.dllearner.algorithms.qtl.filters.QueryTreeFilter; +import org.dllearner.algorithms.qtl.operations.NBR; +import org.dllearner.algorithms.qtl.operations.lgg.LGGGenerator; +import org.dllearner.algorithms.qtl.operations.lgg.LGGGeneratorImpl; +import org.dllearner.algorithms.qtl.util.SPARQLEndpointEx; +import org.dllearner.core.AbstractComponent; +import org.dllearner.core.AbstractLearningProblem; +import org.dllearner.core.ComponentAnn; +import org.dllearner.core.ComponentManager; +import org.dllearner.core.LearningProblem; +import org.dllearner.core.LearningProblemUnsupportedException; +import org.dllearner.core.SparqlQueryLearningAlgorithm; +import org.dllearner.core.options.CommonConfigOptions; +import org.dllearner.core.options.ConfigOption; +import org.dllearner.core.options.IntegerConfigOption; +import org.dllearner.core.owl.Individual; +import org.dllearner.kb.SparqlEndpointKS; +import org.dllearner.kb.sparql.CachingConciseBoundedDescriptionGenerator; +import org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator; +import org.dllearner.kb.sparql.ConciseBoundedDescriptionGeneratorImpl; +import org.dllearner.kb.sparql.ExtractionDBCache; +import org.dllearner.kb.sparql.SparqlEndpoint; +import org.dllearner.kb.sparql.SparqlQuery; +import org.dllearner.learningproblems.PosNegLP; +import org.dllearner.learningproblems.PosOnlyLP; +import org.dllearner.utilities.Helper; +import org.springframework.beans.factory.annotation.Autowired; + +import com.hp.hpl.jena.query.QuerySolution; +import com.hp.hpl.jena.query.ResultSetRewindable; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.Statement; +import com.hp.hpl.jena.util.iterator.Filter; + +/** + * + * Learning algorithm for SPARQL queries based on so called query trees. + * + * @author Lorenz Bühmann + * @author Jens Lehmann + * + * + */ +@ComponentAnn(name="query tree learner", shortName="qtl", version=0.8) +public class QTL extends AbstractComponent implements SparqlQueryLearningAlgorithm { + + private static final Logger logger = Logger.getLogger(QTL.class); + + private LearningProblem learningProblem; + private SparqlEndpointKS endpointKS; +// private QTLConfigurator configurator; + + private SparqlEndpoint endpoint; + private ExtractionDBCache cache; + + private QueryTreeCache treeCache; + + private LGGGenerator<String> lggGenerator; + private NBR<String> nbr; + + private List<String> posExamples; + private List<String> negExamples; + + private List<QueryTree<String>> posExampleTrees; + private List<QueryTree<String>> negExampleTrees; + + private QueryTreeFilter queryTreeFilter; + + private ConciseBoundedDescriptionGenerator cbdGenerator; + + private int maxExecutionTimeInSeconds = 60; + private int maxQueryTreeDepth = 2; + + private QueryTree<String> lgg; + private SortedSet<String> lggInstances; + + public static Collection<ConfigOption<?>> createConfigOptions() { + Collection<ConfigOption<?>> options = new LinkedList<ConfigOption<?>>(); + options.add(CommonConfigOptions.maxExecutionTimeInSeconds(10)); + options.add(new IntegerConfigOption("maxQueryTreeDepth", "recursion depth of query tree extraction", 2)); + return options; + } + + public QTL() { + + } + + public QTL(AbstractLearningProblem learningProblem, SparqlEndpointKS endpointKS) throws LearningProblemUnsupportedException{ + if(!(learningProblem instanceof PosOnlyLP || learningProblem instanceof PosNegLP)){ + throw new LearningProblemUnsupportedException(learningProblem.getClass(), getClass()); + } + this.learningProblem = learningProblem; + this.endpointKS = endpointKS; + +// this.configurator = new QTLConfigurator(this); + } + + public QTL(SPARQLEndpointEx endpoint, ExtractionDBCache cache) { + this.endpoint = endpoint; + this.cache = cache; + + treeCache = new QueryTreeCache(); + cbdGenerator = new CachingConciseBoundedDescriptionGenerator(new ConciseBoundedDescriptionGeneratorImpl(endpoint, cache)); + cbdGenerator.setRecursionDepth(maxQueryTreeDepth); + + lggGenerator = new LGGGeneratorImpl<String>(); + nbr = new NBR<String>(endpoint, cache); + nbr.setMaxExecutionTimeInSeconds(maxExecutionTimeInSeconds); + + posExampleTrees = new ArrayList<QueryTree<String>>(); + negExampleTrees = new ArrayList<QueryTree<String>>(); + } + + public String getQuestion(List<String> posExamples, List<String> negExamples) throws EmptyLGGException, NegativeTreeCoverageExecption, TimeOutException { + this.posExamples = posExamples; + this.negExamples = negExamples; + + generatePositiveExampleTrees(); + generateNegativeExampleTrees(); + + if(negExamples.isEmpty()){ + QueryTree<String> dummyNegTree = new QueryTreeImpl<String>("?"); + dummyNegTree.addChild(new QueryTreeImpl<String>("?"), "dummy"); + negExampleTrees.add(dummyNegTree); + } + + lgg = lggGenerator.getLGG(posExampleTrees); + + if(queryTreeFilter != null){ + lgg = queryTreeFilter.getFilteredQueryTree(lgg); + } + if(logger.isDebugEnabled()){ + logger.debug("LGG: \n" + lgg.getStringRepresentation()); + } + if(lgg.isEmpty()){ + throw new EmptyLGGException(); + } + + int index = coversNegativeQueryTree(lgg); + if(index != -1){ + throw new NegativeTreeCoverageExecption(negExamples.get(index)); + } + + lggInstances = getResources(lgg); + nbr.setLGGInstances(lggInstances); + + String question = nbr.getQuestion(lgg, negExampleTrees, getKnownResources()); + + return question; + } + + public void setExamples(List<String> posExamples, List<String> negExamples){ + this.posExamples = posExamples; + this.negExamples = negExamples; + } + + public void addStatementFilter(Filter<Statement> filter){ + treeCache.setStatementFilter(filter); + } + + public void addQueryTreeFilter(QueryTreeFilter queryTreeFilter){ + this.queryTreeFilter = queryTreeFilter; + } + + public void setMaxExecutionTimeInSeconds(int maxExecutionTimeInSeconds){ + this.maxExecutionTimeInSeconds = maxExecutionTimeInSeconds; + nbr.setMaxExecutionTimeInSeconds(maxExecutionTimeInSeconds); + } + + public void setMaxQueryTreeDepth(int maxQueryTreeDepth){ + this.maxQueryTreeDepth = maxQueryTreeDepth; + cbdGenerator.setRecursionDepth(maxQueryTreeDepth); + } + + public String getSPARQLQuery(){ + if(lgg == null){ + lgg = lggGenerator.getLGG(getQueryTrees(posExamples)); + } + return lgg.toSPARQLQueryString(); + } + + public void setRestrictToNamespaces(List<String> namespaces){ + cbdGenerator.setRestrictToNamespaces(namespaces); + } + + private void generatePositiveExampleTrees(){ + posExampleTrees.clear(); + posExampleTrees.addAll(getQueryTrees(posExamples)); + } + + private void generateNegativeExampleTrees(){ + negExampleTrees.clear(); + negExampleTrees.addAll(getQueryTrees(negExamples)); + } + + private List<QueryTree<String>> getQueryTrees(List<String> resources){ + List<QueryTree<String>> trees = new ArrayList<QueryTree<String>>(); + Model model; + QueryTree<String> tree; + for(String resource : resources){ + if(logger.isDebugEnabled()){ + logger.debug("Tree for resource " + resource); + } + model = cbdGenerator.getConciseBoundedDescription(resource); + tree = treeCache.getQueryTree(resource, model); + if(logger.isDebugEnabled()){ + logger.debug(tree.getStringRepresentation()); + } + trees.add(tree); + } + return trees; + } + + private List<String> getKnownResources(){ + return ListUtils.union(posExamples, negExamples); + } + +// private boolean coversNegativeQueryTree(QueryTree<String> tree){ +// for(QueryTree<String> negTree : negExampleTrees){ +// if(negTree.isSubsumedBy(tree)){ +// return true; +// } +// } +// return false; +// } + + private int coversNegativeQueryTree(QueryTree<String> tree){ + for(int i = 0; i < negExampleTrees.size(); i++){ + if(negExampleTrees.get(i).isSubsumedBy(tree)){ + return i; + } + } + return -1; + } + + private SortedSet<String> getResources(QueryTree<String> tree){ + SortedSet<String> resources = new TreeSet<String>(); + String query = getDistinctSPARQLQuery(tree); + String result = cache.executeSelectQuery(endpoint, query); + ResultSetRewindable rs = SparqlQuery.convertJSONtoResultSet(result); + String uri; + QuerySolution qs; + while(rs.hasNext()){ + qs = rs.next(); + uri = qs.getResource("x0").getURI(); + resources.add(uri); + } + return resources; + } + + private String getDistinctSPARQLQuery(QueryTree<String> tree){ + String query = tree.toSPARQLQueryString(); +// query = "SELECT DISTINCT " + query.substring(7); + return query; + } + + @Override + public void start(){ + generatePositiveExampleTrees(); + + lgg = lggGenerator.getLGG(posExampleTrees); + + if(queryTreeFilter != null){ + lgg = queryTreeFilter.getFilteredQueryTree(lgg); + } + if(logger.isDebugEnabled()){ + logger.debug("LGG: \n" + lgg.getStringRepresentation()); + } + + } + + @Override + public List<String> getCurrentlyBestSPARQLQueries(int nrOfSPARQLQueries) { + return Collections.singletonList(getBestSPARQLQuery()); + } + + @Override + public String getBestSPARQLQuery() { + return lgg.toSPARQLQueryString(); + } + + public void init() { + if(learningProblem instanceof PosOnlyLP){ + this.posExamples = convert(((PosOnlyLP)learningProblem).getPositiveExamples()); + } else if(learningProblem instanceof PosNegLP){ + this.posExamples = convert(((PosNegLP)learningProblem).getPositiveExamples()); + this.negExamples = convert(((PosNegLP)learningProblem).getNegativeExamples()); + } + endpoint = endpointKS.getEndpoint(); + + treeCache = new QueryTreeCache(); + cbdGenerator = new CachingConciseBoundedDescriptionGenerator(new ConciseBoundedDescriptionGeneratorImpl(endpoint, cache)); + cbdGenerator.setRecursionDepth(maxQueryTreeDepth); + + lggGenerator = new LGGGeneratorImpl<String>(); + nbr = new NBR<String>(endpoint); + nbr.setMaxExecutionTimeInSeconds(maxExecutionTimeInSeconds); + + posExampleTrees = new ArrayList<QueryTree<String>>(); + negExampleTrees = new ArrayList<QueryTree<String>>(); + } + + private List<String> convert(Set<Individual> individuals){ + List<String> list = new ArrayList<String>(); + for(Individual ind : individuals){ + list.add(ind.toString()); + } + return list; + } + + public static void main(String[] args) throws Exception { + Set<String> positiveExamples = new HashSet<String>(); + positiveExamples.add("http://dbpedia.org/resource/Liverpool_F.C."); + positiveExamples.add("http://dbpedia.org/resource/Chelsea_F.C."); + + ComponentManager cm = ComponentManager.getInstance(); + SparqlEndpointKS ks = new SparqlEndpointKS(SparqlEndpoint.getEndpointDBpediaLiveAKSW()); + ks.init(); + PosOnlyLP lp = new PosOnlyLP(); + cm.getPool().registerComponent(lp); + lp.setPositiveExamples(Helper.getIndividualSet(positiveExamples)); + QTL qtl = new QTL(lp, ks); + qtl.init(); + qtl.start(); + String query = qtl.getBestSPARQLQuery(); + System.out.println(query); + } + + public LearningProblem getLearningProblem() { + return learningProblem; + } + + @Autowired + public void setLearningProblem(LearningProblem learningProblem) { + this.learningProblem = learningProblem; + } + + public SparqlEndpointKS getEndpointKS() { + return endpointKS; + } + + @Autowired + public void setEndpointKS(SparqlEndpointKS endpointKS) { + this.endpointKS = endpointKS; + } + + +} Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QueryTreeFactory.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QueryTreeFactory.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/QueryTreeFactory.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2007-2010, Jens Lehmann + * + * This file is part of DL-Learner. + * + * DL-Learner is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DL-Learner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +package org.dllearner.algorithms.qtl; + +import org.dllearner.algorithms.qtl.datastructures.impl.QueryTreeImpl; +import org.dllearner.algorithms.qtl.filters.Filter; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.Selector; +import com.hp.hpl.jena.rdf.model.Statement; + +/** + * + * @author Lorenz Bühmann + * + */ +public interface QueryTreeFactory<N> { + + QueryTreeImpl<N> getQueryTree(String example, Model model); + + QueryTreeImpl<N> getQueryTree(String example, Model model, int maxEdges); + + QueryTreeImpl<N> getQueryTree(Resource example, Model model); + + QueryTreeImpl<N> getQueryTree(String example); + + void setPredicateFilter(Filter filter); + + void setObjectFilter(Filter filter); + + void setStatementSelector(Selector selector); + + void setStatementFilter(com.hp.hpl.jena.util.iterator.Filter<Statement> filter); + +} Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/cache/QueryTreeCache.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/cache/QueryTreeCache.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/cache/QueryTreeCache.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -0,0 +1,65 @@ +package org.dllearner.algorithms.qtl.cache; + +import java.util.HashMap; +import java.util.Map; + +import org.dllearner.algorithms.qtl.QueryTreeFactory; +import org.dllearner.algorithms.qtl.datastructures.QueryTree; +import org.dllearner.algorithms.qtl.filters.Filter; +import org.dllearner.algorithms.qtl.impl.QueryTreeFactoryImpl; + +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.Resource; +import com.hp.hpl.jena.rdf.model.Selector; +import com.hp.hpl.jena.rdf.model.Statement; + +public class QueryTreeCache { + + private Map<Model, QueryTree<String>> cache; + private QueryTreeFactory<String> factory; + + public QueryTreeCache(){ + cache = new HashMap<Model, QueryTree<String>>(); + factory = new QueryTreeFactoryImpl(); + } + + public QueryTree<String> getQueryTree(String root, Model model){ + QueryTree<String> tree = cache.get(model); + if(tree == null){ + tree = factory.getQueryTree(root, model); + } + return tree; + } + + public QueryTree<String> getQueryTree(Resource root, Model model){ + QueryTree<String> tree = cache.get(model); + if(tree == null){ + tree = factory.getQueryTree(root, model); + } + return tree; + } + + public void setPredicateFilter(Filter filter){ + factory.setPredicateFilter(filter); + } + + public void setObjectFilter(Filter filter){ + factory.setObjectFilter(filter); + } + + public void setStatementFilter(com.hp.hpl.jena.util.iterator.Filter<Statement> filter){ + factory.setStatementFilter(filter); + } + + public void setStatementSelector(Selector selector){ + factory.setStatementSelector(selector); + } + + public void clear(){ + cache.clear(); + } + + public void dispose(){ + cache = null; + } +} Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/NodeRenderer.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/NodeRenderer.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/NodeRenderer.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2007-2010, Jens Lehmann + * + * This file is part of DL-Learner. + * + * DL-Learner is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DL-Learner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +package org.dllearner.algorithms.qtl.datastructures; + + +/** + * + * @author Lorenz Bühmann + * + */ +public interface NodeRenderer<N> { + + String render(QueryTree<N> node); + +} Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/QueryTree.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/QueryTree.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/QueryTree.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -0,0 +1,144 @@ +/** + * Copyright (C) 2007-2010, Jens Lehmann + * + * This file is part of DL-Learner. + * + * DL-Learner is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DL-Learner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +package org.dllearner.algorithms.qtl.datastructures; + +import java.io.PrintWriter; +import java.util.Comparator; +import java.util.List; +import java.util.Set; + +import org.dllearner.algorithms.qtl.datastructures.impl.QueryTreeImpl; + +import com.hp.hpl.jena.datatypes.RDFDatatype; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.rdf.model.Literal; + +/** + * + * @author Lorenz Bühmann + * + */ +public interface QueryTree<N> { + + /** + * Gets the "content" of this tree node. + * @return The user content of this node. + */ + N getUserObject(); + + void setUserObject(N userObject); + + void setId(int id); + + int getId(); + + boolean isEmpty(); + + QueryTree<N> getNodeById(int nodeId); + + boolean isLiteralNode(); + + void setLiteralNode(boolean isLiteralNode); + + boolean isResourceNode(); + + void setResourceNode(boolean isResourceNode); + + boolean isVarNode(); + + void setVarNode(boolean isVarNode); + + QueryTree<N> getParent(); + + List<QueryTree<N>> getChildren(); + + List<QueryTree<N>> getChildren(Object edge); + + List<QueryTree<N>> getChildrenClosure(); + + Object getEdge(QueryTree<N> child); + + void addChild(QueryTreeImpl<N> child); + + void addChild(QueryTreeImpl<N> child, int position); + + void addChild(QueryTreeImpl<N> child, Object edge); + + void addChild(QueryTreeImpl<N> child, Object edge, int position); + + int removeChild(QueryTreeImpl<N> child); + + Set<Object> getEdges(); + + void sortChildren(Comparator<QueryTree<N>> comparator); + + int getChildCount(); + + int getMaxDepth(); + + boolean isRoot(); + + boolean isLeaf(); + + boolean isSubsumedBy(QueryTree<N> tree); + + boolean isSubsumedBy(QueryTree<N> tree, boolean stopAfterError); + + boolean isSameTreeAs(QueryTree<N> tree); + + void tag(); + + boolean isTagged(); + + QueryTree<N> getRoot(); + + List<QueryTree<N>> getLeafs(); + + List<QueryTree<N>> getPathToRoot(); + + List<N> getUserObjectPathToRoot(); + + void dump(); + + public String getStringRepresentation(); + + void dump(PrintWriter writer); + + void dump(PrintWriter writer, int indent); + + Set<N> getUserObjectClosure(); + + List<N> fillDepthFirst(); + + String toSPARQLQueryString(); + + String toSPARQLQueryString(boolean filtered); + + Query toSPARQLQuery(); + + int getTriplePatternCount(); + + Query toQuery(); + + RDFDatatype getDatatype(); + + List<Literal> getLiterals(); + +} Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/GeneralisedQueryTree.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/GeneralisedQueryTree.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/GeneralisedQueryTree.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -0,0 +1,51 @@ +package org.dllearner.algorithms.qtl.datastructures.impl; + +import java.util.ArrayList; +import java.util.List; + +import org.dllearner.algorithms.qtl.datastructures.QueryTree; +import org.dllearner.algorithms.qtl.datastructures.impl.QueryTreeChange.ChangeType; + +public class GeneralisedQueryTree<N> { + + private QueryTree<N> tree; + private List<QueryTreeChange> changes; + + public GeneralisedQueryTree(QueryTree<N> tree){ + this.tree = tree; + changes = new ArrayList<QueryTreeChange>(); + } + + public GeneralisedQueryTree(QueryTree<N> tree, List<QueryTreeChange> changes){ + this.tree = tree; + this.changes = changes; + } + + public void setQueryTree(QueryTree<N> tree){ + this.tree = tree; + } + + public QueryTree<N> getQueryTree(){ + return tree; + } + + public void addChange(QueryTreeChange change){ + changes.add(change); + } + + public void addChanges(List<QueryTreeChange> changes){ + this.changes.addAll(changes); + } + + public List<QueryTreeChange> getChanges(){ + return changes; + } + + public QueryTreeChange getLastChange(){ + if(changes.isEmpty()){ + return new QueryTreeChange(0, ChangeType.REPLACE_LABEL); + } + return changes.get(changes.size()-1); + } + +} Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeChange.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeChange.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeChange.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -0,0 +1,72 @@ +package org.dllearner.algorithms.qtl.datastructures.impl; + + + +public class QueryTreeChange { + + public enum ChangeType{ + REPLACE_LABEL, + REMOVE_NODE; + } + + private int nodeId; + + private ChangeType type; + + private String object; + private String edge; + + public QueryTreeChange(int nodeId, ChangeType type){ + this.nodeId = nodeId; + this.type = type; + } + + public int getNodeId() { + return nodeId; + } + + public ChangeType getType() { + return type; + } + + public String getObject() { + return object; + } + + public void setObject(String object) { + this.object = object; + } + + public String getEdge() { + return edge; + } + + public void setEdge(String edge) { + this.edge = edge; + } + + @Override + public String toString() { +// return "nodeId" + (type==ChangeType.REPLACE_LABEL ? "Replace" : "Remove"); + return nodeId + (type==ChangeType.REPLACE_LABEL ? "a" : "b"); + } + + @Override + public boolean equals(Object obj) { + if(obj == this){ + return true; + } + if(obj == null || !(obj instanceof QueryTreeChange)){ + return false; + } + QueryTreeChange other = (QueryTreeChange)obj; + return nodeId == other.getNodeId() && type == other.getType(); + } + + @Override + public int hashCode() { + return nodeId + type.hashCode() + 37; + } + + +} Added: trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeImpl.java =================================================================== --- trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeImpl.java (rev 0) +++ trunk/components-core/src/main/java/org/dllearner/algorithms/qtl/datastructures/impl/QueryTreeImpl.java 2013-01-22 09:47:20 UTC (rev 3884) @@ -0,0 +1,905 @@ +/** + * Copyright (C) 2007-2010, Jens Lehmann + * + * This file is part of DL-Learner. + * + * DL-Learner is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DL-Learner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +package org.dllearner.algorithms.qtl.datastructures.impl; + +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.regex.Pattern; + +import javax.xml.bind.DatatypeConverter; + +import org.dllearner.algorithms.qtl.datastructures.NodeRenderer; +import org.dllearner.algorithms.qtl.datastructures.QueryTree; +import org.dllearner.algorithms.qtl.filters.Filters; + +import com.hp.hpl.jena.datatypes.BaseDatatype; +import com.hp.hpl.jena.datatypes.RDFDatatype; +import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; +import com.hp.hpl.jena.graph.Node; +import com.hp.hpl.jena.graph.Triple; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.Syntax; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.sparql.syntax.ElementGroup; +import com.hp.hpl.jena.sparql.syntax.ElementTriplesBlock; + +/** + * + * @author Lorenz Bühmann + * + */ +public class QueryTreeImpl<N> implements QueryTree<N>{ + + private N userObject; + + private QueryTreeImpl<N> parent; + + private List<QueryTreeImpl<N>> children; + + private Map<QueryTree<N>, Object> child2EdgeMap; + private Map<String, List<QueryTree<N>>> edge2ChildrenMap; + + private NodeRenderer<N> toStringRenderer; + + private boolean tagged = false; + + private int cnt; + + private int id; + + private boolean isLiteralNode = false; + private boolean isResourceNode = false; + + private List<Literal> literals = new ArrayList<Literal>(); + + + public QueryTreeImpl(N userObject) { + this.userObject = userObject; + children = new ArrayList<QueryTreeImpl<N>>(); + child2EdgeMap = new HashMap<QueryTree<N>, Object>(); + edge2ChildrenMap = new HashMap<String, List<QueryTree<N>>>(); + toStringRenderer = new NodeRenderer<N>() { + public String render(QueryTree<N> object) { + String label = object.toString() + "(" + object.getId() + ")"; + if(object.isLiteralNode()){ + if(!object.getLiterals().isEmpty()){ + label += "Values: " + object.getLiterals(); + } + } + return label; + } + }; + } + + public QueryTreeImpl(QueryTree<N> tree){ + this(tree.getUserObject()); + setId(tree.getId()); + QueryTreeImpl<N> subTree; + for(QueryTree<N> child : tree.getChildren()){ + subTree = new QueryTreeImpl<N>(child); + subTree.setId(child.getId()); + subTree.setLiteralNode(child.isLiteralNode()); + subTree.setResourceNode(child.isResourceNode()); + addChild(subTree, tree.getEdge(child)); + } + } + + public N getUserObject() { + return userObject; + } + + public void setUserObject(N userObject) { + this.userObject = userObject; + } + + @Override + public void setId(int id) { + this.id = id; + } + + @Override + public int getId() { + return id; + } + + @Override + public boolean isEmpty(){ + return this.children.isEmpty(); + } + + public QueryTree<N> getNodeById(int nodeId){ + QueryTree<N> node = null; + if(this.id == nodeId){ + node = this; + } else { + for(QueryTree<N> child : children){ + node = child.getNodeById(nodeId); + if(node != null){ + return node; + } + } + } + return node; + } + + @Override + public boolean isLiteralNode() { + return isLiteralNode; + } + + @Override + public void setLiteralNode(boolean isLiteralNode) { + this.isLiteralNode = isLiteralNode; + } + + @Override + public boolean isResourceNode() { + return isResourceNode; + } + + @Override + public void setResourceNode(boolean isResourceNode) { + this.isResourceNode = isResourceNode; + } + + @Override + public boolean isVarNode() { + return !isLiteralNode && !isResourceNode; + } + + @Override + public void setVarNode(boolean isVarNode) { + isLiteralNode = false; + isResourceNode = false; + } + + + public void setParent(QueryTreeImpl<N> parent) { + if (this.parent != null) { + this.parent.children.remove(this); + } + this.parent = parent; + this.parent.children.add(this); + } + + + public void addChild(QueryTreeImpl<N> child) { + children.add(child); + child.parent = this; + } + + @Override + public void addChild(QueryTreeImpl<N> child, int position) { + children.add(position, child); + child.parent = this; + } + + public void addChild(QueryTreeImpl<N> child, Object edge) { + addChild(child); + child2EdgeMap.put(child, edge); + + List<QueryTree<N>> children = edge2ChildrenMap.get(edge); + if(children == null){ + children = new ArrayList<QueryTree<N>>(); + edge2ChildrenMap.put((String)edge, children); + } + children.add(child); + } + + @Override + public void addChild(QueryTreeImpl<N> child, Object edge, int position) { + addChild(child, position); + child2EdgeMap.put(child, edge); + + List<QueryTree<N>> children = edge2ChildrenMap.get(edge); + if(children == null){ + children = new ArrayList<QueryTree<N>>(); + edge2ChildrenMap.put((String)edge, children); + } + children.add(child); + + } + + + public int removeChild(QueryTreeImpl<N> child) { + int pos = children.indexOf(child); + children.remove(child); + edge2ChildrenMap.get(child2EdgeMap.get(child)).remove(child); + child.parent = null; + return pos; + } + + public void removeChildren(Set<QueryTreeImpl<N>> children) { + for(QueryTreeImpl<N> child : children){ + this.children.remove(child); + child.parent = null; + } + } + + + public Object getEdge(QueryTree<N> child) { + return child2EdgeMap.get(child); + } + + public Set<Object> getEdges(){ + return new TreeSet<Object>(child2EdgeMap.values()); + } + + + public void sortChildren(Comparator<QueryTree<N>> comparator) { + Collections.sort(children, comparator); + } + + + public void clearChildren() { + for (QueryTreeImpl<N> child : new ArrayList<QueryTreeImpl<N>>(children)) { + removeChild(child); + } + } + + + public QueryTree<N> getParent() { + return parent; + } + + + public List<QueryTree<N>> getChildren() { + return new ArrayList<QueryTree<N>>(children); + } + + public List<QueryTree<N>> getChildren(Object edge) { +// List<QueryTree<N>> children = new ArrayList<QueryTree<N>>(); +// for(Entry<QueryTree<N>, Object> entry : child2EdgeMap.entrySet()){ +// if(entry.getValue().equals(edge)){ +// children.add(entry.getKey()); +// } +// } +// return children; + List<QueryTree<N>> children = edge2ChildrenMap.get(edge); + if(children == null){ + children = new ArrayList<QueryTree<N>>(); + } + return new ArrayList<QueryTree<N>>(children); + } + + public int getChildCount() { + return children.size(); + } + + + public boolean isRoot() { + return parent == null; + } + + + public boolean isLeaf() { + return children.isEmpty(); + } + + @Override + public boolean isSubsumedBy(QueryTree<N> tree) { + if(!(tree.getUserObject().equals("?") || tree.getUserObject().equals(this.userObject))){ + return false; + } + + Object edge; + for(QueryTree<N> child : tree.getChildren()){ + boolean isSubsumed = false; + edge = tree.getEdge(child); + for(QueryTree<N> child2 : this.getChildren(edge)){ + if(child2.isSubsumedBy(child)){ + isSubsumed = true; + break; + } + } + if(!isSubsumed){ + return false; + } + } + return true; + } + + @Override + public boolean isSubsumedBy(QueryTree<N> tree, boolean stopAfterError) { + if(!(tree.getUserObject().equals("?") || tree.getUserObject().equals(this.userObject))){ + return false; + } + + Object edge; + for(QueryTree<N> child : tree.getChildren()){ + boolean isSubsumed = false; + edge = tree.getEdge(child); + for(QueryTree<N> child2 : this.getChildren(edge)){ + if(child2.isSubsumedBy(child, true)){ + isSubsumed = true; + break; + } + } + if(!isSubsumed){ + child.tag(); + return false; + } + } + return true; + } + + public void tag(){ + tagged = true; + } + + public boolean isTagged(){ + return tagged; + } + + + public QueryTree<N> getRoot() { + if (parent == null) { + return this; + } + return parent.getRoot(); + } + + public List<QueryTree<N>> getLeafs(){ + List<QueryTree<N>> leafs = new LinkedList<QueryTree<N>>(); + if(isLeaf()){ + leafs.add(this); + } else { + for(QueryTree<N> child : children){ + leafs.addAll(child.getLeafs()); + } + } + return leafs; + } + + + public List<QueryTree<N>> getPathToRoot() { + List<QueryTree<N>> path = new ArrayList<QueryTree<N>>(); + path.add(0, this); + QueryTree<N> par = parent; + while (par != null) { + path.add(0, par); + par = par.getParent(); + } + return path; + } + + + + + public List<N> getUserObjectPathToRoot() { + List<N> path = new ArrayList<N>(); + path.add(0, this.getUserObject()); + QueryTree<N> par = parent; + while (par != null) { + path.add(0, par.getUserObject()); + par = par.getParent(); + } + return path; + } + + public List<QueryTree<N>> getChildrenClosure() { + List<QueryTree<N>> children = new ArrayList<QueryTree<N>>(); + getChildrenClosure(this, children); + return children; + } + + private void getChildrenClosure(QueryTree<N> tree, List<QueryTree<N>> bin) { + bin.add(tree); + for (QueryTree<N> child : tree.getChildren()) { + getChildrenClosure(child, bin); + } + } + + + public Set<N> getUserObjectClosure() { + Set<N> objects = new HashSet<N>(); + getUserObjectClosure(this, objects); + return objects; + } + + public int getTriplePatternCount(){ + return countTriplePattern(this); + } + + private int countTriplePattern(QueryTree<N> tree){ + int cnt = 0; + Object object; + if(!tree.isLeaf()){ + for(QueryTree<N> child : tree.getChildren()){ + object = child.getUserObject(); + boolean objectIsResource = !object.equals("?"); + cnt++; + if(!objectIsResource){ + cnt+=countTriplePattern(child); + } + } + } + return cnt; + } + + public QueryTree<N> getSPARQLQueryTree(){ + return createSPARQLQueryTree(this); + } + + private QueryTree<N> createSPARQLQueryTree(QueryTree<N> tree){ + QueryTree<N> copy = new QueryTreeImpl<N>(tree.getUserObject()); + if(tree.getUserObject().equals("?")){ + for(QueryTree<N> child : tree.getChildren()){ + copy.addChild((QueryTreeImpl<N>) createSPARQLQueryTree(child), tree.getEdge(child)); + } + } +// for(QueryTree<N> child : tree.getChildren()){ +// if(child.getUserObject().equals("?")){ +// copy.addChild((QueryTreeImpl<N>) createSPARQLQueryTree(child), tree.getEdge(child)); +// } else { +// copy.addChild((QueryTreeImpl<N>) child, tree.getEdge(child)); +// } +// +// } + + return copy; + } + + private void getUserObjectClosure(QueryTree<N> tree, Set<N> bin) { + bin.add(tree.getUserObject()); + for (QueryTree<N> child : tree.getChildren()) { + getUserObjectClosure(child, bin); + } + } + + public String getStringRepresentation(){ + int depth = getPathToRoot().size(); + StringBuilder sb = new StringBuilder(); + if(isRoot()){ + sb.append("TREE\n\n"); + } + String ren = toStringRenderer.render(this); + ren = ren.replace("\n", "\n" + sb); + sb.append(ren); + sb.append("\n"); + for (QueryTree<N> child : getChildren()) { + for (int i = 0; i < depth; i++) { + sb.append("\t"); + } + Object edge = getEdge(child); + if (edge != null) { + sb.append(" "); + sb.append(edge); + sb.append(" ---> "); + } + sb.append(((QueryTreeImpl<N>)child).getStringRepresentation()); + } + return sb.toString(); + } + + public String getStringRepresentation(int indent){ + int depth = getPathToRoot().size(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < depth + indent; i++) { + sb.append("\t"); + } + String ren = toStringRenderer.render(this); + ren = ren.replace("\n", "\n" + sb); + sb.append(ren); + sb.append("\n"); + for (QueryTree<N> child : getChildren()) { + Object edge = getEdge(child); + if (edge != null) { + sb.append("--- "); + sb.append(edge); + sb.append(" ---\n"); + } + sb.append(((QueryTreeImpl<N>)child).getStringRepresentation(indent)); + } + return sb.toString(); + } + + public void dump() { + dump(new PrintWriter(System.out), 0); + } + + public void dump(PrintWriter writer) { + dump(writer, 0); + } + + public void dump(PrintWriter writer, int indent) { + int depth = getPathToRoot().size(); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < depth + indent; i++) { + sb.append("\t"); + } + writer.print(sb.toString()); + String ren = toStringRenderer.render(this); + ren = ren.replace("\n", "\n" + sb); + writer.println(ren); + for (QueryTree<N> child : getChildren()) { + Object edge = getEdge(child); + if (edge != null) { + writer.print(sb.toString()); + writer.print("--- "); + writer.print(edge); + writer.print(" ---\n"); + } + child.dump(writer, indent); + } + writer.flush(); +// int depth = getPathToRoot().size(); +// StringBuilder sb = new StringBuilder(); +// for (int i = 0; i < depth + indent; i++) { +// sb.append("\t"); +// } +// writer.print(sb.toString()); +// String ren = toStringRenderer.render(this); +// ren = ren.replace("\n", "\n" + sb); +// writer.println(ren); +// for (QueryTree<N> child : getChildren()) { +// Object edge = getEdge(child); +// if (edge != null) { +// writer.print(sb.toString()); +// writer.print("--- "); +// writer.print(edge); +// writer.print(" ---\n"); +// } +// child.dump(writer, indent); +// } +// writer.flush(); + } + + + public List<N> fillDepthFirst() { + List<N> results = new ArrayList<N>(); + fillDepthFirst(this, results); + return results; + } + + private void fillDepthFirst(QueryTree<N> tree, List<N> bin) { + bin.add(tree.getUserObject()); + for (QueryTree<N> child : tree.getChildren()) { + fillDepthFirst(child, bin); + } + } + + public void replace(QueryTreeImpl<N> tree) { + parent.children.remove(this); + parent.children.add(tree); + parent = null; + tree.children.clear(); + tree.children.addAll(children); + children.clear(); + } + + public String toString() { + if (userObject != null) { + return userObject.toString(); + } else { + return ""; + } + } + + + public int getSize() { + return getUserObjectClosure().size(); + } + + + + public int getMaxDepth() { + return getMaxDepth(this); + } + + private int getMaxDepth(QueryTree<N> tree) { + int maxChildDepth = tree.getPathToRoot().size(); + for (QueryTree<N> child : tree.getChildren()) { + int childDepth = getMaxDepth(child); + if(childDepth > maxChildDepth) { + maxChildDepth = childDepth; + } + } + return maxChildDepth; + } + + @Override + public Object clone() throws CloneNotSupportedException { + QueryTreeImpl<N> copy = new QueryTreeImpl<N>(this.userObject); + for(QueryTreeImpl<N> child : children){ + copy.addChild((QueryTreeImpl<N>)child.clone(), getEdge(child)); + } + + return copy; + } + +// @Override +// public boolean equals(Object obj) { +// if(obj == this){ +// return true; +// } +// if(!(obj instanceof QueryTreeImpl<?>)){ +// return false; +// } +// QueryTreeImpl<N> other = (QueryTreeImpl<N>)obj; +// if(!this.userObject.equals(other.getUserObject())){ +// return false; +// } +// Object edge; +// for(QueryTreeImpl<N> child : this.children){ +// boolean existsEqualChild = false; +// edge = child2EdgeMap.get(child); +// for(QueryTree<N> child2 : other.getChildren(edge)){ +// if(child.equals(child2)){ +// existsEqualChild = true; +// break; +// } +// } +// if(!existsEqualChild){ +// return false; +// } +// } +// return true; +// } + + public boolean isSameTreeAs(QueryTree<N> tree){ + if(!this.userObject.equals(tree.getUserObject())){ + return false; + } + Object edge; + for(QueryTreeImpl<N> child : this.children){ + boolean existsEqualChild = false; + edge = child2EdgeMap.get(child); + for(QueryTree<N> child2 : tree.getChildren(edge)){ + if(child.isSameTreeAs(child2)){ + existsEqualChild = true; + break; + } + } + if(!existsEqualChild){ + return false; + } + } + return true; + } + + @Override + public Query toSPARQLQuery() { + return QueryFactory.create(toSPARQLQueryString(), Syntax.syntaxARQ); + } + + @Override + public String toSPARQLQueryString() { + if(children.isEmpty()){ + return "SELECT ?x0 WHERE {?x0 ?y ?z.}"; + } + cnt = 0; + StringBuilder sb = new StringBuilder(); + sb.append("SELECT DISTINCT ?x0 WHERE {\n"); + List<String> filters = new ArrayList<String>(); + buildSPARQLQueryString(this, sb, false, filters); + for(String filter : filters){ + sb.append(filter).append("\n"); + } + sb.append("}"); + return sb.toString(); + } + + @Override + public String toSPARQLQueryString(boolean filtered) { + if(children.isEmpty()){ + return "SELECT ?x0 WHERE {?x0 ?y ?z.}"; + } + cnt = 0; + StringBuilder sb = new StringBuilder(); + List<String> filters = new ArrayList<String>(); + sb.append("SELECT DISTINCT ?x0 WHERE {\n"); + buildSPARQLQueryString(this, sb, filtered, filters); + for(String filter : filters){ + sb.append(filter).append("\n"); + } + sb.append("}"); + return sb.toString(); + } + + private void buildSPARQLQueryString(QueryTree<N> tree, StringBuilder sb, boolean filtered, List<String> filters){ + Object subject = null; + if(tree.getUserObject().equals("?")){ + subject = "?x" + cnt++; + if(tree.isLiteralNode() && !tree.getLiterals().isEmpty()){ + filters.add(getFilter(subject.toString(), tree.getLiterals())); + } + } else { + subject = "<" + tree.getUserObject() + ">"; + } + Object predicate; + Object object; + if(!tree.isLeaf()){ + for(QueryTree<N> child : tree.getChildren()){ + predicate = tree.getEdge(child); + if(filtered){ + if(Filters.getAllFilterProperties().contains(predicate.toString())){ + continue; + } + } + object = child.getUserObject(); + boolean objectIsResource = !object.equals("?"); + if(!objectIsResource){ + object = "?x" + cnt; + } else if(((String)object).startsWith("http://")){ + object = "<" + object + ">"; + ... [truncated message content] |