[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