def propose_addition_bound_gen(
    cons: cl.Node,
    curr: state_def.State,
    bounds: list[r.Bound],
    goal_bound_idx: r.Bound,
    gen_class: AssetFactory,
    filter_domain: r.Domain,
):
    """
    Try to propose any addition move involving the specified bound and generator
    """

    goal_bound = bounds[goal_bound_idx]
    logger.debug(
        f"attempt propose_addition for {gen_class.__name__} rels={len(goal_bound.domain.relations)}"
    )

    assert r.domain_finalized(goal_bound.domain), goal_bound
    if not active_for_stage(goal_bound.domain, filter_domain):
        raise ValueError(
            f"Attempted to propose {goal_bound} but it should not be active for {filter_domain=}"
        )
    if len(goal_bound.domain.relations) == 0:
        raise ValueError(
            f"Attempted to propose unconstrained {gen_class.__name__} with no relations"
        )

    found_tags = usage_lookup.usages_of_factory(gen_class)
    goal_pos, *_ = t.decompose_tags(goal_bound.domain.tags)
    if not t.implies(found_tags, goal_pos) and found_tags.issuperset(goal_pos):
        raise ValueError(f"Got {gen_class=} for {goal_pos=}, but it had {found_tags=}")

    prop_dom = goal_bound.domain.intersection(filter_domain)
    prop_dom.tags.update(found_tags)

    # logger.debug(f'GOAL {goal_bound.domain} \nFILTER {filter_domain}\nPROP {prop_dom}\n\n')
    logger.debug(
        "GOAL %s\n FILTER %s\n PROP %s\n",
        goal_bound.domain.repr(abbrv=True),
        filter_domain.repr(abbrv=True),
        prop_dom,
    )

    assert active_for_stage(prop_dom, filter_domain)

    search_rels = [
        rd for rd in prop_dom.relations if not isinstance(rd[0], cl.NegatedRelation)
    ]

    all_assignments = propose_relations.find_assignments(curr, search_rels)

    i = None
    for i, assignments in enumerate(all_assignments):
        logger.debug("Found assignments %d %s %s", i, len(assignments), assignments)

        def sample_name():
            return f"{np.random.randint(1e6):04d}_{gen_class.__name__}"

        target_name = next(
            sample_name() for _ in range(100) if sample_name() not in curr.objs
        )

        yield moves.Addition(
            names=[target_name],  # decided later
            gen_class=gen_class,
            relation_assignments=assignments,
            temp_force_tags=prop_dom.tags,
        )

    if i is None:
        # raise ValueError(f'Found no assignments for {prop_dom}')
        logger.debug(f"Found no assignments for {prop_dom.repr(abbrv=True)}")
        pass
    else:
        logger.debug(f"Exhausted all assignments for {gen_class=}")

    Try to propose any addition move involving the specified bound and generator
    
infinigen/core/constraints/example_solver/propose_discrete.py