def i_required_att_group_cardinality(min_: N, max_: unlimitedNat, qore: Quads_or_Error) -> Set(sctIdGroup):
    if quad_direction(qore) == source_direction:
        nzg = set([q for q in quads_for(qore).v if q.g != zero_group])
        zg = set([q for q in quads_for(qore).v if q.g == zero_group])
        nzg_pass = [q_nz for q_nz in nzg
                    if evalCardinality(min_, max_, [q for q in quads_for(qore).v if q.s == q_nz.s and q.g == q_nz.g])]
        zg_pass = [q_zg for q_zg in zg if evalCardinality(min_, max_, set(q_zg))]
        return Set(sctIdGroup)([sctIdGroup(q.s, quadGroup(q)) for q in (nzg_pass + zg_pass)])
    else:
        nzg = set([q for q in quads_for(qore).v if q.g != zero_group and q.t.inran('t_sctid')])
        zg = set([(q.t, q) for q in quads_for(qore).v if q.g == zero_group and q.t.inran('t_sctid')])
        nzg_pass = [q_nz for q_nz in nzg
                    if evalCardinality(min_, max_, [q for q in quads_for(qore).v if q.t == q_nz.t and q.g == q_nz.g])]
        zg_pass = [q_zg for q_zg in zg if evalCardinality(min_, max_, set(q_zg))]
        return Set(sctIdGroup(nzg_pass + zg_pass))
def i_required_group_cardinality(min_: N, max_: unlimitedNat, groups: Set(sctIdGroup)) -> Set(sctId):
    return Set(sctId)(
        [s.first for s in groups.v if evalCardinality(min_, max_, [g for g in groups.v if g.first == s.first])])