def test_partial_constraint(polar): class User: pass class Post: pass polar.register_class(User) polar.register_class(Post) polar.load_str("f(x: User) if x.user = 1;") polar.load_str("f(x: Post) if x.post = 1;") partial = Partial("x", TypeConstraint("User")) results = polar.query_rule("f", partial) first = next(results)["bindings"]["x"] and_args = unwrap_and(first) assert len(and_args) == 2 assert and_args[0] == Expression("Isa", [Variable("_this"), Pattern("User", {})]) unify = unwrap_and(and_args[1]) assert unify == Expression( "Unify", [Expression("Dot", [Variable("_this"), "user"]), 1] ) with pytest.raises(StopIteration): next(results)
def test_partial(polar): polar.load_str("f(1);") polar.load_str("f(x) if x = 1 and x = 2;") results = polar.query_rule("f", Partial("x")) first = next(results) x = first["bindings"]["x"] assert x == 1 second = next(results) x = second["bindings"]["x"] # Top level should be and and_args = unwrap_and(x) assert and_args[0] == Expression("Unify", [Variable("_this"), 1]) polar.load_str("g(x) if x.bar = 1 and x.baz = 2;") results = polar.query_rule("g", Partial("x")) first = next(results) x = first["bindings"]["x"] and_args = unwrap_and(x) assert len(and_args) == 2 assert unwrap_and(and_args[0]) == Expression( "Unify", [Expression("Dot", [Variable("_this"), "bar"]), 1]) assert unwrap_and(and_args[1]) == Expression( "Unify", [Expression("Dot", [Variable("_this"), "baz"]), 2])
def test_partial(polar): polar.load_str("f(1);") polar.load_str("f(x) if x = 1 and x = 2;") results = polar.query_rule("f", Variable("x"), accept_expression=True) first = next(results) x = first["bindings"]["x"] assert x == 1 with pytest.raises(StopIteration): next(results) polar.load_str("g(x) if x.bar = 1 and x.baz = 2;") results = polar.query_rule("g", Variable("x"), accept_expression=True) first = next(results) x = first["bindings"]["x"] and_args = unwrap_and(x) assert len(and_args) == 2 assert and_args[0] == Expression( "Unify", [1, Expression("Dot", [Variable("_this"), "bar"])]) assert and_args[1] == Expression( "Unify", [2, Expression("Dot", [Variable("_this"), "baz"])])
def test_dot_path(): single = Expression("Dot", [Variable("_this"), "created_by"]) assert dot_path(single) == ("created_by", ) double = Expression("Dot", [single, "username"]) assert dot_path(double) == ("created_by", "username") triple = Expression("Dot", [double, "first"]) assert dot_path(triple) == ("created_by", "username", "first")
def test_dot_path(): non_dot = Expression("And", []) assert dot_path(non_dot) == () this = Variable("_this") assert dot_path(this) == (this, ) var = Variable("x") assert dot_path(var) == (var, ) single_dot = Expression("Dot", [this, "created_by"]) assert dot_path(single_dot) == (this, "created_by") double_dot = Expression("Dot", [single_dot, "username"]) assert dot_path(double_dot) == (this, "created_by", "username") triple_dot = Expression("Dot", [double_dot, "first"]) assert dot_path(triple_dot) == (this, "created_by", "username", "first")
def test_partial_unification(): Oso.load_str("f(x, y) if x = y and x = 1;") results = Oso.query_rule("f", Variable("x"), Variable("y"), accept_expression=True) first = next(results)["bindings"] assert first["x"] == 1 assert first["y"] == 1 with pytest.raises(StopIteration): next(results) Oso.load_str("g(x, y) if x = y and y > 1;") results = Oso.query_rule("g", Variable("x"), Variable("y"), accept_expression=True) first = next(results)["bindings"] assert first["x"] == Expression("And", [Expression("Gt", [Variable("_this"), 1])]) assert first["y"] == Expression("And", [Expression("Gt", [Variable("_this"), 1])])
def test_partial_unification(): Oso.load_str("f(x, y) if x = y and x = 1;") results = Oso.query_rule("f", Variable("x"), Variable("y"), accept_expression=True) first = next(results)["bindings"] assert first["x"] == 1 assert first["y"] == 1 with pytest.raises(StopIteration): next(results) Oso.load_str("g(x, y) if x = y and y > 1;") results = Oso.query_rule("g", Variable("x"), Variable("y"), accept_expression=True) first = next(results)["bindings"] # TODO not ideal that these are swapped in order (y = x) not (x = y). # this is a hard case, we want the (y > 1) to be this in both cases AND keep the x = y. assert first["x"] == Expression( "And", [ Expression("Unify", [Variable("y"), Variable("_this")]), Expression("Gt", [Variable("y"), 1]), ], ) assert first["y"] == Expression( "And", [ Expression("Unify", [Variable("_this"), Variable("x")]), Expression("Gt", [Variable("_this"), 1]), ], )