Simplify error message pertaining to retracting a rule and when a query or trace
fails.
if head in tail:
return ['%s = %s' % (yellow % head, head.value)] \
+ ['|'] \
- + branch([[red % 'continue as before (cyclic structure, will continue forever)']])
+ + branch([[red % 'continue as before (cyclic structure, will continue forever)']]) \
+ + ['']
if head in visited:
return ['%s = %s' % (yellow % head, head.value)] \
+ ['|'] \
- + branch([[red % 'continue as before (shared structure)']])
+ + branch([[red % 'continue as before (shared structure)']]) \
+ + ['']
if head not in groups:
return []
return ['%s = %s' % (yellow % head, cyan % _repr(head.value))] \
+ ['|'] \
- + branch(contribs) + ['']
+ + branch(contribs) #\
+# + ['']
def branch(xs):
return label
fn_args = [self.get_function(y) for y in x.body]
- if not label.isalpha() and not label.startswith('&') and len(fn_args) == 2: # infix
+
+ # infix
+ if (not label.isalpha() and not label.startswith('&') and len(fn_args) == 2) \
+ or label in ('in', 'and', 'or'):
[a,b] = fn_args
return '(%s %s %s)' % (a, label, b)
return '%s(%s)' % (label, ', '.join(fn_args))
else:
+
if not g.incoming[x]: # input
if re.match('u[A-Z].*', x): # user variable
return x[1:] + (cyan % '=%s' % self.values(x))
if len(g.incoming[x]) > 1:
return ' = '.join('(%s%s)' % (self.get_function(e), (cyan % '=%s' % self.values(e.head))) for e in g.incoming[x])
+
[e] = g.incoming[x]
if e.label == '=':
return self.get_function(e)
+ # handle lists
+ if e.label == '& cons':
+ _e = e
+ a = []
+ while e.label == '& cons':
+ x, xs = e.body
+ [e] = g.incoming[xs]
+ a.append(self.get_function(x))
+ if e.label == '& nil':
+ return '[%s]' % ', '.join(a)
+ else:
+ return self.get_function(_e) # malformed list.
+
if e.label.startswith('&'):
return self.get_function(e)
try:
query = "$query dict= %s." % q
+
self.default(query, show_changed=False)
+
try:
[(_, _, results)] = self.interp.chart['$query/0'][:,]
return results
except ValueError:
return []
+
finally:
# cleanup:
# retract newly added rules.
for r in self.interp.new_rules:
- self.interp.retract_rule(r)
+ if r in self.interp.rules:
+ self.interp.retract_rule(r)
try:
# drop $out chart
if len(results) == 0:
print 'No results.'
return
- for val, bindings in results:
+ for val, bindings in sorted(results):
print _repr(val), 'where', drepr(dict(bindings))
print
try:
query = "$trace dict= _ is %s, &(%s)." % (q,q)
+
self.default(query, show_changed=False)
+
try:
[(_, _, results)] = self.interp.chart['$trace/0'][:,]
except ValueError:
# cleanup:
# retract newly added rules.
for r in self.interp.new_rules:
- self.interp.retract_rule(r)
+ if r in self.interp.rules:
+ self.interp.retract_rule(r)
try:
# drop $out chart
def split(s, delim='\s+'):
return todynalist(re.split(delim, s))
+def crash():
+ class Crasher(Exception):
+ pass
+ raise Crasher('Hey, you asked for it!')
+
def pycall(name, *args):
"""
Temporary foreign function interface - call Python functions from dyna!
return todyna(x)
def todyna(x):
- if isinstance(x, (list, tuple)):
+ if isinstance(x, (set, list, tuple)):
return todynalist(x)
return x
def topython(x):
- if isinstance(x, (Cons, Nil)):
+ if isinstance(x, Cons) or x is Nil:
return x.aslist
return x