def values(self, x): if x in self.vs: return _repr(self.vs[x]) try: return _repr(eval(x.replace('\\"', '"'))) except (SyntaxError, NameError): if x.startswith('_'): # looks like an intermediate variable and it's not in vs # TODO: we could double check that this is a temp variable by # looking it up in anf. return '?' return x
def values(self, x): if x in self.vs: return _repr(self.vs[x]) try: return _repr(eval(x.replace('\\"', '"'))) except (SyntaxError, NameError): if x.startswith( '_' ): # looks like an intermediate variable and it's not in vs # TODO: we could double check that this is a temp variable by # looking it up in anf. return '?' return x
def do_vquery(self, q): """ See query. """ results = self._query(q) if results is None: return if len(results) == 0: print 'No results.' return results = [(b.pop('$val'), b) for b in results] for val, b in sorted(results): print _repr(val), 'where', drepr(b) print
def do_vquery(self, q): """ See query. """ results = self._query(q) if results is None: return if len(results) == 0: print "No results." return results = [(b.pop("$val"), b) for b in results] for val, b in sorted(results): print _repr(val), "where", drepr(b) print
def fold(self): s = [x for x, m in self.iteritems() if m > 0] for val in s: if val is not true: raise TypeError('%s is not true.' % _repr(val)) # TODO: can short circuit as soon as we get a true... but above we check # the types.. so we don't get the benefit. if len(s): return true
def fold(self): s = [x for x, m in self.iteritems() if m > 0] if len(s): for val in s: if not isbool(val): raise TypeError('%s is not Boolean.' % _repr(val)) # TODO: can short circuit as soon as we get a true... but above we # check the types.. so we don't get the benefit. return todyna(any(s))
def dig(head, visited, tail, groups, interp, depth_limit=-1): if depth_limit >= 0 and len(tail) >= depth_limit: return [yellow % '*max depth*'] if head in tail: return ['%s = %s' % (yellow % head, _repr(head.value))] \ + ['|'] \ + branch([[red % 'continue as before (cyclic structure, will continue forever)']]) \ + [''] if head in visited: return ['%s = %s' % (yellow % head, _repr(head.value))] \ + ['|'] \ + branch([[red % 'continue as before (shared structure)']]) \ + [''] if head not in groups: return [] visited.add(head) contribs = [] for ruleix in groups[head]: for (_, _, body, vs) in groups[head][ruleix]: crux = Crux(head, interp.rules[ruleix], body, dict(vs)) block = branch([ dig(x, visited, tail + (head, ), groups, interp, depth_limit) for x in body ]) if block: contribs.append(crux.fvalue() + [''] + crux.format() + ['|'] + block) else: contribs.append(crux.fvalue() + [''] + crux.format() + ['']) return ['%s = %s' % (yellow % head, cyan % _repr(head.value))] \ + ['|'] \ + branch(contribs)
def __repr__(self): rows = [ term for term in self.intern.values() if term.value is not None ] if not rows: return '' heading = [self.name, '=' * len(self.name)] # special handing `:-` aggregator -- only list true facts (and errors) if self.agg_name == ':-': lines = [] for term in sorted(rows): if term.value is true: lines.append('%s.' % _repr(term)) else: # e.g. $error lines.append('%s = %s.' % (_repr(term), _repr(term.value))) if self.arity != 0: lines = heading + lines # heading return '\n'.join(lines) if self.arity == 0: [term] = rows return '%s = %s.' % (term, _repr(term.value)) p = [(_repr(term), _repr(term.value)) for term in sorted(rows)] lines = [] terms, values = zip(*p) widths = map(len, terms) fmt = '%%-%ds = %%s.' % min(max(widths), 40) for term, value in zip(terms, values): lines.append(fmt % (term, value)) return '\n'.join(heading + lines)
def __repr__(self): rows = [term for term in self.intern.values() if term.value is not None] if not rows: return '' heading = [self.name, '='*len(self.name)] # special handing `:-` aggregator -- only list true facts (and errors) if self.agg_name == ':-': lines = [] for term in sorted(rows): if term.value is true: lines.append('%s.' % _repr(term)) else: # e.g. $error lines.append('%s = %s.' % (_repr(term), _repr(term.value))) if self.arity != 0: lines = heading + lines # heading return '\n'.join(lines) if self.arity == 0: [term] = rows return '%s = %s.' % (term, _repr(term.value)) p = [(_repr(term), _repr(term.value)) for term in sorted(rows)] lines = [] terms, values = zip(*p) widths = map(len, terms) fmt = '%%-%ds = %%s.' % min(max(widths), 40) for term, value in zip(terms, values): lines.append(fmt % (term, value)) return '\n'.join(heading + lines)
def dig(head, visited, tail, groups, interp, depth_limit=-1): if depth_limit >= 0 and len(tail) >= depth_limit: return [yellow % '*max depth*'] if head in tail: return ['%s = %s' % (yellow % head, _repr(head.value))] \ + ['|'] \ + branch([[red % 'continue as before (cyclic structure, will continue forever)']]) \ + [''] if head in visited: return ['%s = %s' % (yellow % head, _repr(head.value))] \ + ['|'] \ + branch([[red % 'continue as before (shared structure)']]) \ + [''] if head not in groups: return [] visited.add(head) contribs = [] for ruleix in groups[head]: for (_, _, body, vs) in groups[head][ruleix]: crux = Crux(head, interp.rules[ruleix], body, dict(vs)) block = branch([dig(x, visited, tail + (head,), groups, interp, depth_limit) for x in body]) if block: contribs.append(crux.fvalue() + [''] + crux.format() + ['|'] + block) else: contribs.append(crux.fvalue() + [''] + crux.format() + ['']) return ['%s = %s' % (yellow % head, cyan % _repr(head.value))] \ + ['|'] \ + branch(contribs)
def _changed(self, changed): if not changed: return changed = [x for x in changed if not x.fn.startswith('$rule/')] if not changed: return print print 'Changes' print '=======' for x in sorted(changed): if x.fn in self.interp._gbc: # skip BC continue print '%s = %s.' % (x, _repr(x.value)) print
def _changed(self, changed): if not changed: return changed = [x for x in changed if not x.fn.startswith("$rule/")] if not changed: return print print "Changes" print "=======" for x in sorted(changed): if x.fn in self.interp._gbc: # skip BC continue print "%s = %s." % (x, _repr(x.value)) print
def do_query(self, q): """ Query solution. Consider the following example; > f(1) := 1. > f(2) := 4. There a few versions of query: - `vquery` shows variable bindings > vquery f(X) 1 where {X=1} 4 where {X=1} - `query` shows variable bindings applied to query > query f(X) f(1) = 1. f(2) = 4. - `trace` is an introspection tool for visualizing the derivation of an item and its value. Type `help trace` for more information. """ results = self._query(q) if results is None: return if len(results) == 0: print 'No results.' return print for term, result in sorted( (subst(q, result), result) for result in results): print '%s = %s.' % (term, _repr(todyna(result['$val']))) print
def do_query(self, q): """ Query solution. Consider the following example; > f(1) := 1. > f(2) := 4. There a few versions of query: - `vquery` shows variable bindings > vquery f(X) 1 where {X=1} 4 where {X=1} - `query` shows variable bindings applied to query > query f(X) f(1) = 1. f(2) = 4. - `trace` is an introspection tool for visualizing the derivation of an item and its value. Type `help trace` for more information. """ results = self._query(q) if results is None: return if len(results) == 0: print "No results." return print for term, result in sorted((subst(q, result), result) for result in results): print "%s = %s." % (term, _repr(todyna(result["$val"]))) print
def dump_errors(self, out=None): if out is None: out = sys.stdout # separate errors into aggregation errors and update handler errors I = defaultdict(lambda: defaultdict(list)) E = defaultdict(lambda: defaultdict(list)) for item, x in self.error.items(): if isinstance(item, Rule): continue (val, es) = x for e, h in es: if h is None: I[item.fn][type(e)].append((item, e)) else: assert h.rule.index in self.rules E[h.rule][type(e)].append((item, val, e)) # We only dump the error chart if it's non empty. if not I and not E and not self.uninitialized_rules and not self.recompile: return print >> out print >> out, red % 'Errors' print >> out, red % '======' # aggregation errors for fn in sorted(I): print >> out, 'Error(s) aggregating %s:' % fn for etype in I[fn]: print >> out, ' %s:' % etype.__name__ for i, (item, e) in enumerate(sorted(I[fn][etype])): if i >= 5: print >> out, ' %s more ...' % (len(I[fn][etype]) - i) break print >> out, ' `%s`: %s' % (item, e) print >> out # errors pertaining to rules for r in sorted(E): print >> out, 'Error(s) in rule %s:' % r.index, r.span print >> out for line in r.src.split('\n'): print >> out, ' ', line print >> out for etype in E[r]: print >> out, ' %s:' % etype.__name__ for i, (item, value, e) in enumerate(sorted(E[r][etype])): if i >= 5: print >> out, ' %s more ...' % (len(E[r][etype]) - i) break print >> out, ' when `%s` = %s' % (item, _repr(value)) if 'maximum recursion depth exceeded' in str(e): # simplify recurision limit error because it prints some # unpredictable stuff. print >> out, ' maximum recursion depth exceeded' else: print >> out, ' %s' % (e) #print >> out #print >> out, magenta % indent(e.traceback.rstrip(), indent=' ') print >> out print >> out, r.render_ctx(e.exception_frame, indent=' ') print >> out # uninitialized rules if self.uninitialized_rules: print >> out, red % 'Uninitialized rules' print >> out, red % '===================' for rule in sorted(self.uninitialized_rules): e = self.error[rule] print >> out, 'Failed to initialize rule:' print >> out, ' ', rule.src print >> out, ' due to `%s`' % e print >> out, rule.render_ctx(e.exception_frame, indent=' ') print >> out # rules which failed to recompile if self.recompile: print >> out, red % 'Failed to recompile' print >> out, red % '===================' for rule in sorted(self.recompile): e = self.error[rule] print >> out, 'Failed to recompile rule:' print >> out, ' ', rule.src print >> out, ' with error' for line in str(e).split('\n'): print >> out, ' ', line print >> out print >> out