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 java.util.List;
022import java.util.Set;
023import java.util.TreeSet;
024
025import org.dllearner.core.EvaluatedAxiom;
026import org.dllearner.kb.SparqlEndpointKS;
027import org.semanticweb.owlapi.model.AxiomType;
028import org.semanticweb.owlapi.model.IRI;
029import org.semanticweb.owlapi.model.OWLIndividual;
030import org.semanticweb.owlapi.model.OWLObjectProperty;
031import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom;
032import org.semanticweb.owlapi.model.OWLObjectPropertyCharacteristicAxiom;
033import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;
034
035import org.apache.jena.query.ParameterizedSparqlString;
036import org.apache.jena.query.QuerySolution;
037import org.apache.jena.query.ResultSet;
038import org.apache.jena.rdf.model.Model;
039
040/**
041 * A learning algorithm for object property characteristic axioms. 
042 * @author Lorenz Buehmann
043 *
044 */
045public abstract class ObjectPropertyCharacteristicsAxiomLearner<T extends OWLObjectPropertyCharacteristicAxiom> extends ObjectPropertyAxiomLearner<T>{
046
047        protected final ParameterizedSparqlString ALREADY_DECLARED_QUERY = new ParameterizedSparqlString("ASK {?p a ?type .}");
048        
049        protected ParameterizedSparqlString POS_FREQUENCY_QUERY = null;
050        
051        protected boolean declared;
052        
053        public ObjectPropertyCharacteristicsAxiomLearner(SparqlEndpointKS ks) {
054                this.ks = ks;
055        }
056        
057        /* (non-Javadoc)
058         * @see org.dllearner.algorithms.properties.ObjectPropertyAxiomLearner#setPropertyToDescribe(org.semanticweb.owlapi.model.OWLObjectProperty)
059         */
060        @Override
061        public void setEntityToDescribe(OWLObjectProperty entityToDescribe) {
062                super.setEntityToDescribe(entityToDescribe);
063                
064                POS_FREQUENCY_QUERY.setIri("p", entityToDescribe.toStringID());
065                ALREADY_DECLARED_QUERY.setIri("p", entityToDescribe.toStringID());
066                
067                IRI type;
068                if(axiomType.equals(AxiomType.SYMMETRIC_OBJECT_PROPERTY)){
069                        type = OWLRDFVocabulary.OWL_SYMMETRIC_PROPERTY.getIRI();
070                } else if(axiomType.equals(AxiomType.ASYMMETRIC_OBJECT_PROPERTY)){
071                        type = OWLRDFVocabulary.OWL_ASYMMETRIC_PROPERTY.getIRI();
072                } else if(axiomType.equals(AxiomType.FUNCTIONAL_OBJECT_PROPERTY)){
073                        type = OWLRDFVocabulary.OWL_FUNCTIONAL_PROPERTY.getIRI();
074                } else if(axiomType.equals(AxiomType.INVERSE_FUNCTIONAL_OBJECT_PROPERTY)){
075                        type = OWLRDFVocabulary.OWL_INVERSE_FUNCTIONAL_PROPERTY.getIRI();
076                } else if(axiomType.equals(AxiomType.REFLEXIVE_OBJECT_PROPERTY)){
077                        type = OWLRDFVocabulary.OWL_REFLEXIVE_PROPERTY.getIRI();
078                } else if(axiomType.equals(AxiomType.IRREFLEXIVE_OBJECT_PROPERTY)){
079                        type = OWLRDFVocabulary.OWL_IRREFLEXIVE_PROPERTY.getIRI();
080                } else if(axiomType.equals(AxiomType.TRANSITIVE_OBJECT_PROPERTY)){
081                        type = OWLRDFVocabulary.OWL_TRANSITIVE_PROPERTY.getIRI();
082                }else {
083                        throw new IllegalArgumentException("Axiom type cannot be " + axiomType);
084                }
085                ALREADY_DECLARED_QUERY.setIri("type", type.toString()); 
086        }
087        
088        /*
089         * (non-Javadoc)
090         * 
091         * @see
092         * org.dllearner.core.AbstractAxiomLearningAlgorithm#getExistingAxioms()
093         */
094        @Override
095        protected void getExistingAxioms() {
096                // check if property is already declared as asymmetric in knowledge base
097                declared = executeAskQuery(ALREADY_DECLARED_QUERY.toString());
098                if (declared) {
099                        existingAxioms.add(getAxiom(entityToDescribe));
100                        logger.info("Property is already declared as asymmetric in knowledge base.");
101                }
102        }
103        
104        /* (non-Javadoc)
105         * @see org.dllearner.algorithms.properties.ObjectPropertyAxiomLearner#run()
106         */
107        @Override
108        protected void run() {
109                boolean declared = !existingAxioms.isEmpty();
110                
111                int frequency = getPositiveExamplesFrequency();
112
113                currentlyBestAxioms.add(new EvaluatedAxiom<>(
114                                getAxiom(entityToDescribe),
115                                computeScore(popularity, frequency, useSampling),
116                                declared));
117        }
118        
119        protected abstract T getAxiom(OWLObjectProperty property);
120        
121        protected int getPositiveExamplesFrequency(){
122                return getCountValue(POS_FREQUENCY_QUERY.toString());
123        }
124        
125        protected int getPositiveExamplesFrequency(Model model){
126                return getCountValue(POS_FREQUENCY_QUERY.toString(), model);
127        }
128        
129        @Override
130        public Set<OWLObjectPropertyAssertionAxiom> getPositiveExamples(EvaluatedAxiom<T> evAxiom) {
131                T axiom = evAxiom.getAxiom();
132                posExamplesQueryTemplate.setIri("p", axiom.getProperty().asOWLObjectProperty().toStringID());
133
134                Set<OWLObjectPropertyAssertionAxiom> posExamples = new TreeSet<>();
135
136                ResultSet rs = executeSelectQuery(posExamplesQueryTemplate.toString());
137
138                List<String> vars = rs.getResultVars();
139                boolean onlySubject = vars.size() == 1;
140                while (rs.hasNext()) {
141                        QuerySolution qs = rs.next();
142                        OWLIndividual subject = df.getOWLNamedIndividual(IRI.create(qs.getResource("s").getURI()));
143                        OWLIndividual object = df.getOWLNamedIndividual(IRI.create(qs.getResource(onlySubject ? "s" : "o").getURI()));
144                        posExamples.add(df.getOWLObjectPropertyAssertionAxiom(entityToDescribe, subject, object));
145                }
146
147                return posExamples;
148        }
149
150        @Override
151        public Set<OWLObjectPropertyAssertionAxiom> getNegativeExamples(EvaluatedAxiom<T> evaluatedAxiom) {
152                T axiom = evaluatedAxiom.getAxiom();
153                negExamplesQueryTemplate.setIri("p", axiom.getProperty().asOWLObjectProperty().toStringID());
154
155                Set<OWLObjectPropertyAssertionAxiom> negExamples = new TreeSet<>();
156
157                ResultSet rs = executeSelectQuery(negExamplesQueryTemplate.toString());
158
159                List<String> vars = rs.getResultVars();
160                boolean onlySubject = vars.size() == 1;
161                while (rs.hasNext()) {
162                        QuerySolution qs = rs.next();
163                        OWLIndividual subject = df.getOWLNamedIndividual(IRI.create(qs.getResource("s").getURI()));
164                        OWLIndividual object = df.getOWLNamedIndividual(IRI.create(qs.getResource(onlySubject ? "s" : "o").getURI()));
165                        negExamples.add(df.getOWLObjectPropertyAssertionAxiom(entityToDescribe, subject, object));
166                }
167
168                return negExamples;
169        }
170
171}