]> hydra-www.ietfng.org Git - dyna2/commitdiff
pretty print lists, which are still cons/nil under the hood.
authorTim Vieira <tim.f.vieira@gmail.com>
Fri, 28 Jun 2013 19:38:19 +0000 (15:38 -0400)
committerTim Vieira <tim.f.vieira@gmail.com>
Fri, 28 Jun 2013 19:38:19 +0000 (15:38 -0400)
Moved some library functions in into stdlib.py

Moved attempt at unifiction into it's own file... it will probably be deleted
entirely in favor of something else (it's unused at the moment).

src/Dyna/Backend/Python/chart.py
src/Dyna/Backend/Python/interpreter.py
src/Dyna/Backend/Python/stdlib.py [new file with mode: 0644]
src/Dyna/Backend/Python/term.py
src/Dyna/Backend/Python/unify.py [new file with mode: 0644]
test/repl/load.dyna

index 7b90ad6f680a9191e096ee91e9839b23a60f9d01..0b14aeb17d17062476c958d3b93bbfa75c7ed9e4 100644 (file)
@@ -1,6 +1,7 @@
 from collections import defaultdict
 from defn import aggregator
-from term import Term, _repr
+from term import Term
+from utils import _repr
 
 
 class Chart(object):
index f55ddbbe4c7e0f4e21cdb32cb2d95a43284fb49c..d717a5a3753820302bd845524d32edc5c6fcbc20 100644 (file)
@@ -196,40 +196,18 @@ from path import path
 
 import load, post
 
-from chart import Chart, Term, _repr
+from term import Term, Cons, Nil
+from chart import Chart
 from defn import aggregator
 from utils import ip, red, green, blue, magenta, yellow, parse_attrs, \
-    ddict, dynac, read_anf, strip_comments
+    ddict, dynac, read_anf, strip_comments, _repr
 
 from prioritydict import prioritydict
 from config import dotdynadir
 from errors import notimplemented, enable_crash_handler, \
     DynaInitializerException, DynaCompilerError
 
-try:
-    from numpy import log, exp, sqrt
-    from numpy.random import uniform
-except ImportError:                       # XXX: should probably issue a warning.
-    from math import log, exp, sqrt
-    from random import random as _random
-    def uniform(a=0, b=1):
-        return _random() * (b - a) + a
-
-import re
-def split(s, delim='\s+'):
-    return re.split(delim, s)
-
-# used as a work around to bring arbitrary python functions into dyna
-def pycall(name, *args):
-    x = eval(name)(*args)
-    if isinstance(x, list):
-        return todynalist(x)
-    return x
-
-def todynalist(x):
-    if not x:
-        return Term('nil/0', ())
-    return Term('cons/2', (x[0], todynalist(x[1:])))
+from stdlib import *
 
 
 class Rule(object):
@@ -362,11 +340,17 @@ class Interpreter(object):
 
     def build(self, fn, *args):
         # TODO: codegen should handle true/0 is True and false/0 is False
-        if fn == "true/0":
+        if fn == 'true/0':
             return True
-        if fn == "false/0":
+        if fn == 'false/0':
             return False
 
+        if fn == 'cons/2':
+            return Cons(*args)
+        if fn == 'nil/0':
+            return Nil
+
+
         # FIXME:
         if fn not in self.agg_name:
             # item has no aggregator (e.g purely structural stuff) -- what
diff --git a/src/Dyna/Backend/Python/stdlib.py b/src/Dyna/Backend/Python/stdlib.py
new file mode 100644 (file)
index 0000000..1da99ad
--- /dev/null
@@ -0,0 +1,26 @@
+from term import Term, Cons, Nil
+
+try:
+    from numpy import log, exp, sqrt
+    from numpy.random import uniform
+except ImportError:                       # XXX: should probably issue a warning.
+    from math import log, exp, sqrt
+    from random import random as _random
+    def uniform(a=0, b=1):
+        return _random() * (b - a) + a
+
+import re
+def split(s, delim='\s+'):
+    return re.split(delim, s)
+
+# used as a work around to bring arbitrary python functions into dyna
+def pycall(name, *args):
+    x = eval(name)(*args)
+    if isinstance(x, list):
+        return todynalist(x)
+    return x
+
+def todynalist(x):
+    if not x:
+        return Nil
+    return Cons(x[0], todynalist(x[1:]))
index 79b96b26e97ac61f4608a808076dfed97cc9e3ac..f0846a3f00c0ad3cac798c7f40c451871a3081be 100644 (file)
@@ -45,191 +45,29 @@ class Term(object):
 
     __add__ = __sub__ = __mul__ = notimplemented
 
-#    def subst(self, v):
-#        if self in v:
-#            return v[self]
-#        # TODO: this should go thru the Chart
-#        return Term(self.fn, tuple(x if isconst(x) else x.subst(v) for x in self.args))
-
-
-def isconst(x):
-    return not isinstance(x, (Variable, Term))
-
-
-
-class Variable(object):
-
-    def __init__(self, name):
-        self.fn = name
-        self._val = None
-
-    @property
-    def value(self):
-        return self.root._val
-
-    @property
-    def root(self):
-        if isinstance(self._val, Variable):
-            return self._val.root
-        else:
-            return self
-
-    @value.setter
-    def value(self, v):
-        self._val = v
-
-#    def __repr__(self, other):
-#        if self.value is None:
-#            return self.fn + '=' + self.root.fn
-#        else:
-#            return _repr(self.value)
-#            return '%s=%s' % (self.fn, _repr(self.value))
 
+class Cons(Term):
+    def __init__(self, head, tail):
+        self.head = head
+        self.tail = tail
+        assert isinstance(tail, (Cons, _Nil)), tail
+        Term.__init__(self, 'cons/2', (head, tail))
+    def tolist(self):
+        return [self.head] + self.tail.tolist()
     def __repr__(self):
-        if self.value is None:
-            return self.root.fn
-        else:
-            return _repr(self.value)
-
+        return repr(self.tolist())
     def __eq__(self, other):
-        if isinstance(other, Variable):
-
-            if self.root is other.root:
-                return True
-
-            if self.value is not None:
-                return other.value == self.value
-
+        try:
+            return self.tolist() == other.tolist()
+        except AttributeError:
             return False
 
-        else:
-            return other == self.value
-
-#    def subst(self, v):
-#        if self in v:
-#            return v[self]
-#        return self
-
-
-def extend(v, x, t):
-    """
-    Extend valuation v with v[x] = t
-    """
-    v1 = v.copy()
-    v1[x] = t
-#    x.value = t
-    return v1
-
-
-def occurs_check(v, t):
-    """
-    Return true if variable ``v`` occurs anywhere in term ``t``."
-
-    >>> [f,g,h,X,Y,Z] = map(symbol, ['f','g','h','X','Y','Z'])
-
-    >>> occurs_check(X, f(g(h(X,Y),X)))
-    True
-
-    >>> occurs_check(Z, f(g(h(X,Y),X)))
-    False
-
-    """
-    if v == t:
-        return True
-    elif isinstance(t, Term):
-        return any(occurs_check(v, x) for x in t.args)
-    return False
-
-
-def unify_var(x, t, v):
-    """
-    Test if v can be extended with v[x] = t;
-    In that case return the extention
-    Else return None
-    """
-    if x in v:
-        return _unify(v[x], t, v)
-    elif occurs_check(x, t):
-        return None
-    else:
-        return extend(v, x, t)
-
-
-def unify(x,y):
-    return _unify(x,y,{})
-
-
-def _unify(x,y,v):
-    """
-    Find one valuation extending v and unifying x with y
-    """
-    if v is None:
-        return None
-    elif x == y:
-        return v
-    elif isinstance(x, Variable):
-        return unify_var(x, y, v)
-    elif isinstance(y, Variable):
-        return unify_var(y, x, v)
-    elif isinstance(x, Term) and isinstance(y, Term) and x.fn == y.fn:
-        if len(x.args) == len(y.args):
-            for a, b in zip(x.args, y.args):
-                v = _unify(a, b, v)
-            return v
-
-
-def symbol(name):
-    if name[0].isupper():
-        return Variable(name)
-
-    class Symbol(object):
-        def __init__(self, name):
-            self.name = name
-        def __call__(self, *args):
-            return Term('%s/%s' % (self.name, len(args)), args)
-        def __str__(self):
-            return self.name
-
-    return Symbol(name)
-
+class _Nil(Term):
+    def __init__(self):
+        Term.__init__(self, 'nil/0', ())
+    def tolist(self):
+        return []
+    def __repr__(self):
+        return '[]'
 
-#if __name__ == '__main__':
-#
-#    [f,g,h] = map(symbol, ['f','g','h'])
-#    vs = [X,Y,Z] = map(symbol, ['X','Y','Z'])
-#
-#    def test(a, b):
-#        for v in vs:
-#            v.value = None
-#
-#        print
-#        print 'unify %s and %s' % (a,b)
-#        s = unify(a, b)
-#        print '->', s
-#        if s is None:
-#            return
-#
-#        # apply new bindings
-#        for v, now in s.iteritems():
-#            print '%s [was: %r, now: %r]' % (v, v.value, now)
-#            v.value = now
-#
-#        print a, b
-#        assert a == b
-#        assert repr(a) == repr(b), [a,b]
-#
-#        for v in vs:
-#            v.value = None
-#
-#    test(f(X), f(g(h(X,Y),X)))
-#    test(f(X), f(g(h(Z),"foo")))
-#    test(f(X, Y), f("cat", 123))
-#    test(f(X), f(X))
-#    test(f(X), f(Y))
-#    test("abc", "abc")
-#
-#    Z.value = 3
-#    Y.value = Z
-#    X.value = Y
-#    print [X,Y,Z]
-#    assert X.value == Y.value == Z.value == 3
+Nil = _Nil()
diff --git a/src/Dyna/Backend/Python/unify.py b/src/Dyna/Backend/Python/unify.py
new file mode 100644 (file)
index 0000000..c5f6f6f
--- /dev/null
@@ -0,0 +1,183 @@
+from term import Term
+from utils import _repr
+
+def isconst(x):
+    return not isinstance(x, (Variable, Term))
+
+
+class Variable(object):
+
+    def __init__(self, name):
+        self.fn = name
+        self._val = None
+
+    @property
+    def value(self):
+        return self.root._val
+
+    @property
+    def root(self):
+        if isinstance(self._val, Variable):
+            return self._val.root
+        else:
+            return self
+
+    @value.setter
+    def value(self, v):
+        self._val = v
+
+#    def __repr__(self, other):
+#        if self.value is None:
+#            return self.fn + '=' + self.root.fn
+#        else:
+#            return _repr(self.value)
+#            return '%s=%s' % (self.fn, _repr(self.value))
+
+    def __repr__(self):
+        if self.value is None:
+            return self.root.fn
+        else:
+            return _repr(self.value)
+
+    def __eq__(self, other):
+        if isinstance(other, Variable):
+
+            if self.root is other.root:
+                return True
+
+            if self.value is not None:
+                return other.value == self.value
+
+            return False
+
+        else:
+            return other == self.value
+
+#    def subst(self, v):
+#        if self in v:
+#            return v[self]
+#        return self
+
+
+def extend(v, x, t):
+    """
+    Extend valuation v with v[x] = t
+    """
+    v1 = v.copy()
+    v1[x] = t
+#    x.value = t
+    return v1
+
+
+def occurs_check(v, t):
+    """
+    Return true if variable ``v`` occurs anywhere in term ``t``."
+
+    >>> [f,g,h,X,Y,Z] = map(symbol, ['f','g','h','X','Y','Z'])
+
+    >>> occurs_check(X, f(g(h(X,Y),X)))
+    True
+
+    >>> occurs_check(Z, f(g(h(X,Y),X)))
+    False
+
+    """
+    if v == t:
+        return True
+    elif isinstance(t, Term):
+        return any(occurs_check(v, x) for x in t.args)
+    return False
+
+
+def unify_var(x, t, v):
+    """
+    Test if v can be extended with v[x] = t;
+    In that case return the extention
+    Else return None
+    """
+    if x in v:
+        return _unify(v[x], t, v)
+    elif occurs_check(x, t):
+        return None
+    else:
+        return extend(v, x, t)
+
+
+def unify(x,y):
+    return _unify(x,y,{})
+
+
+def _unify(x,y,v):
+    """
+    Find one valuation extending v and unifying x with y
+    """
+    if v is None:
+        return None
+    elif x == y:
+        return v
+    elif isinstance(x, Variable):
+        return unify_var(x, y, v)
+    elif isinstance(y, Variable):
+        return unify_var(y, x, v)
+    elif isinstance(x, Term) and isinstance(y, Term) and x.fn == y.fn:
+        if len(x.args) == len(y.args):
+            for a, b in zip(x.args, y.args):
+                v = _unify(a, b, v)
+            return v
+
+
+def symbol(name):
+    if name[0].isupper():
+        return Variable(name)
+
+    class Symbol(object):
+        def __init__(self, name):
+            self.name = name
+        def __call__(self, *args):
+            return Term('%s/%s' % (self.name, len(args)), args)
+        def __str__(self):
+            return self.name
+
+    return Symbol(name)
+
+
+#if __name__ == '__main__':
+#
+#    [f,g,h] = map(symbol, ['f','g','h'])
+#    vs = [X,Y,Z] = map(symbol, ['X','Y','Z'])
+#
+#    def test(a, b):
+#        for v in vs:
+#            v.value = None
+#
+#        print
+#        print 'unify %s and %s' % (a,b)
+#        s = unify(a, b)
+#        print '->', s
+#        if s is None:
+#            return
+#
+#        # apply new bindings
+#        for v, now in s.iteritems():
+#            print '%s [was: %r, now: %r]' % (v, v.value, now)
+#            v.value = now
+#
+#        print a, b
+#        assert a == b
+#        assert repr(a) == repr(b), [a,b]
+#
+#        for v in vs:
+#            v.value = None
+#
+#    test(f(X), f(g(h(X,Y),X)))
+#    test(f(X), f(g(h(Z),"foo")))
+#    test(f(X, Y), f("cat", 123))
+#    test(f(X), f(X))
+#    test(f(X), f(Y))
+#    test("abc", "abc")
+#
+#    Z.value = 3
+#    Y.value = Z
+#    X.value = Y
+#    print [X,Y,Z]
+#    assert X.value == Y.value == Z.value == 3
index 42bd9e6ee815fb912a4aeec9dc620dbc109b85f7..b933930193cc29e50bfae5968ef7030ebfa6a174 100644 (file)
@@ -1,5 +1,8 @@
 % accompanies load.bash
 
+:- dispos &cons(&,&).
+:- dispos &nil.
+
 % binary rules
 rewrite(X, Y, Z) :=
     rules_tsv(Linenum, Cost, X, R),