def test_appendo(): reset_names() w, x, y, z = variables("w, x, y, z") goal = conj(same(z, (x, y)), appendo(x, y, [1, 2, 3])) assert list(run(z, goal)) == [([], [1, 2, 3]), ([1], [2, 3]), ([1, 2], [3]), ([1, 2, 3], [])] goal = conj(same(z, (x, y)), appendo([1, 2, 3], x, y)) assert list(run(3, z, goal)) == [([], [1, 2, 3]), (['_0'], [1, 2, 3, '_0']), (['_0', '_1'], [1, 2, 3, '_0', '_1'])] goal = conj(same(z, (x, y)), appendo(x, [1, 2, 3], y)) assert list(run(3, z, goal)) == [([], [1, 2, 3]), (['_0'], ['_0', 1, 2, 3]), (['_0', '_1'], ['_0', '_1', 1, 2, 3])] goal = conj(same(z, (w, x, y)), appendo(w, x, y)) assert list(run(6, z, goal)) == [([], [], []), ([], ['_0'], ['_0']), (['_0'], [], ['_0']), ([], ['_0', '_1'], ['_0', '_1']), (['_0'], ['_1'], ['_0', '_1']), (['_0', '_1'], [], ['_0', '_1'])]
def run(*args): if isinstance(args[0], int): n = args[0] args = args[1:] else: n = None var, goals = args[0], args[1:] if isinstance(var, tuple): raise NotImplementedError("run with multiple fresh variables") if n is None: return map(reify(var), run_goal(conj(*goals))) else: return map(reify(var), run_goal(n, conj(*goals)))
def fresh(body): spec = inspect.signature(body) var_names = spec.parameters.keys() fresh_vars = [variables(gen_name(name)) for name in var_names] subgoals = body(*fresh_vars) try: return conj(*subgoals) except TypeError: return subgoals
def test_symeq_integers(): a, x, y, z = variables("a, x, y, z") goal = conj(same(a, (x, y, z)), rangeo(-1, y, 2), rangeo(1, z, 3), symeq(x + y, z)) assert list(run(a, goal)) == [(2, -1, 1), (1, 0, 1), (3, -1, 2), (0, 1, 1), (2, 0, 2), (1, 1, 2)]
def test_conj_succeed(): x = variables("x") goal = conj(same(42, x), succeed) assert list(goal(Substitution())) == [Substitution({x: 42})]
def test_conj(): x = variables("x") goal = conj(same("olive", x), same("oil", x)) assert set(goal(Substitution())) == set()