]> hydra-www.ietfng.org Git - dyna2/commitdiff
Queries return variable assignments
authortimv <tim.f.vieira@gmail.com>
Mon, 3 Jun 2013 15:45:17 +0000 (11:45 -0400)
committertimv <tim.f.vieira@gmail.com>
Mon, 3 Jun 2013 15:45:17 +0000 (11:45 -0400)
:- query rewrite(X,Y)
(1, {'Y': 'ate', 'X': 'V'})
(1, {'Y': 'caviar', 'X': 'N'})
(1, {'Y': 'spoon', 'X': 'N'})
(1, {'Y': 'the', 'X': 'Det'})
(1, {'Y': 'with', 'X': 'P'})
(1, {'Y': 'a', 'X': 'Det'})
(1, {'Y': 'Papa', 'X': 'NP'})

Added `dict=` (name might changed) and aggregator which stores user variable
assignments. [This is what is used for answering queries like the one above.qq]

src/Dyna/Backend/Python/defn.py
src/Dyna/Backend/Python/interpreter.py

index f3267024f9c79d1b56d5deeabf59f2652ae020d0..8362854bea6a053c1eaac5727cd544b99a7ba29b 100644 (file)
@@ -19,25 +19,18 @@ class Aggregator(object):
 
 
 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):
@@ -46,23 +39,32 @@ 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):
@@ -109,6 +111,15 @@ def b_or_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,
@@ -121,6 +132,8 @@ defs = {
     '|=': b_or_equals,
     ':-': or_equals,
     'majority=': majority_equals,
+    'set=': set_equals,
+    'bag=': bag_equals,
 }
 
 
@@ -131,13 +144,10 @@ def aggregator(name):
         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])
index c429896c0515b732ca3c91cdb8b88323b1b76d2b..1d552e52a818013afbc15f45b7f5d726f9646b37 100644 (file)
@@ -5,15 +5,48 @@
 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?
@@ -38,23 +71,6 @@ Warnings/lint checking
    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
 ====
 
@@ -511,7 +527,7 @@ class REPL(cmd.Cmd, object):
 
     @property
     def prompt(self):
-        return 'in(%s) :- ' % self.lineno
+        return ':- ' #% self.lineno
 
     def do_exit(self, _):
         readline.write_history_file(self.hist)
@@ -596,7 +612,7 @@ class REPL(cmd.Cmd, object):
             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