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.learningproblems; 020 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024import java.util.SortedSet; 025import java.util.TreeMap; 026 027import org.dllearner.utilities.datastructures.SortedSetTuple; 028import org.semanticweb.owlapi.model.OWLClassExpression; 029import org.semanticweb.owlapi.model.OWLIndividual; 030import org.semanticweb.owlapi.model.OWLObjectIntersectionOf; 031import org.semanticweb.owlapi.model.OWLObjectUnionOf; 032 033import com.google.common.collect.Sets; 034 035/** 036 * Caches results of previous concept evaluation to speed up 037 * further evaluations. Implements a fast evaluation approach, 038 * which tries to infer the covered examples of a given concept 039 * from previous results. 040 * 041 * TODO Under construction. 042 * @author Jens Lehmann 043 * 044 */ 045public class EvaluationCache { 046 047 // maps a concept to a list of individuals it covers 048 private Map<OWLClassExpression,SortedSet<OWLIndividual>> cache; 049 private boolean checkForEqualConcepts = false; 050 051 private SortedSet<OWLIndividual> examples; 052 053 public EvaluationCache(SortedSet<OWLIndividual> examples) { 054 this.examples = examples; 055 cache = new TreeMap<>(); 056 } 057 058 public void put(OWLClassExpression concept, SortedSet<OWLIndividual> individuals) { 059 cache.put(concept, individuals); 060 } 061 062 /** 063 * Determines which examples are instances of a concept. 064 * @param concept the concept 065 * @return A tuple of two sets, where the first element is the 066 * set of individuals belonging to the class and the second element 067 * is the set of individuals not belonging to the class. For all 068 * elements, which are in neither of the sets, the cache cannot 069 * safely determine whether they are concept instances or not. 070 */ 071 public SortedSetTuple<OWLIndividual> infer(OWLClassExpression concept) { 072 if(checkForEqualConcepts) { 073 Set<OWLIndividual> pos = cache.get(concept); 074 Set<OWLIndividual> neg = Sets.difference(examples, pos); 075 return new SortedSetTuple<>(pos, neg); 076 } else { 077 // for a negation NOT C we can only say which concepts are not in it 078 // (those in C), but we cannot say which ones are in NOT C 079 080 // for a conjunction we know that the intersection of instances 081 // of all children belongs to the concept 082 if(concept instanceof OWLObjectIntersectionOf) { 083 handleMultiConjunction((OWLObjectIntersectionOf)concept); 084 // disjunctions are similar to conjunctions but we use union here; 085 // note that there can be instances which are neither in a concept 086 // C nor in a concept D, but in (C OR D) 087 } else if(concept instanceof OWLObjectUnionOf) { 088 List<OWLClassExpression> operands = ((OWLObjectUnionOf) concept).getOperandsAsList(); 089 Set<OWLIndividual> pos = cache.get(operands.get(0)); 090 for (int i = 1; i < operands.size(); i++) { 091 pos = Sets.union(pos, cache.get(operands.get(i))); 092 } 093 // in all other cases we cannot infer anything, so we return an 094 // empty tuple 095 } else { 096 return new SortedSetTuple<>(); 097 } 098 } 099 100 return null; 101 } 102 103 private SortedSetTuple<OWLIndividual> handleMultiConjunction(OWLObjectIntersectionOf mc) { 104 List<OWLClassExpression> operands = mc.getOperandsAsList(); 105 Set<OWLIndividual> pos = cache.get(operands.get(0)); 106 for (int i = 1; i < operands.size(); i++) { 107 pos = Sets.intersection(pos, cache.get(operands.get(i))); 108 } 109 // TODO: handle the case that some children may not be in cache 110 return null; 111 } 112}