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.util.HashMap;
023    import java.util.HashSet;
024    import java.util.LinkedList;
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.ComponentInitException;
031    import org.dllearner.core.AbstractKnowledgeSource;
032    import org.dllearner.core.AbstractReasonerComponent;
033    import org.dllearner.core.owl.ClassAssertionAxiom;
034    import org.dllearner.core.owl.Description;
035    import org.dllearner.core.owl.EquivalentClassesAxiom;
036    import org.dllearner.core.owl.Individual;
037    import org.dllearner.core.owl.Intersection;
038    import org.dllearner.core.owl.KB;
039    import org.dllearner.core.owl.NamedClass;
040    import org.dllearner.core.owl.ObjectExactCardinalityRestriction;
041    import org.dllearner.core.owl.ObjectProperty;
042    import org.dllearner.core.owl.PropertyAxiom;
043    import org.dllearner.core.owl.Thing;
044    import org.dllearner.kb.KBFile;
045    import org.dllearner.parser.KBParser;
046    import org.dllearner.reasoning.OWLAPIReasoner;
047    import org.dllearner.utilities.statistics.SimpleClock;
048    import org.semanticweb.owlapi.model.OWLOntology;
049    
050    public class OntologyCloser {
051            KB kb;
052            KBFile kbFile;
053            OWLOntology onto;
054            OWLAPIReasoner reasoner;
055            boolean isKB = true;
056    
057            // Set<KnowledgeSource> ks;
058            AbstractReasonerComponent rs;
059            HashMap<Individual, Set<ObjectExactCardinalityRestriction>> indToRestr;
060            HashMap<Individual, Set<Description>> indToNamedClass;
061            HashSet<Description> classes;
062    
063            public OntologyCloser(KB kb) {
064                    super();
065                    this.kb = kb;
066                    this.kbFile = new KBFile(this.kb);
067                    Set<AbstractKnowledgeSource> ks = new HashSet<AbstractKnowledgeSource>();
068                    ks.add(this.kbFile);
069                    OWLAPIReasoner owlapi = new OWLAPIReasoner(ks);
070                    try {
071                            owlapi.init();
072                    } catch (ComponentInitException e) {
073                            // TODO Auto-generated catch block
074                            e.printStackTrace();
075                    }
076                    this.indToRestr = new HashMap<Individual, Set<ObjectExactCardinalityRestriction>>();
077                    this.classes = new HashSet<Description>();
078    //              this.rs = new ReasonerComponent(owlapi);
079                    rs = owlapi;
080    
081            }
082            
083            public void updateReasoner() {
084                    SimpleClock sc = new SimpleClock();
085                    sc.printAndSet();
086                    this.kbFile = new KBFile(this.kb);
087                    Set<AbstractKnowledgeSource> ks = new HashSet<AbstractKnowledgeSource>();
088                    ks.add(this.kbFile);
089                    
090                    sc.printAndSet("updating reasoner");
091                    OWLAPIReasoner owlapi = new OWLAPIReasoner(ks);
092                    sc.printAndSet("init");
093                    try {
094                            owlapi.init();
095                    } catch (ComponentInitException e) {
096                            // TODO Auto-generated catch block
097                            e.printStackTrace();
098                    }
099                    sc.printAndSet();
100    //              this.rs = new ReasonerComponent(owlapi);
101                    rs = owlapi;
102                    
103            }
104    
105            /**
106             * counts the number of roles used by each individual and assigns
107             * ExactCardinalityRestriction
108             */
109            public void applyNumberRestrictions() {
110                    Set<ObjectProperty> allRoles = this.rs.getObjectProperties();
111                    // Set<Individual> allind = this.rs.getIndividuals();
112                    testForTransitiveProperties(true);
113    
114                    for (ObjectProperty oneRole : allRoles) {
115    
116                            // System.out.println(oneRole.getClass());
117                            Map<Individual, SortedSet<Individual>> allRoleMembers = this.rs
118                                            .getPropertyMembers(oneRole);
119                            for (Individual oneInd : allRoleMembers.keySet()) {
120                                    SortedSet<Individual> fillers = allRoleMembers.get(oneInd);
121                                    if (fillers.size() > 0) {
122                                            ObjectExactCardinalityRestriction oecr = new ObjectExactCardinalityRestriction(
123                                                            fillers.size(), oneRole, new Thing());
124                                            kb.addABoxAxiom(new ClassAssertionAxiom(oecr, oneInd));
125                                    }
126                            }
127    
128                    }
129                    // System.out.println("good ontology? " + rs.isSatisfiable());
130    
131            }
132    
133            
134    
135            /**
136             * counts the number of roles used by each individual and assigns
137             * ExactCardinalityRestriction
138             */
139            public void applyNumberRestrictionsConcise() {
140                    Set<ObjectProperty> allRoles = this.rs.getObjectProperties();
141                    // Set<Individual> allind = this.rs.getIndividuals();
142                    testForTransitiveProperties(true);
143    
144                    for (ObjectProperty oneRole : allRoles) {
145    
146                            // System.out.println(oneRole.getClass());
147                            Map<Individual, SortedSet<Individual>> allRoleMembers = this.rs
148                                            .getPropertyMembers(oneRole);
149                            for (Individual oneInd : allRoleMembers.keySet()) {
150                                    SortedSet<Individual> fillers = allRoleMembers.get(oneInd);
151                                    if (fillers.size() > 0) {
152                                            ObjectExactCardinalityRestriction oecr = new ObjectExactCardinalityRestriction(
153                                                            fillers.size(), oneRole, new Thing());
154                                            // indToRestr.put(oneInd,)
155                                            collectExObjRestrForInd(oneInd, oecr);
156                                    }
157                            }
158    
159                            //
160    
161                    }// end for
162    
163                    // Intersection intersection = null;
164                    LinkedList<Description> ll = new LinkedList<Description>();
165                    Set<ObjectExactCardinalityRestriction> s = null;
166    
167                    for (Individual oneInd : indToRestr.keySet()) {
168                            s = indToRestr.get(oneInd);
169                            for (ObjectExactCardinalityRestriction oecr : s) {
170                                    ll.add(oecr);
171                            }
172                            kb.addABoxAxiom(new ClassAssertionAxiom(new Intersection(ll),
173                                            oneInd));
174                            s = null;
175                            ll = new LinkedList<Description>();
176                    }
177    
178                    //
179    
180                    // System.out.println("good ontology? " + rs.isSatisfiable());
181    
182            }
183            
184    
185    
186            /**
187             * counts the number of roles used by each individual and assigns
188             * ExactCardinalityRestriction
189             */
190            public void applyNumberRestrictionsNamed() {
191                    Set<ObjectProperty> allRoles = this.rs.getObjectProperties();
192                    // Set<Individual> allind = this.rs.getIndividuals();
193                    testForTransitiveProperties(true);
194    
195                    for (ObjectProperty oneRole : allRoles) {
196    
197                            // System.out.println(oneRole.getClass());
198                            Map<Individual, SortedSet<Individual>> allRoleMembers = this.rs
199                                            .getPropertyMembers(oneRole);
200                            for (Individual oneInd : allRoleMembers.keySet()) {
201                                    SortedSet<Individual> fillers = allRoleMembers.get(oneInd);
202                                    //if (fillers.size() > 0) {
203                                            ObjectExactCardinalityRestriction oecr = new ObjectExactCardinalityRestriction(
204                                                            fillers.size(), oneRole, new Thing());
205                                            // indToRestr.put(oneInd,)
206                                            //make Description
207                                            Description d = new NamedClass(oneRole+"Exact"+fillers.size()+"gen");
208                                            //d.addChild(oecr);
209                                            kb.addTBoxAxiom(new EquivalentClassesAxiom(d,oecr));
210                                            //System.out.println(d.toManchesterSyntaxString("", new HashMap<String, String>()));
211                                            kb.addABoxAxiom(new ClassAssertionAxiom(d,oneInd));
212                                            //collectExObjRestrForInd(oneInd, oecr);
213                                    
214                            }
215    
216                            //
217    
218                    }// end for
219    
220                    // Intersection intersection = null;
221                    /*
222                    LinkedList<Description> ll = new LinkedList<Description>();
223                    Set<ObjectExactCardinalityRestriction> s = null;
224    
225                    for (Individual oneInd : indToRestr.keySet()) {
226                            s = indToRestr.get(oneInd);
227                            for (ObjectExactCardinalityRestriction oecr : s) {
228                                    ll.add(oecr);
229                            }
230                            kb.addABoxAxiom(new ClassAssertionAxiom(new Intersection(ll),
231                                            oneInd));
232                            s = null;
233                            ll = new LinkedList<Description>();
234                    }*/
235    
236                    //
237    
238                    // System.out.println("good ontology? " + rs.isSatisfiable());
239    
240            }
241    
242            public boolean testForTransitiveProperties(boolean printflag) {
243                    boolean retval = false;
244                    Set<PropertyAxiom> ax = kb.getRbox();
245                    for (PropertyAxiom propertyAxiom : ax) {
246                            if (propertyAxiom.getClass().getSimpleName().equals(
247                                            "TransitiveObjectPropertyAxiom")) {
248                                    retval = true;
249                                    if (printflag) {
250                                            System.out
251                                                            .println("WARNING transitive object property can't be used in cardinality restriction\n"
252                                                                            + propertyAxiom.toString());
253                                    }
254                            }
255                    }
256    
257                    return retval;
258            }
259    
260            public static void closeKB(KB kb) {
261                    new OntologyCloser(kb).applyNumberRestrictions();
262            }
263    
264            public SortedSet<Individual> verifyConcept(String conceptStr) {
265                    Description d;
266                    SimpleClock sc = new SimpleClock();
267                    StringBuffer sb = new StringBuffer();
268                    sb.append(conceptStr);
269                    conceptStr = sb.toString();
270                    SortedSet<Individual> ind = new TreeSet<Individual>();
271                    try {
272                            d = KBParser.parseConcept(conceptStr);
273                            System.out.println("\n*******************\nStarting retrieval");
274                            System.out.println(d.toManchesterSyntaxString("",
275                                            new HashMap<String, String>()));
276                            // System.out.println(d.toString());
277                            sc.setTime();
278                            this.rs.getIndividuals(d);
279    
280                            System.out.println("retrieved: " + ind.size() + " instances");
281                            sc.printAndSet();
282                            for (Individual individual : ind) {
283                                    System.out.print(individual + "|");
284                            }
285    
286                    } catch (Exception e) {
287                            e.printStackTrace();
288                    }
289                    return ind;
290            }
291    
292            private boolean collectExObjRestrForInd(Individual ind,
293                            ObjectExactCardinalityRestriction oecr) {
294                    Set<ObjectExactCardinalityRestriction> s = indToRestr.get(ind);
295                    if (s == null) {
296                            indToRestr.put(ind,
297                                            new HashSet<ObjectExactCardinalityRestriction>());
298                            s = indToRestr.get(ind);
299                    }
300                    return s.add(oecr);
301            }
302            
303            @SuppressWarnings("unused")
304            private boolean collectDescriptionForInd(Individual ind,
305                            Description d) {
306                    Set<Description> s = indToNamedClass.get(ind);
307                    if (s == null) {
308                            indToNamedClass.put(ind,
309                                            new HashSet<Description>());
310                            s = indToNamedClass.get(ind);
311                    }
312                    return s.add(d);
313            }
314    
315    }