'Return an iterator over the edges in this chart.  Any
new edges that are added to the chart before the iterator
is exahusted will also be generated.  ``restrictions``
can be used to restrict the set of edges that will be
generated.
:param span: Only generate edges ``e`` where ``e.span()==span``
:param start: Only generate edges ``e`` where ``e.start()==start``
:param end: Only generate edges ``e`` where ``e.end()==end``
:param length: Only generate edges ``e`` where ``e.length()==length``
:param lhs: Only generate edges ``e`` where ``e.lhs()==lhs``
:param rhs: Only generate edges ``e`` where ``e.rhs()==rhs``
:param nextsym: Only generate edges ``e`` where
``e.nextsym()==nextsym``
:param dot: Only generate edges ``e`` where ``e.dot()==dot``
:param is_complete: Only generate edges ``e`` where
``e.is_complete()==is_complete``
:param is_incomplete: Only generate edges ``e`` where
``e.is_incomplete()==is_incomplete``
:rtype: iter(EdgeI)'

def select(self, **restrictions):

    if (restrictions == {}):
        return iter(self._edges)
    restr_keys = sorted(restrictions.keys())
    restr_keys = tuple(restr_keys)
    if (restr_keys not in self._indexes):
        self._add_index(restr_keys)
    vals = tuple((restrictions[key] for key in restr_keys))
    return iter(self._indexes[restr_keys].get(vals, []))
