def test_unify_slice(): x = var('x') y = var('y') assert unify(slice(1), slice(1), {}) == {} assert unify(slice(1, 2, 3), x, {}) == {x: slice(1, 2, 3)} assert unify(slice(1, 2, None), slice(x, y), {}) == {x: 1, y: 2}
def test_unify_complex(): assert unify((1, {2: 3}), (1, {2: 3}), {}) == {} assert unify((1, {2: 3}), (1, {2: 4}), {}) == False assert unify((1, {2: var(5)}), (1, {2: 4}), {}) == {var(5): 4} assert unify({1: (2, 3)}, {1: (2, var(5))}, {}) == {var(5): 3} assert unify({1: [2, 3]}, {1: [2, var(5)]}, {}) == {var(5): 3}
def unify_object_attrs(u, v, s, attrs): """ Unify only certain attributes of two Python objects >>> from logpy.unifymore import unify_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) >>> g = Foo(1, 2) >>> print(unify_object_attrs(f, g, {}, ['a', 'b'])) #doctest: +SKIP {~x: 1, ~y: 2} >>> print(unify_object_attrs(f, g, {}, ['a'])) {~x: 1} This function is meant to be partially specialized >>> from functools import partial >>> unify_Foo_a = partial(unify_object_attrs, attrs=['a']) attrs contains the list of attributes which participate in reificiation """ return unify([getattr(u, a) for a in attrs], [getattr(v, a) for a in attrs], s)
def test_seq_registry(): seq_registry.append((Foo, lambda x: (type(x), x.a, x.b))) x = var('x') y = var('y') f, g = Foo(1, 2), Foo(x, y) assert unify(f, g, {}) == {x: 1, y: 2} seq_registry.pop()
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_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 unify_object(u, v, s): """ Unify two Python objects Unifies their type and ``__dict__`` attributes >>> from logpy.unifymore import unify_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) >>> g = Foo(1, 2) >>> unify_object(f, g, {}) {~x: 2} """ if type(u) != type(v): return False return unify(u.__dict__, v.__dict__, s)
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
def _unify(u, v, s): """ Unify a Python ``slice`` object """ return unify((u.start, u.stop, u.step), (v.start, v.stop, v.step), s)
def goal_eq(s): result = unify(u, v, s) if result is not False: yield result
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_unify_dict(): assert unify({1: 2}, {1: 2}, {}) == {} assert unify({1: 2}, {1: 3}, {}) == False assert unify({2: 2}, {1: 2}, {}) == False assert unify({1: var(5)}, {1: 2}, {}) == {var(5): 2}
def test_unify_seq(): assert unify((1, 2), (1, 2), {}) == {} assert unify([1, 2], [1, 2], {}) == {} assert unify((1, 2), (1, 2, 3), {}) == False assert unify((1, var(1)), (1, 2), {}) == {var(1): 2} assert unify((1, var(1)), (1, 2), {var(1): 3}) == False
def test_unify(): assert unify(1, 1, {}) == {} assert unify(1, 2, {}) == False assert unify(var(1), 2, {}) == {var(1): 2} assert unify(2, var(1), {}) == {var(1): 2}
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)