Exemplo n.º 1
0
def member(E: Term, A_List: Union[SuperSequence, Var]):
    """
  Is E in A_List?
  """
    # If A_List is empty, it can't have a member. So fail.
    if A_List.is_empty():
        return

    # The following is an implicit 'or'. Either unify E with A_List.head() or call member(E, A_List.tail()).

    # The first case is easy.
    # for _ in unify(E, A_List.head( )):
    #   yield
    yield from unify(E, A_List.head())

    # The second case--member(E, A_List.tail())--is trickier.
    # Since A_List may be an open-ended LinkedList, A_List.tail() may be a Var.
    # In that case, we must first instantiate A_List.tail() to LinkedList( (Var, Var) ).
    A_List_Tail = A_List.tail()
    # Create A_List_New_Tail to be unified with A_List_Tail.
    # A_List_New_Tail will be A_List_Tail in most cases.
    # But if isinstance(A_List_Tail, Var), make A_List_New_Tail = LinkedList( (Var( ), Var( )) ).
    # In either case, unify A_List_Tail with A_List_New_Tail and call member(E, A_List_New_Tail).
    # An issue is that we can't import LinkedList since that would create an import cycle.
    # Instead use type(A_List), which will be LinkedList if A_List_Tail is a Var.
    A_List_New_Tail = type(A_List)(
        (Var(), Var())) if isinstance(A_List_Tail, Var) else A_List_Tail
    # If A_List_New_Tail is A_List_Tail, this unify does nothing.
    for _ in unify(A_List_New_Tail, A_List_Tail):
        yield from member(E, A_List_New_Tail)
Exemplo n.º 2
0
 def __add__(self, Other: Union[PySequence, Var]) -> PySequence:
     Other_EoT = Other.unification_chain_end()
     # If not, can't append.
     assert isinstance(Other_EoT, PySequence)
     Result = Var()
     for _ in append(self, Other_EoT, Result):
         Result_EoT = Result.unification_chain_end()
         # To make the PyCharm type checker happy.
         assert isinstance(Result_EoT, PySequence)
         return Result_EoT
Exemplo n.º 3
0
 def clue_4(self, Students: SuperSequence):
     """ 4. Erma has a $10,000 larger scholarship than Carrie.
     This means that Erma comes after the person who comes after Carrie.
 """
     yield from is_contiguous_in(
         [Student(name='Carrie'),
          Var(), Student(name='Erma')], Students)
Exemplo n.º 4
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)
Exemplo n.º 5
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)
Exemplo n.º 6
0
 def has_contiguous_sublist(self, As: List):
     """ Can As be unified with a segment of this list? """
     # Initially, As is a standard Python list. Make it a LinkedList.
     As = LinkedList(As)
     (len_As, len_self) = (len(As), len(self))
     if len_As == 0:
         yield  # Succeed once.
     elif len_As > len_self:
         return  # Fail.
     else:
         (Xs, Ys) = n_Vars(2)
         # Succeed if we can find a way to divide self into Xs and Ys so that As is an initial sublist of Ys.
         # for _ in forall([lambda: append(Xs, Ys, self),
         #                  lambda: append(As, Var( ), Ys)
         #                  ]):
         #   yield
         for _ in append(Xs, Ys, self):
             yield from append(As, Var(), Ys)
Exemplo n.º 7
0
  # If is_even_1(i) fails to unify, for _ in is_even_1(i) fails.
  # It works similarly to an if condition.
  evens_1 = [i for i in range(5) for _ in is_even_1(i)]
  print(f'\n1. evens_1: {evens_1}')    # => 1. evens_1: [0, 2, 4]

  # Same as is_even_1 but includes the range generator.
  def is_even_2(n: int, Res: Var) -> Generator[None, None, None]:
    for i in range(n):
        for _ in unify_pairs([ (PyValue(i % 2 == 0), PyValue(True)),
                               (PyValue(i), Res)
                               ]):
          yield

  # Can reuse this variable in all examples.
  # After each example, it is left uninstantiated.
  Result = Var()

  # This version uses the function directly as a generator.
  evens_2 = [Result.get_py_value() for _ in is_even_2(7, Result)]
  print(f'2. evens_2: {evens_2}')    # => 2. evens_2: [0, 2, 4, 6]

  evens_3 = []
  # Here we apply the decorator function explicitly.
  # bool_yield_wrapper makes it possible to use the generator with .has_more() as a boolean.
  # The has_more() function, defined in the BoolYIeldWrapper class, both calls next() on
  # the generator and returns True or False depending on whether next() has succeeded. If
  # next() succeeds, the next value is unified with Result. The next value is also stored
  # within the BoolYIeldWrapper object as self.next, and can be retrieved that way.
  with bool_yield_wrapper(is_even_2)(9, Result) as is_even_gen_3:
    while is_even_gen_3.has_more( ):
      evens_3.append(Result.get_py_value())
Exemplo n.º 8
0
                lambda: unify_pairs([(Xs, LinkedList((XZ_Head, Xs_Tail))),
                                     (Zs, LinkedList((XZ_Head, Zs_Tail)))]),
                lambda: append(Xs_Tail, Ys, Zs_Tail)
            ])
    ]):
        yield


if __name__ == '__main__':

    print(emptyLinkedList)
    E = PyValue(3)
    for _ in member(E, emptyLinkedList):
        print(f'Error: should not get here.')

    A = LinkedList((Var(), Var()))
    A112 = A[4:11:2]
    A37 = A[3:7]
    print(f'\nA: {A}\nA[3:7]: {A37}\nA[4:11:2]: {A112}')
    for _ in unify(A37, LinkedList('ABCD')):
        print(f'\nA: {A}\nA[3:7]: {A37}\nA[4:11:2]: {A112}')
        print()

    print(f'A[:4]: {A[:4]}')
    A_tail = A.tail()
    print(f'A.tail()[:3]: {A_tail[:3]}')
    print(f'A.tail().tail()[:2]: {A.tail().tail()[:2]}')

    print(f'\nemptyLinkedList: {emptyLinkedList}')

    Xs = LinkedList([*range(10)])
Exemplo n.º 9
0
                *Xs.unification_chain_end().args,
                *Ys.unification_chain_end().args
            ]
            yield from unify_sequences(XYs, Zs.args)
            # for _ in unify_sequences(XYs, Zs.args):
            #   yield


if __name__ == '__main__':

    print(PyTuple((1, 2, 3)))
    print(PyList([1, 2, 3]))

    Xs = PyList(['Python'])  # list(map(PyValue, range(3)))
    Ys = PyList([PyValue('Q')])  # [PyValue(i+3) for i in range(3)]
    Zs = Var()

    print(f'\nappend({Xs}, {Ys}, {Zs})')
    for _ in append(Xs, Ys, Zs):
        print(f'\tXs: {Xs}, Ys: {Ys}, Zs: {Zs}')

    Xs = Var()
    Ys = Var()
    Zs = PyList(list(range(5)))

    print(f'\nappend({Xs}, {Ys}, {Zs})')
    for _ in append(Xs, Ys, Zs):
        print(f'\tXs: {Xs}, Ys: {Ys}, Zs: {Zs}')

    Xs = Var()
    Ys = Var()
Exemplo n.º 10
0
 def clue_4(self, Stdnts):
     """ Marie has a $10,000 larger scholarship than
     Lynn. """
     yield from is_contiguous_in(
         [Stdnt(name='Lynn'),
          Var(), Stdnt(name='Marie')], Stdnts)
Exemplo n.º 11
0
 def clue_2(self, Stdnts):
     """ Emmy studies either Math or Bio. """
     # Create Major as a local logic variable.
     Major = Var()
     for _ in member(Stdnt(name='Emmy', major=Major), Stdnts):
         yield from member(Major, PyList(['Math', 'Bio']))
Exemplo n.º 12
0
        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)


if __name__ == '__main__':
    print('\n\n latest')
    Trace.trace = True
    print(f'\n{"=" * 15}')
    (A, B, C) = (Var(), Var(), Var())
    Py_Sets = [PySet(set) for set in sets]
    N = PyValue(6)
    for _ in tnvsl_dfs_gen_lv(Py_Sets, (A, B, C)):
        sum_string = ' + '.join(str(i) for i in (A, B, C))
        equals = '==' if A + B + C == N else '!='
        print(f'{sum_string} {equals} 6')
        if A + B + C == N: break
    print(f'{"=" * 15}')

# propagate = True
# smallest_first = True
# def find_transversal_with_sum_n(py_sets: List[PySet], n: PyValue):
#     (A, B, C) = (Var(), Var(), Var())
#     for _ in tnvsl_dfs_gen_lv(py_sets, (A, B, C)):
#         if A + B + C == n:
Exemplo n.º 13
0
        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)


if __name__ == '__main__':
    print(
        f'\n{"-"*75}\ntransversal_yield_lv([[1, 2, 3], [2, 4], [1]], [], Ans)\n'
    )
    Complete_Transversal = Var()
    for _ in transversal_yield_lv(
        [PyList([1, 2, 3]), PyList([2, 4]),
         PyList([1])], PyList([]), Complete_Transversal):
        print(f'{" "*30}  =>  {Complete_Transversal}')
"""
---------------------------------------------------------------------------
transversal_yield_lv([[1, 2, 3], [2, 4], [1]], [], Ans)

Sets/[[1, 2, 3], [2, 4], [1]]; Partial_Transversal/[]
Sets/[[2, 4], [1]]; Partial_Transversal/[1]
Sets/[[1]]; Partial_Transversal/[1, 2]
Sets/[[1]]; Partial_Transversal/[1, 4]
Sets/[[2, 4], [1]]; Partial_Transversal/[2]
Sets/[[1]]; Partial_Transversal/[2, 4]
Sets/[]; Partial_Transversal/[2, 4, 1]
Exemplo n.º 14
0
"""                  transversal_yield_lv                   """
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)


if __name__ == '__main__':
  print(f'\n{"-"*75}\ntransversal_yield_lv([[1, 2, 3], [2, 4], [1]], [], Ans)\n')
  Ans = Var( )
  for _ in transversal_yield_lv([PyList([1, 2, 3]), PyList([2, 4]), PyList([1])], PyList([]), Ans):
    print(f'{" "*30}  =>  {Ans}')

"""
---------------------------------------------------------------------------
transversal_yield_lv([[1, 2, 3], [2, 4], [1]], [], Ans)

sets/[[1, 2, 3], [2, 4], [1]]; so_far_reversed/[]
sets/[[2, 4], [1]]; so_far_reversed/[1]
sets/[[1]]; so_far_reversed/[1, 2]
sets/[[1]]; so_far_reversed/[1, 4]
sets/[[2, 4], [1]]; so_far_reversed/[2]
sets/[[1]]; so_far_reversed/[2, 4]
sets/[]; so_far_reversed/[2, 4, 1]
                                =>  [1, 4, 2]