returns all the tags that are relevant at this state
    cache should be a dictionary and it is updated
    by the function

def reltags(self, src, cache=None):
    '''
    returns all the tags that are relevant at this state
    cache should be a dictionary and it is updated
    by the function
    '''
    if not self._tag_assocs:
      return set()

    # fucking python and it's terrible support for recursion makes this
    # far more complicated than it needs to be
    if cache == None:
      cache = {}

    q = _otq()
    q.append(src)
    updateq = _otq()


    while q:
      i = q.popleft()
      if i in cache:
        continue

      cache[i] = set()
      for (s,t) in self.transitions_to(i):
        q.append(s)
        if self.is_tagged(t,s,i):
          cache[i].add((self.tag(t,s,i),s, i))
        updateq.appendleft((i, s))

    while updateq:
      i = updateq.popleft()
      cache[i[0]].update(cache[i[1]])

    return cache[src]