Passed
Push — master ( e0b928...937cde )
by Julian
03:04 queued 12s
created

getAxiomsWithClassesOnTheLeft(Set,OptMap)   A

Complexity

Conditions 2

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
c 0
b 0
f 0
dl 0
loc 10
rs 10
1
/*
2
 *
3
 * Copyright (C) 2009-2017 Julian Mendez
4
 *
5
 *
6
 * This file is part of jcel.
7
 *
8
 *
9
 * The contents of this file are subject to the GNU Lesser General Public License
10
 * version 3
11
 *
12
 *
13
 * This program is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Lesser General Public License as published by
15
 * the Free Software Foundation, either version 3 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU Lesser General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU Lesser General Public License
24
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25
 *
26
 *
27
 * Alternatively, the contents of this file may be used under the terms
28
 * of the Apache License, Version 2.0, in which case the
29
 * provisions of the Apache License, Version 2.0 are applicable instead of those
30
 * above.
31
 *
32
 *
33
 * Licensed under the Apache License, Version 2.0 (the "License");
34
 * you may not use this file except in compliance with the License.
35
 * You may obtain a copy of the License at
36
 *
37
 *     http://www.apache.org/licenses/LICENSE-2.0
38
 *
39
 * Unless required by applicable law or agreed to in writing, software
40
 * distributed under the License is distributed on an "AS IS" BASIS,
41
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42
 * See the License for the specific language governing permissions and
43
 * limitations under the License.
44
 *
45
 */
46
47
package de.tudresden.inf.lat.jcel.core.algorithm.module;
48
49
import java.util.Collection;
50
import java.util.HashMap;
51
import java.util.HashSet;
52
import java.util.Optional;
53
import java.util.Set;
54
import java.util.TreeSet;
55
56
import de.tudresden.inf.lat.jcel.coreontology.axiom.NormalizedIntegerAxiom;
57
import de.tudresden.inf.lat.jcel.coreontology.datatype.IntegerAxiom;
58
import de.tudresden.inf.lat.util.map.OptMap;
59
import de.tudresden.inf.lat.util.map.OptMapImpl;
60
61
/**
62
 * An object of this class is a module extractor, i.e. it can extract a subset
63
 * of axioms that are relevant to answer a query.
64
 * 
65
 * @author Julian Mendez
66
 */
67
public class DefaultModuleExtractor {
68
69
	/**
70
	 * Constructs a new module extractor.
71
	 */
72
	public DefaultModuleExtractor() {
73
	}
74
75
	/**
76
	 * Returns a map that relates a class with the set of axioms where this
77
	 * class occurs on the left side of the axiom
78
	 * 
79
	 * @param normalizedAxioms
80
	 *            normalized axioms
81
	 * @return a map that relates a class with the set of axioms where this
82
	 *         class occurs on the left side of the axiom
83
	 */
84
	OptMap<Integer, Set<DefaultIdentifierCollector>> buildMapOfAxioms(
85
			Set<DefaultIdentifierCollector> normalizedAxioms) {
86
		OptMap<Integer, Set<DefaultIdentifierCollector>> map = new OptMapImpl<>(new HashMap<>());
87
		normalizedAxioms.forEach(axiom -> {
88
			Set<Integer> classesOnTheLeft = axiom.getClassesOnTheLeft();
89
			classesOnTheLeft.forEach(classId -> {
90
				Optional<Set<DefaultIdentifierCollector>> optValue = map.get(classId);
91
				if (!optValue.isPresent()) {
92
					optValue = Optional.of(new HashSet<>());
93
					map.put(classId, optValue.get());
94
				}
95
				optValue.get().add(axiom);
96
			});
97
		});
98
		return map;
99
	}
100
101
	Set<NormalizedIntegerAxiom> getAxiomsWithoutEntitiesOnTheLeft(Set<DefaultIdentifierCollector> axioms) {
102
		Set<NormalizedIntegerAxiom> ret = new HashSet<>();
103
		axioms.forEach(axiom -> {
104
			if (axiom.getClassesOnTheLeft().isEmpty() && axiom.getObjectPropertiesOnTheLeft().isEmpty()) {
105
				ret.add(axiom.getAxiom());
106
			}
107
		});
108
		return ret;
109
	}
110
111
	Set<DefaultIdentifierCollector> getAxiomsWithClassesOnTheLeft(Set<Integer> classesToVisit,
112
			OptMap<Integer, Set<DefaultIdentifierCollector>> map) {
113
		Set<DefaultIdentifierCollector> ret = new HashSet<>();
114
		classesToVisit.forEach(classId -> {
115
			Optional<Set<DefaultIdentifierCollector>> optNewAxioms = map.get(classId);
116
			if (optNewAxioms.isPresent()) {
117
				ret.addAll(optNewAxioms.get());
118
			}
119
		});
120
		return ret;
121
	}
122
123
	Set<Integer> getEntities(IntegerAxiom axiom) {
124
		Set<Integer> ret = new TreeSet<>();
125
		ret.addAll(axiom.getClassesInSignature());
126
		ret.addAll(axiom.getObjectPropertiesInSignature());
127
		ret.addAll(axiom.getIndividualsInSignature());
128
		ret.addAll(axiom.getDataPropertiesInSignature());
129
		ret.addAll(axiom.getDatatypesInSignature());
130
		return ret;
131
	}
132
133
	/**
134
	 * Returns a module, i.e. a subset of axioms relevant to answer a query.
135
	 * 
136
	 * @param setOfAxioms
137
	 *            set of axioms
138
	 * @param setOfClasses
139
	 *            set of classes
140
	 * @return a module, i.e. a subset of axioms relevant to answer a query
141
	 */
142
	public Module extractModule(Collection<NormalizedIntegerAxiom> setOfAxioms, Set<Integer> setOfClasses) {
143
144
		Set<NormalizedIntegerAxiom> newAxioms = new HashSet<>();
145
146
		Set<DefaultIdentifierCollector> axioms = new HashSet<>();
147
		setOfAxioms.forEach(axiom -> axioms.add(new DefaultIdentifierCollector(axiom)));
148
149
		newAxioms.addAll(getAxiomsWithoutEntitiesOnTheLeft(axioms));
150
151
		OptMap<Integer, Set<DefaultIdentifierCollector>> map = buildMapOfAxioms(axioms);
152
153
		Set<Integer> visitedClasses = new TreeSet<>();
154
		Set<Integer> classesToVisit = new TreeSet<>();
155
		classesToVisit.addAll(setOfClasses);
156
		int resultSize = -1;
157
		while (newAxioms.size() > resultSize) {
158
			resultSize = newAxioms.size();
159
160
			Set<DefaultIdentifierCollector> axiomsToVisit = getAxiomsWithClassesOnTheLeft(classesToVisit, map);
161
			visitedClasses.addAll(classesToVisit);
162
			classesToVisit.clear();
163
164
			axiomsToVisit.forEach(axiom -> {
165
				classesToVisit.addAll(axiom.getClassesOnTheRight());
166
				newAxioms.add(axiom.getAxiom());
167
			});
168
			classesToVisit.removeAll(visitedClasses);
169
		}
170
171
		Set<Integer> entities = new TreeSet<>();
172
		entities.addAll(visitedClasses);
173
		newAxioms.forEach(axiom -> entities.addAll(getEntities(axiom)));
174
		return new Module(entities, newAxioms);
175
	}
176
177
}
178