]> hydra-www.ietfng.org Git - dyna2/commitdiff
refactor load and post-process. both are availabl and the REPL and command-line ...
authorTim Vieira <tim.f.vieira@gmail.com>
Tue, 18 Jun 2013 00:40:18 +0000 (20:40 -0400)
committerNathaniel Wesley Filardo <nwf@cs.jhu.edu>
Tue, 18 Jun 2013 01:25:09 +0000 (21:25 -0400)
23 files changed:
dyna
examples/force.dyna
src/Dyna/Backend/Python/draw_circuit.py [deleted file]
src/Dyna/Backend/Python/graph.py [deleted file]
src/Dyna/Backend/Python/interpreter.py
src/Dyna/Backend/Python/load.py [deleted file]
src/Dyna/Backend/Python/load/__init__.py [new file with mode: 0644]
src/Dyna/Backend/Python/load/matrix.py [new file with mode: 0644]
src/Dyna/Backend/Python/load/pickled.py [new file with mode: 0644]
src/Dyna/Backend/Python/load/sexpr.py [new file with mode: 0644]
src/Dyna/Backend/Python/load/tsv.py [new file with mode: 0644]
src/Dyna/Backend/Python/loadmat.py [deleted file]
src/Dyna/Backend/Python/post/__init__.py [new file with mode: 0644]
src/Dyna/Backend/Python/post/draw_circuit.py [new file with mode: 0644]
src/Dyna/Backend/Python/post/dump_chart.py [new file with mode: 0644]
src/Dyna/Backend/Python/post/graph.py [new file with mode: 0644]
src/Dyna/Backend/Python/post/save.py [new file with mode: 0644]
src/Dyna/Backend/Python/repl.py
src/Dyna/Backend/Python/save.py [deleted file]
src/Dyna/Backend/Python/sexpr.py [deleted file]
src/Dyna/Backend/Python/term.py
src/Dyna/Backend/Python/tsv.py [deleted file]
test/repl/load.bash

diff --git a/dyna b/dyna
index d0549fa92e06e92ac31ceb29c2fd11edf992f0e6..a082bd9aa99d7d363676efea917ecd7be99dbd60 100755 (executable)
--- a/dyna
+++ b/dyna
@@ -1,3 +1,3 @@
 #!/usr/bin/env bash
 
-exec python ${DYNAHOME:-.}/src/Dyna/Backend/Python/interpreter.py $@
+exec python ${DYNAHOME:-.}/src/Dyna/Backend/Python/interpreter.py "$@"
index 4d0c1dd85eecca1a8922974adf861db2c4d39ed9..2872fa772ef3ee1f72b3d48803880b32c6c4a18c 100644 (file)
@@ -39,8 +39,8 @@ node(U) := true for edge(_,U).
 pos(U,T) := tuple(x(U, T), y(U, T)).
 
 % visualization
-frame(T, Item) := node(Name), Item is &text(Name, pos(Name, T)).
-frame(T, Item) := edge(U,V), Item is &line(pos(U, T), pos(V, T)).
+frame(T, &text(Name, pos(Name, T))) := true for _ is node(Name).
+frame(T, &line(pos(U, T), pos(V, T))) := true for _ is edge(U,V).
 
 % declare some edges
 edge("a", "b") := 1.
diff --git a/src/Dyna/Backend/Python/draw_circuit.py b/src/Dyna/Backend/Python/draw_circuit.py
deleted file mode 100644 (file)
index 0ebb466..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-"""
-Crude visualization of circuit pertaining to state of the interpreter.
-"""
-
-import webbrowser
-from debug import Hypergraph
-from cStringIO import StringIO
-
-def circuit(edges):
-    # create hypergraph object
-    g = Hypergraph()
-    for e in edges:
-        head, label, body = e
-        g.edge(str(head), str(label), map(str, body))
-    return g
-
-
-def infer_edges(interp):
-    edges = set()
-
-    # Use rule initializers to find all active hyperedges in the current Chart.
-    def _emit(item, _, ruleix, variables):
-        b = variables['nodes']
-        b.sort()
-        b = tuple(b)
-        edges.add((item, ruleix, b))
-
-    for r in interp.rules.values():
-        r.init(emit=_emit)
-
-    return edges
-
-
-def main(interp):
-    es = infer_edges(interp)
-    c = circuit(es)
-
-    with file('/tmp/state.html', 'wb') as f:
-        print >> f, """
-        <html>
-        <head>
-        <style>
-        body {
-          background-color: black;
-          color: white;
-        }
-        </style>
-        </head>
-        <body>
-        """
-
-        x = StringIO()
-        interp.dump_charts(x)
-
-        print >> f, '<div style="position:absolute;">%s</div>' \
-            % '<h1>Charts</h1>%s' \
-            % '<pre style="width: 500px;">%s</pre>' \
-            % x.getvalue()
-
-        print >> f, """
-        <div style="width: 800px; position:absolute; left: 550px">
-        <h1>Hypergraph</h1>
-        %s
-        </div>
-        """ % c.render('circuit')
-
-        print >> f, '</body></html>'
-
-    webbrowser.open(f.name)
diff --git a/src/Dyna/Backend/Python/graph.py b/src/Dyna/Backend/Python/graph.py
deleted file mode 100644 (file)
index 44f3628..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-"""
-Postprocessor for animated visualization of basic elements such as lines and
-text.
-
-We look for the following patterns in the dynabase
-
-         visual element
-               v
-    frame(T, &text(String, tuple(X, Y))).
-          ^
-       time index
-
-Frames should have value true. The example above places a text element reading
-`String` at position `(X,Y)` in a frame at time `T`. This element can be
-specified by dyna rule.
-"""
-
-import pylab as pl
-from matplotlib.animation import FuncAnimation
-from collections import defaultdict
-
-def main(interp):
-
-    frame = defaultdict(list)
-    for _, [t, item], val in interp.chart['frame/2'][:,:,:]:
-        if val:
-            frame[t].append(item)
-
-    nframes = max(frame)
-
-    def draw_frame(t):
-        ax.cla()
-        ax.set_title(t)
-        ax.set_xlim(-2,2)   # TODO: this isn't right...
-        ax.set_ylim(-2,2)
-        if t not in frame:
-            print 'frame', t, 'missing.'
-        for item in frame[t]:
-            if item.fn == 'line/2':
-                [(a,b), (c,d)] = item.args
-                ax.plot([a,c], [b,d], color='b', alpha=0.5)
-            elif item.fn == 'text/2':
-                (s,(x,y)) = item.args
-                ax.text(x,y,s)
-            else:
-                print 'dont know how to render', item
-
-    fig = pl.figure()
-    ax = pl.axes()
-
-    print 'creating animation..'
-    anim = FuncAnimation(fig, draw_frame, frames=nframes)
-    print 'saving...'
-    anim.save('examples/force.dyna.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
-    print 'wrote examples/force.dyna.mp4'
index 966bb5150e69e0e9d8465d455fa2d4420661aa13..47e8b048934bc60298964737bc124daa780a0e22 100644 (file)
@@ -23,20 +23,16 @@ TODO
 
  - doc tests for Dyna code.
 
- - think about indices as memoized queries
-
- - let Dyna do some of the work for you. think about using Dyna to maintain
-   rules and update handlers.
+ - Use Dyna do some more work! think about using Dyna to maintain rules, update
+   handlers, and indices (as Jason points out indices are just memoized
+   queries).
 
  - magic templates transform for backward chaining, for example:
 
    :- sigmoid(X) := needs(X), 1 / (1 + exp(-X)).
    :- needs(0.5).
 
- - operator for getattr (this will generate slightly different code because we
-   don't want to look up by string -- i.e. call the getattr builtin).
-
- - hook for python imports?
+ - hook for python imports? or maybe an arbirary preamble/epilogue.
 
    :- python: from numpy import exp, sqrt, log
 
@@ -58,16 +54,17 @@ BUGS
 FASTER
 ======
 
- - specialize calls to emit, don't build the big dictionaries if the aggregator
-   doesn't use them. Consider generate both version (or an argument to the
-   update handler which will skip the appropriate code paths).
+ - specialize calls to emit: don't build the local variable dictionaries if the
+   aggregator doesn't use them. Consider generate both versions (or an argument
+   to the update handler which will skip the appropriate code paths).
 
  - faster charts (dynamic argument types? jason's trie data structure)
 
  - teach planner to prefer not to use the value column, because it's not
    indexed.
 
- - Consider indexing value column if plans will need it.
+ - Collect all query modes use by the planner. Consider indexing value column if
+   plans need it.
 
  - dynac should provide routines for building terms. We can hack something
    together with anf output, but this will be prety kludgy and inefficient.
@@ -174,6 +171,9 @@ from collections import defaultdict
 from hashlib import sha1
 from time import time
 
+import load, post
+
+
 from chart import Chart, Term, _repr
 from defn import aggregator
 from utils import ip, red, green, blue, magenta, yellow, parse_attrs, \
@@ -596,29 +596,24 @@ def peel(fn, item):
 
 def main():
     parser = argparse.ArgumentParser(description="The dyna interpreter!")
-    parser.add_argument('source',
-                        help='Path to Dyna source file (or plan if --plan=true).', nargs='?')
+    parser.add_argument('source', nargs='?',
+                        help='Path to Dyna source file (or plan if --plan=true).')
     parser.add_argument('--plan', action='store_true',
                         help='`source` specifies output of the compiler instead of dyna source code.')
     parser.add_argument('-i', dest='interactive', action='store_true',
-                        help='Fire-up an IPython shell.')
-    parser.add_argument('-o', dest='output',
+                        help='Fire-up REPL after runing solver..')
+    parser.add_argument('-o', '--output', dest='output',
                         type=argparse.FileType('wb'),
                         help='Output chart.')
-    parser.add_argument('--post-process',
-                        help='run post-processing script.')
+    parser.add_argument('--post-process', nargs='*',
+                        help='run post-processor.')
+    parser.add_argument('--load', nargs='*',
+                        help='run loaders.')
     parser.add_argument('--profile', action='store_true',
                         help='run profiler.')
 
     args = parser.parse_args()
 
-    if args.post_process is not None:
-        try:
-            pp = __import__(args.post_process)
-        except ImportError:
-            print ('ERROR: No postprocessor named %r' % args.post_process)
-            return
-
     interp = Interpreter()
 
     enable_crash_handler()
@@ -652,15 +647,19 @@ def main():
             return
 
         interp.do(plan)
+        interp.dump_charts(args.output)      # should be a post-processor
 
-        interp.dump_charts(args.output)
+    if args.load:
+        for cmd in args.load:
+            load.run(interp, cmd)
+
+    if args.post_process:
+        for cmd in args.post_process:
+            post.run(interp, cmd)
 
     if args.interactive or not args.source:
         interp.repl()
 
-    if args.post_process is not None:
-        pp.main(interp)
-
 
 if __name__ == '__main__':
     main()
diff --git a/src/Dyna/Backend/Python/load.py b/src/Dyna/Backend/Python/load.py
deleted file mode 100644 (file)
index 18b94f0..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-"""
-Load interpreter state using python's pickle protocol.
-"""
-
-import cPickle
-
-from interpreter import Interpreter, foo, none
-
-
-def main():
-    with file('save.pkl', 'r') as f:
-        interp = cPickle.load(f)
-    interp.repl()
-
-
-if __name__ == '__main__':
-    main()
diff --git a/src/Dyna/Backend/Python/load/__init__.py b/src/Dyna/Backend/Python/load/__init__.py
new file mode 100644 (file)
index 0000000..eca4929
--- /dev/null
@@ -0,0 +1,12 @@
+from sexpr import sexpr
+from tsv import tsv
+from matrix import matrix
+from pickled import pickled
+
+import re
+
+def run(interp, line):
+    [(name, module, args)] = re.findall('^([a-z][a-zA-Z_0-9]*) = ([a-z][a-zA-Z_0-9]*)\((.*)\)', line)
+    m = getattr(__import__('load'), module)(interp, name)
+    exec 'm.main(%s)' % args
+    interp.go()
diff --git a/src/Dyna/Backend/Python/load/matrix.py b/src/Dyna/Backend/Python/load/matrix.py
new file mode 100644 (file)
index 0000000..de827a6
--- /dev/null
@@ -0,0 +1,54 @@
+"""
+mat - Load a text file as a (jagged) matrix.
+
+For example
+
+1 2 3
+4 5
+
+6 7
+
+
+m(0,0) := 1. m(0,1) := 2. m(0,2) := 3
+m(1,0) := 4. m(1,1) := 5.
+
+m(3,0) := 6. m(3,1) := 7.
+
+"""
+
+import re
+
+class matrix(object):
+
+    def __init__(self, interp, name):
+        self.interp = interp
+        self.name = name
+
+    # TODO: option for strict width
+    # TODO: option for stripping comments
+    def main(self, filename, astype=float, delim='\s+'):
+
+        interp = self.interp
+
+        fn = '%s/2' % self.name
+        if interp.agg_name[fn] is None:
+            interp.new_fn(fn, ':=')
+
+        def term(a, v):
+            interp.emit(interp.build(fn, *a),
+                        v,
+                        ruleix=None,
+                        variables=None,
+                        delete=False)
+
+        with file(filename) as f:
+            for i, line in enumerate(f):
+                line = line.rstrip()
+                if not line:
+                    continue
+                if delim is not None:
+                    line = re.split(delim, line)
+                else:
+                    line = [line]
+                for j, v in enumerate(line):
+                    term((i, j), astype(v))
diff --git a/src/Dyna/Backend/Python/load/pickled.py b/src/Dyna/Backend/Python/load/pickled.py
new file mode 100644 (file)
index 0000000..fa592c4
--- /dev/null
@@ -0,0 +1,27 @@
+"""
+Load interpreter state using python's pickle protocol. This is the output of
+`save`.
+
+TODO: Can we merge a pickled interpreter into an existing one?
+
+"""
+
+import cPickle
+
+
+class pickled(object):
+
+    def __init__(self, interp=None, name=None):
+        self.interp = interp
+        self.name = name
+
+    def main(self, filename):
+        with file(filename, 'r') as f:
+            interp = cPickle.load(f)
+        return interp
+
+
+if __name__ == '__main__':
+    from interpreter import Interpreter, foo, none
+    import sys
+    pickled().main(sys.argv[1]).repl()
diff --git a/src/Dyna/Backend/Python/load/sexpr.py b/src/Dyna/Backend/Python/load/sexpr.py
new file mode 100644 (file)
index 0000000..453bf77
--- /dev/null
@@ -0,0 +1,84 @@
+"""
+Read lisp-style S-Expressions from a file.
+"""
+
+from cStringIO import StringIO
+from utils import parse_sexpr
+
+
+class sexpr(object):
+
+    def __init__(self, interp, name):
+        self.interp = interp
+        self.name = name
+
+    def main(self, filename):
+
+        interp = self.interp
+        name = self.name
+
+        def obj(*a):
+            fn = '%s/%s' % (name, len(a))
+            if interp.agg_name[fn] is None:
+                interp.new_fn(fn, ':=')
+            return interp.build(fn, *a)
+
+        def node(*a):
+            fn = '%s/%s' % ('node', len(a))
+            if interp.agg_name[fn] is None:
+                interp.new_fn(fn, ':=')
+            return interp.build(fn, *a)
+
+        def t(xs):
+            if isinstance(xs, basestring):
+                return xs
+            else:
+                assert len(xs) > 1
+                if len(xs) == 2:
+                    [sym, a] = map(t, xs)
+                    return node(sym, a)
+                elif len(xs) == 3:
+                    [sym, a, b] = map(t, xs)
+                    return node(sym, a, b)
+                else:
+                    [sym, a] = t(xs[0]), t(xs[1])
+                    rest = t(['@' + xs[0]] + xs[2:])
+                    return node(sym, a, rest)
+
+        contents = file(filename).read()
+
+        for i, [x] in enumerate(parse_sexpr(contents)):
+            interp.emit(obj(i),
+                        t(x),
+                        ruleix=None,
+                        variables=None,
+                        delete=False)
+
+
+# TODO: maybe really big terms should have a pretty printer
+def pretty(t, initialindent=0):
+    "Pretty print tree as a tabbified s-expression."
+    f = StringIO()
+    out = f.write
+    def pp(t, indent=initialindent, indentme=True):
+        if indentme:
+            out(' '*indent)
+        if isinstance(t, basestring):                    # base case
+            return out('"%s"' % t)
+        if len(t) == 1:
+            if t[0]:
+                pp('"%s"' % t[0], indent, indentme)
+            return
+        label, children = t[0], t[1:]
+        label = '"%s"' % label
+        assert isinstance(label, basestring)
+        out('&t(%s, ' % label)
+        n = len(children)
+        for i, child in enumerate(children):
+            pp(child, indent + len(label) + 5, i != 0)   # first child already indented
+            if i != n-1:                                 # no newline after last child
+                out(',\n')
+        out(')')
+    pp(t)
+    out('\n')
+    return f.getvalue()
diff --git a/src/Dyna/Backend/Python/load/tsv.py b/src/Dyna/Backend/Python/load/tsv.py
new file mode 100644 (file)
index 0000000..be67a79
--- /dev/null
@@ -0,0 +1,42 @@
+import re
+
+class tsv(object):
+
+    """
+    Load tab-delimited files.
+
+    TODO: option for stripping comments
+    TODO: option for strict number of columns.
+    """
+
+    def __init__(self, interp, name):
+        self.interp = interp
+        self.name = name
+
+    def main(self, filename, delim='\t'):
+
+        interp = self.interp
+        name = self.name
+
+        def term(a):
+            fn = '%s/%s' % (name, len(a))
+
+            if interp.agg_name[fn] is None:
+                interp.new_fn(fn, ':=')
+
+            interp.emit(interp.build(fn, *a),
+                        True,
+                        ruleix=None,
+                        variables=None,
+                        delete=False)
+
+        with file(filename) as f:
+            for i, line in enumerate(f):
+                line = line.rstrip()
+                if not line:
+                    continue
+                if delim is not None:
+                    line = re.split(delim, line)
+                else:
+                    line = [line]
+                term([i] + line)
diff --git a/src/Dyna/Backend/Python/loadmat.py b/src/Dyna/Backend/Python/loadmat.py
deleted file mode 100644 (file)
index 9bd7551..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-"""
-loadmat - Load a text file as a (jagged) matrix.
-
-For example
-
-1 2 3
-4 5
-
-6 7
-
-
-m(0,0) := 1. m(0,1) := 2. m(0,2) := 3
-m(1,0) := 4. m(1,1) := 5.
-
-m(3,0) := 6. m(3,1) := 7.
-
-"""
-
-import re
-
-interp = None
-name = None
-
-# TODO: option for strict width
-# TODO: option for stripping comments
-def main(filename, astype=float, delim='\s+'):
-
-    fn = '%s/2' % name
-    if interp.agg_name[fn] is None:
-        interp.new_fn(fn, ':=')
-
-    def term(a, v):
-        interp.emit(interp.build(fn, *a),
-                    v,
-                    ruleix=None,
-                    variables=None,
-                    delete=False)
-
-    with file(filename) as f:
-        for i, line in enumerate(f):
-            line = line.rstrip()
-            if not line:
-                continue
-            if delim is not None:
-                line = re.split(delim, line)
-            else:
-                line = [line]
-
-            for j, v in enumerate(line):
-                term((i, j), astype(v))
diff --git a/src/Dyna/Backend/Python/post/__init__.py b/src/Dyna/Backend/Python/post/__init__.py
new file mode 100644 (file)
index 0000000..30aa68e
--- /dev/null
@@ -0,0 +1,11 @@
+import re
+from save import save
+from graph import graph
+from draw_circuit import draw_circuit
+from dump_chart import dump_chart
+
+
+def run(interp, line):
+    [(name, args)] = re.findall('([a-z][a-zA-Z_0-9]*)\((.*)\)$', line)
+    m = globals()[name](interp)
+    eval('m.main(%s)' % args)
diff --git a/src/Dyna/Backend/Python/post/draw_circuit.py b/src/Dyna/Backend/Python/post/draw_circuit.py
new file mode 100644 (file)
index 0000000..3d4ed5d
--- /dev/null
@@ -0,0 +1,77 @@
+"""
+Crude visualization of circuit pertaining to state of the interpreter.
+"""
+
+import webbrowser
+from debug import Hypergraph
+from cStringIO import StringIO
+
+
+def circuit(edges):
+    # create hypergraph object
+    g = Hypergraph()
+    for e in edges:
+        head, label, body = e
+        g.edge(str(head), str(label), map(str, body))
+    return g
+
+
+def infer_edges(interp):
+    edges = set()
+
+    # Use rule initializers to find all active hyperedges in the current Chart.
+    def _emit(item, _, ruleix, variables):
+        b = variables['nodes']
+        b.sort()
+        b = tuple(b)
+        edges.add((item, ruleix, b))
+
+    for r in interp.rules.values():
+        r.init(emit=_emit)
+
+    return edges
+
+
+class draw_circuit(object):
+
+    def __init__(self, interp):
+        self.interp = interp
+
+    def main(self, outfile):
+        interp = self.interp
+
+        es = infer_edges(interp)
+        c = circuit(es)
+
+        with file(outfile, 'wb') as f:
+            print >> f, """
+            <html>
+            <head>
+            <style>
+            body {
+              background-color: black;
+              color: white;
+            }
+            </style>
+            </head>
+            <body>
+            """
+
+            x = StringIO()
+            interp.dump_charts(x)
+
+            print >> f, '<div style="position:absolute;">%s</div>' \
+                % '<h1>Charts</h1>%s' \
+                % '<pre style="width: 500px;">%s</pre>' \
+                % x.getvalue()
+
+            print >> f, """
+            <div style="width: 800px; position:absolute; left: 550px">
+            <h1>Hypergraph</h1>
+            %s
+            </div>
+            """ % c.render('circuit')
+
+            print >> f, '</body></html>'
+
+        webbrowser.open(f.name)
diff --git a/src/Dyna/Backend/Python/post/dump_chart.py b/src/Dyna/Backend/Python/post/dump_chart.py
new file mode 100644 (file)
index 0000000..438d3d9
--- /dev/null
@@ -0,0 +1,20 @@
+
+
+"""
+Save interpreter state using python's pickle protocol.
+"""
+
+import sys
+
+
+class dump_chart(object):
+
+    def __init__(self, interp):
+        self.interp = interp
+
+    def main(self, filename=None):
+        if filename is None:
+            self.interp.dump_charts(sys.stdout)
+        else:
+            with file(filename, 'wb') as f:
+                self.interp.dump_charts(f)
diff --git a/src/Dyna/Backend/Python/post/graph.py b/src/Dyna/Backend/Python/post/graph.py
new file mode 100644 (file)
index 0000000..f06b460
--- /dev/null
@@ -0,0 +1,60 @@
+"""
+Postprocessor for animated visualization of basic elements such as lines and
+text.
+
+We look for the following patterns in the dynabase
+
+         visual element
+               v
+    frame(T, &text(String, tuple(X, Y))).
+          ^
+       time index
+
+Frames should have value true. The example above places a text element reading
+`String` at position `(X,Y)` in a frame at time `T`. This element can be
+specified by dyna rule.
+"""
+
+import pylab as pl
+from matplotlib.animation import FuncAnimation
+from collections import defaultdict
+
+class graph(object):
+
+    def __init__(self, interp):
+        self.interp = interp
+
+    def main(self, outfile):
+        
+        frame = defaultdict(list)
+        for _, [t, item], val in self.interp.chart['frame/2'][:,:,:]:
+            if val:
+                frame[t].append(item)
+    
+        nframes = max(frame)
+    
+        def draw_frame(t):
+            ax.cla()
+            ax.set_title(t)
+            ax.set_xlim(-2,2)   # TODO: this isn't right...
+            ax.set_ylim(-2,2)
+            if t not in frame:
+                print 'frame', t, 'missing.'
+            for item in frame[t]:
+                if item.fn == 'line/2':
+                    [(a,b), (c,d)] = item.args
+                    ax.plot([a,c], [b,d], color='b', alpha=0.5)
+                elif item.fn == 'text/2':
+                    (s,(x,y)) = item.args
+                    ax.text(x,y,s)
+                else:
+                    print 'dont know how to render', item
+    
+        fig = pl.figure()
+        ax = pl.axes()
+    
+        print 'creating animation..'
+        anim = FuncAnimation(fig, draw_frame, frames=nframes)
+        print 'saving...'
+        anim.save(outfile, fps=30, extra_args=['-vcodec', 'libx264'])
+        print 'wrote examples/force.dyna.mp4'
diff --git a/src/Dyna/Backend/Python/post/save.py b/src/Dyna/Backend/Python/post/save.py
new file mode 100644 (file)
index 0000000..9e3ba8c
--- /dev/null
@@ -0,0 +1,15 @@
+"""
+Save interpreter state using python's pickle protocol.
+"""
+
+import cPickle
+
+
+class save(object):
+
+    def __init__(self, interp):
+        self.interp = interp
+
+    def main(self, filename):
+        with file(filename, 'wb') as f:
+            cPickle.dump(self.interp, f)
index fa963f369d4f89aabd4aae6bab1684b7c582be08..225710e5d61ecfe4a93513b71ba510dc4bb5d832 100644 (file)
@@ -6,6 +6,11 @@ from errors import DynaCompilerError, DynaInitializerException
 from chart import _repr
 from config import dotdynadir
 
+from errors import show_traceback
+import load, post
+
+from interpreter import Interpreter, foo, none
+
 
 class REPL(cmd.Cmd, object):
 
@@ -116,10 +121,6 @@ class REPL(cmd.Cmd, object):
         print
         self.interp.dump_errors()
 
-    def do_draw_circuit(self, _):
-        import draw_circuit
-        draw_circuit.main(self.interp)
-
     def cmdloop(self, _=None):
         try:
             super(REPL, self).cmdloop()
@@ -130,22 +131,17 @@ class REPL(cmd.Cmd, object):
         finally:
             readline.write_history_file(self.hist)
 
-    def do_load(self, cmd):
+    def do_load(self, line):
         try:
-            self._load(cmd)
+            load.run(self.interp, line)
+            self.interp.dump_charts()
         except:
-            from errors import show_traceback
             show_traceback()
+            readline.write_history_file(self.hist)
 
-    def _load(self, cmd):
-        import re
-        [(name, module, args)] = re.findall('^([a-z][a-zA-Z_0-9]*) = ([a-z][a-zA-Z_0-9]*)\((.*)\)', cmd)
-
-        m = __import__(module)
-        m.interp = self.interp
-        m.name = name
-
-        exec 'm.main(%s)' % args
-
-        self.interp.go()
-        self.interp.dump_charts()
+    def do_post(self, line):
+        try:
+            post.run(self.interp, line)
+        except:
+            show_traceback()
+            readline.write_history_file(self.hist)
diff --git a/src/Dyna/Backend/Python/save.py b/src/Dyna/Backend/Python/save.py
deleted file mode 100644 (file)
index ed99a3c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-"""
-Save interpreter state using python's pickle protocol.
-"""
-
-import cPickle
-
-
-def main(interp):
-    with file('save.pkl', 'wb') as f:
-        cPickle.dump(interp, f)
-    print 'wrote', f.name
diff --git a/src/Dyna/Backend/Python/sexpr.py b/src/Dyna/Backend/Python/sexpr.py
deleted file mode 100644 (file)
index 7a2eff9..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-import sys
-from cStringIO import StringIO
-from utils import parse_sexpr
-
-
-if __name__ == '__main__':
-
-    def t(xs):
-        if isinstance(xs, basestring):
-#            return '"%s"' % xs
-            return xs
-        else:
-            assert len(xs) > 1
-            if len(xs) == 2:
-                [sym, a] = map(t, xs)
-#                return '&t(%s)' % ', '.join(t(x) for x in xs)
-                return [sym, a]
-            elif len(xs) == 3:
-                [sym, a, b] = map(t, xs)
-#                return '&t(%s, %s, %s)' % (sym, a, b)
-                return [sym, a, b]
-            else:
-                [sym, a] = t(xs[0]), t(xs[1])
-                rest = t(['@' + xs[0]] + xs[2:])
-#                return '&t(%s, %s, %s)' % (sym, a, rest)
-                return [sym, a, rest]
-
-
-    def check_binary(x):
-        if isinstance(x, basestring):
-            return True
-        elif len(x) in (2, 3):
-            return all(map(check_binary, x))
-        else:
-            return False
-
-
-    def pretty(t, initialindent=0):
-        "Pretty print tree as a tabbified s-expression."
-        f = StringIO()
-        out = f.write
-        def pp(t, indent=initialindent, indentme=True):
-            if indentme:
-                out(' '*indent)
-            if isinstance(t, basestring):                    # base case
-                return out('"%s"' % t)
-            if len(t) == 1:
-                if t[0]:
-                    pp('"%s"' % t[0], indent, indentme)
-                return
-            label, children = t[0], t[1:]
-
-            label = '"%s"' % label
-
-            assert isinstance(label, basestring)
-            out('&t(%s, ' % label)
-            n = len(children)
-            for i, child in enumerate(children):
-                pp(child, indent + len(label) + 5, i != 0)   # first child already indented
-                if i != n-1:                                 # no newline after last child
-                    out(',\n')
-            out(')')
-        pp(t)
-        out('\n')
-        return f.getvalue()
-
-    for i, [x] in enumerate(parse_sexpr(sys.stdin.read())):
-        btree = t(x)
-
-        assert check_binary(btree)
-        print
-        print 'sentence(%s) :=\n%s.' % (i, pretty(btree, 4).rstrip())
-        print
index f1816d555f130925ac0fcd6f84569fda62512f5e..6efaf4d704eda45344c027097aee7ed8db49d05e 100644 (file)
@@ -38,11 +38,11 @@ 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 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 _repr(x):
@@ -63,6 +63,7 @@ def isconst(x):
     return not isinstance(x, (Variable, Term))
 
 
+
 class Variable(object):
 
     def __init__(self, name):
@@ -111,10 +112,10 @@ class Variable(object):
         else:
             return other == self.value
 
-    def subst(self, v):
-        if self in v:
-            return v[self]
-        return self
+#    def subst(self, v):
+#        if self in v:
+#            return v[self]
+#        return self
 
 
 def extend(v, x, t):
@@ -123,7 +124,7 @@ def extend(v, x, t):
     """
     v1 = v.copy()
     v1[x] = t
-    x.value = t
+#    x.value = t
     return v1
 
 
@@ -199,38 +200,44 @@ def symbol(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
-
-        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")
+#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
 
-    Z.value = 3
-    Y.value = Z
-    X.value = Y
-    print [X,Y,Z]
-    assert X.value == Y.value == Z.value == 3
diff --git a/src/Dyna/Backend/Python/tsv.py b/src/Dyna/Backend/Python/tsv.py
deleted file mode 100644 (file)
index 85bc48d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-import re
-
-interp = None
-name = None
-
-# TODO: option for stripping comments
-def main(filename, ncols=None, delim='\t'):
-
-    def term(a):
-        fn = '%s/%s' % (name, len(a))
-
-        if interp.agg_name[fn] is None:
-            interp.new_fn(fn, ':=')
-
-        interp.emit(interp.build(fn, *a),
-                    True,
-                    ruleix=None,
-                    variables=None,
-                    delete=False)
-
-    with file(filename) as f:
-        for i, line in enumerate(f):
-            line = line.rstrip()
-            if not line:
-                continue
-            if delim is not None:
-                line = re.split(delim, line)
-            else:
-                line = [line]
-            term([i] + line)
index 7cb0e8be6c1787f766ccadb01d70c186d3858bb5..02d0cfbde06e208b44775cfdbc68abe0b86926cc 100755 (executable)
@@ -2,9 +2,8 @@
 
 # The example shows off some of the REPL's data loading commands.
 
-echo '
-load rules_tsv = tsv("test/repl/papa.gr").
-load token = loadmat("test/repl/sentences.txt", astype=str).
-' |./dyna test/repl/load.dyna -i
-
-#load tree_sexpr = sexpr("trees.txt", binarize=True)
+./dyna test/repl/load.dyna \
+  --load 'rules_tsv = tsv("test/repl/papa.gr")' \
+         'token = matrix("test/repl/sentences.txt", astype=str)' \
+         'tree = sexpr("test/repl/trees.txt")' \
+  --post 'dump_chart()'