示例#1
0
    def test_two_without_branching(self):
        with conj(traveller), conj as testConj:
            Eq(traveller, self.var1)
            Eq(traveller, 'Alice')

        result = list(testConj.run())
        self.assertEqual(len(result), 1)
        self.assertEqual(result[0][self.var1], 'Alice')
示例#2
0
def rule1(street):
    """1. There are five houses."""
    with conj(house0, house1, house2, house3, house4):
        isHouse(house0)
        isHouse(house1)
        isHouse(house2)
        isHouse(house3)
        isHouse(house4)
        Eq(street, [house0, house1, house2, house3, house4])
示例#3
0
def indexoIs(index, val, lst):
    with conj as base:
        firsto(lst, val)
    with conj(rest), conj as recurse:
        resto(lst, rest)
        indexoIs(index - 1, val, rest)

    if index <= 0:
        return base
    else:
        return recurse
示例#4
0
    def test_two_with_branching(self):
        with conj(rattle, dum), conj as testConj:
            with disj:
                Eq(rattle, 'spoiled')
                Eq(rattle, 'spoilt')
            Eq(rattle, self.var2)
            Eq(dum, 'angry')
            Eq(dum, self.var1)

        result = list(testConj.run())
        self.assertEqual(len(result), 2)
        for r in result:
            self.assertEqual(r[self.var1], 'angry')
        isSpoiled = [st for st in result if st[self.var2] == 'spoiled']
        isSpoilt = [st for st in result if st[self.var2] == 'spoilt']
        self.assertEqual(len(isSpoiled), 1)
        self.assertEqual(len(isSpoilt), 1)
示例#5
0
    def __run__(self, state):
        lst = state.reify(self.lst)
        start = state.reify(self.start)
        end = state.reify(self.end)
        sublst = state.reify(self.sublst)

        lvar_count = varq(lst) + varq(start) + varq(end) + varq(sublst)
        if lvar_count > 1:
            with conj(lst_len), conj as full_gen:
                list_leno(lst, lst_len)
                rangeo(start)
                rangeo(end)
                sliceo(lst, start, end, sublst)
            yield from full_gen.run(state)
        elif varq(lst):
            if start is None:
                if end is None:
                    # If both start and end are none,
                    #  then the lst and sublst are the
                    #  same.
                    yield from Eq(lst, sublst).run(state)
                    return
                elif end >= 0:
                    # The end is a positive number, the start is
                    #  undefined, therefore the list could be the
                    #  sublist or go past the end.
                    if end < len(sublst):
                        yield state.update(valid=False)
                        return
                    else:
                        lst_len = end
                else:
                    # If we know how far from the end it is,
                    #  then we know the total length of the
                    #  list because everything before the
                    #  end is the sublst.
                    with conj as bounded_length:
                        list_leno(lst, len(sublst) + -end)
                        sliceo(lst, start, end, sublst)
                    yield from bounded_length.run(state)
                    return
            elif start >= 0:
                if end is None:
                    # Full length is known because start is where
                    #  it begins, and its end matches the end of the
                    #  sublst.
                    lst_len = start + len(sublst)
                    with conj as bounded_length:
                        list_leno(lst, len(sublst) + start)
                        sliceo(lst, start, end, sublst)
                    yield from bounded_length.run(state)
                    return
                elif end >= 0:
                    # Where end is the last value from the lst in the
                    #  sublst, we know that the lst is at least that long,
                    #  but could be longer.
                    if (end - start) < len(sublst):
                        yield state.update(valid=False)
                        return
                    else:
                        lst_len = min(end - start, len(sublst))
                else:
                    # Since we know where it starts, the interval in the middle, and
                    #  how far from the end the end of the sublst is, that means
                    #  that lst can only have one length.
                    with conj as bounded_length:
                        list_leno(lst, start + len(sublst) - end)
                        sliceo(lst, start, end, sublst)
                    yield from bounded_length.run(state)
                    return
            else:
                if end is None:
                    # The end will match the list, the position of the front
                    #  of the sublst is defined from the end, therefore the
                    #  start can't go before the front of the sublst, and
                    #  the lst can be any length that's longer than the sublst.
                    if -start < len(sublst):
                        yield state.update(valid=False)
                        return
                    else:
                        lst_len = max(len(sublst), -start)
                elif end >= 0:
                    # The start is measured from the back, the end from the beginning.
                    # Where either the start could hang off the beginning or the end
                    #  could hang off the end of `lst` and still match the sublist,
                    #  ex. ['Mad Hatter', 'March Hare', 'The Dormouse'][-1:100] == ['The Dormouse']
                    #  and ['March Hare', 'The Dormouse'][-1:100] == ['The Dormouse']
                    # Multiple lists can match, limited by the absolute value of the largest
                    #  absolute value between the start and end, so in the above example the
                    #  list could be as long as 100 elements and still return the same value
                    #  so long as the last value is 'The Dormouse'.
                    if end < len(sublst) or abs(start) < len(sublst):
                        yield state.update(valid=False)
                        return
                    else:
                        lst_len = len(sublst)
                        while lst_len <= (max(end, abs(start) + 1)):
                            with conj as lst_gen:
                                list_leno(lst, lst_len)
                                sliceo(lst, start, end, sublst)
                            yield from lst_gen.run(state)
                            lst_len += 1
                        return
                else:
                    if end <= start:
                        yield from Eq(lst, []).run(state)
                        return
                    lst_len = -start
            while True:
                with conj as lst_gen:
                    list_leno(lst, lst_len)
                    sliceo(lst, start, end, sublst)
                yield from lst_gen.run(state)
                lst_len += 1
        elif varq(sublst):
            yield from Eq(sublst, lst[start:end]).run(state)
        elif varq(start):
            front = lst[:end]
            if len(sublst) > len(front):
                yield state.update(valid=False)
            else:
                start_val_pos = end - len(sublst)
                start_val_neg = start_val_pos - len(lst)
                if start_val_pos > 0:
                    with conj as get_start:
                        with disj:
                            Eq(start, start_val_pos)
                            Eq(start, start_val_neg)
                        sliceo(lst, start, end, sublst)
                    yield from get_start.run(state)
                else:
                    with conj as get_start_zero:
                        with disj:
                            Eq(start, None)
                            Eq(start, 0)
                        sliceo(lst, start, end, sublst)
                    yield from get_start_zero.run(state)
                    start_val = -1
                    while True:
                        with conj as get_start:
                            with disj:
                                Eq(start, start_val)
                            sliceo(lst, start, end, sublst)
                        yield from get_start.run(state)
                        start_val -= 1
        elif varq(end):
            back = lst[start:]
            if len(sublst) > len(back):
                yield state.update(valid=False)
            else:
                end_val_pos = len(sublst) + start
                if end_val_pos < len(lst):
                    end_val_neg = end_val_pos - len(lst)
                    with conj as get_end:
                        with disj:
                            Eq(end, end_val_pos)
                            Eq(end, end_val_neg)
                        sliceo(lst, start, end, sublst)
                    yield from get_end.run(state)
                else:
                    with conj as get_endless:
                        Eq(end, None)
                        sliceo(lst, start, end, sublst)
                    yield from get_endless.run(state)

                    while True:
                        with conj as get_end:
                            Eq(end, end_val_pos)
                            sliceo(lst, start, end, sublst)
                        yield from get_end.run(state)
                        end_val_pos += 1
        else:
            if len(sublst) > len(lst):
                yield state.update(valid=False)
            else:
                yield from Eq(lst[start:end], sublst).run(state)
示例#6
0
def isHouse(var):
    with conj(nationality, pet, color, drink, brand):
        Eq(var, [nationality, pet, color, drink, brand])
示例#7
0
def rule10(street):
    """10. The Norwegian lives in the first house."""
    with conj(house):
        firsto(street, house)
        indexoIs(nati, norwegian, house)
示例#8
0
def rule9(street):
    """9. In the middle house they drink milk."""
    with conj(house):
        indexoIs(2, house, street)
        indexoIs(drinki, milk, house)
示例#9
0
def rule5(street):
    """5. The green house is immediately to the left of the white house."""
    with conj(left, right):
        inordero(left, right, street)
        indexoIs(colori, green, left)
        indexoIs(colori, white, right)
示例#10
0
def rule0(street):
    """Who Owns the Zebra?"""
    with conj(house):
        membero(house, street)
        indexoIs(peti, "zebra", house)