def test_model_induced_functions(): """ Test evaluating a model with an ontology which has induced functions. """ fake_scene = { "objects": ["foo", "bar"], } types = TypeSystem(["a"]) functions = [ types.new_function("test", ("a", "a"), lambda x: True), types.new_function("test2", ("a", "a"), Expression.fromstring(r"\x.test(test(x))")), ] ontology = Ontology(types, functions, []) model = Model(scene=fake_scene, ontology=ontology) cases = [ ("Test basic call of an abstract function", r"\a.test2(a)", {"foo": True, "bar": True}), ("Test embedded call of an abstract function", r"\a.test(test2(a))", {"foo": True, "bar": True}), ] def test(msg, expr, expected): eq_(model.evaluate(Expression.fromstring(expr)), expected) for msg, expr, expected in cases: yield test, msg, expr, expected
def test_model_constants(): """ Test evaluating with constant values. """ types = TypeSystem(["num"]) functions = [ types.new_function("add", ("num", "num", "num"), lambda a, b: str(int(a) + int(b))) ] constants = [types.new_constant("1", "num"), types.new_constant("2", "num")] ontology = Ontology(types, functions, constants) model = Model(scene={"objects": []}, ontology=ontology) cases = [ ("Test basic constant evaluation", r"1", "1"), ("Test constants as arguments to functions", r"add(1,1)", "2"), ] def test(msg, expr, expected): print("ret", model.evaluate(Expression.fromstring(expr))) eq_(model.evaluate(Expression.fromstring(expr)), expected) for msg, expr, expected in cases: yield test, msg, expr, expected
def test_model_partial_application(): types = TypeSystem(["obj"]) functions = [ types.new_function("lotsofargs", ("obj", "obj", "obj"), lambda a, b: b), ] constants = [ types.new_constant("obj1", "obj"), types.new_constant("obj2", "obj"), ] ontology = Ontology(types, functions, constants) scene = {"objects": []} model = Model(scene, ontology) eq_(model.evaluate(Expression.fromstring(r"(lotsofargs(obj1))(obj2)")), "obj2")
def _make_mock_ontology(): def fn_unique(xs): true_xs = [x for x, matches in xs.items() if matches] assert len(true_xs) == 1 return true_xs[0] types = TypeSystem(["object", "boolean"]) functions = [ types.new_function("left_of", ("object", "object", "boolean"), lambda a, b: a["x"] < b["x"]), types.new_function("unique", (("object", "boolean"), "object"), fn_unique), types.new_function("cube", ("object", "boolean"), lambda x: x["shape"] == "cube"), types.new_function("sphere", ("object", "boolean"), lambda x: x["shape"] == "sphere"), types.new_function("and_", ("boolean", "boolean", "boolean"), lambda x, y: x and y), ] constants = [] ontology = Ontology(types, functions, constants) return ontology
def make_ontology(self, anonymous_constants=False): """Construct a pyccg-compatible ontology system based on the type definitions and signatures.""" types = TypeSystem(list(set(self.parameter_types).union(set(self.variable_types)).union(set(self.return_types)))) functions = list() constants = list() for fname, parameter_inputs, variable_inputs, return_type in self.operation_signatures: if len(parameter_inputs) == 0 and len(variable_inputs) == 0: function = types.new_function(self.escape_funcname(fname), (return_type, ), None) functions.append(function) # constants.append(types.new_constant(fname, return_type)) else: all_inputs = tuple(variable_inputs + parameter_inputs) function = types.new_function(self.escape_funcname(fname), all_inputs + (return_type, ), None) functions.append(function) for concept_category, concept_list in zip( ['concept', 'attribute', 'relational_concept'], [self.all_attribute_concepts, self.all_attributes, self.all_relational_concepts] ): for i, v in enumerate(concept_list): constants.append(types.new_constant( v if not anonymous_constants else '{}_{:06d}'.format(concept_category, i + 1), concept_category )) for i in range(5): constants.append(types.new_constant( '{}_{:06d}'.format(concept_category, len(concept_list) + i), concept_category )) ontology = Ontology(types, functions, constants) return ontology
def _make_mock_lexicon(): types = TypeSystem(["obj", "boolean"]) functions = [ types.new_function("unique", (("obj", "boolean"), "obj"), lambda x: x[0]), types.new_function("twoplace", ("boolean", ("obj", "boolean"), "obj"), lambda a, b: b[0]), types.new_function("dog", ("obj", "boolean"), lambda x: x["dog"]), types.new_function("not_", ("boolean", "boolean"), lambda a: not a), types.new_function("enlarge", ("obj", "obj"), lambda x: x), ] constants = [types.new_constant("true", "boolean")] ontology = Ontology(types, functions, constants) lex = Lexicon.fromstring(r""" :- S, N the => N/N {\x.unique(x)} thee => N\N {\x.unique(x)} twoplace => N/N {\x.twoplace(true,x)} twoplacee => N\N {\x.twoplace(true,x)} abc => N/N {\a.not_(a)} def => N/N {\b.not_(b)} qrs => N/N {\a.enlarge(a)} tuv => N/N {\b.enlarge(b)} twoarg => N/N/N {\a b.twoplace(a,b)} doggish => N/N {\x.dog(x)} dog => N {dog} # NB, won't typecheck cat => N {unique} """, ontology=ontology, include_semantics=True) # TODO hack: this needs to be integrated into lexicon construction.. for w in ["the", "twoplace", "thee", "twoplacee"]: e = lex._entries[w][0] sem = e.semantics() tx = lex.ontology.infer_type(sem, "x") sem.variable.type = tx lex.ontology.typecheck(sem) return lex
from nose.tools import * from pyccg.chart import WeightedCCGChartParser, printCCGDerivation from pyccg.model import Model from pyccg.lexicon import Lexicon from pyccg.logic import TypeSystem, Ontology, Expression from pyccg.word_learner import WordLearner ######## # Ontology: defines a type system, constants, and predicates available for use # in logical forms. dummy_fn_1 = lambda x: x dummy_fn_2 = lambda x, y: x types = TypeSystem(["object", "boolean", "shape", "size"]) functions = [ types.new_function("has_shape", ("object", "shape", "boolean"), dummy_fn_2), types.new_function("unique", (("object", "boolean"), "object"), dummy_fn_1), types.new_function("object_exists", (("object", "boolean"), "boolean"), dummy_fn_1), ] constants = [ types.new_constant("sphere", "shape"), types.new_constant("cube", "shape"), types.new_constant("cylinder", "shape"), types.new_constant("true", "boolean"),
comparison_class = set([obj ]) # TODO critical: need global scene info here.. return max(comparison_class, key=operator.itemgetter(key), reverse=reverse) == obj def fn_is_edge(obj): # true when obj is at the edge of the grid. return obj["col"] in [0, SCENE_WIDTH - 1 ] or obj["row"] in [0, SCENE_HEIGHT - 1] type_names = ["object", "boolean", "action", "direction", "int"] type_names.extend(['model']) # For EC enumeration on grounded scenes types = TypeSystem(type_names) functions = [ types.new_function("move", ("object", "action"), fn_pick), types.new_function("relate", ("object", "object", "direction", "boolean"), fn_relate), types.new_function("relate_n", ("object", "object", "direction", "int", "boolean"), fn_relate_n), types.new_function("unique", (("object", "boolean"), "object"), fn_unique), types.new_function("in_half", ("object", "direction", "boolean"), fn_in_half), types.new_function("apply", (("object", "boolean"), "object", "boolean"), lambda f, o: f(o)), types.new_function("and_", ("boolean", "boolean", "boolean"), lambda a, b: a and b), types.new_function("max_in_dir", ("object", "direction", "boolean"),
def __str__(self): return "Object(%s, %s, %s)" % (self.shape, self.size, self.material) def fn_unique(xs): true_xs = [x for x, matches in xs.items() if matches] assert len(true_xs) == 1 return true_xs[0] def fn_exists(xs): true_xs = [x for x, matches in xs.items() if matches] return len(true_xs) > 0 types = TypeSystem(["object", "boolean", "shape", "size"]) functions = [ types.new_function("has_shape", ("object", "shape", "boolean"), lambda x, s: x.shape == s), types.new_function("unique", (("object", "boolean"), "object"), fn_unique), types.new_function("object_exists", (("object", "boolean"), "boolean"), fn_exists), ] constants = [ types.new_constant("sphere", "shape"), types.new_constant("cube", "shape"), types.new_constant("cylinder", "shape"), types.new_constant("true", "boolean"), ]