r"""
Kontsevich graph sums

"""
from sage.kontsevich_graph_series.kontsevich_graph import KontsevichGraph
from sage.structure.element import ModuleElement
from sage.modules.module import Module

class KontsevichGraphSum(ModuleElement):
    def __init__(self, parent, terms):
        """
        Kontsevich graph sum.
        """
        if terms == 0:
            terms = []
        if not isinstance(terms, list):
            raise TypeError('Input must be a list of terms.')
        if not all(isinstance(t, tuple) and len(t) == 2 for t in terms):
            raise TypeError('Terms must be (coefficient, graph) tuples.')
        if not all(c in parent.base_ring() and isinstance(g, KontsevichGraph)
                   for (c,g) in terms):
            raise TypeError('Coefficients must be in base ring, and ' +
                            'graphs must be KontsevichGraphs.')
        self._terms = terms
        ModuleElement.__init__(self, parent=parent)
    def _rmul_(self, c):
        return self.parent()([(c*d,g) for (d,g) in self._terms])
    def _add_(self, other):
        return self.parent()(self._terms + other._terms)
    def __cmp__(self, other):
        return cmp(self._terms, other._terms)
    def __hash__(self):
        return hash(tuple(self._terms))
    def _repr_(self):
        return repr(self._terms)

class KontsevichGraphSums(Module):
    Element = KontsevichGraphSum
    def _element_constructor_(self, terms):
        if isinstance(terms, KontsevichGraphSum): terms = terms._terms
        return self.element_class(self, terms)
    def __cmp__(self, other):
        if not isinstance(other, KontsevichGraphSums):
            return cmp(type(other), KontsevichGraphSums)
        return cmp(self.base_ring(), other.base_ring())
    def _an_element_(self):
        return self.element_class(self, [])

@@ -186,16 +186,73 @@
 t Module
+%0Afrom sage.symbolic.ring import is_SymbolicExpressionRing
 %0A%0Aclass 
@@ -770,16 +770,52 @@
         
+ and getattr(g, '_immutable', False)
  for (c,
@@ -944,16 +944,26 @@
 must be 
+immutable 
 Kontsevi
@@ -1381,42 +1381,620 @@
 def 
-_repr_(self):%0A        return repr(
+reduce(self):%0A        graphs = set(g for (c,g) in self._terms)%0A        coefficient = lambda g: sum(c for (c,h) in self._terms if h == g)%0A        self._terms = %5B(coefficient(g), g) for g in graphs%5D%0A    def _repr_(self):%0A        self.reduce()%0A        parenthesize = lambda c: str(c)%0A        if is_SymbolicExpressionRing(self.base_ring()):%0A            from sage.symbolic.operators import add_vararg%0A            is_sum = lambda x: self.base_ring()(x).operator() == add_vararg%0A            parenthesize = lambda c: '(%25s)' %25 c if is_sum(c) else c%0A        return ' + '.join('%25s*(%25s)' %25 (parenthesize(c), g) for (c,g) in 
 self

Add basic reduction (collecting terms) and representation (for printing) to KontsevichGraphSum.