]> hydra-www.ietfng.org Git - dyna2/commitdiff
tweaks, fixes.
authortimv <tim.f.vieira@gmail.com>
Mon, 10 Jun 2013 17:49:27 +0000 (13:49 -0400)
committertimv <tim.f.vieira@gmail.com>
Mon, 10 Jun 2013 17:49:27 +0000 (13:49 -0400)
README.md
examples/force.dyna
src/Dyna/Backend/Python/Backend.hs
src/Dyna/Backend/Python/chart.py
src/Dyna/Backend/Python/debug.py
src/Dyna/Backend/Python/graph.py
src/Dyna/Backend/Python/interpreter.py
src/Dyna/Backend/Python/repl.py
src/Dyna/Backend/Python/utils.py

index e60513969e13b994edb6abfa11f1c876be867e3f..ebd60274f9eb5136cda0814f6b36c44f15f73940 100644 (file)
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ You'll want to have the following programs installed:
 
 The python modules required
 
-    $ easy_install path.py ipython pygments
+    $ easy_install numpy ipython pygments path.py
 
 You should probably run
 
index bc31d7cdb19995703fc291d053adc04fb0117c48..fb9885b4b98c780bfda62f9f0fc7efa2f3e64a91 100644 (file)
@@ -15,7 +15,7 @@ shortestpath(U,U) min= 0 for node(U).
 shortestpath(U,V) min= shortestpath(U,W) + edge(W,V).
 
 % "the unit edge length"
-edgelen := 5.0.
+edgelen := 4.0.
 
 f(U,V,T) := (U != V), dist(U,V,T) / (shortestpath(U,V) * edgelen) - 1.
 
index 85103c86a5ad803afc5b4e8998c9695bc41d1d09..85d599a5329e9f3322780ed0b7549244fdc3ada1 100644 (file)
@@ -189,8 +189,11 @@ pslice vs = brackets $
        sepBy "," (map (\x -> if nGround (x^.mv_mi) then pretty (x^.mv_var) else ":") vs)
        <> "," -- add a comma to ensure getitem is always passed a tuple.
 
-piterate vs = parens $
-       sepBy "," (map (\x -> if nGround (x^.mv_mi) then "_" else pretty (x^.mv_var)) vs)
+ground2underscore x = if nGround (x^.mv_mi) then "_" else pretty (x^.mv_var)
+
+piterate vs = if length vs == 0 then "_"
+              else parens $
+       sepBy "," (map ground2underscore vs)
        <> "," -- add a comma to ensure tuple.
 
 
@@ -205,13 +208,13 @@ pdope_ (OPCheq v val) = return $ "if" <+> pretty v <+> "!="
 pdope_ (OPCkne v val) = return $ "if" <+> pretty v <+> "=="
                                       <+> pretty val <> ": continue"
 pdope_ (OPPeel vs i f _) = return $
-    --"try:" `above` (indent 4 $
+    "try:" `above` (indent 4 $
            tupledOrUnderscore vs
             <+> equals
                 <+> "peel" <> (parens $ pfas f vs <> comma <> pretty i)
-    --)
+    )
     -- you'll get a "TypeError: 'NoneType' is not iterable."
-    --`above` "except (TypeError, AssertionError): continue"
+    `above` "except (TypeError, AssertionError): continue"
 pdope_ (OPWrap v vs f) = return $ pretty v
                            <+> equals
                            <+> "build"
@@ -225,7 +228,7 @@ pdope_ (OPIter v vs f Det (Just (PDBS c))) = return $ pretty (v^.mv_var)
 pdope_ (OPIter o m f _ Nothing) = do
       i <- incState
       return $ let mo = m ++ [o] in
-          "for" <+> "d" <> pretty i <> "," <> piterate mo
+          "for" <+> "d" <> pretty i <> "," <> piterate m <> comma <> (ground2underscore o)
                 <+> "in" <+> functorIndirect "chart" f m <> pslice mo <> colon
 
     -- XXX Ought to make i and vs conditional on... doing debugging or the
index a5cb9d44dcb7ec3f8792e110ffc56c0d90350d15..a9a8b0cec2a2de7772d3e936716b049c7eb003b8 100644 (file)
@@ -16,6 +16,8 @@ class Term(object):
     def __cmp__(self, other):
         if other is None:
             return 1
+        if not isinstance(other, Term):
+            return 1
         return cmp((self.fn, self.args), (other.fn, other.args))
 
     # default hash and eq suffice because we intern
@@ -95,11 +97,11 @@ class Chart(object):
         if isinstance(val, slice):
             for term in candidates:
                 if term.value is not None:
-                    yield term, term.args + (term.value,)
+                    yield term, term.args, term.value
         else:
             for term in candidates:
                 if term.value == val:
-                    yield term, term.args + (term.value,)   # TODO: change codegen to avoid addition..
+                    yield term, term.args, term.value
 
     def insert(self, args):        # TODO: rename
         try:
index 96f816a82be7739efa9233d05cfd298ad4366889..a71e16bd185ad72ee60f2323881b72f6f4eb2547 100644 (file)
@@ -82,22 +82,21 @@ class Hypergraph(object):
                                                                  id=id(e),
                                                                  label=e.label)
 
-                # connect body variables to edge
+                # connect body variables to edge crux
                 for b in e.body:
+#                    print >> f, '"%s" -> "%s" [arrowhead=none];' % (b, id(e))
                     print >> f, '"%s" -> "%s";' % (b, id(e))
 
                 # connect head variables to edge
-                print >> f, '"%s" -> "%s";' % (id(e), e.head)
+#                print >> f, '  "%s" [label="",shape=point];' % (id(e))
+                print >> f, '  "%s" -> "%s";' % (id(e), e.head)
 
             # node styles
             for x in self.nodes:
-#                sty[x].update({'shape': 'circle'})
-                sty[e].update({'shape': 'rectangle'})
                 print >> f, '"%s" [%s]' % (x, ','.join('%s="%s"' % (k,v) for k,v in sty[x].items()))
 
             # edge styles
             for e in self.edges:
-                sty[e].update({'shape': 'rectangle'})
                 print >> f, '"%s" [%s]' % (id(e), ','.join('%s="%s"' % (k,v) for k,v in sty[e].items()))
 
             print >> f, '}'
index c6d01dec443c358d63e9d94e53c01afa85309c71..aa0f21353476aad021614126c9338d32ae1ec4f8 100644 (file)
@@ -9,7 +9,7 @@ def g(nodes, edges, t, ax, interp):
     ax.set_ylim(-2,2)
 
     pos = defaultdict(lambda: (0,0))
-    pos.update({node: p for _, (node, _, p) in interp.chart['pos/2'][:,t,:]})
+    pos.update({node: p for _, (node, _), p in interp.chart['pos/2'][:,t,:]})
 
     for u,v in edges:
         if u < v:
@@ -21,10 +21,10 @@ def g(nodes, edges, t, ax, interp):
         ax.text(x,y,s)
 
 def animate(interp):
-    [(_, (niter,))] = interp.chart['niter/0'][:,]
+    [(_, _, niter)] = interp.chart['niter/0'][:,]
 
-    nodes = [name for _, (name, _) in interp.chart['node/1'][:,:]]
-    edges = [(u,v) for _, (u,v,_) in interp.chart['edge/2'][:,:,:]]
+    nodes = [name for _, [name], _ in interp.chart['node/1'][:,:]]
+    edges = [(u,v) for _, [u,v] ,_ in interp.chart['edge/2'][:,:,:]]
 
     fig = pl.figure()
     ax = pl.axes()
index ffd229877bede9d7332c36001d3f1b474bf8c719..70c918572f14136fc8efea638bb29833d02ff6da 100644 (file)
@@ -17,12 +17,21 @@ TODO
  - let Dyna do some of the work for you. think about using Dyna to maintain
    rules and update handlers.
 
+ - magic templates transform for backward chaining, for example:
+
+   :- sigmoid(X) := needs(X), 1 / (1 + exp(-X)).
+   :- needs(0.5).
+
 
 BIGGER (new features)
 =====================
 
- - TODO: operator for getattr (this will generate slightly different code becase
-   we don't want to look up by string -- i.e. call the getattr builtin).
+ - TODO: 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?
+
+   :- python: from numpy import exp, sqrt, log
 
 
 FASTER
@@ -38,7 +47,7 @@ FASTER
    indexed.
 
  - TODO: dynac should provide routines for building terms. We can hack something
-   together with anf output.
+   together with anf output, but this will be prety kludgy and inefficient.
 
  - TODO: prioritization
 
@@ -81,7 +90,7 @@ USERS
 DEVELOPERS
 ==========
 
- - TODO: visualize execution of algorithm on hypergraph -- recreate nwf's
+ - TODO: visualize execution of solver on hypergraph -- recreate nwf's
    animations from his ICLP talk.
 
 
@@ -183,7 +192,8 @@ from utils import ip, red, green, blue, magenta, yellow, \
     DynaCompilerError, DynaInitializerException, AggregatorConflict
 from prioritydict import prioritydict
 from config import dotdynadir, dynahome
-
+from numpy import log, exp, sqrt
+from numpy.random import uniform
 from time import time
 
 
@@ -213,6 +223,8 @@ class Interpreter(object):
         self.agenda = prioritydict()
         self.parser_state = ''
 
+        self.tape = []
+
         def newchart(fn):
             arity = int(fn.split('/')[-1])
             return Chart(fn, arity, lambda: aggregator(self.agg_name[fn]))
@@ -220,8 +232,6 @@ class Interpreter(object):
         self.chart = ddict(newchart)
         self.rules = ddict(Rule)
         self.errors = {}
-        # misc
-        self.trace = file(dotdynadir / 'trace', 'wb')
 
     def new_fn(self, fn, agg):
         # check for aggregator conflict.
@@ -343,11 +353,17 @@ class Interpreter(object):
 
     def _go(self):
         "the main loop"
+
+        tape = self.tape
+
         changed = {}
         agenda = self.agenda
         errors = self.errors
         while agenda:
             item = agenda.pop_smallest()
+
+            tape.append(item)
+
             was = item.value
             try:
                 now = item.aggregator.fold()
@@ -441,16 +457,16 @@ class Interpreter(object):
         """
         assert os.path.exists(filename)
 
+        # TODO: need a new tracing tool
         # for debuggging
-        with file(filename) as h:
-            print >> self.trace, magenta % 'Loading new code'
-            print >> self.trace, yellow % h.read()
-
-        from numpy.random import uniform
+#        with file(filename) as h:
+#            print >> self.trace, magenta % 'Loading new code'
+#            print >> self.trace, yellow % h.read()
 
         env = {'_initializers': [], '_updaters': [], '_agg_decl': {},
                'chart': self.chart, 'build': self.build, 'peel': peel,
-               'parser_state': None, 'uniform': uniform}
+               'parser_state': None, 'uniform': uniform,
+               'log': log, 'exp': exp, 'sqrt': sqrt}
 
         # load generated code.
         execfile(filename, env)
@@ -541,7 +557,6 @@ def main():
     parser.add_argument('source', help='Path to Dyna source file (or plan if --plan=true).', nargs='?')
     parser.add_argument('--plan', action='store_true', default=False,
                         help='`source` specifies output of the compiler instead of dyna source code.')
-    parser.add_argument('--trace', default='/tmp/dyna.log')
     parser.add_argument('-i', dest='interactive', action='store_true', help='Fire-up an IPython shell.')
     parser.add_argument('-o', dest='output', help='Output chart.')
     parser.add_argument('--draw', action='store_true',
@@ -553,14 +568,6 @@ def main():
 
     interp = Interpreter()
 
-    if argv.trace == 'stderr':
-        interp.trace = sys.stderr
-    elif argv.trace == 'stdout':
-        interp.trace = sys.stdout
-    else:
-        interp.trace = file(argv.trace, 'wb')
-
-
     if argv.source:
 
         if not os.path.exists(argv.source):
index 3893b3c78ea62efb6cb2eeb8431ae3f04711aec9..89ed971cf4238671b08056b931334b8970953e93 100644 (file)
@@ -89,7 +89,7 @@ class REPL(cmd.Cmd, object):
         self.default(query)
 
         try:
-            [(_, (_, results))] = self.interp.chart['out/1'][self.lineno,:]
+            [(_, _, results)] = self.interp.chart['out/1'][self.lineno,:]
         except ValueError:
             print 'No results.'
             return
index a32ef64cca48312161223d8911fe1375e5c9c3b5..fcaadd22f90eb0719000fce01b8dd76321df7692 100644 (file)
@@ -147,4 +147,15 @@ def rule_source(span, src=None):
 
 
 if __name__ == '__main__':
-    rule_source('examples/papa.dyna:4:1-examples/papa.dyna:4:47')
+    #rule_source('examples/papa.dyna:4:1-examples/papa.dyna:4:47')
+    import sys
+
+    def t(xs):
+        if isinstance(xs, basestring):
+            return '"%s"' % xs
+        else:
+            return '&t(%s)' % ','.join(t(x) for x in xs)
+
+    for i, [x] in enumerate(parse_sexpr(sys.stdin.read())):
+        print 'sentence(%s) := %s.' % (i, t(x))
+        print