001    /**
002     * Copyright (C) 2007-2011, 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     */
019    
020    package org.dllearner.utilities.owl;
021    
022    import java.net.URI;
023    import java.util.HashMap;
024    import java.util.HashSet;
025    import java.util.Map;
026    import java.util.Set;
027    import java.util.SortedSet;
028    import java.util.TreeSet;
029    
030    import org.dllearner.core.owl.Description;
031    import org.dllearner.core.owl.Individual;
032    import org.dllearner.core.owl.ObjectProperty;
033    import org.dllearner.parser.KBParser;
034    import org.dllearner.reasoning.OWLAPIReasoner;
035    import org.dllearner.utilities.statistics.SimpleClock;
036    import org.semanticweb.owlapi.apibinding.OWLManager;
037    import org.semanticweb.owlapi.io.RDFXMLOntologyFormat;
038    import org.semanticweb.owlapi.model.AddAxiom;
039    import org.semanticweb.owlapi.model.AxiomType;
040    import org.semanticweb.owlapi.model.IRI;
041    import org.semanticweb.owlapi.model.OWLAxiom;
042    import org.semanticweb.owlapi.model.OWLClassExpression;
043    import org.semanticweb.owlapi.model.OWLDataFactory;
044    import org.semanticweb.owlapi.model.OWLObjectExactCardinality;
045    import org.semanticweb.owlapi.model.OWLObjectIntersectionOf;
046    import org.semanticweb.owlapi.model.OWLOntology;
047    import org.semanticweb.owlapi.model.OWLOntologyManager;
048    import org.semanticweb.owlapi.model.OWLPropertyAxiom;
049    import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom;
050    
051    public class OntologyCloserOWLAPI {
052    
053            OWLOntology onto;
054            OWLAPIReasoner rs;
055    //      ReasonerComponent rs;
056            HashMap<Individual, Set<OWLObjectExactCardinality>> indToRestr;
057            OWLDataFactory factory;
058            OWLOntologyManager manager;
059            public int numberOfStatementsChanged = 0;
060    
061            public OntologyCloserOWLAPI(OWLAPIReasoner reasoner) {
062                    this.rs = reasoner;
063                    this.indToRestr = new HashMap<Individual, Set<OWLObjectExactCardinality>>();
064    //              this.rs = new ReasonerComponent(reasoner);
065                    this.manager = OWLManager.createOWLOntologyManager();
066                    this.factory = manager.getOWLDataFactory();
067                    this.onto = reasoner.getOWLAPIOntologies().get(0);
068            }
069    
070            /**
071             * counts the number of roles used by each individual and assigns
072             * ExactCardinalityRestriction to Individuals
073             */
074            public void applyNumberRestrictions() {
075                    System.out.println("apply ExactCardinalityRestriction to Individuals");
076                    Set<ObjectProperty> allRoles = this.rs.getObjectProperties();
077                    System.out.println("found: " + allRoles.size() + " roles");
078                    testForTransitiveProperties(true);
079    
080                    for (ObjectProperty oneRole : allRoles) {
081    
082                            Map<Individual, SortedSet<Individual>> allRoleMembers = this.rs
083                                            .getPropertyMembers(oneRole);
084                            for (Individual oneInd : allRoleMembers.keySet()) {
085                                    SortedSet<Individual> fillers = allRoleMembers.get(oneInd);
086                                    // only where roles exist
087                                    if (fillers.size() > 0) {
088                                            OWLObjectExactCardinality oecr = factory
089                                                            .getOWLObjectExactCardinality(fillers.size(), factory.getOWLObjectProperty(IRI
090                                                                            .create(oneRole.getName())), factory.getOWLThing());
091    
092                                            OWLAxiom axiom = factory.getOWLClassAssertionAxiom(oecr, factory
093                                                            .getOWLNamedIndividual(IRI.create(oneInd.getName())));
094                                            AddAxiom addAxiom = new AddAxiom(this.onto, axiom);
095                                            try {
096                                                    // add change
097                                                    manager.applyChange(addAxiom);
098                                            } catch (Exception e) {
099                                                    e.printStackTrace();
100                                            }
101                                    }
102                            }
103    
104                    }
105    
106            }
107    
108            /**
109             * counts the number of roles used by each individual and assigns
110             * ExactCardinalityRestriction, but uses only one Intersection: role1
111             * exactly 1 and role2 exactly 2 and ....
112             * 
113             */
114            public void applyNumberRestrictionsConcise() {
115    
116                    Set<ObjectProperty> allRoles = this.rs.getObjectProperties();
117                    testForTransitiveProperties(true);
118    
119                    // collect info for roles and individuals
120                    for (ObjectProperty oneRole : allRoles) {
121                            Map<Individual, SortedSet<Individual>> allRoleMembers = this.rs
122                                            .getPropertyMembers(oneRole);
123                            for (Individual oneInd : allRoleMembers.keySet()) {
124                                    SortedSet<Individual> fillers = allRoleMembers.get(oneInd);
125                                    if (fillers.size() > 0) {
126                                            OWLObjectExactCardinality oecr = factory.getOWLObjectExactCardinality(fillers.size(), factory.getOWLObjectProperty(IRI
127                                                                            .create(oneRole.getName())),
128                                                            factory.getOWLThing());
129                                            collectExObjRestrForInd(oneInd, oecr);
130                                    }
131                            }
132                    }// end for
133    
134                    Set<OWLClassExpression> target = new HashSet<OWLClassExpression>();
135                    Set<OWLObjectExactCardinality> s = null;
136    
137                    for (Individual oneInd : indToRestr.keySet()) {
138                            s = indToRestr.get(oneInd);
139                            for (OWLObjectExactCardinality oecr : s) {
140                                    target.add(oecr);
141                            }
142                            // collect everything in an intersection
143                            OWLObjectIntersectionOf intersection = factory.getOWLObjectIntersectionOf(target);
144                            s = null;
145                            target = new HashSet<OWLClassExpression>();
146    
147                            OWLAxiom axiom = factory.getOWLClassAssertionAxiom(intersection, factory
148                                            .getOWLNamedIndividual(IRI.create(oneInd.getName())));
149                            AddAxiom addAxiom = new AddAxiom(this.onto, axiom);
150                            try {
151                                    manager.applyChange(addAxiom);
152                                    numberOfStatementsChanged++;
153                            } catch (Exception e) {
154                                    e.printStackTrace();
155                            }
156    
157                    }// end for
158            }
159    
160            /**
161             * @param printflag
162             *            boolean for some output
163             * @return true if some roles are transitive
164             */
165            public boolean testForTransitiveProperties(boolean printflag) {
166    
167                    Set<OWLTransitiveObjectPropertyAxiom> ax = onto.getAxioms(AxiomType.TRANSITIVE_OBJECT_PROPERTY);
168                    boolean retval = !ax.isEmpty();
169                    for (OWLPropertyAxiom propertyAxiom : ax) {
170                            if (printflag) {
171                                    System.out.println("WARNING transitive object property can't be used in cardinality restriction\n"
172                                                    + propertyAxiom.toString() + "but I'm ignoring it");
173                            }
174                    }
175                    if (printflag) {
176                            System.out.println("No transitive Properties found");
177                    }
178                    return retval;
179            }
180    
181            /*
182             * public static void closeKB(KB kb) { new
183             * OntologyCloserOWLAPI(kb).applyNumberRestrictions(); }
184             */
185    
186            /**
187             * makes some retrieval queries
188             * @param conceptStr
189             */
190            public SortedSet<Individual> verifyConcept(String conceptStr) {
191    
192                    Description d;
193                    SimpleClock sc = new SimpleClock();
194                    StringBuffer sb = new StringBuffer();
195                    sb.append(conceptStr);
196                    conceptStr = sb.toString();
197                    SortedSet<Individual> ind = new TreeSet<Individual>();
198                    try {
199                            d = KBParser.parseConcept(conceptStr);
200                            System.out.println("\n*******************\nStarting retrieval");
201                            System.out.println(d.toManchesterSyntaxString("",
202                                            new HashMap<String, String>()));
203                            // System.out.println(d.toString());
204                            sc.setTime();
205                            this.rs.getIndividuals(d);
206    
207                            System.out.println("retrieved: " + ind.size() + " instances");
208                            sc.printAndSet();
209                            for (Individual individual : ind) {
210                                    System.out.print(individual + "|");
211                            }
212    
213                    } catch (Exception e) {
214                            e.printStackTrace();
215                    }
216                    return ind;
217            }
218    
219            public void writeOWLFile(URI filename) {
220                    try {
221                            manager.saveOntology(this.onto, new RDFXMLOntologyFormat(),
222                                            IRI.create(filename));
223                    } catch (Exception e) {
224                            e.printStackTrace();
225                    }
226            }
227    
228            private boolean collectExObjRestrForInd(Individual ind,
229                            OWLObjectExactCardinality oecr) {
230                    Set<OWLObjectExactCardinality> s = indToRestr.get(ind);
231    
232                    if (s == null) {
233    
234                            indToRestr.put(ind,
235                                            new HashSet<OWLObjectExactCardinality>());
236                            s = indToRestr.get(ind);
237                    }
238                    return s.add(oecr);
239            }
240    
241    }