def test_reify(): x, y, z = var(), var(), var() s = {x: 1, y: 2, z: (x, y)} assert reify(x, s) == 1 assert reify(10, s) == 10 assert reify((1, y), s) == (1, 2) assert reify((1, (x, (y, 2))), s) == (1, (1, (2, 2))) assert reify(z, s) == (1, 2)
def allgoal(s): for i, g in enumerate(goals): try: goal = goaleval(reify(g, s)) except EarlyGoalError: continue other_goals = tuple(goals[:i] + goals[i+1:]) return unique(interleave(goaleval( reify((lallfirst,) + other_goals, ss))(ss) for ss in goal(s)), key=dicthash) else: raise EarlyGoalError()
def reify_object(o, s): """ Reify a Python object with a substitution >>> from logpy.unifymore import reify_object >>> from logpy import var >>> class Foo(object): ... def __init__(self, a, b): ... self.a = a ... self.b = b ... def __str__(self): ... return "Foo(%s, %s)"%(str(self.a), str(self.b)) >>> x = var('x') >>> f = Foo(1, x) >>> print(f) Foo(1, ~x) >>> print(reify_object(f, {x: 2})) Foo(1, 2) """ obj = object.__new__(type(o)) d = reify(o.__dict__, s) if d == o.__dict__: return o obj.__dict__.update(d) return obj
def test_objects_full(): _unify.add((Foo, Foo, dict), unify_object) _unify.add((Bar, Bar, dict), unify_object) _reify.add((Foo, dict), reify_object) _reify.add((Bar, dict), reify_object) assert unify_object(Foo(1, Bar(2)), Foo(1, Bar(var(3))), {}) == {var(3): 2} assert reify(Foo(var('a'), Bar(Foo(var('b'), 3))), {var('a'): 1, var('b'): 2}) == Foo(1, Bar(Foo(2, 3)))
def test_logify_slots(): x = var('x') f = Aslot() f.a = 1 f.b = 2 g = Aslot() g.a = 1 g.b = x assert unify(f, g, {}) == {x: 2} assert reify(g, {x: 2}) == f
def test_unify_isinstance_list(): class Foo2(Foo): pass x = var('x') y = var('y') f, g = Foo2(1, 2), Foo2(x, y) _unify.add((Foo, Foo, dict), unify_object) _reify.add((Foo, dict), reify_object) assert unify(f, g, {}) assert reify(g, {x: 1, y: 2}) == f
def test_objects_full(): _unify.add((Foo, Foo, dict), unify_object) _unify.add((Bar, Bar, dict), unify_object) _reify.add((Foo, dict), reify_object) _reify.add((Bar, dict), reify_object) assert unify_object(Foo(1, Bar(2)), Foo(1, Bar(var(3))), {}) == {var(3): 2} assert reify(Foo(var('a'), Bar(Foo(var('b'), 3))), { var('a'): 1, var('b'): 2 }) == Foo(1, Bar(Foo(2, 3)))
def test_unify_isinstance_list(): class Foo2(Foo): pass x = var('x') y = var('y') f, g = Foo2(1, 2), Foo2(x, y) unify_isinstance_list.append(((Foo, Foo), unify_object)) reify_isinstance_list.append((Foo, reify_object)) assert unify(f, g, {}) assert reify(g, {x: 1, y: 2}) == f unify_isinstance_list.pop() reify_isinstance_list.pop()
def test_objects_full(): unify_dispatch[(Foo, Foo)] = unify_object unify_dispatch[(Bar, Bar)] = unify_object reify_dispatch[Foo] = reify_object reify_dispatch[Bar] = reify_object assert unify_object(Foo(1, Bar(2)), Foo(1, Bar(var(3))), {}) == {var(3): 2} assert reify(Foo(var('a'), Bar(Foo(var('b'), 3))), {var('a'): 1, var('b'): 2}) == Foo(1, Bar(Foo(2, 3))) del reify_dispatch[Bar] del reify_dispatch[Foo] del unify_dispatch[(Foo, Foo)] del unify_dispatch[(Bar, Bar)]
def run(n, x, *goals, **kwargs): """ Run a logic program. Obtain n solutions to satisfy goals. n - number of desired solutions. See ``take`` 0 for all None for a lazy sequence x - Output variable goals - a sequence of goals. All must be true >>> from logpy import run, var, eq >>> x = var() >>> run(1, x, eq(x, 1)) (1,) """ results = (reify(x, s) for s in goaleval(lallearly(*goals))({})) return take(n, unique(results, key=multihash))
def reify_object_attrs(o, s, attrs): """ Reify only certain attributes of a Python object >>> from logpy.unifymore import reify_object_attrs >>> from logpy import var >>> class Foo(object): ... def __init__(self, a, b): ... self.a = a ... self.b = b ... def __str__(self): ... return "Foo(%s, %s)"%(str(self.a), str(self.b)) >>> x = var('x') >>> y = var('y') >>> f = Foo(x, y) >>> print(f) Foo(~x, ~y) >>> print(reify_object_attrs(f, {x: 1, y: 2}, ['a', 'b'])) Foo(1, 2) >>> print(reify_object_attrs(f, {x: 1, y: 2}, ['a'])) Foo(1, ~y) This function is meant to be partially specialized >>> from functools import partial >>> reify_Foo_a = partial(reify_object_attrs, attrs=['a']) attrs contains the list of attributes which participate in reificiation """ obj = object.__new__(type(o)) d = dict(zip(attrs, [getattr(o, attr) for attr in attrs])) d2 = reify(d, s) # reified attr dict if d2 == d: return o obj.__dict__.update(o.__dict__) # old dict obj.__dict__.update(d2) # update w/ reified vals return obj
def reify_object_slots(o, s): """ >>> from logpy.unifymore import reify_object_slots >>> from logpy import var >>> class Foo(object): ... __slots__ = 'a', 'b' ... def __init__(self, a, b): ... self.a = a ... self.b = b ... def __str__(self): ... return "Foo(%s, %s)"%(str(self.a), str(self.b)) >>> x = var('x') >>> print(reify_object_slots(Foo(x, 2), {x: 1})) Foo(1, 2) """ attrs = [getattr(o, attr) for attr in o.__slots__] new_attrs = reify(attrs, s) if attrs == new_attrs: return o else: newobj = object.__new__(type(o)) for slot, attr in zip(o.__slots__, new_attrs): setattr(newobj, slot, attr) return newobj
def test_objects_as_logpy(): x = var() assert unify(Foo2(1, x), Foo2(1, 2), {}) == {x: 2} assert reify(Foo2(1, x), {x: 2}) == Foo2(1, 2)
def _reify(o, s): """ Reify a Python ``slice`` object """ return slice(*reify((o.start, o.stop, o.step), s))
def test_reify_dict(): x, y = var(), var() s = {x: 2, y: 4} e = {1: x, 3: {5: y}} assert reify(e, s) == {1: 2, 3: {5: 4}}
def allgoal(s): g = goaleval(reify(goals[0], s)) return unique(interleave( goaleval(reify((lall,) + tuple(goals[1:]), ss))(ss) for ss in g(s)), key=dicthash)
def test_reify_list(): x, y = var(), var() s = {x: 2, y: 4} e = [1, [x, 3], y] assert reify(e, s) == [1, [2, 3], 4]
def f(goals): for goal in goals: try: yield goaleval(reify(goal, s))(s) except EarlyGoalError: pass
def test_logify(): x = var('x') f = A(1, 2) g = A(1, x) assert unify(f, g, {}) == {x: 2} assert reify(g, {x: 2}) == f
def test_reify_complex(): x, y = var(), var() s = {x: 2, y: 4} e = {1: [x], 3: (y, 5)} assert reify(e, s) == {1: [2], 3: (4, 5)}
def test_reify_slice(): x = var('x') assert reify(slice(1, var(2), 3), {var(2): 10}) == slice(1, 10, 3)
def test_unifiable(): x = var('x') f = Aslot(1, 2) g = Aslot(1, x) assert unify(f, g, {}) == {x: 2} assert reify(g, {x: 2}) == f