class SearchProblem:
    
    def start_state():
        pass
    def is_goal(state):
        pass
    def neighbours(state):
        pass

class Edge:
    def __init__(self, from_state, to_state, action, cost=1):
        self.from_state = from_state
        self.to_state = to_state
        self.action = action
        self.cost = cost

    def __repr__(self):
        return f"Edge({self.from_state} -> {self.to_state}, action='{self.action}', cost={self.cost})"

class WaterJugProblem(SearchProblem):
    def __init__(self, capacity=(4, 2), start=(0, 0)):
        self.capacity = capacity
        self.start = start
    
    def start_state(self):
        return self.start
    
    def is_goal(self, state):
        x, y = state
        if (x == 4):
            return True
        else:
            return False
    
    def neighbours(self, state):
        x, y = state
        edges = []
        seen = set()

        def add(to_state, action):
            if (to_state != state) and to_state not in seen:
                seen.add(to_state)
                edges.append(Edge(state, to_state, action, 1))
        
        add(self.capacity[0], y, "Fill A")
        add(x, self.capacity[1], "Fill B")
        add((0, y), "Empty A")
        add((x, 0), "Empty B")

        # pour
