ModuleLabels.java
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 datathrows 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, (ModuleContextlabel2Context.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 (KernelNodeBolabel2Bo.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 (PredicateDefinitiongetPredicateDefinitions().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 = (ModuleContextpredicateContexts.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 (FunctionDefinitiongetFunctionDefinitions().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 = (ModuleContextfunctionContexts.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 = (RuleKeyruleMaximum.get(definition.getName());
273         if (oldMaximum == null || oldMaximum.getVersion() == null || (key.getVersion() != null
274                 && < 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 = (RuleKeyruleMaximum.get(cr.getName());
295         if (oldMaximum == null || oldMaximum.getVersion() == null || (key.getVersion() != null
296                 && < 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 (RuleKeyruleMaximum.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 (RulegetRuleDefinitions().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 (StringruleLabels.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 = (ModuleContextruleContexts.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 = (KernelNodeBoobj;
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 = (KernelNodeBoobj;
398                 bo.setProved(CheckLevel.UNCHECKED);
399             }
400         }
401     }
402 
403 }