001    /**
002     * Copyright (C) 2007-2008, 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.test.junit;
021    
022    import static org.junit.Assert.assertTrue;
023    
024    import java.io.File;
025    import java.io.IOException;
026    import java.net.MalformedURLException;
027    import java.util.Set;
028    import java.util.SortedSet;
029    import java.util.TreeSet;
030    
031    import org.apache.log4j.FileAppender;
032    import org.apache.log4j.Level;
033    import org.apache.log4j.Logger;
034    import org.apache.log4j.SimpleLayout;
035    import org.dllearner.algorithms.el.ELDescriptionNode;
036    import org.dllearner.algorithms.el.ELDescriptionTree;
037    import org.dllearner.core.ComponentInitException;
038    import org.dllearner.core.ComponentManager;
039    import org.dllearner.core.KnowledgeSource;
040    import org.dllearner.core.ReasonerComponent;
041    import org.dllearner.core.owl.Description;
042    import org.dllearner.core.owl.NamedClass;
043    import org.dllearner.core.owl.ObjectProperty;
044    import org.dllearner.kb.OWLFile;
045    import org.dllearner.parser.KBParser;
046    import org.dllearner.parser.ParseException;
047    import org.dllearner.reasoning.OWLAPIReasoner;
048    import org.dllearner.refinementoperators.ELDown2;
049    import org.dllearner.refinementoperators.RefinementOperator;
050    import org.dllearner.test.junit.TestOntologies.TestOntology;
051    import org.dllearner.utilities.Files;
052    import org.dllearner.utilities.Helper;
053    import org.dllearner.utilities.owl.ConceptComparator;
054    import org.dllearner.utilities.owl.ConceptTransformation;
055    import org.dllearner.utilities.statistics.Stat;
056    import org.junit.Test;
057    
058    import com.jamonapi.Monitor;
059    import com.jamonapi.MonitorFactory;
060    
061    /**
062     * Tests related to the EL downward refinement operator.
063     * 
064     * @author Jens Lehmann
065     *
066     */
067    public class ELDownTests {
068    
069            @SuppressWarnings("unused")
070            private static Logger logger = Logger.getLogger(ELDownTests.class);             
071            
072            /**
073             * Implementation of test case created by Christoph Haase for 
074             * new operator.
075             * 
076             * @throws ParseException Thrown if concept syntax does not correspond
077             * to current KB syntax.
078             * @throws ComponentInitException 
079             * @throws IOException 
080             */
081            @Test
082            public void test1() throws ParseException, ComponentInitException, IOException {
083                    System.out.println("TEST 1");           
084                    ReasonerComponent rs = TestOntologies.getTestOntology(TestOntology.SIMPLE);
085                    
086    //              ELDescriptionTree t = new ELDescriptionTree(rs);
087    //              ObjectProperty p1 = new ObjectProperty("p1");
088    //              ObjectProperty p2 = new ObjectProperty("p2");
089    //              NamedClass a1 = new NamedClass("a1");
090    //              ELDescriptionNode n1 = new ELDescriptionNode(t, a1);
091    //              ELDescriptionNode n2 = new ELDescriptionNode(n1, p1, a1);
092    //              
093    //              System.out.println(t);
094    //              System.out.println(t.getSize());
095    //              System.exit(0);
096                    
097                    // input description
098                    Description input = KBParser.parseConcept("(human AND EXISTS has.animal)");
099                    System.out.println("refining: " + input.toString(KBParser.internalNamespace, null));            
100                    
101                    // TODO For this test, we need to turn instance based disjoints
102                    // off! (We do not have any instances here.)
103                    RefinementOperator operator = new ELDown2(rs);
104                    
105                    // desired refinements as strings
106                    Set<String> desiredString = new TreeSet<String>();
107                    desiredString.add("(human AND EXISTS hasPet.animal)");
108                    desiredString.add("(human AND EXISTS has.bird)");
109                    desiredString.add("(human AND EXISTS has.cat)");
110                    desiredString.add("((human AND EXISTS hasPet.TOP) AND EXISTS has.animal)");
111                    desiredString.add("((human AND EXISTS hasChild.TOP) AND EXISTS has.animal)");
112                    desiredString.add("((human AND EXISTS hasPet.TOP) AND EXISTS has.animal)");
113                    desiredString.add("((human AND EXISTS has.human) AND EXISTS has.animal)");
114                    desiredString.add("((human AND EXISTS has.EXISTS has.TOP) AND EXISTS has.animal)");
115                    desiredString.add("(human AND EXISTS has.(animal AND EXISTS has.TOP))");
116                    
117                    ConceptComparator cc = new ConceptComparator();
118                    SortedSet<Description> desired = new TreeSet<Description>(cc);
119                    for(String str : desiredString) {
120                            Description tmp = KBParser.parseConcept(str);
121                            // eliminate conjunctions nested in other conjunctions
122                            ConceptTransformation.cleanConcept(tmp);
123                            ConceptTransformation.transformToOrderedForm(tmp, cc);
124                            desired.add(tmp);
125                            System.out.println("desired: " + tmp.toString(KBParser.internalNamespace, null));
126                    }
127                    
128                    Logger logger = Logger.getRootLogger();
129                    logger.setLevel(Level.TRACE);
130                    SimpleLayout layout = new SimpleLayout();
131                    FileAppender app = new FileAppender(layout, "log/el/test.txt", false);
132                    logger.removeAllAppenders();
133                    logger.addAppender(app);                        
134                    
135                    // perform refinement and compare solutions
136                    long startTime = System.nanoTime();
137                    Set<Description> refinements = operator.refine(input);
138                    long runTime = System.nanoTime() - startTime;
139                    logger.debug("Refinement step took " + Helper.prettyPrintNanoSeconds(runTime, true, true) + ".");
140                    boolean runStats = false;
141                    if(runStats) {
142                            Stat stat = new Stat();
143                            int runs = 1000;
144                            for(int run=0; run<runs; run++) {
145                                    Monitor refinementTime = MonitorFactory.start("extraction time");
146                                    startTime = System.nanoTime();
147                                    refinements = operator.refine(input);
148                                    runTime = System.nanoTime() - startTime;
149                                    refinementTime.stop();
150                                    
151                                    stat.addNumber(runTime/1000000);
152                            }
153    //                      System.out.println("Identical 2nd refinement step took " + Helper.prettyPrintNanoSeconds(runTime, true, true) + ".");
154                            System.out.println("average over " + runs + " runs:");
155                            System.out.println(stat.prettyPrint("ms"));
156                    }
157            
158                    // number of refinements has to be correct and each produced
159                    // refinement must be in the set of desired refinements
160                    assertTrue(refinements.size() == desired.size());
161                    System.out.println("\nproduced refinements and their unit test status (true = assertion satisfied):");
162                    for(Description refinement : refinements) {
163                            boolean ok = desired.contains(refinement);                      
164                            System.out.println(ok + ": " + refinement.toString(KBParser.internalNamespace, null));
165                            assertTrue(desired.contains(refinement));
166                    }
167                    
168                    File jamonlog = new File("log/jamontest.html");
169                    Files.createFile(jamonlog, MonitorFactory.getReport());         
170                    
171                    // generated by operator (and currently corresponding to its definition):
172                    // false (http://localhost/foo#human AND EXISTS http://localhost/foo#has.(http://localhost/foo#animal AND http://localhost/foo#human
173                    // false (http://localhost/foo#animal AND http://localhost/foo#human AND EXISTS http://localhost/foo#has.http://localhost/foo#animal
174                    // solution: element of ncc should be tested for disjointness with any other candidate (here: animal and human)
175                    
176                    // edge added, but refinement not recognized as being minimal
177                    // (http://localhost/foo#human AND EXISTS http://localhost/foo#has.http://localhost/foo#animal AND EXISTS http://localhost/foo#has.TOP)
178            }
179            
180            @Test
181            public void test2() throws ParseException, IOException {
182                    System.out.println("TEST 2");                   
183                    
184                    ReasonerComponent rs = TestOntologies.getTestOntology(TestOntology.SIMPLE_NO_DR);
185                    
186                    // input description
187                    Description input = KBParser.parseConcept("(human AND EXISTS hasPet.bird)");
188                    ConceptTransformation.cleanConcept(input);
189                    
190                    Set<String> desiredString = new TreeSet<String>();
191                    desiredString.add("(human AND (EXISTS hasPet.bird AND EXISTS has.human))");
192                    desiredString.add("(human AND (EXISTS hasPet.bird AND EXISTS has.cat))");
193                    desiredString.add("(human AND (EXISTS hasPet.bird AND EXISTS has.EXISTS has.TOP))");
194                    desiredString.add("(human AND (EXISTS hasPet.bird AND EXISTS has.(cat AND bird)))");
195                    desiredString.add("(human AND (EXISTS hasPet.bird AND EXISTS hasPet.cat))");
196                    desiredString.add("(human AND (EXISTS hasPet.bird AND EXISTS hasPet.EXISTS has.TOP))");
197                    desiredString.add("(human AND (EXISTS hasPet.bird AND EXISTS hasChild.TOP))");
198                    desiredString.add("(human AND (EXISTS hasPet.bird AND EXISTS hasPet.human))");
199                    desiredString.add("(human AND (EXISTS hasPet.bird AND EXISTS hasPet.(animal AND EXISTS has.TOP)))"); 
200                    desiredString.add("(human AND EXISTS hasPet.(bird AND cat))");
201                    desiredString.add("(human AND (EXISTS has.(animal AND EXISTS has.TOP) AND EXISTS hasPet.bird))");
202                    desiredString.add("(human AND (EXISTS has.(bird AND EXISTS has.TOP) AND EXISTS hasPet.bird))");
203                    desiredString.add("(human AND EXISTS hasPet.(bird AND EXISTS has.TOP))"); 
204                    
205                    ConceptComparator cc = new ConceptComparator();
206                    SortedSet<Description> desired = new TreeSet<Description>(cc);
207                    for(String str : desiredString) {
208                            Description tmp = KBParser.parseConcept(str);
209                            ConceptTransformation.cleanConcept(tmp);
210                            ConceptTransformation.transformToOrderedForm(tmp, cc);
211                            desired.add(tmp);
212                            System.out.println("desired: " + tmp.toString(KBParser.internalNamespace, null));
213                    }               
214                    
215                    Logger logger = Logger.getRootLogger();
216                    logger.setLevel(Level.TRACE);
217                    SimpleLayout layout = new SimpleLayout();
218                    FileAppender app = new FileAppender(layout, "log/el/test_no_dr.txt", false);
219                    logger.removeAllAppenders();
220                    logger.addAppender(app);                
221                    
222                    RefinementOperator operator = new ELDown2(rs);
223                    
224                    Set<Description> refinements = operator.refine(input);
225                    
226    //              assertTrue(refinements.size() == desired.size());
227                    System.out.println("\nproduced refinements and their unit test status (true = assertion satisfied):");
228                    for(Description refinement : refinements) {
229                            ConceptTransformation.transformToOrderedForm(refinement, cc);
230                            boolean ok = desired.contains(refinement);
231                            System.out.println(ok + ": " + refinement.toString(KBParser.internalNamespace, null));
232    //                      assertTrue(desired.contains(refinement));
233                    }               
234            }
235            
236            @Test
237            public void test3() throws ParseException, IOException {
238                    System.out.println("TEST 3");
239                    
240                    ReasonerComponent rs = TestOntologies.getTestOntology(TestOntology.SIMPLE_NO_DISJOINT);
241                    
242                    // input description
243                    Description input = KBParser.parseConcept("(human AND (EXISTS hasChild.human AND EXISTS has.animal))");
244                    ConceptTransformation.cleanConcept(input);
245                    
246                    Set<String> desiredString = new TreeSet<String>();
247                    desiredString.add("(human AND (animal AND (EXISTS hasChild.human AND EXISTS has.animal)))");
248                    desiredString.add("(human AND (EXISTS hasChild.human AND EXISTS has.(animal AND human)))");
249                    desiredString.add("(human AND (EXISTS hasChild.human AND EXISTS has.bird))");
250                    desiredString.add("(human AND (EXISTS hasChild.human AND EXISTS has.cat))");
251                    desiredString.add("(human AND (EXISTS hasChild.human AND EXISTS hasPet.animal))");
252                    desiredString.add("(human AND (EXISTS hasChild.human AND (EXISTS has.TOP AND EXISTS has.animal)))");
253                    desiredString.add("(human AND (EXISTS hasChild.human AND EXISTS has.(animal AND EXISTS has.TOP)))");
254                    desiredString.add("(human AND (EXISTS hasChild.human AND (EXISTS has.animal AND EXISTS has.EXISTS has.TOP)))");
255                    
256                    ConceptComparator cc = new ConceptComparator();
257                    SortedSet<Description> desired = new TreeSet<Description>(cc);
258                    for(String str : desiredString) {
259                            Description tmp = KBParser.parseConcept(str);
260                            ConceptTransformation.cleanConcept(tmp);
261                            ConceptTransformation.transformToOrderedForm(tmp, cc);
262                            desired.add(tmp);
263                            System.out.println("desired: " + tmp.toString(KBParser.internalNamespace, null));
264                    }               
265                    
266                    Logger logger = Logger.getRootLogger();
267                    logger.setLevel(Level.TRACE);
268                    SimpleLayout layout = new SimpleLayout();
269                    FileAppender app = new FileAppender(layout, "log/el/test_no_disjoint.txt", false);
270                    logger.removeAllAppenders();
271                    logger.addAppender(app);                
272                    
273                    RefinementOperator operator = new ELDown2(rs);
274                    
275                    Set<Description> refinements = operator.refine(input);
276                    
277    //              assertTrue(refinements.size() == desired.size());
278                    System.out.println("\nproduced refinements and their unit test status (true = assertion satisfied):");
279                    for(Description refinement : refinements) {
280                            ConceptTransformation.transformToOrderedForm(refinement, cc);
281                            boolean ok = desired.contains(refinement);
282                            System.out.println(ok + ": " + refinement.toString(KBParser.internalNamespace, null));
283    //                      assertTrue(desired.contains(refinement));
284                    }               
285            }       
286            
287    //      @Test
288            public void test4() throws ComponentInitException, ParseException, IOException {
289                    
290                    Logger logger = Logger.getRootLogger();
291                    logger.setLevel(Level.TRACE);
292                    SimpleLayout layout = new SimpleLayout();
293                    FileAppender app = new FileAppender(layout, "log/el/log.txt", false);
294                    logger.removeAllAppenders();
295                    logger.addAppender(app);        
296                    
297                    ComponentManager cm = ComponentManager.getInstance();
298                    KnowledgeSource source = cm.knowledgeSource(OWLFile.class);
299                    String ont = "/home/jl/ontologien/galen2.owl";
300                    cm.applyConfigEntry(source, "url", new File(ont).toURI().toURL());
301                    source.init();
302                    ReasonerComponent reasoner = cm.reasoner(OWLAPIReasoner.class, source);
303                    reasoner.init();
304                    System.out.println("Galen loaded.");
305                    
306    //              Description input = KBParser.parseConcept("(\"http://www.co-ode.org/ontologies/galen#15.0\" AND (\"http://www.co-ode.org/ontologies/galen#30.0\" AND (EXISTS \"http://www.co-ode.org/ontologies/galen#Attribute\".\"http://www.co-ode.org/ontologies/galen#5.0\" AND EXISTS \"http://www.co-ode.org/ontologies/galen#Attribute\".\"http://www.co-ode.org/ontologies/galen#6.0\")))");
307                    Description input = KBParser.parseConcept("(\"http://www.co-ode.org/ontologies/galen#1.0\" AND (\"http://www.co-ode.org/ontologies/galen#10.0\" AND (EXISTS \"http://www.co-ode.org/ontologies/galen#DomainAttribute\".(\"http://www.co-ode.org/ontologies/galen#1.0\" AND (\"http://www.co-ode.org/ontologies/galen#6.0\" AND \"http://www.co-ode.org/ontologies/galen#TopCategory\")) AND EXISTS \"http://www.co-ode.org/ontologies/galen#Attribute\".(\"http://www.co-ode.org/ontologies/galen#1.0\" AND (\"http://www.co-ode.org/ontologies/galen#TopCategory\" AND EXISTS \"http://www.co-ode.org/ontologies/galen#Attribute\".TOP)))))");
308                    ConceptTransformation.cleanConcept(input);
309                    
310                    ELDown2 operator = new ELDown2(reasoner);
311                    operator.refine(input);
312                    
313            }
314    
315    //      @Test
316            public void asTest() throws ComponentInitException, MalformedURLException {
317                    
318                    ComponentManager cm = ComponentManager.getInstance();
319                    KnowledgeSource source = cm.knowledgeSource(OWLFile.class);
320                    String ont = "/home/jl/ontologien/galen2.owl";
321                    cm.applyConfigEntry(source, "url", new File(ont).toURI().toURL());
322                    source.init();
323                    ReasonerComponent reasoner = cm.reasoner(OWLAPIReasoner.class, source);
324                    reasoner.init();
325                    System.out.println("Galen loaded.");
326                    
327                    ELDescriptionTree tree = new ELDescriptionTree(reasoner);
328                    NamedClass a1 = new NamedClass("http://www.co-ode.org/ontologies/galen#1.0");
329                    NamedClass a2 = new NamedClass("http://www.co-ode.org/ontologies/galen#10.0");
330                    NamedClass a3 = new NamedClass("http://www.co-ode.org/ontologies/galen#6.0");
331                    NamedClass a4 = new NamedClass("http://www.co-ode.org/ontologies/galen#TopCategory");
332                    ObjectProperty r1 = new ObjectProperty("http://www.co-ode.org/ontologies/galen#Attribute");
333                    ObjectProperty r2 = new ObjectProperty("http://www.co-ode.org/ontologies/galen#DomainAttribute");
334                    ELDescriptionNode v1 = new ELDescriptionNode(tree, a1, a2);
335                    ELDescriptionNode v2 = new ELDescriptionNode(v1, r2, a1, a3, a4);
336                    ELDescriptionNode v3 = new ELDescriptionNode(v1, r1, a1, a4);
337                    new ELDescriptionNode(v3, r1);
338                    
339                    ELDescriptionNode w = new ELDescriptionNode(v2, r1);
340    
341                    ELDown2 operator = new ELDown2(reasoner);
342                    System.out.println(operator.asCheck(w));                
343                    
344            }
345            
346    }