def test_combo(self): x_obj = qterm.Variable('x', pq('obj')) x_var = qterm.Variable('x', pq('?a')) phi_var = qterm.Constant('phi', pq('?b->bool')) phi_obj = qterm.Constant('phi', pq('obj->bool')) combo_var = term_builder.build_combination(phi_var, x_var) combo_obj = term_builder.build_combination(phi_obj, x_obj) combo_var2 = term_builder.build_combination(phi_var, x_obj) x, combo = unify_types([x_obj, combo_var]) assert x == x_obj assert combo == combo_obj phi_a, phi_b = unify_types([phi_var, phi_obj]) assert phi_a == phi_var assert phi_b == phi_obj combo_a, combo_b = unify_types([combo_var, combo_obj]) assert combo_a == combo_obj assert combo_b == combo_obj combo_a, combo_b = unify_types([combo_var2, combo_obj]) assert combo_a == combo_obj assert combo_b == combo_obj f = qterm.Variable('f', pq('?x->?y')) raises(UnificationError, term_builder.build_combination, f, f) raises(UnificationError, term_builder.build_combination, x_var, x_var)
def infer_types(left, right): all = left + right if len(all) > 1: all = unify_types(all) left = all[:len(left)] right = all[len(left):] return left, right
def test_unify_types2(self): x1 = qterm.Variable('x', qvar()) x2 = qterm.Variable('x', qvar()) assert x1 != x2 x1u, x2u = unify_types([x1, x2]) assert x1u == x2u
def test_unify_types(self): f1 = qterm.Variable('f', qfun(qvar(), qvar())) f2 = qterm.Variable('f', qfun(qvar(), qvar())) assert f1 != f2 f1u, f2u = unify_types([f1, f2]) assert f1u == f2u # this is a particularly tricky situation v1 = qvar() v2 = qvar() g1 = qterm.Variable('g', qfun(v1, v2)) g2 = qterm.Variable('g', qfun(v2, qobj())) assert g1 != g2 g1u, g2u = unify_types([g1, g2]) assert g1u == g2u
def test_atom(self): x_obj = qterm.Constant('x', pq('obj')) x_bool = qterm.Constant('x', pq('bool')) x_var = qterm.Constant('x', pq('?a')) x_var2 = qterm.Constant('x', pq('?a')) y_bool = qterm.Constant('y', pq('bool')) x, y = unify_types([x_obj, y_bool]) assert x == x_obj assert y == y_bool # raises(qtype.UnificationError, unify_types, [x_obj, x_bool]) xa, xb = unify_types([x_obj, x_var]) assert xa == x_obj assert xb == x_var assert x_var != x_var2 xa, xb = unify_types([x_var, x_var2]) assert xa == x_var
def build_combination(self, operator, operand): if qtype.is_variable(operator.qtype): operator = operator.substitute_type(qtype.qfun(operand.qtype, qtype.qvar()), operator.qtype) if operator.qtype.name != "fun": raise TypeError("operators must be functions") unifier = qtype_unifier.TypeUnifier() unifier.unify(operator.qtype.args[0], operand.qtype) for key, value in unifier.get_substitutions().iteritems(): operator = operator.substitute_type(value, key) operand = operand.substitute_type(value, key) operator, operand = unify_types([operator, operand]) if operator.qtype.args[0] != operand.qtype: raise TypeError("operand type must match operator argument type") return qterm.Combination(operator, operand)
def build_abstraction(self, bound, body): bound, body = unify_types([bound, body]) return qterm.Abstraction(bound, body)
def expand_definition(term, definition): atom, value = definition.operator.operand, definition.operand atom, term = unify_types([atom, term]) return substitution.substitute(value, atom, term)