from utils import drepr, _repr, user_vars
from errors import AggregatorError
-"""
-class Aggregator(object):
- def fold(self):
- raise NotImplementedError
- def inc(self, val, ruleix, variables):
- raise NotImplementedError
- def dec(self, val, ruleix, variables):
- raise NotImplementedError
- def clear(self):
- raise NotImplementedError
-"""
class NoAggregatorError(Exception):
"""
def clear(self):
pass
+
NoAggregator = Aggregator()
+
class BAggregator(Counter, Aggregator):
# def __init__(self):
# super(BAggregator, self).__init__()
assert False, "This method should never be called."
-#class PlusEquals(object):
-# __slots__ = 'pos', 'neg'
-# def __init__(self):
-# self.pos = 0
-# self.neg = 0
-# def inc(self, val, ruleix, variables):
-# self.pos += val
-# def dec(self, val, ruleix, variables):
-# self.neg += val
-# def fold(self):
-# return self.pos - self.neg
-
-
class ColonEquals(BAggregator):
def inc(self, val, ruleix, _variables):
self[ruleix, val] += 1
raise AggregatorError('`=` got conflicting values %s' % (vs,))
-
-#from collections import namedtuple
-#class Result(namedtuple('Result', 'value variables')):
-# def __repr__(self):
-# return 'Result(value=%s, variables=%s)' % (_repr(self.value), drepr(dict(self.variables)))
-
-
class DictEquals(BAggregator):
def inc(self, val, _ruleix, variables):
if c > 0:
return k
+
class mean_equals(BAggregator):
def fold(self):
# TODO: support negative multiplicity or throw an error
n = sum(m for _, m in self.iteritems() if m > 0)
return reduce(operator.add, s) / n
+
class max_equals(BAggregator):
def fold(self):
s = [k for k, m in self.iteritems() if m > 0]
if len(s):
return max(s)
+
class min_equals(BAggregator):
def fold(self):
s = [k for k, m in self.iteritems() if m > 0]
if len(s):
return min(s)
-#class maxwithkey_equals(max_equals):
-# def fold(self):
-# m = max_equals.fold(self)
-# self.key = None
-# if m is not None:
-# if not hasattr(m, 'aslist') or len(m.aslist) != 2:
-# raise AggregatorError("argmax expects a pair of values")
-# self.key = m.aslist[1]
-# return m.aslist[0]
-
-#class minwithkey_equals(min_equals):
-# def fold(self):
-# m = min_equals.fold(self)
-# self.key = None
-# if m is not None:
-# if not hasattr(m, 'aslist') or len(m.aslist) != 2:
-# raise AggregatorError("argmin expects a pair of values")
-# self.key = m.aslist[1]
-# return m.aslist[0]
-
class plus_equals(BAggregator):
def fold(self):
if len(s):
return reduce(operator.add, s)
+
class times_equals(BAggregator):
def fold(self):
s = [k**m for k, m in self.iteritems() if m != 0]
if len(s):
return reduce(operator.mul, s)
-#class and_equals(BAggregator):
-# def fold(self):
-# s = [k for k, m in self.iteritems() if m > 0]
-# if len(s):
-# return reduce(lambda x,y: x and y, s)
-#class or_equals(BAggregator):
-# def fold(self):
-# s = [k for k, m in self.iteritems() if m > 0]
-# if len(s):
-# return reduce(lambda x,y: x or y, s)
-
-class boolean_or_equals(BAggregator):
+class or_equals(BAggregator):
def fold(self):
s = [x for x, m in self.iteritems() if m > 0]
if len(s):
return reduce(lambda x,y: x or y, s)
-class boolean_and_equals(BAggregator):
+
+class and_equals(BAggregator):
def fold(self):
s = [x for x, m in self.iteritems() if m > 0]
if len(s):
raise TypeError('%s is not Boolean.' % _repr(val))
return reduce(lambda x,y: x and y, s)
+
class set_equals(BAggregator):
def fold(self):
from stdlib import todyna
if len(s):
return todyna(s)
+
class bag_equals(BAggregator):
def fold(self):
from stdlib import todyna
'min=': min_equals,
'+=': plus_equals,
'*=': times_equals,
- '&=': boolean_and_equals,
- '|=': boolean_or_equals,
- ':-': boolean_or_equals,
+ '&=': and_equals,
+ ':-': or_equals,
'majority=': majority_equals,
'set=': set_equals,
'bag=': bag_equals,
'mean=': mean_equals,
-# 'argmax=': maxwithkey_equals,
-# 'argmin=': minwithkey_equals,
}
+
def aggregator(name, term):
"Create aggregator by ``name``."
e = TFunctor "cons"
[ _tNumeric (Left 1) :~ Span (Columns 1 1) (Columns 2 2) s
, TFunctor "cons"
- [ TFunctor "+"
+ [ TFunctor "+"
[ _tNumeric (Left 2) :~ Span (Columns 3 3) (Columns 4 4) s
, _tNumeric (Left 3) :~ Span (Columns 5 5) (Columns 6 6) s
]
:~ Span (Columns 3 3) (Columns 6 6) s
- , TFunctor "nil" [] :~ Span (Columns 7 7) (Columns 7 7) s
- ]
+ , TFunctor "nil" [] :~ Span (Columns 7 7) (Columns 7 7) s
+ ]
:~ Span (Columns 3 3) (Columns 7 7) s
]
:~ Span (Columns 0 0) (Columns 7 7) s
e = TFunctor "cons"
[ _tNumeric (Left 1) :~ Span (Columns 1 1) (Columns 2 2) s
, TFunctor "cons"
- [ TFunctor "+"
+ [ TFunctor "+"
[ _tNumeric (Left 2) :~ Span (Columns 3 3) (Columns 4 4) s
, _tNumeric (Left 3) :~ Span (Columns 5 5) (Columns 6 6) s
]
:~ Span (Columns 3 3) (Columns 6 6) s
- , TVar "X" :~ Span (Columns 7 7) (Columns 8 8) s
- ]
+ , TVar "X" :~ Span (Columns 7 7) (Columns 8 8) s
+ ]
:~ Span (Columns 3 3) (Columns 8 8) s
]
:~ Span (Columns 0 0) (Columns 8 8) s
where
e = Rule
(TFunctor "goal" [] :~ Span (Columns 0 0) (Columns 4 4) sr)
- "|="
+ ":-"
(TFunctor "true" [] :~ Span (Columns 4 4) (Columns 5 5) sr)
:~ ts
ts = Span (Columns 0 0) (Columns 5 5) sr
arbAtom = elements [ "f", "+" ]
prop_pragma_roundtrip :: Property
-prop_pragma_roundtrip =
+prop_pragma_roundtrip =
forAll arbPragma (\p -> p == unsafeParse (testPragma defDLC)
(BU.fromString
(flip PP.displayS "" $ PP.renderCompact