The python modules required
- $ easy_install path.py ipython pygments
+ $ easy_install numpy ipython pygments path.py
You should probably run
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.
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.
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"
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
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
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:
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, '}'
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:
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()
- 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
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
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.
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
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]))
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.
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()
"""
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)
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',
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):
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
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