def _trace(self, q, depth_limit=-1): query = "$trace dict= _ is (%s), &(%s)." % (q, q) (new_rules, _changed) = self.add_rule(query, show_changed=False) try: [(_, _, results)] = self.interp.chart['$trace/0'][:, ] results = topython(results) results = [dict(r)['$val'] for r in results] except ValueError: print 'no items matching `%s`.' % q return finally: # cleanup: retract temporary rules used to answer query. for r in new_rules: self.interp.retract_rule(r) from post.trace import Tracer tracer = Tracer(self.interp) for item in results: print tracer(todyna(item), depth_limit=depth_limit) try: # drop temporary chart del self.interp.chart['$trace/0'] except KeyError: # query must have failed. pass
def _trace(self, q, depth_limit=-1): query = "$trace dict= _ is (%s), &(%s)." % (q, q) (new_rules, _changed) = self.add_rule(query, show_changed=False) try: [(_, _, results)] = self.interp.chart["$trace/0"][:,] results = topython(results) results = [dict(r)["$val"] for r in results] except ValueError: print "no items matching `%s`." % q return finally: # cleanup: retract temporary rules used to answer query. for r in new_rules: self.interp.retract_rule(r) from post.trace import Tracer tracer = Tracer(self.interp) for item in results: print tracer(todyna(item), depth_limit=depth_limit) try: # drop temporary chart del self.interp.chart["$trace/0"] except KeyError: # query must have failed. pass
def add_rule(self, index, span, anf, init=None, query=None): assert index not in self.rules for (x, label, ys) in anf.unifs: if x == anf.head: assert label == '&' head_fn = '%s/%d' % (ys[0], len(ys) - 1) break else: raise AssertionError('Did not find head.') self.rules[index] = rule = Rule(index) rule.span = hide_ugly_filename(span) rule.src = span_to_src(span).strip() rule.anf = anf rule.head_fn = head_fn self.update_coarse(rule) if init: rule.init = init init.rule = rule self.uninitialized_rules.append(rule) elif query: rule.query = query query.rule = rule # fix dependents if head_fn not in self._gbc: # retract and replan rules dependent on this predicate which is # now backchained. for d in self.rule_dep[head_fn]: if rule != d and d.head_fn not in self._gbc: self.needs_recompile(d) self._gbc[head_fn].append(query) if head_fn in self.chart: # if we've added a new rule we need to recompute memos for # existing memos. (TODO: can do slightly better than recompute # -- only need to evaluate contributions from this new rule) self.recompute_gbc_memo(head_fn) else: raise AssertionError("Can't add rule with out an initializer or query handler.") if True: args = (index, rule.src, todyna([anf.head, anf.agg, anf.result, anf.evals, anf.unifs]), init, query) fn = '$rule/%s' % len(args) if self.agg_name[fn] is None: self.new_fn(fn, ':=') rule.item = self.build(fn, *args) self.emit(rule.item, true, ruleix=None, variables=None, delete=False)
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 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 main(self, filename): filename = path(filename) if not filename.exists(): print 'file `%s` does not exist.' % filename return 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) contents = file(filename).read() for i, x in enumerate(parse_sexpr(contents)): interp.emit(obj(i), todyna(x), ruleix=None, variables=None, delete=False)
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 fold(self): if not self.empty(): return todyna([dict(b + (('$val', val),)) for (val, b), cnt in self.iteritems() if cnt > 0])
def fold(self): if any(m > 0 for m in self.itervalues()): x = list(Counter(self).elements()) x.sort() return todyna(x)
def fold(self): s = {x for x, m in self.iteritems() if m > 0} if len(s): return todyna(s)
def add_rule(self, index, span, anf, init=None, query=None): assert index not in self.rules for (x, label, ys) in anf.unifs: if x == anf.head: assert label == '&' head_fn = '%s/%d' % (ys[0], len(ys) - 1) break else: raise AssertionError('Did not find head.') self.rules[index] = rule = Rule(index) rule.span = hide_ugly_filename(span) rule.src = span_to_src(span).strip() rule.anf = anf rule.head_fn = head_fn self.update_coarse(rule) if init: rule.init = init init.rule = rule self.uninitialized_rules.append(rule) elif query: rule.query = query query.rule = rule # fix dependents if head_fn not in self._gbc: # retract and replan rules dependent on this predicate which is # now backchained. for d in self.rule_dep[head_fn]: if rule != d and d.head_fn not in self._gbc: self.needs_recompile(d) self._gbc[head_fn].append(query) if head_fn in self.chart: # if we've added a new rule we need to recompute memos for # existing memos. (TODO: can do slightly better than recompute # -- only need to evaluate contributions from this new rule) self.recompute_gbc_memo(head_fn) else: raise AssertionError( "Can't add rule with out an initializer or query handler.") if True: args = (index, rule.src, todyna( [anf.head, anf.agg, anf.result, anf.evals, anf.unifs]), init, query) fn = '$rule/%s' % len(args) if self.agg_name[fn] is None: self.new_fn(fn, ':=') rule.item = self.build(fn, *args) self.emit(rule.item, true, ruleix=None, variables=None, delete=False)