def qmap(f, q):
    """
    Apply `f` post-order to all sub-terms in query term `q`.
    """
    if hasattr(q, '_fields'):
        attrs = []
        for field in q._fields:
            attr = getattr(q, field)
            attrs.append(qmap(f, attr))

        cls = type(q)
        obj = cls(*attrs)
        return f(obj)

    elif isinstance(q, (list, tuple)):
        cls = type(q)
        return cls(qmap(f, x) for x in q)

    return f(q)