from dataclasses import dataclass


@dataclass
class ReducePath:
    path: list[bool]
    index: int = 0

    def explore(self, choice):
        self.index = 0
        self.path.append(choice)
        return self

    def didGuess(self):
        return self.index > len(self.path)

    def dispensable(self):
        self.index += 1
        try:
            return self.path[self.index - 1]
        except IndexError:
            return False


def reduce(predicate, rtree):
    r = ReducePath([])
    i = rtree(r)

    if not predicate(i):
        return None

    while r.didGuess():
        # Explore the left tree
        i = rtree(r.explore(True))
        # If the predcate fails, move right
        r.path[-1] = predicate(i)

    return i


def debug(predicate):
    def newpred(i):
        t = predicate(i)
        print(t, i)
        return t

    return newpred


def reduce_list(items: list):
    def rtree(r: ReducePath) -> list:
        results = []
        for i in items:
            if r.dispensable():
                continue
            results.append(i)
        return results

    return rtree


if __name__ == "__main__":
    reduce(debug(lambda a: 1 in a), reduce_list([1, 2, 3]))