001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002 *
003 * Copyright 2000-2014, Michael Meyling <mime@qedeq.org>.
004 *
005 * "Hilbert II" is free software; you can redistribute
006 * it and/or modify it under the terms of the GNU General Public
007 * License as published by the Free Software Foundation; either
008 * version 2 of the License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 */
015
016 package org.qedeq.kernel.bo.module;
017
018 import java.util.HashMap;
019 import java.util.Iterator;
020 import java.util.Map;
021
022 import org.qedeq.kernel.bo.common.ModuleReferenceList;
023 import org.qedeq.kernel.se.base.module.ChangedRule;
024 import org.qedeq.kernel.se.base.module.FunctionDefinition;
025 import org.qedeq.kernel.se.base.module.PredicateDefinition;
026 import org.qedeq.kernel.se.base.module.Rule;
027 import org.qedeq.kernel.se.common.CheckLevel;
028 import org.qedeq.kernel.se.common.IllegalModuleDataException;
029 import org.qedeq.kernel.se.common.ModuleContext;
030 import org.qedeq.kernel.se.common.RuleKey;
031 import org.qedeq.kernel.se.dto.module.NodeVo;
032 import org.qedeq.kernel.se.visitor.QedeqNumbers;
033
034 /**
035 * Maps labels of an QEDEQ module to their nodes. Knows all label names.
036 *
037 * @author Michael Meyling
038 */
039 public final class ModuleLabels {
040
041 /** External QEDEQ module references. */
042 private ModuleReferenceList references = new KernelModuleReferenceList();
043
044 /** Maps labels to business objects. */
045 private final Map label2Bo = new HashMap();
046
047 /** Maps labels to context of business objects. */
048 private final Map label2Context = new HashMap();
049
050 /** Maps predicate identifiers to {@link PredicateDefinition}s. */
051 private final Map predicateDefinitions = new HashMap();
052
053 /** Maps predicate identifiers to {@link ModuleContext}s. */
054 private final Map predicateContexts = new HashMap();
055
056 /** Maps function identifiers to {@link FunctionDefinition}s. */
057 private final Map functionDefinitions = new HashMap();
058
059 /** Maps function identifiers to {@link ModuleContext}s. */
060 private final Map functionContexts = new HashMap();
061
062 /** Maps rule names to maximum {@link RuleKey}s. (That is rule key with maximum version number). */
063 private final Map ruleMaximum = new HashMap();
064
065 /** Maps rule keys to {@link Rule}s. */
066 private final Map ruleDefinitions = new HashMap();
067
068 /** Maps rule keys to {@link ModuleContext}s. */
069 private final Map ruleContexts = new HashMap();
070
071 /** Maps rule keys to labels. */
072 private final Map ruleLabels = new HashMap();
073
074 /**
075 * Constructs a new empty module label list.
076 */
077 public ModuleLabels() {
078 // nothing to do
079 }
080
081 /**
082 * Set list of external QEDEQ module references.
083 *
084 * @param references External QEDEQ module references.
085 */
086 public void setModuleReferences(final ModuleReferenceList references) {
087 this.references = references;
088 }
089
090 /**
091 * Get list of external QEDEQ module references.
092 *
093 * @return External QEDEQ module references.
094 */
095 public ModuleReferenceList getReferences() {
096 return this.references;
097 }
098
099 /**
100 * Add node with certain id. All numbers should start with 1.
101 *
102 * @param node Add this node.
103 * @param context The node has this context.
104 * @param qedeq Parent module the node is within.
105 * @param data Various number counters.
106 * @throws IllegalModuleDataException The <code>id</code> already exists (perhaps as a label)
107 * or is <code>null</code>.
108 */
109 public final void addNode(final ModuleContext context, final NodeVo node, final KernelQedeqBo qedeq,
110 final QedeqNumbers data) throws IllegalModuleDataException {
111 // don't forget to use the copy constructor because the context could change!
112 final ModuleContext con = new ModuleContext(context);
113 if (null == node.getId()) {
114 throw new IllegalModuleDataException(10001, "An id was not defined.", con, null,
115 null); // LATER mime 20071026: organize exception codes
116 }
117 checkLabelIntern(con, node.getId());
118 label2Context.put(node.getId(), con);
119 final KernelNodeBo nodeBo = new KernelNodeBo(node, context, qedeq, data);
120 label2Bo.put(node.getId(), nodeBo);
121 }
122
123 /**
124 * Add unique label for module.
125 *
126 * @param label Add this label.
127 * @param context With this context.
128 * @throws IllegalModuleDataException The <code>id</code> already exists or is <code>null</code>.
129 */
130 public final void addLabel(final ModuleContext context, final String label)
131 throws IllegalModuleDataException {
132 // don't forget to use the copy constructor because the context could change!
133 final ModuleContext con = new ModuleContext(context);
134 checkLabelIntern(con, label);
135 label2Context.put(label, con);
136 }
137
138 /**
139 * Check that label doesn't exist.
140 *
141 * @param label Check this label.
142 * @param context With this context (already copied).
143 * @throws IllegalModuleDataException The <code>id</code> already exists or is
144 * <code>null</code>.
145 */
146 private final void checkLabelIntern(final ModuleContext context, final String label)
147 throws IllegalModuleDataException {
148 if (label2Context.containsKey(label)) {
149 throw new IllegalModuleDataException(ModuleErrors.LABEL_DEFINED_MORE_THAN_ONCE_CODE,
150 ModuleErrors.LABEL_DEFINED_MORE_THAN_ONCE_TEXT + "\"" + label + "\"",
151 context, (ModuleContext) label2Context.get(label), null);
152 }
153 }
154
155 /**
156 * Get node for given id.
157 *
158 * @param id Label to search node for.
159 * @return Node for given label. Maybe <code>null</code>.
160 */
161 public final KernelNodeBo getNode(final String id) {
162 return (KernelNodeBo) label2Bo.get(id);
163 }
164
165 /**
166 * Is the given label id a node? Local node labels are not considered.
167 *
168 * @param id Label to search node for.
169 * @return Is this an node of this module?
170 */
171 public final boolean isNode(final String id) {
172 return label2Bo.get(id) != null;
173 }
174
175 /**
176 * Is the given label id a module?
177 *
178 * @param id Label to search module reference for.
179 * @return Is this an module reference id?
180 */
181 public final boolean isModule(final String id) {
182 return label2Bo.get(id) == null && label2Context.get(id) != null;
183 }
184
185 /**
186 * Add predicate definition. If such a definition already exists it is overwritten.
187 *
188 * @param definition Definition to add.
189 * @param context Here the definition stands.
190 */
191 public void addPredicate(final PredicateDefinition definition, final ModuleContext context) {
192 final String identifier = definition.getName() + "_" + definition.getArgumentNumber();
193 getPredicateDefinitions().put(identifier, definition);
194 predicateContexts.put(identifier, new ModuleContext(context));
195 }
196
197 /**
198 * Get predicate definition.
199 *
200 * @param name Predicate name.
201 * @param argumentNumber Number of predicate arguments.
202 * @return Definition. Might be <code>null</code>.
203 */
204 public PredicateDefinition getPredicate(final String name, final int argumentNumber) {
205 return (PredicateDefinition) getPredicateDefinitions().get(name + "_" + argumentNumber);
206 }
207
208 /**
209 * Get predicate context. This is only a copy.
210 *
211 * @param name Predicate name.
212 * @param argumentNumber Number of predicate arguments.
213 * @return Module context. Might be <code>null</code>.
214 */
215 public ModuleContext getPredicateContext(final String name, final int argumentNumber) {
216 final ModuleContext context = (ModuleContext) predicateContexts.get(name + "_" + argumentNumber);
217 if (context != null) {
218 return new ModuleContext(context);
219 }
220 return null;
221 }
222
223 /**
224 * Add function definition. If such a definition already exists it is overwritten.
225 *
226 * @param definition Definition to add.
227 * @param context Here the definition stands.
228 */
229 public void addFunction(final FunctionDefinition definition, final ModuleContext context) {
230 final String identifier = definition.getName() + "_" + definition.getArgumentNumber();
231 getFunctionDefinitions().put(identifier, definition);
232 functionContexts.put(identifier, new ModuleContext(context));
233 }
234
235 /**
236 * Get function definition.
237 *
238 * @param name Function name.
239 * @param argumentNumber Number of function arguments.
240 * @return Definition. Might be <code>null</code>.
241 */
242 public FunctionDefinition getFunction(final String name, final int argumentNumber) {
243 return (FunctionDefinition) getFunctionDefinitions().get(name + "_" + argumentNumber);
244 }
245
246 /**
247 * Get function context. This is only a copy.
248 *
249 * @param name Function name.
250 * @param argumentNumber Number of function arguments.
251 * @return Module context. Might be <code>null</code>.
252 */
253 public ModuleContext getFunctionContext(final String name, final int argumentNumber) {
254 final ModuleContext context = (ModuleContext) functionContexts.get(name + "_" + argumentNumber);
255 if (context != null) {
256 return new ModuleContext(context);
257 }
258 return null;
259 }
260
261 /**
262 * Add rule definition. If such a definition already exists it is overwritten. Also sets the
263 * key for the maximum rule version.
264 *
265 * @param label Node label the rule is defined within.
266 * @param definition Definition to add.
267 * @param context Here the definition stands.
268 */
269 public void addRule(final String label, final Rule definition, final ModuleContext context) {
270 final RuleKey key = new RuleKey(definition.getName(), definition.getVersion());
271 ruleLabels.put(key, label);
272 final RuleKey oldMaximum = (RuleKey) ruleMaximum.get(definition.getName());
273 if (oldMaximum == null || oldMaximum.getVersion() == null || (key.getVersion() != null
274 && 0 < key.getVersion().compareTo(oldMaximum.getVersion()))) {
275 ruleMaximum.put(definition.getName(), key);
276 }
277 getRuleDefinitions().put(key, definition);
278 ruleContexts.put(key, new ModuleContext(context));
279 }
280
281 /**
282 * Add rule definition. If such a definition already exists it is overwritten. Also sets the
283 * key for the maximum rule version.
284 *
285 * @param label Node label the rule is defined within.
286 * @param definition Here we have the new rule.
287 * @param cr New modification to an old rule.
288 * @param context Here the definition stands.
289 */
290 public void addChangedRule(final String label, final Rule definition, final ChangedRule cr,
291 final ModuleContext context) {
292 final RuleKey key = new RuleKey(cr.getName(), cr.getVersion());
293 ruleLabels.put(key, label);
294 final RuleKey oldMaximum = (RuleKey) ruleMaximum.get(cr.getName());
295 if (oldMaximum == null || oldMaximum.getVersion() == null || (key.getVersion() != null
296 && 0 < key.getVersion().compareTo(oldMaximum.getVersion()))) {
297 ruleMaximum.put(cr.getName(), key);
298 }
299 getRuleDefinitions().put(key, definition);
300 ruleContexts.put(key, new ModuleContext(context));
301 }
302
303 /**
304 * Get rule key with maximum rule version.
305 *
306 * @param ruleName Get maximum rule key for rule with this name.
307 * @return Rule key with maximum rule version. Might be <code>null</code>.
308 */
309 public RuleKey getRuleKey(final String ruleName) {
310 return (RuleKey) ruleMaximum.get(ruleName);
311 }
312
313 /**
314 * Get rule definition.
315 *
316 * @param key Rule key.
317 * @return Definition. Might be <code>null</code>.
318 */
319 public Rule getRule(final RuleKey key) {
320 return (Rule) getRuleDefinitions().get(key);
321 }
322
323 /**
324 * Get node id of rule key.
325 *
326 * @param key Rule key.
327 * @return Label. Might be <code>null</code>.
328 */
329 public String getRuleLabel(final RuleKey key) {
330 return (String) ruleLabels.get(key);
331 }
332
333 /**
334 * Get rule context. This is only a copy.
335 *
336 * @param key Rule key.
337 * @return Module context. Might be <code>null</code>.
338 */
339 public ModuleContext getRuleContext(final RuleKey key) {
340 final ModuleContext context = (ModuleContext) ruleContexts.get(key);
341 if (context != null) {
342 return new ModuleContext(context);
343 }
344 return null;
345 }
346
347 /**
348 * Get mapping of predicate definitions.
349 *
350 * @return Mapping of predicate definitions.
351 */
352 public Map getPredicateDefinitions() {
353 return this.predicateDefinitions;
354 }
355
356 /**
357 * Get mapping of function definitions.
358 *
359 * @return Mapping of function definitions.
360 */
361 public Map getFunctionDefinitions() {
362 return this.functionDefinitions;
363 }
364
365 /**
366 * Get mapping of rule definitions.
367 *
368 * @return Mapping of rule definitions. Key is {@link RuleKey}, value is {@link Rule}.
369 */
370 public Map getRuleDefinitions() {
371 return this.ruleDefinitions;
372 }
373
374 /**
375 * Set the state of all nodes to UNCHECKED for being well formed and proved.
376 */
377 public void resetNodesToWellFormedUnchecked() {
378 final Iterator i = label2Bo.entrySet().iterator();
379 while (i.hasNext()) {
380 Object obj = i.next();
381 if (obj instanceof KernelNodeBo) {
382 KernelNodeBo bo = (KernelNodeBo) obj;
383 bo.setWellFormed(CheckLevel.UNCHECKED);
384 bo.setProved(CheckLevel.UNCHECKED);
385 }
386 }
387 }
388
389 /**
390 * Set the state of all nodes to UNCHECKED for proved.
391 */
392 public void resetNodesToProvedUnchecked() {
393 final Iterator i = label2Bo.entrySet().iterator();
394 while (i.hasNext()) {
395 Object obj = i.next();
396 if (obj instanceof KernelNodeBo) {
397 KernelNodeBo bo = (KernelNodeBo) obj;
398 bo.setProved(CheckLevel.UNCHECKED);
399 }
400 }
401 }
402
403 }
|