[Formed-commits] r314 - in trunk: . formed/formed/plugins/modify

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Fri Mar 13 16:58:56 CET 2009


Author: teichmann
Date: 2009-03-13 16:58:54 +0100 (Fri, 13 Mar 2009)
New Revision: 314

Modified:
   trunk/ChangeLog
   trunk/formed/formed/plugins/modify/rules.py
Log:
generate date sequence rules.



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2009-03-13 09:50:05 UTC (rev 313)
+++ trunk/ChangeLog	2009-03-13 15:58:54 UTC (rev 314)
@@ -1,5 +1,9 @@
-2009-03-13	Torsten Irländer <torsten.irlaender at intevation.de>
+2009-03-13	Sascha L. Teichmann <teichmann at intevation.de>
 
+	* formed/formed/plugins/modify/rules.py: generate date sequence rules.
+
+2009-03-13	Sascha L. Teichmann <teichmann at intevation.de>
+
 	* formed/formed/model/exprtree.py: New tree based expression engine.
 
 	* formed/formed/model/__init__.py, formed/formed/model/data.py:

Modified: trunk/formed/formed/plugins/modify/rules.py
===================================================================
--- trunk/formed/formed/plugins/modify/rules.py	2009-03-13 09:50:05 UTC (rev 313)
+++ trunk/formed/formed/plugins/modify/rules.py	2009-03-13 15:58:54 UTC (rev 314)
@@ -13,6 +13,63 @@
 
 import formed.model.data as data
 
+import re
+import sys
+
+ORDER_RE = re.compile("([^;]*);(.*)")
+
+DATE_RULE_VALUE = \
+u"Das '%(b_desc)s' darf zeitlich nicht nach '%(a_desc)s' liegen."
+
+DATE_RULE_DESC = \
+u"'%(a)s' muss vor '%(b)s' liegen."
+
+DATE_RULE_EXPR = \
+u"$%(a)s isset $%(a)s known and $%(b)s isset $%(b)s known and and $%(a)s $%(b)s > and not"
+
+
+def traverse_recursive(current, graph, chain, found):
+
+    xchain = chain[:]
+    xchain.append(current)
+
+    succs = graph[current][1]
+
+    if not succs:
+        found(xchain)
+        return
+
+    for succ in succs:
+        if succ in chain:
+            found(xchain)
+        else:
+            traverse_recursive(succ, graph, xchain[:], found)
+
+def all_paths(graph):
+
+    # find all starting node (no preds)
+
+    starts = []
+    for name, preds_succs in graph.iteritems():
+        if not preds_succs[0]:
+            starts.append(name)
+
+    paths = []
+
+    def found(chain):
+        paths.append(chain)
+
+    for start in starts:
+        traverse_recursive(start, graph, [], found)
+
+    return paths
+
+def all_pairs(path):
+    N = len(path)
+    for i in xrange(N):
+        for j in xrange(i + 1, N):
+            yield (path[i], path[j])
+
 class GenerateRequiredRules(Filter):
 
     def getMenuName(self):
@@ -21,15 +78,101 @@
     def getDescription(self):
         return u"Generate rules for fields that are required."
 
-    def filterDocument(self, main):
+    def generateDateSequenceRules(self, main):
         document = main.getDocument()
         mode     = main.getSelectedMode()
         allModes = main.getAllModes()
 
+        all_dates = list(document.findAllByClass(data.DateLeaf, mode, allModes))
+
+        date_graph = dict([(d.getName(), (set(), set())) for d in all_dates])
+
+        for date in all_dates:
+            order = date.getOrder()
+            m = ORDER_RE.match(order)
+            if not m: continue
+
+            name = date.getName()
+
+            preds, succs = m.group(1), m.group(2)
+            p_set, s_set = date_graph[name]
+
+            for pred in preds.split(","):
+                pred = pred.strip()
+                if not pred: continue
+                try:
+                    # add current to succs of pred
+                    date_graph[pred][1].add(name)
+                except KeyError:
+                    print >> sys.stderr, "pred date '%s' not found" % pred
+                    continue
+                # add to preds
+                p_set.add(pred)
+
+            for succ in succs.split(","):
+                succ = succ.strip()
+                if not succ: continue
+                try:
+                    # add current to preds of succ
+                    date_graph[succ][0].add(name)
+                except KeyError:
+                    print >> sys.stderr, "succ date '%s' not found" % pred
+                    continue
+                # add to succs
+                s_set.add(succ)
+
+        # consolidate date graph
+        for name, preds_succs in date_graph.iteritems():
+            for pred in preds_succs[0]:
+                date_graph[pred][1].add(name)
+            for succ in preds_succs[1]:
+                date_graph[succ][0].add(name)
+
+        # eliminate isolated dates
+        to_be_deleted = []
+        for name, preds_succs in date_graph.iteritems():
+            if not preds_succs[0] and not preds_succs[1]:
+                print >> sys.stderr, \
+                    "Date '%s' is not neighbored to other dates." % name
+                to_be_deleted.append(name)
+
+        for name in to_be_deleted:
+            del date_graph[name]
+
+        # generate all paths from start to end dates.
+        paths = all_paths(date_graph)
+
+        # build all pairs of dates to be checked
+        pairs = set()
+        for path in paths:
+            for pair in all_pairs(path):
+                pairs.add(pair)
+
+        dates = dict([(d.getName(), d) for d in all_dates])
+
+        for idx, pair in enumerate(pairs):
+            rule = data.RuleLeaf()
+            rule.setName("date-sequence-rule-%d" % idx)
+            d1, d2 = dates[pair[0]], dates[pair[1]]
+            rule.setValue(DATE_RULE_VALUE % { 
+                'a_desc': d1.getDescription(),
+                'b_desc': d2.getDescription()})
+            param = { 'a': pair[0], 'b': pair[1] }
+            rule.setDescription(DATE_RULE_DESC % param)
+            rule.setExpr(DATE_RULE_EXPR % param)
+
+            d1.getParent().addChild(rule)
+
+    def generateRequiredRules(self, main):
+        document = main.getDocument()
+        mode     = main.getSelectedMode()
+        allModes = main.getAllModes()
+
         collector = data.WidgetCollector()
         document.visit(collector.visitor)
         widgets = collector.widgets
         # Get all rules in document
+
         known_fields = set()
         for r in document.findAllByClass(data.RuleLeaf, mode, allModes):
             known_fields = known_fields.union(r.getExpr().getDependencies())
@@ -55,5 +198,9 @@
                 parent = w.getParent()
                 parent.addChild(rule)
 
+    def filterDocument(self, main):
+        self.generateRequiredRules(main)
+        self.generateDateSequenceRules(main)
+
 # vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 enc=utf-8 :
 



More information about the Formed-commits mailing list