--- /dev/null
+# .coveragerc to control coverage.py
+[run]
+branch = True
+
+[report]
+# Regexes for lines to exclude from consideration
+exclude_lines =
+ # Have to re-enable the standard pragma
+ pragma: no cover
+
+ # Don't complain about missing debug-only code:
+ #def __repr__
+ #if self\.debug
+
+ # Don't complain if tests don't hit defensive assertion code:
+ raise AssertionError
+ raise NotImplementedError
+
+ # Don't complain if non-runnable code isn't run:
+ if 0:
+ if __name__ == .__main__.:
+
+ignore_errors = True
+
+[html]
+directory = coverage_html_report
class Aggregator(object):
def fold(self):
- raise AggregatorError("item doesn't have an aggregator.")
+ raise NotImplementedError('')
def inc(self, _val, _ruleix, _variables):
- pass
+ raise NotImplementedError('')
def dec(self, _val, _ruleix, _variables):
- pass
+ raise NotImplementedError('')
def clear(self):
- pass
+ raise NotImplementedError('')
NoAggregator = Aggregator()
def dec(self, val, _ruleix, _variables):
self[val] -= 1
def fromkeys(self, *_):
- assert False, "This method should never be called."
+ raise NotImplementedError("This method should never be called.")
def empty(self):
return not any(m > 0 for m in self.itervalues())
class majority_equals(BAggregator):
def fold(self):
- [(k,c)] = self.most_common(1)
+ [(k,c)] = self.most_common(1) # how are ties handled?
if c > 0:
return k
heading = [self.name, '='*len(self.name)]
- # special handing or-equals aggregators -- only list true facts (and errors)
+ # 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))
- elif term.value: # e.g. $error
+ else: # e.g. $error
lines.append('%s = %s.' % (_repr(term), _repr(term.value)))
if self.arity != 0:
lines = heading + lines # heading
def run_uninitialized(self):
q = set(self.uninitialized_rules)
failed = []
+ # run to fixed point
while q:
rule = q.pop()
try:
if isinstance(item, Rule):
continue
(v, es) = x
- self.error[item] = (v, [(e, h) for e, h in es if h is None or h.rule.index == rule.index])
+ self.error[item] = (v, [(e, h) for e, h in es if h is None or h.rule == rule])
self.recompute_coarse()
# Communication with Dyna compiler
def dynac(self, filename):
- """
- Compile a file full of dyna code. Note: this routine does not pass along
- parser_state.
- """
+ "Compile a string of dyna code."
return self.compiler.dynac(filename)
def dynac_code(self, code):
print >> out
# errors pertaining to rules
- for r in sorted(E, key=lambda r: r.index):
+ 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'):
if self.uninitialized_rules:
print >> out, red % 'Uninitialized rules'
print >> out, red % '==================='
- for rule in sorted(self.uninitialized_rules, key=lambda r: r.index):
+ for rule in sorted(self.uninitialized_rules):
e = self.error[rule]
print >> out, 'Failed to initialize rule:'
print >> out, ' ', rule.src
if self.recompile:
print >> out, red % 'Failed to recompile'
print >> out, red % '==================='
- for rule in sorted(self.recompile, key=lambda r: r.index):
+ for rule in sorted(self.recompile):
e = self.error[rule]
print >> out, 'Failed to recompile rule:'
print >> out, ' ', rule.src
self._heap = [(v, k) for k, v in self.iteritems()]
heapify(self._heap)
- def smallest(self):
- """
- Return the item with the lowest priority.
-
- Raises IndexError if the object is empty.
- """
- heap = self._heap
- v, k = heap[0]
- while k not in self or self[k] != v:
- heappop(heap)
- v, k = heap[0]
- return k
-
def pop_smallest(self):
"""
Return the item with the lowest priority and remove it.
Raises IndexError if the object is empty.
"""
+
+ # Implementation note: Since we don't eagerly remove an element when
+ # it's priority changes, we need to filter our pops to make sure the
+ # priority isn't stale.
+
heap = self._heap
v, k = heappop(heap)
- while k not in self or self[k] != v:
+ while k not in self or self[k] != v: # while `k` is stale
v, k = heappop(heap)
del self[k]
return k
"""
if not q.strip():
- print 'No query specified. Type `help trace` for usage information.'
+ print 'No query specified. Type `help trace` for usage.'
return
if q.endswith('.'):
self.value = None
self.aggregator = None
- def __eq__(self, other):
- return self is other
+# def __eq__(self, other):
+# return self is other
def __cmp__(self, other):
if self is other:
else:
yield a, (None,), a
- def __iter__(self):
- return iter(self.aslist)
+# def __iter__(self):
+# return iter(self.aslist)
class Error(NoIntern, Term):
def like_chart(self):
return iter([])
- def __iter__(self):
- return iter([])
+# def __iter__(self):
+# return iter([])
Nil = _Nil()
--- /dev/null
+> a majority= 1.
+| a majority= 1.
+| a majority= 1.
+| a majority= 2.
+| a majority= 2.
+
+Changes
+=======
+a = 1.
+
+%> rules
+%Rules
+%=====
+% 0: a majority= 1.
+% 1: a majority= 1.
+% 2: a majority= 1.
+% 3: a majority= 2.
+% 4: a majority= 2.
+
+
+% ties are broken arbitrarily
+> retract_rule 0
+> retract_rule 1
+
+Changes
+=======
+a = 2.
+
+% retract remaining rules to make sure the aggregator goes null
+> retract_rule 2
+> retract_rule 3
+> retract_rule 4
+
+Changes
+=======
+a = null.
+
+
+> a mean= 1.
+| a mean= 2.
+| a mean= 3.
+
+Changes
+=======
+a = 2.0.
+
+%> rules
+%
+%Rules
+%=====
+% 5: a mean= 1.
+% 6: a mean= 2.
+% 7: a mean= 3.
+
+> retract_rule 5
+
+Changes
+=======
+a = 2.5.
+
+> retract_rule 6
+
+Changes
+=======
+a = 3.0.
+
+> retract_rule 7
+
+Changes
+=======
+a = null.
+
+
+
+% A few simple tests for `*=`
+
+> a *= 3.
+| a *= 3.
+
+Changes
+=======
+a = 9.
+
+> retract_rule 8
+
+Changes
+=======
+a = 3.
+
+> retract_rule 9
+
+Changes
+=======
+a = null.
>>> 1 new errors. Type `sol` for details.
+> sol
+
+Solution
+========
+e = $error.
+
+Errors
+======
+Error(s) aggregating e/0:
+ TypeError:
+ `e`: false is not true.
+
> e :- true.
f/2
===
f(1,2).
-f(2,2).
\ No newline at end of file
+f(2,2).
+
+
+% type checking for `|=`
+
+> foo |= 10.
+
+Changes
+=======
+foo = $error.
+>>> 1 new errors. Type `sol` for details.
+
+
+> goo &= true.
+
+Changes
+=======
+goo = true.
+
+> goo &= false.
+
+Changes
+=======
+goo = false.
+
+
+> goo &= 10.
+
+Changes
+=======
+goo = $error.
+>>> 1 new errors. Type `sol` for details.
=======
thingsbag = [true, 1, 1, 2, "three"].
thingset = [true, 1, 2, "three"].
+
+
+% comparison operator
+> foobar([]).
+| foobar([1,2]).
+| foobar([1,3]).
+| foobar("a").
+| foobar(&a, &b).
+| foobar(&a, &c).
+
+Changes
+=======
+foobar("a") = true.
+foobar([1, 2]) = true.
+foobar([1, 3]) = true.
+foobar([]) = true.
+foobar(a,b) = true.
+foobar(a,c) = true.
--- /dev/null
+> rules
+
+No rules found.
+
+> a += 1.
+
+Changes
+=======
+a = 1.
+
+> rules
+
+Rules
+=====
+ 0: a += 1.
+
+> a += 1
+
+ERROR: Line doesn't end with period.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Retract rule
+
+> retract_rule asdf
+
+Please specify an integer. Type `help retract_rule` to read more.
+
+> retract_rule 1000
+
+Rule 1000 not found.
+List available by typing `rules`
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Query
+
+> query
+
+No query specified. Type `help query` for usage.
+
+> query a.
+
+Queries don't end with a dot.
+
+> query a
+
+a = 1.
+
+%%% TODO: a query with an error > query a/0
+
+> query xxxx
+
+No results.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% vquery
+
+> vquery
+
+No query specified. Type `help query` for usage.
+
+> vquery a.
+
+Queries don't end with a dot.
+
+> vquery a
+
+1 where {}
+
+> vquery xxxx
+
+No results.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% trace
+
+> trace
+
+No query specified. Type `help trace` for usage.
+
+> trace a.
+
+Queries don't end with a dot.
+
+> trace xxxx
+
+no items matching `xxxx`.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Help
+
+> help query
+
+ 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.
+
+> help vquery
+
+See query.