class BAggregator(Counter, Aggregator):
- def __init__(self, name):
+ def __init__(self, name, folder):
+ self.folder = folder
Aggregator.__init__(self, name)
Counter.__init__(self)
+ def fold(self):
+ return self.folder(self)
def inc(self, val, ruleix, variables):
self[val] += 1
def dec(self, val, ruleix, variables):
self[val] -= 1
- def fold(self):
- return self
def fromkeys(self, *_):
- assert False, 'bah.'
-
-
-class MultisetAggregator(BAggregator):
- def __init__(self, name, folder):
- self.folder = folder
- BAggregator.__init__(self, name)
- def fold(self):
- return self.folder(self)
+ assert False, "This method should never be called."
class LastEquals(BAggregator):
def dec(self, val, ruleix, variables):
self[ruleix, val] -= 1
def fold(self):
- return max(x for x, cnt in self.items() if cnt > 0)[1]
+ return max(ruleix for ruleix, cnt in self.iteritems() if cnt > 0)[1]
-class SetEquals(Aggregator):
- def __init__(self, name):
- self.set = set([])
- Aggregator.__init__(self, name)
+def user_vars(variables):
+ "Post process the variables past to emit (which passes them to aggregator)."
+ # remove the 'u' prefix on user variables 'uX'
+
+ # Note: We also ignore user variables with an underscore prefix
+
+ return tuple((name[1:], val) for name, val in variables.items() if name.startswith('u') and not name.startswith('u_'))
+
+
+class DictEquals(BAggregator):
+
def inc(self, val, ruleix, variables):
- self.set.add(val)
- def dec(self, val, ruleix, variables):
- self.set.remove(val)
- def fold(self):
- return self.set
- def clear(self):
- self.set.clear()
+ # I think we only want user variables -- XXX: are we guaranteed to have
+ # all of the user variables?
+ vs = user_vars(variables)
+ self[val, vs] += 1
+ def dec(self, val, ruleix, variables):
+ vs = user_vars(variables)
+ self[val, vs] -= 1
+ def fold(self):
+ return list((x[0], dict(x[1])) for x, cnt in self.iteritems() if cnt > 0)
def majority_equals(a):
if len(s):
return reduce(operator.or_, s)
+def set_equals(a):
+ s = {x for x, m in a.iteritems() if m > 0}
+ if len(s):
+ return s
+
+def bag_equals(a):
+ return Counter(a)
+
+
# map names to functions
defs = {
'max=': max_equals,
'|=': b_or_equals,
':-': or_equals,
'majority=': majority_equals,
+ 'set=': set_equals,
+ 'bag=': bag_equals,
}
return None
if name == ':=':
- return LastEquals(name)
-
- elif name == 'bag=':
- return BAggregator(name)
+ return LastEquals(name, folder=None)
- elif name == 'set=':
- return SetEquals(name)
+ elif name == 'dict=':
+ return DictEquals(name, folder=None)
else:
- return MultisetAggregator(name, defs[name])
+ return BAggregator(name, defs[name])
MISC
====
-TODO: create an Interpreter object to hold what is now global state.
+ - TODO: create an Interpreter object to hold what is now global state.
-FIXME: set= is wrong .. needs to keep counts like bag=
+ - FIXME: timv: I think that set= is wrong .. needs to keep counts like bag=
+ - TODO: sorted order of Chart seems to have changed. Check that this changed order
+ makes sense
-This has an absurd parse:
+ - "initializers" aren't just initializers, they are the fully-naive bottom-up
+ inference rules.
+
+ - XXX: we should probably fuse update handlers instead of dispatching to each
+ one independently.
+
+ - TODO: deleting a rule: (1) remove update handlers (2) run initializers in
+ delete mode (3) remove initializers.
+
+ - TODO: hooks from introspection, eval, and prioritization.
+
+ - TODO: Term's should only be aggregated with ``=`` or ``:=``. We should
+ disallow ``a += &b.``
+
+ - TODO: doc tests for Dyna code!
+
+
+
+PARSER
+======
+
+ - Singled quoted strings:
+
+ x += f('result = 5').
- x += f('result = 5').
+ - Nested expressions:
+
+ out(0) dict= _VALUE is (rewrite(X,Y) + rewrite(X,Y,Z)), _VALUE.
+
+ FATAL: Encountered error in input program:
+ Parser error
+ /tmp/tmp.dyna:1:14: error: expected: "."
+ rewrite(X,Y) + rewrite(X,Y,Z)<EOF>
+ ^
What is null?
the LHS of a rule and it's not quoted (i.e. not some new piece of structure).
-===
-
- - "initializers" aren't just initializers, they are the fully-naive bottom-up
- inference rules.
-
- - XXX: we should probably fuse update handlers instead of dispatching to each
- one independently.
-
- - TODO: deleting a rule: (1) remove update handlers (2) run initializers in
- delete mode (3) remove initializers.
-
- - TODO: hooks from introspection, eval, and prioritization.
-
- - TODO: Term's should only be aggregated with ``=`` or ``:=``. We should
- disallow ``a += &b.``
-
-
REPL
====
@property
def prompt(self):
- return 'in(%s) :- ' % self.lineno
+ return ':- ' #% self.lineno
def do_exit(self, _):
readline.write_history_file(self.hist)
print "Queries don't end with a dot."
return
- query = 'out(%s) bag= _VALUE is %s, &result(&(%s), _VALUE).' % (self.lineno, line, line)
+ query = 'out(%s) dict= _VALUE is %s, _VALUE.' % (self.lineno, line)
print blue % query