View Javadoc

1   /* This file is part of the project "Hilbert II" - http://www.qedeq.org" target="alexandria_uri">http://www.qedeq.org
2    *
3    * Copyright 2000-2014,  Michael Meyling <mime@qedeq.org>.
4    *
5    * "Hilbert II" is free software; you can redistribute
6    * it and/or modify it under the terms of the GNU General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU General Public License for more details.
14   */
15  
16  package org.qedeq.kernel.bo.module;
17  
18  import java.util.HashMap;
19  import java.util.Iterator;
20  import java.util.Map;
21  
22  import org.qedeq.kernel.bo.common.ModuleReferenceList;
23  import org.qedeq.kernel.se.base.module.ChangedRule;
24  import org.qedeq.kernel.se.base.module.FunctionDefinition;
25  import org.qedeq.kernel.se.base.module.PredicateDefinition;
26  import org.qedeq.kernel.se.base.module.Rule;
27  import org.qedeq.kernel.se.common.CheckLevel;
28  import org.qedeq.kernel.se.common.IllegalModuleDataException;
29  import org.qedeq.kernel.se.common.ModuleContext;
30  import org.qedeq.kernel.se.common.RuleKey;
31  import org.qedeq.kernel.se.dto.module.NodeVo;
32  import org.qedeq.kernel.se.visitor.QedeqNumbers;
33  
34  /**
35   * Maps labels of an QEDEQ module to their nodes. Knows all label names.
36   *
37   * @author  Michael Meyling
38   */
39  public final class ModuleLabels {
40  
41      /** External QEDEQ module references. */
42      private ModuleReferenceList references = new KernelModuleReferenceList();
43  
44      /** Maps labels to business objects. */
45      private final Map label2Bo = new HashMap();
46  
47      /** Maps labels to context of business objects. */
48      private final Map label2Context = new HashMap();
49  
50      /** Maps predicate identifiers to {@link PredicateDefinition}s. */
51      private final Map predicateDefinitions = new HashMap();
52  
53      /** Maps predicate identifiers to {@link ModuleContext}s. */
54      private final Map predicateContexts = new HashMap();
55  
56      /** Maps function identifiers to {@link FunctionDefinition}s. */
57      private final Map functionDefinitions = new HashMap();
58  
59      /** Maps function identifiers to {@link ModuleContext}s. */
60      private final Map functionContexts = new HashMap();
61  
62      /** Maps rule names to maximum {@link RuleKey}s. (That is rule key with maximum version number). */
63      private final Map ruleMaximum = new HashMap();
64  
65      /** Maps rule keys to {@link Rule}s. */
66      private final Map ruleDefinitions = new HashMap();
67  
68      /** Maps rule keys to {@link ModuleContext}s. */
69      private final Map ruleContexts = new HashMap();
70  
71      /** Maps rule keys to labels. */
72      private final Map ruleLabels = new HashMap();
73  
74      /**
75       * Constructs a new empty module label list.
76       */
77      public ModuleLabels() {
78          // nothing to do
79      }
80  
81      /**
82       * Set list of external QEDEQ module references.
83       *
84       * @param   references  External QEDEQ module references.
85       */
86      public void setModuleReferences(final ModuleReferenceList references) {
87          this.references = references;
88      }
89  
90      /**
91       * Get list of external QEDEQ module references.
92       *
93       * @return  External QEDEQ module references.
94       */
95      public ModuleReferenceList getReferences() {
96          return this.references;
97      }
98  
99      /**
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 }