def transversal_yield_lv(sets: List[PySet], transversal: Tuple[PyValue, PyValue, PyValue]):
    """
    transversal is a tuple of length len(sets).
    Initially it consists of uninstaniated PyValues.
    When all the PyValues are instantiated, it is yielded as the answer.
    """
    remaining_indices = uninstantiated_indices_lv(transversal)
    if not remaining_indices:
        yield transversal
    else:
        if propagate:
            # If we are propagating, we will have removed used values from all the sets.
            # If any of those sets are now empty but are associated with
            # an uninstantiated position in transversal, fail;
            empty_sets = [sets[indx].is_empty() for indx in remaining_indices]
            if any(empty_sets):
                return None

        next_index = min(remaining_indices,
                         key=lambda indx: indx if not smallest_first else len(sets[indx]))
        # T_next is the PyValue to be instantiated this time around.
        T_next = transversal[next_index]
        used_values = PyList([transversal[i] for i in range(len(transversal)) if i not in remaining_indices])
        for _ in member(T_next, sets[next_index]):
            for _ in fails(member)(T_next, used_values):
                new_sets = sets if not propagate else [set.discard(T_next) for set in sets]
                yield from transversal_yield_lv(new_sets, transversal)
Beispiel #2
0
def all_all_distinct(lists: List[List[Term]]):
    for lst in lists:
        for _ in fails(all_distinct)(lst):
            # Fail if any of the lists fails all_distinct.
            return
    # Succeed if they all succeed.
    yield
Beispiel #3
0
def transversal_yield_lv(sets: List[PyList], so_far: PyList, Answer: Var):
  print(f'sets/[{", ".join([str(S) for S in sets])}]; so_far_reversed/{reversed(so_far)}')
  if not sets:
    yield from unify(reversed(so_far), Answer)
  else:
    [S, *Ss] = sets
    X = Var( )
    for _ in member(X, S):
      for _ in fails(member)(X, so_far):
        yield from transversal_yield_lv(Ss, PyList([X]) + so_far, Answer)
Beispiel #4
0
def transversal_yield_lv(Sets: List[PyList], Partial_Transversal: PyList,
                         Complete_Transversal: Var):
    print(
        f'Sets/[{", ".join([str(S) for S in Sets])}]; Partial_Transversal/{Partial_Transversal}'
    )
    if not Sets:
        yield from unify(Partial_Transversal, Complete_Transversal)
    else:
        (S, Ss) = (Sets[0], Sets[1:])
        Element = Var()
        for _ in member(Element, S):
            for _ in fails(member)(Element, Partial_Transversal):
                yield from transversal_yield_lv(
                    Ss, Partial_Transversal + PyList([Element]),
                    Complete_Transversal)
Beispiel #5
0
def tnvsl_dfs_gen_lv(sets, tnvsl):
    var_indxs = uninstan_indices_lv(tnvsl)

    if not var_indxs: yield tnvsl
    else:
        empty_sets = [sets[indx].is_empty() for indx in var_indxs]
        if any(empty_sets): return None

        nxt_indx = min(var_indxs, key=lambda indx: len(sets[indx]))
        used_values = PyList(
            [tnvsl[i] for i in range(len(tnvsl)) if i not in var_indxs])
        T_Var = tnvsl[nxt_indx]
        for _ in member(T_Var, sets[nxt_indx]):
            for _ in fails(member)(T_Var, used_values):
                new_sets = [set.discard(T_Var) for set in sets]
                yield from tnvsl_dfs_gen_lv(new_sets, tnvsl)