def run_test_cp_phrases(self, parents, parser): test_count = 0 fail_count = 0 last_class = None if parents: parents = [logic.expr(parent) for parent in parents] for test in self.cp_tests: class_name = test.result if len(parents) > 0 and not self.class_is_one_of(parser.kb, logic.expr(class_name), parents): continue phrase = test.phrase if class_name != last_class: sys.stdout.write('Class: %s\n' % class_name) last_class = class_name sys.stdout.write(' %-70s ==> ' % (phrase,)) test_count = test_count + 1 parses = parser.parse(str(phrase)) if not test.succeeded(parses): sys.stdout.write('FAIL\n') print 'CP parse test failure, %r should have parsed to a' % (phrase,) print 'Description of type %s.' % (class_name,) if len(parses) > 0: for parse in parses: parse.pprint() else: print 'None' fail_count = fail_count + 1 else: sys.stdout.write('ok\n') return [test_count, fail_count]
def test_sequence(self): """Test :sequence patterns.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object(logic.expr('c-thing'), [':sequence', 'a', 'b', 'c']) self.assertParseEqual(p.parse('a b c'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a b c d'), []) self.assertParseEqual(p.parse('g a b c'), []) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'a', [':sequence', 'x', 'y', 'z']]) p.add_phrasal_pattern_object(logic.expr('c-thing'), [':sequence', 'a', [':sequence', 'x']]) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', [':sequence', 'x', 'y', 'z'], 'a']) self.assertParseEqual(p.parse('a x y z'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a x'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('x y z a'), [logic.Description('c-thing')]) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', [':sequence', 'x', 0, 'z'], 'a']) self.assertRaises(TypeError, lambda: p.parse_tokens(['x', 0, 'z', 'a']))
def test_fluents2(self): """More fluent tests.""" kb = logic.PropKB() kb.define_fluent(logic.expr('PartColor')) kb.tell(logic.expr('PartColor(john, hand, red)')) kb.tell(logic.expr('PartColor(john, hair, brown)')) kb.tell(logic.expr('PartColor(john, hand, green)')) kb.tell(logic.expr('PartColor(john, hair, black)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('PartColor(john, hair, ?a)')), [{ '?a': 'black' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('PartColor(john, hand, ?a)')), [{ '?a': 'green' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('PartColor(john, hair, brown)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('PartColor(john, hand, red)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('PartColor(john, ?x, ?y)')), [{ '?x': 'hand', '?y': 'green' }, { '?x': 'hair', '?y': 'black' }])
def test_optional(self): """Test :optional patterns.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'the', [':optional', 'big'], 'thing']) self.assertParseEqual(p.parse('the thing'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('the big thing'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('the'), []) self.assertParseEqual(p.parse('thing'), []) p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', [':optional', 'the'], 'thing']) self.assertParseEqual(p.parse('thing'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('the thing'), [logic.Description('c-thing')]) p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'the', [':optional', 'thing']]) self.assertParseEqual(p.parse('the'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('the thing'), [logic.Description('c-thing')])
def run_test_cp_phrases(self, parents, parser): test_count = 0 fail_count = 0 last_class = None if parents: parents = [logic.expr(parent) for parent in parents] for test in self.cp_tests: class_name = test.result if len(parents) > 0 and not self.class_is_one_of( parser.kb, logic.expr(class_name), parents): continue phrase = test.phrase if class_name != last_class: sys.stdout.write('Class: %s\n' % class_name) last_class = class_name sys.stdout.write(' %-70s ==> ' % (phrase, )) test_count = test_count + 1 parses = parser.parse(str(phrase)) if not test.succeeded(parses): sys.stdout.write('FAIL\n') print 'CP parse test failure, %r should have parsed to a' % ( phrase, ) print 'Description of type %s.' % (class_name, ) if len(parses) > 0: for parse in parses: parse.pprint() else: print 'None' fail_count = fail_count + 1 else: sys.stdout.write('ok\n') return [test_count, fail_count]
def handle_generates(self, frame, generates): class_name = frame['class_name'] self.kb.define_fluent(logic.expr('$generate'), inherited=True) for template in generates: self.kb.tell( logic.expr('$generate')(logic.expr(class_name), logic.Expr(str(template))))
def handle_constraints(self, frame, constraints): class_name = frame['class_name'] for name in constraints: self.kb.tell( logic.expr('$constraint')(logic.expr(class_name), logic.expr(name), logic.expr(constraints[name])))
def test_simple_unification(self): """Test simple queries with variables.""" kb = logic.PropKB() kb.tell(logic.expr('color(cat, black)')) kb.tell(logic.expr('age(cat, 35)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, ?x)')), [{'?x': 'black'}])
def maybe_use_filler(indices, current_filler, candidate_filler): if current_filler is None: return candidate_filler elif self.kb.isa(logic.expr(indices[candidate_filler]), logic.expr(indices[current_filler])): return candidate_filler else: return current_filler
def succeeded(self, parses): if self.match_type == CPTest.EXACT: return len(parses) == 1 and parses[0].base == logic.expr(self.result) elif self.match_type == CPTest.ONEOF: for parse in parses: if parse.base == logic.expr(self.result): return True return False
def test_dupes(self): """Test duplicate propositions.""" kb = logic.PropKB() kb.tell(logic.expr('Foo(x, y)')) kb.tell(logic.expr('Foo(x, y)')) kb.tell(logic.expr('Foo(x, y) & Foo(x, y)')) self.assertAllBindingsEqual(kb.ask_all(logic.expr('Foo(x, ?y)')), [{'?y': 'y'}])
def succeeded(self, parses): if self.match_type == CPTest.EXACT: return len(parses) == 1 and parses[0].base == logic.expr( self.result) elif self.match_type == CPTest.ONEOF: for parse in parses: if parse.base == logic.expr(self.result): return True return False
def test_simple_assertions(self): """Test simple propositional assertions.""" kb = logic.PropKB() kb.tell(logic.expr('color(cat, black)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, black)')), [{}]) kb.tell(logic.expr('age(cat, 35)')) self.assertAllBindingsEqual(kb.ask_all(logic.expr('age(cat, 35)')), [{}])
def test_simple_unification(self): """Test simple queries with variables.""" kb = logic.PropKB() kb.tell(logic.expr('color(cat, black)')) kb.tell(logic.expr('age(cat, 35)')) self.assertAllBindingsEqual(kb.ask_all(logic.expr('color(cat, ?x)')), [{ '?x': 'black' }])
def test_dupes(self): """Test duplicate propositions.""" kb = logic.PropKB() kb.tell(logic.expr('Foo(x, y)')) kb.tell(logic.expr('Foo(x, y)')) kb.tell(logic.expr('Foo(x, y) & Foo(x, y)')) self.assertAllBindingsEqual(kb.ask_all(logic.expr('Foo(x, ?y)')), [{ '?y': 'y' }])
def test_disjunction(self): """Test disjunctive queries.""" kb = logic.PropKB() kb.tell(logic.expr('Color(Cat, Black)')) kb.tell(logic.expr('Age(Cat, 35)')) kb.tell(logic.expr('Name(Cat, Ted)')) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, Black) | Age(Cat, 35))')), {}) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, Black) | Age(Cat, 36))')), {}) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, White) | Age(Cat, 35))')), {}) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, White) | Age(Cat, 36))')), False) self.assertAllBindingsEqual( kb.ask_all(logic.expr('(Color(Cat, ?c) | Age(Cat, ?a))')), [{ '?c': 'Black' }, { '?a': '35' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('(Color(Cat, ?c) | Age(Cat, 36))')), [{ '?c': 'Black' }])
def test_simple_unification2(self): """Test more simple queries with variables.""" kb = logic.PropKB() kb.tell(logic.expr('color(cat, fur, black)')) kb.tell(logic.expr('age(cat, mental, 3)')) self.assertAllBindingsEqual(kb.ask_all(logic.expr('color(cat, ?x)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, fur, ?x)')), [{ '?x': 'black' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('age(cat, ?type, 3)')), [{ '?type': 'mental' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('age(cat, ?type, 4)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, ?thing, ?c)')), [{ '?c': 'black', '?thing': 'fur' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(?a, ?b, ?c)')), [{ '?a': 'cat', '?b': 'fur', '?c': 'black' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(?a, ?b, ?c, ?d)')), [])
def cook_bindings(b): """Converts a set of bindings made of strings (e.g., {"?x": "Petunia"}) to one containing Expr's (e.g., {logic.expr("?x"): logic.expr("Petunia")}. Saves a lot of wordiness in the tests. """ if b is False: return b bindings = {} for var in b: bindings[logic.expr(var)] = logic.expr(b[var]) return bindings
def handle_slots(self, frame, slots): class_name = frame['class_name'] for name in slots: self.kb.define_fluent(logic.expr(name), inherited=True) slot_value_str = str(slots[name]) if len(slot_value_str) > 0 and slot_value_str[0] == '{': slot_frame = parse_frame_literal(slot_value_str) self.handle_fdl_frame(slot_frame) slot_value = logic.Expr(slot_frame['class_name']) else: slot_value = logic.Expr(slot_value_str) self.kb.tell(logic.expr(name)(logic.expr(class_name), slot_value))
def test_non_directives(self): """Test that we get expected errors when using non-directives.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) self.assertRaises( parser.Error, lambda: p.add_phrasal_pattern_object( logic.expr('c-thing'), [':not-a-directive', 'a', 'b', 'c']))
def test_slot_filling(self): """Test slot filling.""" kb = logic.PropKB() kb.tell(logic.expr('$constraint(BigRedThing, color, red)')) p = parser.ConceptualParser(kb) p.add_phrasal_pattern(logic.expr('BigRedThing'), 'big <color> thing') p.add_phrasal_pattern(logic.expr('red'), 'red') self.assertParseEqual( p.parse('big red thing'), [logic.Description('BigRedThing', {'color': 'red'})]) p.add_phrasal_pattern(logic.expr('BigRedThing'), 'big <rudolph> thing') self.assertRaises(parser.Error, lambda: p.parse('big crazy thing')) p.add_phrasal_pattern(logic.expr('BigRedThing'), 'big <doesnotexist> thing') self.assertRaises(parser.Error, lambda: p.parse('big floppy thing'))
def test_slot_filling(self): """Test slot filling.""" kb = logic.PropKB() kb.tell(logic.expr('$constraint(BigRedThing, color, red)')) p = parser.ConceptualParser(kb) p.add_phrasal_pattern(logic.expr('BigRedThing'), 'big <color> thing') p.add_phrasal_pattern(logic.expr('red'), 'red') self.assertParseEqual( p.parse('big red thing'), [logic.Description('BigRedThing', {'color': 'red'})]) p.add_phrasal_pattern(logic.expr('BigRedThing'), 'big <rudolph> thing') self.assertRaises(parser.Error, lambda: p.parse('big crazy thing')) p.add_phrasal_pattern( logic.expr('BigRedThing'), 'big <doesnotexist> thing') self.assertRaises(parser.Error, lambda: p.parse('big floppy thing'))
def test_any(self): """Test :any patterns.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'a', [':any', 'b', 'c', 'd'], 'e']) self.assertParseEqual(p.parse('a b e'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a c e'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a d e'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a z e'), []) p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', [':optional', 'the'], 'thing']) self.assertParseEqual(p.parse('thing'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('the thing'), [logic.Description('c-thing')])
def add_index_set(self, target_concept, indexsetpattern): """Adds an index set to the target concept. The indexsetpattern must be a string containing an indexset pattern (see IndexSetPatternParser). """ indexset = self.index_set_pattern_parser.parse( logic.expr(target_concept), indexsetpattern) self.install(indexset)
def test_conjuction_with_disjunction(self): """Test queries that combine conjunction and disjunction.""" kb = logic.PropKB() kb.tell(logic.expr('Color(Cat, Black)')) kb.tell(logic.expr('Age(Cat, 35)')) kb.tell(logic.expr('Name(Cat, Ted)')) self.assertBindingsEqual( kb.ask( logic.expr( '(Color(Cat, Black) & (Age(Cat, 36) | Name(Cat, Ted)))')), {}) self.assertBindingsEqual( kb.ask( logic.expr( '(Color(Cat, Black) & (Age(Cat, 36) | Name(Cat, John)))')), False) self.assertBindingsEqual( kb.ask( logic.expr( '((Age(Cat, 36) | Name(Cat, Ted)) & Color(Cat, Black))')), {}) self.assertBindingsEqual( kb.ask( logic.expr( '((Age(Cat, 36) | Name(Cat, John)) & Color(Cat, Black))')), False)
def test_simple_assertions2(self): """Test more simple propositional assertions.""" kb = logic.PropKB() kb.tell(logic.expr('color(cat, coat, black)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, coat, black)')), [{}]) kb.tell(logic.expr('age(cat, toy, 35)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('age(cat, toy, 35)')), [{}]) kb.tell(logic.expr('color(cat, mitten, left, black)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, mitten, left, black)')), [{}]) kb.tell(logic.expr('age(cat, toy, top, 35)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('age(cat, toy, top, 35)')), [{}]) kb.tell(logic.expr('age(cat, toy, top, x, y, z, 35)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('age(cat, toy, top, x, y, z, 35)')), [{}])
def all_abstractions(self, item): if isinstance(item, basestring): return [item] elif isinstance(item, logic.Expr): return self.kb.all_parents(item) elif isinstance(item, logic.Description): return self.kb.all_parents(logic.expr(item.base)) else: raise Error('%s must be a string or Expr.' % (repr(item,)))
def all_abstractions(self, item): if isinstance(item, basestring): return [item] elif isinstance(item, logic.Expr): return self.kb.all_parents(item) elif isinstance(item, logic.Description): return self.kb.all_parents(logic.expr(item.base)) else: raise Error('%s must be a string or Expr.' % (repr(item, )))
def test_fluents2(self): """More fluent tests.""" kb = logic.PropKB() kb.define_fluent(logic.expr('PartColor')) kb.tell(logic.expr('PartColor(john, hand, red)')) kb.tell(logic.expr('PartColor(john, hair, brown)')) kb.tell(logic.expr('PartColor(john, hand, green)')) kb.tell(logic.expr('PartColor(john, hair, black)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr( 'PartColor(john, hair, ?a)')), [{'?a': 'black'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('PartColor(john, hand, ?a)')), [{'?a': 'green'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('PartColor(john, hair, brown)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('PartColor(john, hand, red)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('PartColor(john, ?x, ?y)')), [{'?x': 'hand', '?y': 'green'}, {'?x': 'hair', '?y': 'black'}])
def test_icp_with_literal_tokens(self): """Very simple tests with simple ICP index sets containing only literal tokens. """ kb = logic.PropKB() p = parser.IndexedConceptParser(kb) p.add_index_set('c-number', 'one two three numberorjohn') p.add_index_set('c-john', 'john numberorjohn') # Check some of the lower-level computations on which scoring is # based. self.assertEqual(p.target_concept_cardinality('john'), 1) self.assertEqual(p.target_concept_cardinality('numberorjohn'), 2) self.assertApproxEqual(p.probability_of_index('john'), 0.5, 0.001) self.assertApproxEqual(p.probability_of_index('numberorjohn'), 1.0, 0.001) self.assertApproxEqual(p.information_value('john'), 1.0, 0.001) self.assertApproxEqual(p.information_value('numberorjohn'), 0.0, 0.001) self.assertEqual(len(p.unique_target_concepts), 2) # Parsing nothing should result in nothing. results = p.parse('') self.assertEqual(len(results), 0) # Should result in a c-number. results = p.parse('one') self.assertEqual(len(results), 1) self.assertEqual(results[0].target_concept, logic.expr('c-number')) # 'john' should have a better score than 'john boy' for c-john. results1 = p.parse('john') self.assertEqual(len(results1), 1) self.assertEqual(results1[0].target_concept, logic.expr('c-john')) results2 = p.parse('john boy woo bloo') self.assertEqual(len(results2), 1) self.assertEqual(results2[0].target_concept, logic.expr('c-john')) self.assertTrue(results1[0].score > results2[0].score) # 'one two' should have a better score than 'one' for c-number. results1 = p.parse('one') self.assertEqual(len(results1), 1) self.assertEqual(results1[0].target_concept, logic.expr('c-number')) results2 = p.parse('one two') self.assertEqual(len(results2), 1) self.assertEqual(results2[0].target_concept, logic.expr('c-number')) self.assertTrue(results1[0].score < results2[0].score) # 'numberorjohn' should result in both c-number and c-john, but # c-john should have a higher score. results = p.parse('numberorjohn') self.assertEqual(len(results), 2) self.assertEqual(results[0].target_concept, logic.expr('c-john')) self.assertEqual(results[1].target_concept, logic.expr('c-number')) self.assertTrue(results[0].score > results[1].score)
def test_erasures(self): """Test retractions with variables.""" kb = logic.PropKB() kb.tell(logic.expr('has(john, cat)')) kb.tell(logic.expr('has(john, car)')) kb.tell(logic.expr('has(cat, toy)')) kb.retract(logic.expr('has(john, ?t)')) self.assertBindingsEqual(kb.ask(logic.expr('has(john, ?t)')), False) self.assertAllBindingsEqual(kb.ask_all(logic.expr('has(john, ?t)')), []) self.assertAllBindingsEqual(kb.ask_all(logic.expr('has(cat, toy)')), [{}])
def test_sequence(self): """Test :sequence patterns.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'a', 'b', 'c']) self.assertParseEqual(p.parse('a b c'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a b c d'), []) self.assertParseEqual(p.parse('g a b c'), []) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'a', [':sequence', 'x', 'y', 'z']]) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'a', [':sequence', 'x']]) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', [':sequence', 'x', 'y', 'z'], 'a']) self.assertParseEqual(p.parse('a x y z'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a x'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('x y z a'), [logic.Description('c-thing')]) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', [':sequence', 'x', 0, 'z'], 'a']) self.assertRaises(TypeError, lambda: p.parse_tokens(['x', 0, 'z', 'a']))
def check_constraints(self): def can_be_constraint(concept): for c in self.kb.all_children(logic.expr(concept)): if c in self.cp_parser.phrasal_patterns: return True return False for class_name in self.fdl_handler.constraints: constraints = self.fdl_handler.constraints[class_name] for name in constraints: req_type = constraints[name] if not can_be_constraint(req_type): logging.warning( "%s has constraint '%s IS-A %s' which has no phrasal patterns", class_name, name, req_type) sv = self.kb.slot_value(logic.expr(class_name), logic.expr(name)) if sv: if not self.kb.isa(sv, logic.expr(req_type)): logging.warning( ("%s has constraint '%s IS-A %s' which is not consistent " 'with slot value %s'), class_name, name, req_type, sv)
def test_instances(self): """Test INSTANCEOF and ISINSTANCE.""" kb = logic.PropKB() kb.tell(logic.expr('ISA(mammal, animal)')) kb.tell(logic.expr('ISA(cat, mammal)')) kb.tell(logic.expr('INSTANCEOF(petunia, cat)')) self.assertAllBindingsEqual(kb.ask_all(logic.expr('ISA(petunia, ?x)')), [{ '?x': 'petunia' }, { '?x': 'cat' }, { '?x': 'mammal' }, { '?x': 'animal' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('ISINSTANCE(petunia)')), [{}]) self.assertAllBindingsEqual(kb.ask_all(logic.expr('ISINSTANCE(?x)')), [{ '?x': 'petunia' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('INSTANCEOF(petunia, ?x)')), [{ '?x': 'cat' }]) self.assertAllBindingsEqual(kb.ask_all(logic.expr('ISINSTANCE(?x)')), [{ '?x': 'petunia' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('INSTANCEOF(?x, ?y)')), [{ '?x': 'petunia', '?y': 'cat' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('ISINSTANCE(petunia)')), [{}])
def test_instances(self): """Test INSTANCEOF and ISINSTANCE.""" kb = logic.PropKB() kb.tell(logic.expr('ISA(mammal, animal)')) kb.tell(logic.expr('ISA(cat, mammal)')) kb.tell(logic.expr('INSTANCEOF(petunia, cat)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('ISA(petunia, ?x)')), [{'?x': 'petunia'}, {'?x': 'cat'}, {'?x': 'mammal'}, {'?x': 'animal'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('ISINSTANCE(petunia)')), [{}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('ISINSTANCE(?x)')), [{'?x': 'petunia'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('INSTANCEOF(petunia, ?x)')), [{'?x': 'cat'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('ISINSTANCE(?x)')), [{'?x': 'petunia'}]) self.assertAllBindingsEqual(kb.ask_all(logic.expr('INSTANCEOF(?x, ?y)')), [{'?x': 'petunia', '?y': 'cat'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('ISINSTANCE(petunia)')), [{}])
def check_constraints(self): def can_be_constraint(concept): for c in self.kb.all_children(logic.expr(concept)): if c in self.cp_parser.phrasal_patterns: return True return False for class_name in self.fdl_handler.constraints: constraints = self.fdl_handler.constraints[class_name] for name in constraints: req_type = constraints[name] if not can_be_constraint(req_type): logging.warning( "%s has constraint '%s IS-A %s' which has no phrasal patterns", class_name, name, req_type) sv = self.kb.slot_value(logic.expr(class_name), logic.expr(name)) if sv: if not self.kb.isa(sv, logic.expr(req_type)): logging.warning(( "%s has constraint '%s IS-A %s' which is not consistent " 'with slot value %s'), class_name, name, req_type, sv)
def test_disjunction(self): """Test disjunctive queries.""" kb = logic.PropKB() kb.tell(logic.expr('Color(Cat, Black)')) kb.tell(logic.expr('Age(Cat, 35)')) kb.tell(logic.expr('Name(Cat, Ted)')) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, Black) | Age(Cat, 35))')), {}) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, Black) | Age(Cat, 36))')), {}) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, White) | Age(Cat, 35))')), {}) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, White) | Age(Cat, 36))')), False) self.assertAllBindingsEqual( kb.ask_all(logic.expr('(Color(Cat, ?c) | Age(Cat, ?a))')), [{'?c': 'Black'}, {'?a': '35'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('(Color(Cat, ?c) | Age(Cat, 36))')), [{'?c': 'Black'}])
def test_optional(self): """Test :optional patterns.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'the', [':optional', 'big'], 'thing']) self.assertParseEqual(p.parse('the thing'), [logic.Description('c-thing')]) self.assertParseEqual( p.parse('the big thing'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('the'), []) self.assertParseEqual(p.parse('thing'), []) p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', [':optional', 'the'], 'thing']) self.assertParseEqual(p.parse('thing'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('the thing'), [logic.Description('c-thing')]) p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'the', [':optional', 'thing']]) self.assertParseEqual(p.parse('the'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('the thing'), [logic.Description('c-thing')])
def test_simple_parsing(self): """Simple parsing tests.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) p.add_phrasal_pattern(logic.expr('BigRedThing'), 'big red thing') self.assertParseEqual(p.parse_tokens(['big', 'red', 'thing']), [logic.Description('BigRedThing')]) self.assertParseEqual(p.parse('big red thing'), [logic.Description('BigRedThing')]) self.assertParseEqual(p.parse('BIG red THING'), [logic.Description('BigRedThing')]) self.assertRaises(TypeError, lambda: p.parse_tokens(0)) self.assertRaises(TypeError, lambda: p.parse_tokens([0])) self.assertRaises(TypeError, lambda: p.parse(0)) self.assertRaises(TypeError, lambda: p.parse([0]))
def test_simple_parsing(self): """Simple parsing tests.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) p.add_phrasal_pattern(logic.expr('BigRedThing'), 'big red thing') self.assertParseEqual(p.parse_tokens(['big', 'red', 'thing']), [logic.Description('BigRedThing')]) self.assertParseEqual( p.parse('big red thing'), [logic.Description('BigRedThing')]) self.assertParseEqual( p.parse('BIG red THING'), [logic.Description('BigRedThing')]) self.assertRaises(TypeError, lambda: p.parse_tokens(0)) self.assertRaises(TypeError, lambda: p.parse_tokens([0])) self.assertRaises(TypeError, lambda: p.parse(0)) self.assertRaises(TypeError, lambda: p.parse([0]))
def __init__(self, target=None, indices=None, required_indices=None, slots=None): def cond(test, a, b): if test: return a else: return b if isinstance(target, basestring): self.target_concept = logic.expr(target) else: self.target_concept = target self.indices = cond(indices is None, [], indices) self.required_indices = cond( required_indices is None, [], required_indices) self.slots = cond(slots is None, [], slots)
def test_descriptions2(self): """More description tests.""" kb = logic.PropKB() kb.tell(logic.expr('ISA(c-cat, c-animal)')) kb.tell(logic.expr('INSTANCEOF(i-petunia, c-cat)')) kb.tell(logic.expr('color(i-petunia, i-gray)')) kb.tell(logic.expr('ISA(i-gray, c-color)')) kb.tell(logic.expr('alternate-spelling(i-gray, grey)')) # Description of a cat whose color is something with an alternate # spelling 'grey'. d = logic.Description( 'c-cat', {'color': logic.Description('c-color', {'alternate-spelling': 'grey'})}) self.assertEqual(d.find_all(kb), [logic.expr('i-petunia')]) self.assertEqual(d.find_instances(kb), [logic.expr('i-petunia')])
def test_simple_erasures2(self): """Test more simple variable-less retractions.""" kb = logic.PropKB() kb.tell(logic.expr('color(cat, coat, black)')) kb.tell(logic.expr('age(cat, toy, 35)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, coat, black)')), [{}]) kb.retract(logic.expr('color(cat, coat, black)')) self.assertBindingsEqual(kb.ask(logic.expr('color(cat, coat, black)')), False) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, coat, black)')), [])
def test_descriptions2(self): """More description tests.""" kb = logic.PropKB() kb.tell(logic.expr('ISA(c-cat, c-animal)')) kb.tell(logic.expr('INSTANCEOF(i-petunia, c-cat)')) kb.tell(logic.expr('color(i-petunia, i-gray)')) kb.tell(logic.expr('ISA(i-gray, c-color)')) kb.tell(logic.expr('alternate-spelling(i-gray, grey)')) # Description of a cat whose color is something with an alternate # spelling 'grey'. d = logic.Description('c-cat', { 'color': logic.Description('c-color', {'alternate-spelling': 'grey'}) }) self.assertEqual(d.find_all(kb), [logic.expr('i-petunia')]) self.assertEqual(d.find_instances(kb), [logic.expr('i-petunia')])
def test_combo_directives(self): """Test more combinations of directives.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object( logic.expr('c-thing'), [':sequence', 'a', [':any', [':sequence', 'b', [':optional', [':any', 'c', 'd']], 'e'], 'z']]) self.assertParseEqual(p.parse('a b e'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a b c e'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a b d e'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a b d e e'), []) self.assertParseEqual(p.parse('a z'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a z e'), [])
def test_fill_slots_at_most_once(self): """Test that slots get filled at most once.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) kb.tell(logic.expr('ISA(c-red, c-color)')) p.add_phrasal_pattern(logic.expr('c-red'), 'red') kb.tell(logic.expr('ISA(c-blue, c-color)')) p.add_phrasal_pattern(logic.expr('c-blue'), 'blue') kb.tell(logic.expr('$constraint(c-thing, color, c-color)')) p.add_phrasal_pattern(logic.expr('c-thing'), '[thing|{color} {:head}]') self.assertParseEqual( p.parse('red thing'), [logic.Description('c-thing', {'color': 'c-red'})]) self.assertParseEqual(p.parse('red blue thing'), [])
def test_simple_unification2(self): """Test more simple queries with variables.""" kb = logic.PropKB() kb.tell(logic.expr('color(cat, fur, black)')) kb.tell(logic.expr('age(cat, mental, 3)')) self.assertAllBindingsEqual(kb.ask_all(logic.expr('color(cat, ?x)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, fur, ?x)')), [{'?x': 'black'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('age(cat, ?type, 3)')), [{'?type': 'mental'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('age(cat, ?type, 4)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(cat, ?thing, ?c)')), [{'?c': 'black', '?thing': 'fur'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(?a, ?b, ?c)')), [{'?a': 'cat', '?b': 'fur', '?c': 'black'}]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(?a, ?b, ?c, ?d)')), [])
def test_combo_directives(self): """Test more combinations of directives.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) p.add_phrasal_pattern_object(logic.expr('c-thing'), [ ':sequence', 'a', [ ':any', [':sequence', 'b', [':optional', [':any', 'c', 'd']], 'e'], 'z' ] ]) self.assertParseEqual(p.parse('a b e'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a b c e'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a b d e'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a b d e e'), []) self.assertParseEqual(p.parse('a z'), [logic.Description('c-thing')]) self.assertParseEqual(p.parse('a z e'), [])
def test_fluents(self): """Test that fluents work correctly. Fluents are propositions that can have only one value--e.g., people have only one age; I can't be 35 and 40 simultaneously, so Age(John, 35) and Age(John, 40) can't both be true. """ kb = logic.PropKB() kb.tell(logic.expr('Has(John, Cat)')) kb.tell(logic.expr('Has(John, Computer)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr( 'Has(John, ?w)')), [{'?w': 'Computer'}, {'?w': 'Cat'}]) kb.define_fluent(logic.expr('Age')) kb.tell(logic.expr('Age(John, 35)')) kb.tell(logic.expr('Age(John, 40)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('Age(John, ?a)')), [{'?a': '40'}]) self.assertRaises(logic.Error, lambda: kb.define_fluent('Foo'))