|
From: <lor...@us...> - 2014-01-29 14:24:21
|
Revision: 4214
http://sourceforge.net/p/dl-learner/code/4214
Author: lorenz_b
Date: 2014-01-29 14:24:16 +0000 (Wed, 29 Jan 2014)
Log Message:
-----------
Added copy of EL algorithm able to handle data properties.
Modified Paths:
--------------
trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java
trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/PCELOE.java
trunk/components-core/src/main/java/org/dllearner/algorithms/el/ELLearningAlgorithm.java
trunk/components-core/src/main/java/org/dllearner/algorithms/el/ELLearningAlgorithmDisjunctive.java
trunk/components-core/src/main/java/org/dllearner/algorithms/fuzzydll/FuzzyCELOE.java
trunk/components-core/src/main/java/org/dllearner/algorithms/isle/metrics/PMIRelevanceMetric.java
trunk/components-core/src/main/java/org/dllearner/core/AbstractCELA.java
trunk/components-core/src/main/java/org/dllearner/core/AbstractReasonerComponent.java
trunk/components-core/src/main/java/org/dllearner/core/ComponentManager.java
trunk/components-core/src/main/java/org/dllearner/core/owl/BooleanDataRange.java
trunk/components-core/src/main/java/org/dllearner/core/owl/DataRange.java
trunk/components-core/src/main/java/org/dllearner/core/owl/Datatype.java
trunk/components-core/src/main/java/org/dllearner/core/owl/DatatypePropertyHierarchy.java
trunk/components-core/src/main/java/org/dllearner/core/owl/DatatypeQuantorRestriction.java
trunk/components-core/src/main/java/org/dllearner/core/owl/DatatypeSomeRestriction.java
trunk/components-core/src/main/java/org/dllearner/core/owl/Description.java
trunk/components-core/src/main/java/org/dllearner/core/owl/DoubleMaxValue.java
trunk/components-core/src/main/java/org/dllearner/core/owl/DoubleMinValue.java
trunk/components-core/src/main/java/org/dllearner/kb/sparql/CachingConciseBoundedDescriptionGenerator.java
trunk/components-core/src/main/java/org/dllearner/kb/sparql/ConciseBoundedDescriptionGenerator.java
trunk/components-core/src/main/java/org/dllearner/kb/sparql/ConciseBoundedDescriptionGeneratorImpl.java
trunk/components-core/src/main/java/org/dllearner/kb/sparql/SymmetricConciseBoundedDescriptionGeneratorImpl.java
trunk/components-core/src/main/java/org/dllearner/reasoning/FastInstanceChecker.java
trunk/components-core/src/main/java/org/dllearner/reasoning/OWLAPIReasoner.java
trunk/components-core/src/main/java/org/dllearner/reasoning/SPARQLReasoner.java
trunk/components-core/src/main/java/org/dllearner/refinementoperators/RhoDRDown.java
trunk/components-core/src/main/java/org/dllearner/refinementoperators/Utility.java
trunk/components-core/src/main/java/org/dllearner/utilities/examples/AutomaticNegativeExampleFinderSPARQL2.java
trunk/components-core/src/main/java/org/dllearner/utilities/owl/ConceptComparator.java
trunk/components-core/src/main/java/org/dllearner/utilities/owl/DescriptionMinimizer.java
trunk/components-core/src/test/java/org/dllearner/algorithms/isle/DBpediaExperiment.java
trunk/components-core/src/test/java/org/dllearner/algorithms/isle/ISLETestCorpus.java
trunk/components-core/src/test/java/org/dllearner/algorithms/isle/ISLETestNoCorpus.java
trunk/components-core/src/test/java/org/dllearner/algorithms/isle/KnowledgebaseSampleGenerator.java
trunk/components-core/src/test/java/org/dllearner/algorithms/isle/SemanticBibleExperiment.java
Added Paths:
-----------
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/DisjunctiveHeuristic.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionEdge.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionEdgeComparator.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionNode.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionNodeComparator.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionTree.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionTreeComparator.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELHeuristic.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELLearningAlgorithm.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELLearningAlgorithmDisjunctive.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/SearchTreeNode.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/Simulation.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/StableHeuristic.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/TreeAndRoleSet.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/TreeAndRoleSetComparator.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/TreeTuple.java
trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/package.html
trunk/components-core/src/main/java/org/dllearner/refinementoperators/ELDown3.java
Removed Paths:
-------------
trunk/components-core/src/main/java/org/dllearner/algorithms/isle/ISLE.java
trunk/components-core/src/test/java/org/dllearner/algorithms/isle/DBpediaPlainExperiment.java
trunk/components-core/src/test/java/org/dllearner/algorithms/isle/DBpediaSemanticIndexExperiment.java
trunk/components-core/src/test/java/org/dllearner/algorithms/isle/DBpediaSyntacticIndexBasedExperiment.java
trunk/components-core/src/test/java/org/dllearner/algorithms/isle/Experiment.java
Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java 2014-01-21 12:49:51 UTC (rev 4213)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/CELOE.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -20,12 +20,10 @@
package org.dllearner.algorithms.celoe;
import java.io.File;
-import java.text.DecimalFormat;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -50,7 +48,6 @@
import org.dllearner.kb.OWLFile;
import org.dllearner.learningproblems.ClassLearningProblem;
import org.dllearner.learningproblems.PosNegLP;
-import org.dllearner.learningproblems.PosNegLPStandard;
import org.dllearner.learningproblems.PosOnlyLP;
import org.dllearner.reasoning.FastInstanceChecker;
import org.dllearner.refinementoperators.CustomHierarchyRefinementOperator;
@@ -108,7 +105,6 @@
// all descriptions in the search tree plus those which were too weak (for fast redundancy check)
private TreeSet<Description> descriptions;
- private EvaluatedDescriptionSet bestEvaluatedDescriptions;
// if true, then each solution is evaluated exactly instead of approximately
// private boolean exactBestDescriptionEvaluation = false;
@@ -140,10 +136,6 @@
private boolean forceMutualDifference = false;
// utility variables
- private String baseURI;
- private Map<String, String> prefixes;
- private DecimalFormat dfPercent = new DecimalFormat("0.00%");
- private ConceptComparator descriptionComparator = new ConceptComparator();
// statistical variables
private int expressionTests = 0;
@@ -305,8 +297,7 @@
}
// operator = new RhoDRDown(reasoner, classHierarchy, startClass, configurator);
- baseURI = reasoner.getBaseURI();
- prefixes = reasoner.getPrefixes();
+
if(writeSearchTree) {
File f = new File(searchTreeFile );
Files.clearFile(f);
@@ -797,7 +788,7 @@
// check whether the node is a potential solution candidate
private Description rewriteNode(OENode node) {
Description description = node.getDescription();
- // minimize description (expensive!) - also performes some human friendly rewrites
+ // minimize description (expensive!) - also performs some human friendly rewrites
Description niceDescription;
if(useMinimizer) {
niceDescription = minimizer.minimizeClone(description);
@@ -809,6 +800,21 @@
return niceDescription;
}
+ // check whether the node is a potential solution candidate
+ private Description rewriteNodeSimple(OENode node) {
+ Description description = node.getDescription();
+ // minimize description (expensive!) - also performs some human friendly rewrites
+ Description niceDescription;
+ if(useMinimizer) {
+ niceDescription = minimizer.minimizeClone(description);
+ } else {
+ niceDescription = description;
+ }
+ // replace \exists r.\top with \exists r.range(r) which is easier to read for humans
+ ConceptTransformation.replaceRange(niceDescription, reasoner);
+ return niceDescription;
+ }
+
private boolean terminationCriteriaSatisfied() {
return
stop ||
@@ -843,33 +849,12 @@
return startNode;
}
- // central function for printing description
- private String descriptionToString(Description description) {
- return description.toManchesterSyntaxString(baseURI, prefixes);
- }
-
@SuppressWarnings("unused")
private String bestDescriptionToString() {
EvaluatedDescription best = bestEvaluatedDescriptions.getBest();
return best.getDescription().toManchesterSyntaxString(baseURI, prefixes) + " (accuracy: " + dfPercent.format(best.getAccuracy()) + ")";
}
- private String getSolutionString() {
- int current = 1;
- String str = "";
- for(EvaluatedDescription ed : bestEvaluatedDescriptions.getSet().descendingSet()) {
- // temporary code
- if(learningProblem instanceof PosNegLPStandard) {
- str += current + ": " + descriptionToString(ed.getDescription()) + " (pred. acc.: " + dfPercent.format(((PosNegLPStandard)learningProblem).getPredAccuracyOrTooWeakExact(ed.getDescription(),1)) + ", F-measure: "+ dfPercent.format(((PosNegLPStandard)learningProblem).getFMeasureOrTooWeakExact(ed.getDescription(),1)) + ")\n";
- } else {
- str += current + ": " + descriptionToString(ed.getDescription()) + " " + dfPercent.format(ed.getAccuracy()) + "\n";
-// System.out.println(ed);
- }
- current++;
- }
- return str;
- }
-
// private String getTemporaryString(Description description) {
// return descriptionToString(description) + " (pred. acc.: " + dfPercent.format(((PosNegLPStandard)learningProblem).getPredAccuracyOrTooWeakExact(description,1)) + ", F-measure: "+ dfPercent.format(((PosNegLPStandard)learningProblem).getFMeasureOrTooWeakExact(description,1)) + ")";
// }
Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/PCELOE.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/PCELOE.java 2014-01-21 12:49:51 UTC (rev 4213)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/celoe/PCELOE.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -20,15 +20,12 @@
package org.dllearner.algorithms.celoe;
import java.io.File;
-import java.text.DecimalFormat;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
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.SortedSet;
import java.util.TreeSet;
@@ -41,7 +38,6 @@
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
-import org.dllearner.algorithms.celoe.PCELOE.Worker;
import org.dllearner.core.AbstractCELA;
import org.dllearner.core.AbstractKnowledgeSource;
import org.dllearner.core.AbstractLearningProblem;
@@ -60,7 +56,6 @@
import org.dllearner.kb.OWLFile;
import org.dllearner.learningproblems.ClassLearningProblem;
import org.dllearner.learningproblems.PosNegLP;
-import org.dllearner.learningproblems.PosNegLPStandard;
import org.dllearner.learningproblems.PosOnlyLP;
import org.dllearner.reasoning.FastInstanceChecker;
import org.dllearner.refinementoperators.CustomHierarchyRefinementOperator;
@@ -153,11 +148,6 @@
// but it can also suppress quite useful expressions
private boolean forceMutualDifference = false;
- // utility variables
- private String baseURI;
- private Map<String, String> prefixes;
- private DecimalFormat dfPercent = new DecimalFormat("0.00%");
- private ConceptComparator descriptionComparator = new ConceptComparator();
// statistical variables
private int expressionTests = 0;
@@ -804,33 +794,12 @@
return startNode;
}
- // central function for printing description
- private String descriptionToString(Description description) {
- return description.toManchesterSyntaxString(baseURI, prefixes);
- }
-
@SuppressWarnings("unused")
private String bestDescriptionToString() {
EvaluatedDescription best = bestEvaluatedDescriptions.getBest();
return best.getDescription().toManchesterSyntaxString(baseURI, prefixes) + " (accuracy: " + dfPercent.format(best.getAccuracy()) + ")";
}
- private String getSolutionString() {
- int current = 1;
- String str = "";
- for(EvaluatedDescription ed : bestEvaluatedDescriptions.getSet().descendingSet()) {
- // temporary code
- if(learningProblem instanceof PosNegLPStandard) {
- str += current + ": " + descriptionToString(ed.getDescription()) + " (pred. acc.: " + dfPercent.format(((PosNegLPStandard)learningProblem).getPredAccuracyOrTooWeakExact(ed.getDescription(),1)) + ", F-measure: "+ dfPercent.format(((PosNegLPStandard)learningProblem).getFMeasureOrTooWeakExact(ed.getDescription(),1)) + ")\n";
- } else {
- str += current + ": " + descriptionToString(ed.getDescription()) + " " + dfPercent.format(ed.getAccuracy()) + "\n";
-// System.out.println(ed);
- }
- current++;
- }
- return str;
- }
-
// private String getTemporaryString(Description description) {
// return descriptionToString(description) + " (pred. acc.: " + dfPercent.format(((PosNegLPStandard)learningProblem).getPredAccuracyOrTooWeakExact(description,1)) + ", F-measure: "+ dfPercent.format(((PosNegLPStandard)learningProblem).getFMeasureOrTooWeakExact(description,1)) + ")";
// }
Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/el/ELLearningAlgorithm.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/el/ELLearningAlgorithm.java 2014-01-21 12:49:51 UTC (rev 4213)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/el/ELLearningAlgorithm.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -34,6 +34,9 @@
import org.dllearner.core.config.BooleanEditor;
import org.dllearner.core.config.ConfigOption;
import org.dllearner.core.owl.Description;
+import org.dllearner.core.owl.Nothing;
+import org.dllearner.core.owl.ObjectProperty;
+import org.dllearner.core.owl.ObjectSomeRestriction;
import org.dllearner.core.owl.Thing;
import org.dllearner.learningproblems.EvaluatedDescriptionPosNeg;
import org.dllearner.learningproblems.PosNegLP;
@@ -62,16 +65,22 @@
private boolean isRunning = false;
private boolean stop = false;
- private double treeSearchTimeSeconds = 1.0;
+ private double treeSearchTimeSeconds = 10.0;
private long treeStartTime;
// "instanceBasedDisjoints", "Specifies whether to use real disjointness checks or instance based ones (no common instances) in the refinement operator."
@ConfigOption(name="instanceBasedDisjoints", required=false, defaultValue="true", description="Specifies whether to use real disjointness checks or instance based ones (no common instances) in the refinement operator.", propertyEditorClass=BooleanEditor.class)
private boolean instanceBasedDisjoints = true;
+ @ConfigOption(name = "stopOnFirstDefinition", defaultValue="false", description="algorithm will terminate immediately when a correct definition is found")
+ private boolean stopOnFirstDefinition = false;
+
+ @ConfigOption(name = "noisePercentage", defaultValue="0.0", description="the (approximated) percentage of noise within the examples")
+ private double noisePercentage = 0.0;
+
+ private double noise;
+
// a set with limited size (currently the ordering is defined in the class itself)
- private EvaluatedDescriptionSet bestEvaluatedDescriptions = new EvaluatedDescriptionSet(AbstractCELA.MAX_NR_OF_RESULTS);
-
private SearchTreeNode startNode;
private ELHeuristic heuristic;
private TreeSet<SearchTreeNode> candidates;
@@ -80,7 +89,7 @@
}
- public ELLearningAlgorithm(PosNegLP problem, AbstractReasonerComponent reasoner) {
+ public ELLearningAlgorithm(AbstractLearningProblem problem, AbstractReasonerComponent reasoner) {
super(problem, reasoner);
// configurator = new ELLearningAlgorithmConfigurator(this);
}
@@ -116,6 +125,8 @@
candidates = new TreeSet<SearchTreeNode>(heuristic);
operator = new ELDown2(reasoner, instanceBasedDisjoints);
+
+ noise = noisePercentage/100d;
}
@Override
@@ -151,29 +162,29 @@
}
// print solution(s)
- logger.info("solution : " + bestEvaluatedDescriptions.getBest() + " [time: " + Helper.prettyPrintNanoSeconds(System.nanoTime()-treeStartTime) + "]");
+ logger.info("solutions[time: " + Helper.prettyPrintNanoSeconds(System.nanoTime()-treeStartTime) + "]\n" + getSolutionString());
isRunning = false;
}
// evaluates a description in tree form
private void addDescriptionTree(ELDescriptionTree descriptionTree, SearchTreeNode parentNode) {
-
// create search tree node
SearchTreeNode node = new SearchTreeNode(descriptionTree);
// convert tree to standard description
Description description = descriptionTree.transformToDescription();
+ description = getNiceDescription(description);
-// double accuracy = getLearningProblem().getAccuracyOrTooWeak(description, 0);
+ double accuracy = getLearningProblem().getAccuracyOrTooWeak(description, noise);
int negCovers = ((PosNegLP)getLearningProblem()).coveredNegativeExamplesOrTooWeak(description);
- if(negCovers == -1) {
-// if(accuracy == -1) {
+// if(negCovers == -1) {
+ if(accuracy == -1) {
node.setTooWeak();
} else {
node.setCoveredNegatives(negCovers);
}
-
+// System.out.println(descriptionTree.transformToDescription() + "|" + negCovers);
// link to parent (unless start node)
if(parentNode == null) {
startNode = node;
@@ -205,6 +216,26 @@
}
+ private Description getNiceDescription(Description d){
+ Description description = d.clone();
+ List<Description> children = description.getChildren();
+ for(int i=0; i<children.size(); i++) {
+ description.replaceChild(i, getNiceDescription(children.get(i)));
+ }
+ if(children.size()==0) {
+ return description;
+ } else if(description instanceof ObjectSomeRestriction) {
+ // \exists r.\bot \equiv \bot
+ if(description.getChild(0) instanceof Thing) {
+ Description range = reasoner.getRange((ObjectProperty) ((ObjectSomeRestriction) description).getRole());
+ description.replaceChild(0, range);
+ } else {
+ description.replaceChild(0, getNiceDescription(description.getChild(0)));
+ }
+ }
+ return description;
+ }
+
private boolean stoppingCriteriaSatisfied() {
// in some cases, there could be no candidate left ...
if(candidates.isEmpty()) {
@@ -222,7 +253,7 @@
// stop if we have a node covering all positives and none of the negatives
SearchTreeNode bestNode = candidates.last();
- return (bestNode.getCoveredNegatives() == 0);
+ return stopOnFirstDefinition && (bestNode.getCoveredNegatives() == 0);
}
private void reset() {
@@ -270,11 +301,40 @@
return bestEvaluatedDescriptions.getSet();
}
+
/**
+ * @param stopOnFirstDefinition the stopOnFirstDefinition to set
+ */
+ public void setStopOnFirstDefinition(boolean stopOnFirstDefinition) {
+ this.stopOnFirstDefinition = stopOnFirstDefinition;
+ }
+
+ /**
+ * @return the stopOnFirstDefinition
+ */
+ public boolean isStopOnFirstDefinition() {
+ return stopOnFirstDefinition;
+ }
+
+ /**
* @return the startNode
*/
public SearchTreeNode getStartNode() {
return startNode;
}
+
+ /**
+ * @return the noisePercentage
+ */
+ public double getNoisePercentage() {
+ return noisePercentage;
+ }
+
+ /**
+ * @param noisePercentage the noisePercentage to set
+ */
+ public void setNoisePercentage(double noisePercentage) {
+ this.noisePercentage = noisePercentage;
+ }
}
Modified: trunk/components-core/src/main/java/org/dllearner/algorithms/el/ELLearningAlgorithmDisjunctive.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/el/ELLearningAlgorithmDisjunctive.java 2014-01-21 12:49:51 UTC (rev 4213)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/el/ELLearningAlgorithmDisjunctive.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -130,7 +130,7 @@
}
- public ELLearningAlgorithmDisjunctive(PosNegLP problem, AbstractReasonerComponent reasoner) {
+ public ELLearningAlgorithmDisjunctive(AbstractLearningProblem problem, AbstractReasonerComponent reasoner) {
super(problem, reasoner);
}
Added: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/DisjunctiveHeuristic.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/DisjunctiveHeuristic.java (rev 0)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/DisjunctiveHeuristic.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -0,0 +1,38 @@
+/**
+ * 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.elcopy;
+
+public class DisjunctiveHeuristic implements ELHeuristic {
+
+ ELDescriptionTreeComparator edt = new ELDescriptionTreeComparator();
+
+ public int compare(SearchTreeNode tree1, SearchTreeNode tree2) {
+ double diff = tree1.getScore()-tree2.getScore();
+ if(diff < 0.00001 && diff > -0.00001) {
+ return edt.compare(tree1.getDescriptionTree(), tree2.getDescriptionTree());
+ } else if(diff > 0){
+ return 1;
+// return (int)Math.signum(diff);
+ } else {
+ return -1;
+ }
+ }
+
+}
Added: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionEdge.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionEdge.java (rev 0)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionEdge.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -0,0 +1,79 @@
+/**
+ * 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.elcopy;
+
+import org.dllearner.core.owl.ObjectProperty;
+import org.dllearner.core.owl.Property;
+
+/**
+ * A (directed) edge in an EL description tree. It consists of an edge
+ * label, which is an object property, and the EL description tree
+ * the edge points to.
+ *
+ * @author Jens Lehmann
+ *
+ */
+public class ELDescriptionEdge {
+
+ private Property label;
+
+ private ELDescriptionNode node;
+
+ /**
+ * Constructs and edge given a label and an EL description tree.
+ * @param label The label of this edge.
+ * @param tree The tree the edge points to (edges are directed).
+ */
+ public ELDescriptionEdge(Property label, ELDescriptionNode tree) {
+ this.label = label;
+ this.node = tree;
+ }
+
+ /**
+ * @param label the label to set
+ */
+ public void setLabel(Property label) {
+ this.label = label;
+ }
+
+ /**
+ * @return The label of this edge.
+ */
+ public Property getLabel() {
+ return label;
+ }
+
+ /**
+ * @return The EL description tree
+ */
+ public ELDescriptionNode getNode() {
+ return node;
+ }
+
+ public boolean isObjectProperty(){
+ return label instanceof ObjectProperty;
+ }
+
+ @Override
+ public String toString() {
+ return "--" + label + "--> " + node.toDescriptionString();
+ }
+
+}
Added: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionEdgeComparator.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionEdgeComparator.java (rev 0)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionEdgeComparator.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -0,0 +1,47 @@
+/**
+ * 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.elcopy;
+
+import java.util.Comparator;
+
+/**
+ * @author Jens Lehmann
+ *
+ */
+public class ELDescriptionEdgeComparator implements Comparator<ELDescriptionEdge> {
+
+ private ELDescriptionNodeComparator nodeComp;
+
+ public ELDescriptionEdgeComparator() {
+ nodeComp = new ELDescriptionNodeComparator();
+ }
+
+ @Override
+ public int compare(ELDescriptionEdge edge1, ELDescriptionEdge edge2) {
+ // perform string comparison on node labels
+ int comp = edge1.getLabel().getURI().compareTo(edge2.getLabel().getURI());
+ if(comp==0) {
+ return nodeComp.compare(edge1.getNode(), edge2.getNode());
+ } else {
+ return comp;
+ }
+ }
+
+}
Added: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionNode.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionNode.java (rev 0)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionNode.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -0,0 +1,768 @@
+/**
+ * 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.elcopy;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.dllearner.core.owl.DataRange;
+import org.dllearner.core.owl.DatatypeProperty;
+import org.dllearner.core.owl.DatatypeSomeRestriction;
+import org.dllearner.core.owl.Description;
+import org.dllearner.core.owl.Intersection;
+import org.dllearner.core.owl.NamedClass;
+import org.dllearner.core.owl.ObjectProperty;
+import org.dllearner.core.owl.ObjectPropertyExpression;
+import org.dllearner.core.owl.ObjectSomeRestriction;
+import org.dllearner.core.owl.Property;
+import org.dllearner.core.owl.Thing;
+
+/**
+ * Represents an EL description tree, which corresponds to a
+ * description in the EL description logic. Note that an EL description tree
+ * can be a subtree of another EL description tree. In general,
+ * an EL description tree is a tree where the node label is a set
+ * of named classes and the edges are labelled with a property.
+ *
+ * In the documentation below "this node" refers to the root node
+ * of this EL description (sub-)tree. One tree cannot be reused,
+ * i.e. used as subtree in several description trees, as some of
+ * the associated variables (level, simulation) depend on the overall
+ * tree.
+ *
+ * @author Jens Lehmann
+ *
+ */
+@SuppressWarnings("unused")
+public class ELDescriptionNode {
+
+ // the reference tree for storing values, must not be null
+ protected ELDescriptionTree tree;
+
+ protected TreeSet<NamedClass> label = new TreeSet<NamedClass>();
+
+ protected List<ELDescriptionEdge> edges = new LinkedList<ELDescriptionEdge>();
+
+ protected int level;
+
+ // parent node in the tree;
+ // null indicates that this node is a root node
+ protected ELDescriptionNode parent = null;
+
+ // simulation information (list or set?)
+ protected Set<ELDescriptionNode> in = new HashSet<ELDescriptionNode>();
+ protected Set<ELDescriptionNode> inSC1 = new HashSet<ELDescriptionNode>();
+ protected Set<ELDescriptionNode> inSC2 = new HashSet<ELDescriptionNode>();
+ protected Set<ELDescriptionNode> out = new HashSet<ELDescriptionNode>();
+ protected Set<ELDescriptionNode> outSC1 = new HashSet<ELDescriptionNode>();
+ protected Set<ELDescriptionNode> outSC2 = new HashSet<ELDescriptionNode>();
+
+ protected boolean isClassNode;
+ protected DataRange dataRange;
+
+ /**
+ * Internal constructor used for cloning nodes.
+ */
+ protected ELDescriptionNode() {
+
+ }
+
+ /**
+ * Constructs an EL description tree with empty root label.
+ */
+ public ELDescriptionNode(ELDescriptionTree tree) {
+ this(tree, new TreeSet<NamedClass>());
+ }
+
+ // convenience constructor
+ public ELDescriptionNode(ELDescriptionTree tree, NamedClass... label) {
+ this(tree, new TreeSet<NamedClass>(Arrays.asList(label)));
+ }
+
+ /**
+ * Constructs an EL description tree given its root label.
+ * @param label Label of the root node.
+ */
+ public ELDescriptionNode(ELDescriptionTree tree, TreeSet<NamedClass> label) {
+ this.label = label;
+ this.edges = new LinkedList<ELDescriptionEdge>();
+ this.tree = tree;
+ level = 1;
+ parent = null;
+ // this is the root node of the overall tree
+ tree.rootNode = this;
+ tree.addNodeToLevel(this, level);
+ tree.size += label.size();
+
+ isClassNode = true;
+ }
+
+ /**
+ * Constructs an EL description tree given its root label.
+ * @param label Label of the root node.
+ */
+ public ELDescriptionNode(ELDescriptionTree tree, DataRange dataRange) {
+ this.dataRange = dataRange;
+ this.edges = new LinkedList<ELDescriptionEdge>();
+ this.tree = tree;
+ level = 1;
+ parent = null;
+ // this is the root node of the overall tree
+ tree.rootNode = this;
+ tree.addNodeToLevel(this, level);
+ tree.size += label.size();
+
+ isClassNode = false;
+ }
+
+ // convenience constructor
+ public ELDescriptionNode(ELDescriptionNode parentNode, Property parentProperty, NamedClass... label) {
+ this(parentNode, parentProperty, new TreeSet<NamedClass>(Arrays.asList(label)));
+ }
+
+ public ELDescriptionNode(ELDescriptionNode parentNode, Property parentProperty, Set<NamedClass> label) {
+// this.label = label;
+ // we first need to add the edge and update the simulation and then add
+ // all classes iteratively to the label (each time updating the simulation again)
+ this.edges = new LinkedList<ELDescriptionEdge>();
+ parent = parentNode;
+ // the reference tree is the same as for the parent tree
+ tree = parentNode.tree;
+ // level increases by 1
+ level = parentNode.level + 1;
+ // we add an edge from the parent to this node
+ ELDescriptionEdge edge = new ELDescriptionEdge(parentProperty, this);
+ parent.edges.add(edge);
+ // we need to update the set of nodes on a particular level
+ tree.addNodeToLevel(this, level);
+
+ // simulation update
+// Monitor mon = MonitorFactory.start("simulation update");
+ // the nodes, which need to be updated
+ Set<ELDescriptionNode> update = new HashSet<ELDescriptionNode>();
+
+ // loop over all nodes on the same level, which are not in the in set
+ Set<ELDescriptionNode> nodes = tree.getNodesOnLevel(level);
+ for(ELDescriptionNode w : nodes) {
+ // to save space, we do not add reflexive relations
+ if(w != this) {
+ // (w,v') is automatically added
+ tree.extendSimulation(w, this);
+
+ // check conditions for (v',w)
+ boolean sc1 = false, sc2 = false;
+
+ if(w.label.size() == 0) {
+ tree.extendSimulationSC1(this, w);
+ sc1 = true;
+ }
+
+ if(w.edges.size() == 0) {
+ tree.extendSimulationSC2(this, w);
+ sc2 = true;
+ }
+
+ if(sc1 && sc2) {
+ tree.extendSimulationSC12(this, w);
+ }
+
+ update.add(w.parent);
+ }
+ }
+ update.add(this.parent);
+
+// if(inSC1.contains(w) && tree.checkSC2(this, w)) {
+// tree.extendSimulation(this, w);
+// update.add(w.parent);
+// }
+
+ // loop over all nodes in out set
+// for(ELDescriptionNode w : out) {
+// if(!tree.checkSC1(this, w)) {
+// tree.shrinkSimulation(this, w);
+// update.add(w.parent);
+// }
+// }
+
+// System.out.println(update);
+
+ // apply updates recursively top-down
+ tree.updateSimulation(update);
+// mon.stop();
+
+ // add all classes in label
+ for(NamedClass nc : label) {
+ extendLabel(nc);
+ }
+
+ // 1 for the edge (labels are already taken care of by extendLabel)
+ tree.size += 1;
+
+ isClassNode = true;
+ }
+
+ public ELDescriptionNode(ELDescriptionNode parentNode, Property parentProperty, DataRange dataRange) {
+ this.dataRange = dataRange;
+ // this.label = label;
+ // we first need to add the edge and update the simulation and then add
+ // all classes iteratively to the label (each time updating the simulation again)
+ this.edges = new LinkedList<ELDescriptionEdge>();
+ parent = parentNode;
+ // the reference tree is the same as for the parent tree
+ tree = parentNode.tree;
+ // level increases by 1
+ level = parentNode.level + 1;
+ // we add an edge from the parent to this node
+ ELDescriptionEdge edge = new ELDescriptionEdge(parentProperty, this);
+ parent.edges.add(edge);
+ // we need to update the set of nodes on a particular level
+ tree.addNodeToLevel(this, level);
+
+ // simulation update
+// Monitor mon = MonitorFactory.start("simulation update");
+ // the nodes, which need to be updated
+ Set<ELDescriptionNode> update = new HashSet<ELDescriptionNode>();
+
+ // loop over all nodes on the same level, which are not in the in set
+ Set<ELDescriptionNode> nodes = tree.getNodesOnLevel(level);
+ for(ELDescriptionNode w : nodes) {
+ // to save space, we do not add reflexive relations
+ if(w != this) {
+ // (w,v') is automatically added
+ tree.extendSimulation(w, this);
+
+ // check conditions for (v',w)
+ boolean sc1 = false, sc2 = false;
+
+ if(w.label.size() == 0) {
+ tree.extendSimulationSC1(this, w);
+ sc1 = true;
+ }
+
+ if(w.edges.size() == 0) {
+ tree.extendSimulationSC2(this, w);
+ sc2 = true;
+ }
+
+ if(sc1 && sc2) {
+ tree.extendSimulationSC12(this, w);
+ }
+
+ update.add(w.parent);
+ }
+ }
+ update.add(this.parent);
+
+// if(inSC1.contains(w) && tree.checkSC2(this, w)) {
+// tree.extendSimulation(this, w);
+// update.add(w.parent);
+// }
+
+ // loop over all nodes in out set
+// for(ELDescriptionNode w : out) {
+// if(!tree.checkSC1(this, w)) {
+// tree.shrinkSimulation(this, w);
+// update.add(w.parent);
+// }
+// }
+
+// System.out.println(update);
+
+ // apply updates recursively top-down
+ tree.updateSimulation(update);
+// mon.stop();
+
+
+ // 1 for the edge (labels are already taken care of by extendLabel)
+ tree.size += 1;
+
+ isClassNode = false;
+ }
+
+ /**
+ * @return the isClassNode
+ */
+ public boolean isClassNode() {
+ return isClassNode;
+ }
+
+ /**
+ * @return the dataRange
+ */
+ public DataRange getDataRange() {
+ return dataRange;
+ }
+
+
+ /**
+ * Constructs an EL description tree given its root label and edges.
+ * @param label Label of the root node.
+ * @param edges Edges connected to the root node.
+ */
+// TODO: probably delete as this constructor is not straightforward to
+// implement within the new structure
+// public ELDescriptionNode(SortedSet<NamedClass> label, List<ELDescriptionEdge> edges) {
+// this.label = label;
+// this.edges = edges;
+// }
+
+ /**
+ * Checks whether this node has a parent. If the parent link
+ * is null, the node is considered to be a root node.
+ * @return True of this is the root node and false otherwise.
+ */
+ public boolean isRoot() {
+ return parent == null;
+ }
+
+ /**
+ * Traverses the EL description tree upwards until it finds
+ * the root and returns it.
+ * @return The root node of this EL description tree.
+ */
+ public ELDescriptionNode getRoot() {
+ ELDescriptionNode root = this;
+ while(root.parent != null) {
+ root = parent;
+ }
+ return root;
+ }
+
+ /**
+ * Traverses the tree until the root node and counts how
+ * many edges are traversed. If this node does not have a parent,
+ * zero is returned. This method is used for checking the integrity
+ * of the tree in unit tests. Use {@link #getLevel()} to get the
+ * level of the tree.
+ * @return The level of this node (or more specifically the root
+ * node of this subtree) within the overall EL description tree.
+ */
+ public int computeLevel() {
+ ELDescriptionNode root = this;
+ int level = 0;
+ while(root.parent != null) {
+ root = parent;
+ level++;
+ }
+ return level;
+ }
+
+ /**
+ * This method transform the tree to an EL description. The
+ * node labels are transformed to an {@link Intersection}
+ * of {@link NamedClass}. Each edge is transformed to an
+ * {@link ObjectSomeRestriction}, where the property is the edge
+ * label and the child description the subtree the edge points
+ * to. Edges are also added to the intersection. If the intersection
+ * is empty, {@link Thing} is returned.
+ * @return The description corresponding to this EL description tree.
+ */
+ public Description transformToDescription() {
+ int nrOfElements = label.size() + edges.size();
+ // leaf labeled with \emptyset stands for owl:Thing
+ if(nrOfElements == 0) {
+ return new Thing();
+ // we want to avoid intersections with only 1 element, so in this
+ // case we return either the NamedClass or ObjectSomeRestriction directly
+ } else if(nrOfElements == 1) {
+ if(label.size()==1) {
+ return label.first();
+ } else {
+ ELDescriptionEdge edge = edges.get(0);
+ if(edge.isObjectProperty()){
+ Description child = edge.getNode().transformToDescription();
+ return new ObjectSomeRestriction((ObjectProperty) edge.getLabel(), child);
+ } else {
+ DataRange range = edge.getNode().getDataRange();
+ return new DatatypeSomeRestriction((DatatypeProperty) edge.getLabel(), range);
+ }
+
+ }
+ // return an intersection of labels and edges
+ } else {
+ Intersection is = new Intersection();
+ for(NamedClass nc : label) {
+ is.addChild(nc);
+ }
+ for(ELDescriptionEdge edge : edges) {
+ if(edge.isObjectProperty()){
+ Description child = edge.getNode().transformToDescription();
+ ObjectSomeRestriction osr = new ObjectSomeRestriction((ObjectProperty) edge.getLabel(),child);
+ is.addChild(osr);
+ } else {
+ DataRange range = edge.getNode().getDataRange();
+ DatatypeSomeRestriction dsr = new DatatypeSomeRestriction((DatatypeProperty) edge.getLabel(), range);
+ is.addChild(dsr);
+ }
+ }
+ return is;
+ }
+ }
+
+ /**
+ * Gets a list describing the position of this node within the
+ * tree. If the list is e.g. [2,5,1], then the node can be reached
+ * by picking the second child of the root node, then picking the
+ * 5th child of this node and finally selecting the first child of
+ * the previous node.
+ * @return The position number of this node within the tree as described above.
+ */
+ public int[] getCurrentPosition() {
+ int[] position = new int[level-1];
+ ELDescriptionNode root = this;
+ while(root.parent != null) {
+ position[root.level-2] = root.getChildNumber();
+ root = root.parent;
+ }
+ return position;
+ }
+
+ // returns the child number of this node, i.e. whether it is
+ // the first, second, third etc. child;
+ // TODO: might be a bit faster to store this explicitly
+ private int getChildNumber() {
+ int count = 0;
+ for(ELDescriptionEdge edge : parent.edges) {
+ if(edge.getNode() == this) {
+ return count;
+ }
+ count++;
+ }
+ throw new RuntimeException("Inconsistent tree. Child tree not reachable from parent.");
+ }
+
+ /**
+ * Replaces an entry in the node label.
+ * @param oldClass Class to remove from label.
+ * @param newClass Class to add to label.
+ */
+ public void replaceInLabel(NamedClass oldClass, NamedClass newClass) {
+ label.remove(oldClass);
+ label.add(newClass);
+ labelSimulationUpdate();
+ }
+
+ /**
+ * Adds an entry to the node label.
+ * @param newClass Class to add to label.
+ */
+ public void extendLabel(NamedClass newClass) {
+ label.add(newClass);
+ labelSimulationUpdate();
+ tree.size += 1;
+// System.out.println(tree);
+// System.out.println(tree.size);
+ }
+
+ // simulation update when extending or refining label
+ // (same in both cases)
+ private void labelSimulationUpdate() {
+// Monitor mon = MonitorFactory.start("simulation update");
+ // compute the nodes, which need to be updated
+ Set<ELDescriptionNode> update = new HashSet<ELDescriptionNode>();
+
+ Set<ELDescriptionNode> tmp = tree.getNodesOnLevel(level);
+ for(ELDescriptionNode w : tmp) {
+ if(w != this) {
+ // SC1(v,w) can only change from false to true
+ if(!inSC1.contains(w) && tree.checkSC1(this, w)) {
+ tree.extendSimulationSC1(this, w);
+ if(inSC2.contains(w)) {
+ tree.extendSimulationSC12(this, w);
+ }
+ update.add(w.getParent());
+ }
+ // SC1(w,v) can only change from true to false
+ if(outSC1.contains(w) && !tree.checkSC1(w, this)) {
+ tree.shrinkSimulationSC1(w, this);
+ if(outSC2.contains(w)) {
+ tree.shrinkSimulationSC12(w, this);
+ }
+ update.add(w.getParent());
+ }
+ }
+ }
+ if(parent != null) {
+ update.add(parent);
+ }
+
+ /*
+ // loop over all nodes on the same level, which are not in the in set
+ Set<ELDescriptionNode> tmp = new HashSet<ELDescriptionNode>(tree.getNodesOnLevel(level));
+ tmp.removeAll(in);
+ for(ELDescriptionNode w : tmp) {
+ if(w != this) {
+ // we only need to recompute SC1
+ if(inSC1.contains(w) && tree.checkSC2(this, w)) {
+ System.out.println("satisfied");
+ tree.extendSimulation(this, w);
+ update.add(w.parent);
+ }
+ }
+ }
+
+ // loop over all nodes in out set (we make a copy, because out
+ // is potentially modified, so we cannot safely iterate over it)
+ tmp = new HashSet<ELDescriptionNode>(out);
+ for(ELDescriptionNode w : tmp) {
+ if(w != this) {
+ if(!tree.checkSC1(w, this)) {
+// tree.shrinkSimulation(w, this);
+ tree.shrinkSimulationSC1(w, this);
+ tree.shrinkSimulationSC12(w, this);
+ update.add(w.parent);
+ }
+ }
+ }
+ */
+
+ // apply updates recursively top-down
+ tree.updateSimulation(update);
+// mon.stop();
+ }
+
+ public void refineEdge(int edgeNumber, Property op) {
+ edges.get(edgeNumber).setLabel(op);
+
+// Monitor mon = MonitorFactory.start("simulation update");
+ // compute the nodes, which need to be updated
+ Set<ELDescriptionNode> update = new HashSet<ELDescriptionNode>();
+ update.add(this);
+
+ /*
+ // loop over all nodes on the same level, which are not in the in set
+ Set<ELDescriptionNode> tmp = new HashSet<ELDescriptionNode>(tree.getNodesOnLevel(level));
+ tmp.removeAll(in);
+ for(ELDescriptionNode w : tmp) {
+ if(w != this) {
+ // we only need to recompute SC1
+ if(inSC2.contains(w) && tree.checkSC1(this, w)) {
+ tree.extendSimulation(this, w);
+ update.add(w.parent);
+ }
+ }
+ }
+
+ // loop over all nodes in out set
+ for(ELDescriptionNode w : out) {
+ if(w != this) {
+ if(!tree.checkSC2(this, w)) {
+ tree.shrinkSimulation(this, w);
+ update.add(w.parent);
+ }
+ }
+ }
+ */
+
+// update.add(this.parent);
+
+ // apply updates recursively top-down
+ tree.updateSimulation(update);
+// mon.stop();
+ }
+
+ /**
+ * Gets the label of this node. Do not modify the returned object,
+ * but use the provided methods instead!
+ * @return The label of root node of this subtree.
+ */
+ public NavigableSet<NamedClass> getLabel() {
+ return label;
+ }
+
+ /**
+ * Gets the edges of this node. Do not modify the
+ * returned object, but use the provided methods instead!
+ * @return The outgoing edges of this subtree.
+ */
+ public List<ELDescriptionEdge> getEdges() {
+ return edges;
+ }
+
+ /**
+ * Gets the level (distance from root) of this node. The root node
+ * has level 1.
+ * @return The level of the (root node of) this subtree in the overall tree.
+ */
+ public int getLevel() {
+ return level;
+ }
+
+ @Override
+ public String toString() {
+ return toString(0);
+ }
+
+ private String toString(int indent) {
+ String indentString = "";
+ for(int i=0; i<indent; i++)
+ indentString += " ";
+
+ String str = indentString + label.toString() + "\n";
+ for(ELDescriptionEdge edge : edges) {
+ str += indentString + "-- " + edge.getLabel() + " -->\n";
+ str += edge.getNode().toString(indent + 2);
+ }
+ return str;
+ }
+
+ public String toDescriptionString() {
+ String str = "";
+ if(isClassNode()){
+ if(label.isEmpty()) {
+ str = "TOP";
+ } else {
+ Iterator<NamedClass> it = label.iterator();
+ while(it.hasNext()) {
+ NamedClass nc = it.next();
+ if(it.hasNext()) {
+ str += nc.toString() + " AND ";
+ } else {
+ str += nc.toString();
+ }
+ }
+ }
+ } else {
+ str += dataRange;
+ }
+ for(ELDescriptionEdge edge : edges) {
+ str += " AND EXISTS " + edge.getLabel().toString() + ".(";
+ str += edge.getNode().toDescriptionString() + ")";
+ }
+ return str;
+ }
+
+ private String toDescriptionString(Set<ELDescriptionNode> nodes) {
+ String str = "";
+ // comma separated list of descriptions
+ for(ELDescriptionNode node : nodes) {
+ str += node.toDescriptionString() + ",";
+ }
+ // remove last comma
+ if(str.length() > 0) {
+ str = str.substring(0, str.length()-1);
+ }
+ return str;
+ }
+
+ public String toSimulationString() {
+ String str = "";
+ str += "in: " + toDescriptionString(in) + "\n";
+ str += "inSC1: " + toDescriptionString(inSC1) + "\n";
+ str += "inSC2: " + toDescriptionString(inSC2) + "\n";
+ str += "out: " + toDescriptionString(out) + "\n";
+ str += "outSC1: " + toDescriptionString(outSC1) + "\n";
+ str += "outSC2: " + toDescriptionString(outSC2) + "\n";
+ return str;
+ }
+
+ /**
+ * A convenience method (for debugging purposes) to get a comma separated list of nodes, where the
+ * nodes are given names (to make them readable).
+ * @param nodes The node objects.
+ * @param nodeNames A mapping to node names.
+ * @return A comma separated list of the node names.
+ */
+ public static String toString(Set<ELDescriptionNode> nodes, Map<ELDescriptionNode,String> nodeNames) {
+ String str = "";
+ // comma separated list of descriptions
+ for(ELDescriptionNode node : nodes) {
+ str += nodeNames.get(node) + ",";
+ }
+ // remove last comma
+ if(str.length() > 0) {
+ str = str.substring(0, str.length()-1);
+ }
+ return str;
+ }
+
+ public String toSimulationString(Map<ELDescriptionNode,String> nodeNames) {
+ String str = "";
+ str += " in: " + toString(in, nodeNames) + "\n";
+ str += " inSC1: " + toString(inSC1, nodeNames) + "\n";
+ str += " inSC2: " + toString(inSC2, nodeNames) + "\n";
+ str += " out: " + toString(out, nodeNames) + "\n";
+ str += " outSC1: " + toString(outSC1, nodeNames) + "\n";
+ str += " outSC2: " + toString(outSC2, nodeNames) + "\n";
+ return str;
+ }
+
+ public ELDescriptionNode getParent() {
+ return parent;
+ }
+
+ public ELDescriptionEdge getParentEdge() {
+ int childNr = getChildNumber();
+ return parent.edges.get(childNr);
+ }
+
+ /**
+ * @return the in
+ */
+ public Set<ELDescriptionNode> getIn() {
+ return in;
+ }
+
+ /**
+ * @return the inSC1
+ */
+ public Set<ELDescriptionNode> getInSC1() {
+ return inSC1;
+ }
+
+ /**
+ * @return the inSC2
+ */
+ public Set<ELDescriptionNode> getInSC2() {
+ return inSC2;
+ }
+
+ /**
+ * @return the out
+ */
+ public Set<ELDescriptionNode> getOut() {
+ return out;
+ }
+
+ /**
+ * @return the outSC1
+ */
+ public Set<ELDescriptionNode> getOutSC1() {
+ return outSC1;
+ }
+
+ /**
+ * @return the outSC2
+ */
+ public Set<ELDescriptionNode> getOutSC2() {
+ return outSC2;
+ }
+
+ public ELDescriptionTree getTree() {
+ return tree;
+ }
+}
Added: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionNodeComparator.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionNodeComparator.java (rev 0)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionNodeComparator.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -0,0 +1,103 @@
+/**
+ * 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.elcopy;
+
+import java.util.Comparator;
+import java.util.Iterator;
+
+import org.dllearner.core.owl.NamedClass;
+import org.dllearner.core.owl.Property;
+
+/**
+ * Compares two EL description trees. It is a lexicographic order
+ * according to the following criteria:
+ * - number of children
+ * - size of label
+ * - string comparison for each class in the label
+ * - recursive call on each child (first compare edge label, then child node)
+ *
+ * @author Jens Lehmann
+ *
+ */
+public class ELDescriptionNodeComparator implements Comparator<ELDescriptionNode> {
+
+ /* (non-Javadoc)
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public int compare(ELDescriptionNode node1, ELDescriptionNode node2) {
+ int nrOfChildren1 = node1.getEdges().size();
+ int nrOfChildren2 = node2.getEdges().size();
+ if(nrOfChildren1 > nrOfChildren2) {
+ return 1;
+ } else if(nrOfChildren1 < nrOfChildren2) {
+ return -1;
+ } else {
+ int labelSize1 = node1.getLabel().size();
+ int labelSize2 = node2.getLabel().size();
+ if(labelSize1 > labelSize2) {
+ return 1;
+ } else if(labelSize1 < labelSize2) {
+ return -1;
+ } else {
+ int compare = 0;
+ if(node1.isClassNode() && node2.isClassNode()){
+ // navigate through both labels
+ Iterator<NamedClass> it1 = node1.getLabel().descendingIterator();
+ Iterator<NamedClass> it2 = node2.getLabel().descendingIterator();
+ while(it1.hasNext()) {
+ NamedClass nc1 = it1.next();
+ NamedClass nc2 = it2.next();
+ compare = nc1.getName().compareTo(nc2.getName());
+
+ }
+ } else if(!node1.isClassNode() && !node2.isClassNode()){
+ compare = node1.getDataRange().toString().compareTo(node2.getDataRange().toString());
+ } else {
+ compare = -1;
+ }
+
+ if(compare != 0)
+ return compare;
+
+ // recursively compare all edges
+ for(int i=0; i<nrOfChildren1; i++) {
+ // compare by edge name
+ Property op1 = node1.getEdges().get(i).getLabel();
+ Property op2 = node2.getEdges().get(i).getLabel();
+ int compare1 = op1.getName().compareTo(op2.getName());
+ if(compare1 != 0)
+ return compare1;
+
+ // compare child nodes
+ ELDescriptionNode child1 = node1.getEdges().get(i).getNode();
+ ELDescriptionNode child2 = node2.getEdges().get(i).getNode();
+ int compare2 = compare(child1, child2);
+ if(compare2 != 0)
+ return compare2;
+ }
+
+ // trees are identical
+ return 0;
+ }
+ }
+ }
+
+}
Added: trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionTree.java
===================================================================
--- trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionTree.java (rev 0)
+++ trunk/components-core/src/main/java/org/dllearner/algorithms/elcopy/ELDescriptionTree.java 2014-01-29 14:24:16 UTC (rev 4214)
@@ -0,0 +1,621 @@
+/**
+ * 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.elcopy;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.log4j.Logger;
+import org.dllearner.core.AbstractReasonerComponent;
+import org.dllearner.core.owl.ClassHierarchy;
+import org.dllearner.core.owl.DatatypeProperty;
+import org.dllearner.core.owl.DatatypeSomeRestriction;
+import org.dllearner.core.owl.Description;
+import org.dllearner.core.owl.Intersection;
+import org.dllearner.core.owl.NamedClass;
+import org.dllearner.core.owl.ObjectProperty;
+import org.dllearner.core.owl.ObjectPropertyHierarchy;
+import org.dllearner.core.owl.ObjectSomeRestriction;
+import org.dllearner.core.owl.Property;
+import org.dllearner.core.owl.Thing;
+import org.dllearner.core.owl.UnsupportedLanguageException;
+
+/**
+ * Represents an EL description tree. Unlike {@link ELDescriptionNode}, this is
+ * a tree-wide structure, i.e. it does not implement the tree structure itself,
+ * but is used to store information about the tree.
+ *
+ * @author Jens Lehmann
+ *
+ */
+public class ELDescriptionTree implements Cloneable {
+
+ @SuppressWarnings("unused")
+ private static Logger logger = Logger.getLogger(ELDescriptionTree.class);
+
+ // to simplify equivalence checks and minimisation, we
+ // attach a simulation relation to the description tree
+ // private Simulation simulation;
+
+ // max level = 0 means that there is no tree at all
+ // (max level = 1 means the root node exists)
+ private int maxLevel = 0;
+
+ protected int size = 1;
+
+ protected ELDescriptionNode rootNode;
+
+ // the set of all nodes in the tree
+ private Collection<ELDescriptionNode> nodes = new LinkedList<ELDescriptionNode>();
+
+ // nodes on a given level of the tree
+ private Map<Integer, Set<ELDescriptionNode>> levelNodeMapping = new HashMap<Integer, Set<ELDescriptionNode>>();
+
+ // the background knowledge (we need to have it explicitly here,
+ // since we store simulation information in the tree and simulation
+ // updates depend on background knowledge)
+ protected AbstractReasonerComponent rs;
+ protected ClassHierarchy subsumptionHierarchy;
+ protected ObjectPropertyHierarchy roleHierarchy;
+
+ public ELDescriptionTree(AbstractReasonerComponent rs) {
+ this.rs = rs;
+ subsumptionHierarchy = rs.getClassHierarchy();
+ roleHierarchy = rs.getObjectPropertyHierarchy();
+ }
+
+ /**
+ * Constructs an EL description tree from an EL description.
+ *
+ * @param description
+ * A description
+ */
+ public ELDescriptionTree(AbstractReasonerComponent rs, Description description) {
+ this(rs);
+ // construct root node and recursively build the tree
+ rootNode = new ELDescriptionNode(this);
+ constructTree(description, rootNode);
+ }
+
+ private void constructTree(Description description, ELDescriptionNode node) {
+ if (description instanceof NamedClass) {
+ node.extendLabel((NamedClass) description);
+ } else if (description instanceof ObjectSomeRestriction) {
+ ObjectProperty op = (ObjectProperty) ((ObjectSomeRestriction) description).getRole();
+ ELDescriptionNode newNode = new ELDescriptionNode(node, op, new TreeSet<NamedClass>());
+ constructTree(description.getChild(0), newNode);
+ } else if (description instanceof DatatypeSomeRestriction) {
+ DatatypeProperty op = (DatatypeProperty) ((DatatypeSomeRestriction) description).getRole();
+ ELDescriptionNode newNode = new ELDescriptionNode(node, op, ((DatatypeSomeRestriction) description).getDataRange());
+ } else if (description instanceof Thing) {
+ // nothing needs to be done as an empty set is owl:Thing
+ } else if (description instanceof Intersection) {
+ // loop through all elements of the intersection
+ for (Description child : description.getChildren()) {
+ if (child instanceof NamedClass) {
+ node.extendLabel((NamedClass) child);
+ } else if (child instanceof ObjectSomeRestriction) {
+ ObjectProperty op = (ObjectProperty) ((ObjectSomeRestriction) child).getRole();
+ ELDescriptionNode newNode = new ELDescriptionNode(node, op,
+ new TreeSet<NamedClass>());
+ constructTree(child.getChild(0), newNode);
+ } else {
+ throw new UnsupportedLanguageException(description + " specifically " + child,
+ "EL");
+ }
+ }
+ } else {
+ throw new UnsupportedLanguageException(description.toString(), "EL");
+ }
+ }
+
+ /**
+ * Gets the nodes on a specific level of the tree. This information is
+ * cached here for performance reasons.
+ *
+ * @param level
+ * ...
[truncated message content] |