001/**
002 * Copyright (C) 2007 - 2016, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package org.dllearner.algorithms.properties;
020
021import static org.semanticweb.owlapi.model.AxiomType.ASYMMETRIC_OBJECT_PROPERTY;
022import static org.semanticweb.owlapi.model.AxiomType.CLASS_ASSERTION;
023import static org.semanticweb.owlapi.model.AxiomType.DATATYPE_DEFINITION;
024import static org.semanticweb.owlapi.model.AxiomType.DATA_PROPERTY_ASSERTION;
025import static org.semanticweb.owlapi.model.AxiomType.DATA_PROPERTY_DOMAIN;
026import static org.semanticweb.owlapi.model.AxiomType.DATA_PROPERTY_RANGE;
027import static org.semanticweb.owlapi.model.AxiomType.DIFFERENT_INDIVIDUALS;
028import static org.semanticweb.owlapi.model.AxiomType.DISJOINT_CLASSES;
029import static org.semanticweb.owlapi.model.AxiomType.DISJOINT_DATA_PROPERTIES;
030import static org.semanticweb.owlapi.model.AxiomType.DISJOINT_OBJECT_PROPERTIES;
031import static org.semanticweb.owlapi.model.AxiomType.DISJOINT_UNION;
032import static org.semanticweb.owlapi.model.AxiomType.EQUIVALENT_CLASSES;
033import static org.semanticweb.owlapi.model.AxiomType.EQUIVALENT_DATA_PROPERTIES;
034import static org.semanticweb.owlapi.model.AxiomType.EQUIVALENT_OBJECT_PROPERTIES;
035import static org.semanticweb.owlapi.model.AxiomType.FUNCTIONAL_DATA_PROPERTY;
036import static org.semanticweb.owlapi.model.AxiomType.FUNCTIONAL_OBJECT_PROPERTY;
037import static org.semanticweb.owlapi.model.AxiomType.HAS_KEY;
038import static org.semanticweb.owlapi.model.AxiomType.INVERSE_FUNCTIONAL_OBJECT_PROPERTY;
039import static org.semanticweb.owlapi.model.AxiomType.INVERSE_OBJECT_PROPERTIES;
040import static org.semanticweb.owlapi.model.AxiomType.IRREFLEXIVE_OBJECT_PROPERTY;
041import static org.semanticweb.owlapi.model.AxiomType.NEGATIVE_DATA_PROPERTY_ASSERTION;
042import static org.semanticweb.owlapi.model.AxiomType.NEGATIVE_OBJECT_PROPERTY_ASSERTION;
043import static org.semanticweb.owlapi.model.AxiomType.OBJECT_PROPERTY_ASSERTION;
044import static org.semanticweb.owlapi.model.AxiomType.OBJECT_PROPERTY_DOMAIN;
045import static org.semanticweb.owlapi.model.AxiomType.OBJECT_PROPERTY_RANGE;
046import static org.semanticweb.owlapi.model.AxiomType.REFLEXIVE_OBJECT_PROPERTY;
047import static org.semanticweb.owlapi.model.AxiomType.SAME_INDIVIDUAL;
048import static org.semanticweb.owlapi.model.AxiomType.SUBCLASS_OF;
049import static org.semanticweb.owlapi.model.AxiomType.SUB_DATA_PROPERTY;
050import static org.semanticweb.owlapi.model.AxiomType.SUB_OBJECT_PROPERTY;
051import static org.semanticweb.owlapi.model.AxiomType.SUB_PROPERTY_CHAIN_OF;
052import static org.semanticweb.owlapi.model.AxiomType.SYMMETRIC_OBJECT_PROPERTY;
053import static org.semanticweb.owlapi.model.AxiomType.TRANSITIVE_OBJECT_PROPERTY;
054
055import java.util.Arrays;
056import java.util.HashMap;
057import java.util.HashSet;
058import java.util.Map;
059import java.util.Set;
060
061import org.dllearner.algorithms.DisjointClassesLearner;
062import org.dllearner.algorithms.SimpleSubclassLearner;
063import org.dllearner.core.AbstractAxiomLearningAlgorithm;
064import org.semanticweb.owlapi.model.AxiomType;
065import org.semanticweb.owlapi.model.EntityType;
066import org.semanticweb.owlapi.model.OWLAxiom;
067import org.semanticweb.owlapi.model.OWLEntity;
068import org.semanticweb.owlapi.model.OWLObject;
069
070import com.google.common.collect.HashBiMap;
071import com.google.common.collect.Sets;
072import org.apache.jena.query.ParameterizedSparqlString;
073
074/**
075 * A utility class that holds links between entity type, axiom types and axiom algorithms.
076 * @author Lorenz Buehmann
077 *
078 */
079public class AxiomAlgorithms {
080        
081         /** set of tbox axiom types */
082    public static final Set<AxiomType<? extends OWLAxiom>> TBoxAxiomTypes = Sets.<AxiomType<? extends OWLAxiom>>newHashSet(
083            Arrays.asList(SUBCLASS_OF, EQUIVALENT_CLASSES, DISJOINT_CLASSES,
084                    OBJECT_PROPERTY_DOMAIN, OBJECT_PROPERTY_RANGE,
085                    INVERSE_OBJECT_PROPERTIES, FUNCTIONAL_OBJECT_PROPERTY,
086                    INVERSE_FUNCTIONAL_OBJECT_PROPERTY,
087                    SYMMETRIC_OBJECT_PROPERTY, ASYMMETRIC_OBJECT_PROPERTY,
088                    TRANSITIVE_OBJECT_PROPERTY, REFLEXIVE_OBJECT_PROPERTY,
089                    IRREFLEXIVE_OBJECT_PROPERTY, DATA_PROPERTY_DOMAIN,
090                    DATA_PROPERTY_RANGE, FUNCTIONAL_DATA_PROPERTY,
091                    DATATYPE_DEFINITION, DISJOINT_UNION, HAS_KEY));
092    
093    /** set of abox axiom types */
094    public static final Set<AxiomType<? extends OWLAxiom>> ABoxAxiomTypes = Sets.<AxiomType<? extends OWLAxiom>>newHashSet(
095            Arrays.asList(CLASS_ASSERTION, SAME_INDIVIDUAL,
096                    DIFFERENT_INDIVIDUALS, OBJECT_PROPERTY_ASSERTION,
097                    NEGATIVE_OBJECT_PROPERTY_ASSERTION,
098                    DATA_PROPERTY_ASSERTION, NEGATIVE_DATA_PROPERTY_ASSERTION));
099    
100    /** set of rbox axiom types */
101    @SuppressWarnings("unchecked")
102        public static final Set<AxiomType<? extends OWLAxiom>> RBoxAxiomTypes = Sets.<AxiomType<? extends OWLAxiom>>newHashSet(
103                                TRANSITIVE_OBJECT_PROPERTY, DISJOINT_DATA_PROPERTIES,
104                    SUB_DATA_PROPERTY, EQUIVALENT_DATA_PROPERTIES,
105                    DISJOINT_OBJECT_PROPERTIES, SUB_OBJECT_PROPERTY,
106                    EQUIVALENT_OBJECT_PROPERTIES, SUB_PROPERTY_CHAIN_OF);
107    
108    /** set of tbox and rbox axiom types */
109    public static final Set<AxiomType<? extends OWLAxiom>> TBoxAndRBoxAxiomTypes = tboxAndRbox();
110
111    private static Set<AxiomType<? extends OWLAxiom>> tboxAndRbox() {
112        Set<AxiomType<?>> axioms = new HashSet<>(TBoxAxiomTypes);
113        axioms.addAll(RBoxAxiomTypes);
114        return axioms;
115    }
116        
117        static class AxiomTypeCluster {
118                private final Set<AxiomType<? extends OWLAxiom>> axiomTypes;
119                private final ParameterizedSparqlString sampleQuery;
120                
121                public AxiomTypeCluster(Set<AxiomType<? extends OWLAxiom>> axiomTypes, ParameterizedSparqlString sampleQuery) {
122                        this.axiomTypes = axiomTypes;
123                        this.sampleQuery = sampleQuery;
124                }
125                
126                /**
127                 * @return the axiomTypes
128                 */
129                public Set<AxiomType<? extends OWLAxiom>> getAxiomTypes() {
130                        return axiomTypes;
131                }
132                
133                /**
134                 * @return the sampleQuery
135                 */
136                public ParameterizedSparqlString getSampleQuery() {
137                        return sampleQuery;
138                }
139                
140                @Override
141                public String toString() {
142                        return axiomTypes.toString();
143                }
144                
145                public static final AxiomTypeCluster OBJECT_PROPERTY_HIERARCHY_CLUSTER = new AxiomTypeCluster(
146                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(SUB_OBJECT_PROPERTY, EQUIVALENT_OBJECT_PROPERTIES, DISJOINT_OBJECT_PROPERTIES),
147                                new ParameterizedSparqlString("PREFIX owl:<http://www.w3.org/2002/07/owl#> CONSTRUCT {?s ?entity ?o . ?s ?p1 ?o . ?p1 a owl:ObjectProperty .} "
148                                                + "WHERE {?s ?entity ?o . OPTIONAL{?s ?p1 ?o . ?p1 a owl:ObjectProperty . FILTER(?entity !=?p1)} }"));
149                
150                public static final AxiomTypeCluster OBJECT_PROPERTY_CHARACTERISTICS_WITHOUT_TRANSITIVITY_CLUSTER = new AxiomTypeCluster(
151                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(SYMMETRIC_OBJECT_PROPERTY, ASYMMETRIC_OBJECT_PROPERTY,
152                                                FUNCTIONAL_OBJECT_PROPERTY, INVERSE_FUNCTIONAL_OBJECT_PROPERTY, REFLEXIVE_OBJECT_PROPERTY, IRREFLEXIVE_OBJECT_PROPERTY),
153                                new ParameterizedSparqlString("CONSTRUCT {?s ?entity ?o.} WHERE {?s ?entity ?o}"));
154                
155                public static final AxiomTypeCluster OBJECT_PROPERTY_TRANSITIVITY_CLUSTER = new AxiomTypeCluster(
156                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(TRANSITIVE_OBJECT_PROPERTY),
157                                new ParameterizedSparqlString("CONSTRUCT {?s ?entity ?o . ?o ?entity ?o1 . ?s ?entity ?o1 .} "
158                                                + "WHERE {?s ?entity ?o . OPTIONAL {?o ?entity ?o1 . ?s ?entity ?o1 .}}"));
159                
160                public static final AxiomTypeCluster OBJECT_PROPERTY_DOMAIN_CLUSTER = new AxiomTypeCluster(
161                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(OBJECT_PROPERTY_DOMAIN),
162                                new ParameterizedSparqlString("PREFIX owl:<http://www.w3.org/2002/07/owl#> CONSTRUCT {?s ?entity ?o; a ?cls . ?cls a owl:Class .} "
163                                                + "WHERE {?s ?entity ?o . OPTIONAL {?s a ?cls . ?cls a owl:Class .}}"));
164                
165                public static final AxiomTypeCluster OBJECT_PROPERTY_RANGE_CLUSTER = new AxiomTypeCluster(
166                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(OBJECT_PROPERTY_RANGE),
167                                new ParameterizedSparqlString("PREFIX owl:<http://www.w3.org/2002/07/owl#> CONSTRUCT {?s ?entity ?o . ?o a ?cls . ?cls a owl:Class .} "
168                                                + "WHERE {?s ?entity ?o . OPTIONAL {?o a ?cls . ?cls a owl:Class .}}"));
169                
170                public static final AxiomTypeCluster INVERSE_OBJECT_PROPERTIES_CLUSTER = new AxiomTypeCluster(
171                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(INVERSE_OBJECT_PROPERTIES),
172                                new ParameterizedSparqlString("CONSTRUCT {?s ?entity ?o . ?o ?p_inv ?s . } "
173                                                + "WHERE {?s ?entity ?o . OPTIONAL {?o ?p_inv ?s . }}"));
174                
175                public static final AxiomTypeCluster DATA_PROPERTY_HIERARCHY_CLUSTER = new AxiomTypeCluster(
176                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(SUB_DATA_PROPERTY, EQUIVALENT_DATA_PROPERTIES, DISJOINT_DATA_PROPERTIES),
177                                new ParameterizedSparqlString("CONSTRUCT {?s ?entity ?o . ?s ?p1 ?o . ?p1 a <http://www.w3.org/2002/07/owl#DatatypeProperty> .} "
178                                                + "WHERE {?s ?entity ?o . OPTIONAL{?s ?p1 ?o . FILTER(!sameTerm(?entity, ?p1))} }"));
179                
180                public static final AxiomTypeCluster DATA_PROPERTY_RANGE_AND_FUNCTIONALITY_CLUSTER = new AxiomTypeCluster(
181                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(DATA_PROPERTY_RANGE, FUNCTIONAL_DATA_PROPERTY),
182                                new ParameterizedSparqlString("CONSTRUCT {?s ?entity ?o.} WHERE {?s ?entity ?o}"));
183                
184                public static final AxiomTypeCluster DATA_PROPERTY_DOMAIN_CLUSTER = new AxiomTypeCluster(
185                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(DATA_PROPERTY_DOMAIN),
186                                new ParameterizedSparqlString("PREFIX owl:<http://www.w3.org/2002/07/owl#> CONSTRUCT {?s ?entity ?o; a ?cls . ?cls a owl:Class .} "
187                                                + "WHERE {?s ?entity ?o . OPTIONAL {?s a ?cls . ?cls a owl:Class .}}"));
188                
189                public static final AxiomTypeCluster CLASS_HIERARCHY_CLUSTER = new AxiomTypeCluster(
190                                Sets.<AxiomType<? extends OWLAxiom>>newHashSet(SUBCLASS_OF, EQUIVALENT_CLASSES, DISJOINT_CLASSES),
191                                new ParameterizedSparqlString("CONSTRUCT{?s a ?entity . ?s a ?cls1 .} WHERE {?s a ?entity . OPTIONAL {?s a ?cls1 .}"));
192        }
193
194        private static final Map<EntityType<? extends OWLEntity>, Set<AxiomType<? extends OWLAxiom>>> entityType2AxiomTypes =
195                        new HashMap<>();
196
197        static {
198                // class axiom types
199                entityType2AxiomTypes.put(EntityType.CLASS, Sets.<AxiomType<? extends OWLAxiom>>newHashSet(
200                                SUBCLASS_OF, EQUIVALENT_CLASSES, DISJOINT_CLASSES));
201                
202                // object property axiom types
203                entityType2AxiomTypes.put(EntityType.OBJECT_PROPERTY, Sets.<AxiomType<? extends OWLAxiom>>newHashSet(
204                                SUB_OBJECT_PROPERTY, EQUIVALENT_OBJECT_PROPERTIES, DISJOINT_OBJECT_PROPERTIES,
205                                SYMMETRIC_OBJECT_PROPERTY, ASYMMETRIC_OBJECT_PROPERTY,FUNCTIONAL_OBJECT_PROPERTY, 
206                                INVERSE_FUNCTIONAL_OBJECT_PROPERTY, REFLEXIVE_OBJECT_PROPERTY, IRREFLEXIVE_OBJECT_PROPERTY, TRANSITIVE_OBJECT_PROPERTY,
207                                OBJECT_PROPERTY_DOMAIN, OBJECT_PROPERTY_RANGE,
208                                INVERSE_OBJECT_PROPERTIES));
209                
210                // data property axiom types
211                entityType2AxiomTypes.put(EntityType.DATA_PROPERTY, Sets.<AxiomType<? extends OWLAxiom>>newHashSet(
212                                SUB_DATA_PROPERTY, EQUIVALENT_DATA_PROPERTIES, DISJOINT_DATA_PROPERTIES,
213                                FUNCTIONAL_DATA_PROPERTY, DATA_PROPERTY_DOMAIN, DATA_PROPERTY_RANGE));
214        }
215        
216        private static final Map<EntityType, Set<AxiomTypeCluster>> sameSampleCluster =
217                        new HashMap<>();
218        
219        static {
220                // object properties
221                sameSampleCluster.put(EntityType.OBJECT_PROPERTY,
222                                Sets.newHashSet(
223                                                AxiomTypeCluster.OBJECT_PROPERTY_HIERARCHY_CLUSTER, 
224                                                AxiomTypeCluster.OBJECT_PROPERTY_CHARACTERISTICS_WITHOUT_TRANSITIVITY_CLUSTER,
225                                                AxiomTypeCluster.OBJECT_PROPERTY_DOMAIN_CLUSTER,
226                                                AxiomTypeCluster.OBJECT_PROPERTY_RANGE_CLUSTER,
227                                                AxiomTypeCluster.OBJECT_PROPERTY_TRANSITIVITY_CLUSTER,
228                                                AxiomTypeCluster.INVERSE_OBJECT_PROPERTIES_CLUSTER));
229                
230                // data properties
231                sameSampleCluster.put(EntityType.DATA_PROPERTY,
232                                Sets.newHashSet(
233                                                AxiomTypeCluster.DATA_PROPERTY_HIERARCHY_CLUSTER, 
234                                                AxiomTypeCluster.DATA_PROPERTY_DOMAIN_CLUSTER,
235                                                AxiomTypeCluster.DATA_PROPERTY_RANGE_AND_FUNCTIONALITY_CLUSTER));
236                
237                // classes
238                sameSampleCluster.put(EntityType.CLASS,
239                                Sets.newHashSet(
240                                                AxiomTypeCluster.OBJECT_PROPERTY_HIERARCHY_CLUSTER, 
241                                                AxiomTypeCluster.OBJECT_PROPERTY_CHARACTERISTICS_WITHOUT_TRANSITIVITY_CLUSTER,
242                                                AxiomTypeCluster.OBJECT_PROPERTY_DOMAIN_CLUSTER,
243                                                AxiomTypeCluster.OBJECT_PROPERTY_RANGE_CLUSTER,
244                                                AxiomTypeCluster.OBJECT_PROPERTY_TRANSITIVITY_CLUSTER));
245        }
246        
247        private static HashBiMap<AxiomType<? extends OWLAxiom>, Class<? extends AbstractAxiomLearningAlgorithm<? extends OWLAxiom, ? extends OWLObject, ? extends OWLEntity>>> axiomType2Class = 
248                        HashBiMap.create();
249        
250        static{
251                axiomType2Class.put(AxiomType.SUBCLASS_OF, SimpleSubclassLearner.class);
252//              axiomType2Class.put(AxiomType.EQUIVALENT_CLASSES, CELOE.class);
253                axiomType2Class.put(AxiomType.DISJOINT_CLASSES, DisjointClassesLearner.class);
254                axiomType2Class.put(AxiomType.SUB_OBJECT_PROPERTY, SubObjectPropertyOfAxiomLearner.class);
255                axiomType2Class.put(AxiomType.EQUIVALENT_OBJECT_PROPERTIES, EquivalentObjectPropertyAxiomLearner.class);
256                axiomType2Class.put(AxiomType.DISJOINT_OBJECT_PROPERTIES, DisjointObjectPropertyAxiomLearner.class);
257                axiomType2Class.put(AxiomType.OBJECT_PROPERTY_DOMAIN, ObjectPropertyDomainAxiomLearner.class);
258                axiomType2Class.put(AxiomType.OBJECT_PROPERTY_RANGE, ObjectPropertyRangeAxiomLearner.class);
259                axiomType2Class.put(AxiomType.INVERSE_OBJECT_PROPERTIES, InverseObjectPropertyAxiomLearner.class);
260                axiomType2Class.put(AxiomType.FUNCTIONAL_OBJECT_PROPERTY, FunctionalObjectPropertyAxiomLearner.class);
261                axiomType2Class.put(AxiomType.INVERSE_FUNCTIONAL_OBJECT_PROPERTY, InverseFunctionalObjectPropertyAxiomLearner.class);
262                axiomType2Class.put(AxiomType.REFLEXIVE_OBJECT_PROPERTY, ReflexiveObjectPropertyAxiomLearner.class);
263                axiomType2Class.put(AxiomType.IRREFLEXIVE_OBJECT_PROPERTY, IrreflexiveObjectPropertyAxiomLearner.class);
264                axiomType2Class.put(AxiomType.SYMMETRIC_OBJECT_PROPERTY, SymmetricObjectPropertyAxiomLearner.class);
265                axiomType2Class.put(AxiomType.ASYMMETRIC_OBJECT_PROPERTY, AsymmetricObjectPropertyAxiomLearner.class);
266                axiomType2Class.put(AxiomType.TRANSITIVE_OBJECT_PROPERTY, TransitiveObjectPropertyAxiomLearner.class);
267                axiomType2Class.put(AxiomType.SUB_DATA_PROPERTY, SubDataPropertyOfAxiomLearner.class);
268                axiomType2Class.put(AxiomType.EQUIVALENT_DATA_PROPERTIES, EquivalentDataPropertyAxiomLearner.class);
269                axiomType2Class.put(AxiomType.DISJOINT_DATA_PROPERTIES, DisjointDataPropertyAxiomLearner.class);
270                axiomType2Class.put(AxiomType.DATA_PROPERTY_DOMAIN, DataPropertyDomainAxiomLearner.class);
271                axiomType2Class.put(AxiomType.DATA_PROPERTY_RANGE, DataPropertyRangeAxiomLearner.class);
272                axiomType2Class.put(AxiomType.FUNCTIONAL_DATA_PROPERTY, FunctionalDataPropertyAxiomLearner.class);
273        }
274        
275        public static <E extends OWLEntity> Set<AxiomType<? extends OWLAxiom>> getAxiomTypes(EntityType<E> entityType){
276                return entityType2AxiomTypes.get(entityType);
277        }
278        
279        public static <E extends OWLEntity> Class<? extends AbstractAxiomLearningAlgorithm<? extends OWLAxiom, ? extends OWLObject, ? extends OWLEntity>> getAlgorithmClass(AxiomType<? extends OWLAxiom> axiomType){
280                return axiomType2Class.get(axiomType);
281        }
282        
283        public static Set<AxiomTypeCluster> getSameSampleClusters(EntityType<? extends OWLEntity> entityType){
284                return sameSampleCluster.get(entityType);
285        }
286}