def run(self): self.kb = logic.PropKB() self.cp_parser = ConceptualParser(self.kb) self.icp_parser = IndexedConceptParser(self.kb) self.fdl_handler = FrameHandler(self.kb, self.cp_parser, self.icp_parser) self.fdl_parser = fdl.FDLParser(self.fdl_handler) self.fdl_parser.parse_fdl_file(self.fdl_file, self.debug) if self.run_tests: self.check_constraints() self.fdl_parser.run_test_phrases(self.test_classes, self.cp_parser, self.icp_parser) if self.transcript_path: for line in open(self.transcript_path): line = line[0:-1] if len(line) > 0: print '\n*** %s' % (line, ) parses = self.cp_parser.parse(line) print ' %s:' % (len(parses), ) pprint.pprint(parses) if not self.run_tests and not self.transcript_path: self.do_parse_loop()
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_constraints_inherited(self): """Test inherited constraints.""" kb = logic.PropKB() # We don't use the parser we create in the next line, but we # depend on its side-effect of making $constraint an heritable # fluent. unused_p = parser.ConceptualParser(kb) kb.tell(logic.expr('ISA(c-child, c-parent)')) kb.tell(logic.expr('$constraint(c-parent, color, c-color)')) self.assertEqual( kb.slot_value(logic.expr('c-parent'), logic.expr('$constraint'), logic.expr('color')), logic.expr('c-color')) self.assertEqual( kb.slot_value(logic.expr('c-child'), logic.expr('$constraint'), logic.expr('color')), logic.expr('c-color')) self.assertEqual( kb.ask_all(logic.expr('$constraint(c-parent, color, ?v)')), [{ logic.expr('?v'): logic.expr('c-color') }]) self.assertEqual( kb.ask_all(logic.expr('$constraint(c-child, color, ?v)')), [{ logic.expr('?v'): logic.expr('c-color') }])
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_conjunction(self): """Test conjunctive 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, 35) & name(cat, ted)))')), {}) self.assertBindingsEqual( kb.ask(logic.expr('(color(cat, white) & age(cat, 35))')), False) self.assertBindingsEqual( kb.ask(logic.expr('(color(cat, black) & age(cat, 34))')), False) self.assertAllBindingsEqual( kb.ask_all(logic.expr('(color(cat, ?c) & age(cat, ?a))')), [{ '?a': '35', '?c': 'black' }]) self.assertBindingsEqual( kb.ask(logic.expr('(color(cat, ?c) & age(cat, ?c))')), False) kb.tell(logic.expr('color(car, black)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('(color(cat, ?b) & color(car, ?b))')), [{ '?b': 'black' }])
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_not(self): """Gotta have NOT.""" 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)))')), {}) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, Black) & (~Age(Cat, 35)))')), False) self.assertBindingsEqual( kb.ask(logic.expr('((~Age(Cat, 35)) & Color(Cat, Black))')), False) self.assertBindingsEqual( kb.ask(logic.expr('((~Age(Cat, 36)) & Color(Cat, Black))')), {}) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, Black) & (~Age(Cat, ?c)))')), False) self.assertBindingsEqual( kb.ask(logic.expr('((~Age(Cat, ?c)) & Color(Cat, Black))')), False) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, ?c) & (~Age(Cat, ?a)))')), False) self.assertBindingsEqual( kb.ask(logic.expr('((~Age(Cat, ?a)) & Color(Cat, ?c))')), False) self.assertBindingsEqual( kb.ask(logic.expr('((~Age(Cat, 36)) & Color(Cat, ?c))')), {'?c': 'Black'}) self.assertBindingsEqual( kb.ask(logic.expr('(Color(Cat, ?c) & (~Age(Cat, 36)))')), {'?c': 'Black'}) self.assertBindingsEqual(kb.ask(logic.expr('~Age(Cat, 35)')), False) self.assertBindingsEqual(kb.ask(logic.expr('~Age(Cat, 36)')), {})
def test_pre_parser(self): """Test the pre-parser.""" kb = logic.PropKB() p = parser.ConceptualParser(kb) self.assertParseEqual(p.parse('123'), [logic.Description('c-number', {'value': 123})]) self.assertParseEqual(p.parse('0'), [logic.Description('c-number', {'value': 0})]) self.assertParseEqual(p.parse('01'), [logic.Description('c-number', {'value': 1})]) self.assertParseEqual(p.parse('019'), [logic.Description('c-number', {'value': 19})]) self.assertParseEqual(p.parse('5'), [logic.Description('c-number', {'value': 5})]) # FIXME: These parse into digits--need to fix this inconsistency. # self.assertParseEqual(p.parse('one'), # [logic.Description('c-number', # {'value': 1})]) # self.assertParseEqual(p.parse('seven'), # [logic.Description('c-number', # {'value': 7})]) self.assertParseEqual( p.parse('HK'), [logic.Description('c-mgrs-square', {'letters': 'hk'})]) self.assertParseEqual( p.parse('XY'), [logic.Description('c-mgrs-square', {'letters': 'xy'})])
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_erasures2(self): """Test more retractions with variables.""" kb = logic.PropKB() kb.tell(logic.expr('has(john, bag, cat)')) kb.tell(logic.expr('has(john, bag, car)')) kb.tell(logic.expr('has(john, bin, cat)')) kb.tell(logic.expr('has(john, bin, car)')) kb.tell(logic.expr('has(cat, bag, toy)')) kb.retract(logic.expr('has(john, bag, ?t)')) self.assertBindingsEqual(kb.ask(logic.expr('has(john, bag, ?t)')), False) self.assertAllBindingsEqual( kb.ask_all(logic.expr('has(john, bin, ?t)')), [{ '?t': 'cat' }, { '?t': 'car' }]) self.assertAllBindingsEqual(kb.ask_all(logic.expr('has(john, ?t)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('has(cat, bag, toy)')), [{}]) kb.tell(logic.expr('has(john, bag, cat)')) kb.tell(logic.expr('has(john, bag, car)')) kb.retract(logic.expr('has(john, ?t, cat)')) self.assertAllBindingsEqual( kb.ask_all(logic.expr('has(john, ?t, cat)')), []) self.assertAllBindingsEqual( kb.ask_all(logic.expr('has(john, ?t, car)')), [{ '?t': 'bin' }, { '?t': 'bag' }])
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_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_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_file_parsing(self): """Test parsing FDL from files.""" kb = logic.PropKB() cp_parser = parser.ConceptualParser(kb) icp_parser = parser.IndexedConceptParser(kb) fdl_handler = fdl.BaseFrameHandler(kb, cp_parser, icp_parser) fdl_parser = fdl.FDLParser(fdl_handler) test_fdl_path = os.path.join(os.path.dirname(__file__), 'test.fdl') self.assertEqual(fdl_parser.parse_fdl_file(test_fdl_path), True) self.assertParseEqual( cp_parser.parse('hog let us restart the talk on'), [ logic.Description( 'c-action-request', { 'action': 'c-restart', 'addressee': 'c-hog', 'object': 'c-talkon' }) ]) self.assertParseEqual( cp_parser.parse("hog why don't we start over with the talk on"), [ logic.Description( 'c-action-request', { 'action': 'c-restart', 'addressee': 'c-hog', 'object': 'c-talkon' }) ])
def testIndexSetPatternParser(self): """Test indexset parsing.""" p = parser.IndexSetPatternParser(None) # Basic stuff -- simple tokens, concepts and required tokens. index_set = p.parse(None, 'big dog') self.assertEqual(index_set.indices, ['big', 'dog']) self.assertEqual(index_set.required_indices, []) index_set = p.parse(None, 'big $dog') self.assertEqual(index_set.indices, ['big', logic.expr('dog')]) self.assertEqual(index_set.required_indices, []) index_set = p.parse(None, '!big !dog') self.assertEqual(index_set.indices, ['big', 'dog']) self.assertEqual(index_set.required_indices, ['big', 'dog']) index_set = p.parse(None, '!big black !$dog') self.assertEqual(index_set.indices, ['big', 'black', logic.expr('dog')]) self.assertEqual(index_set.required_indices, ['big', logic.expr('dog')]) # Try something a little fancier -- slot references. kb = logic.PropKB() p = parser.IndexSetPatternParser(kb) kb.tell(logic.expr('$constraint(c-dog, color, c-color)')) kb.tell(logic.expr('$constraint(c-dog, size, c-size)')) index_set = p.parse('c-dog', '!{size} {color} dog') self.assertEqual(index_set.target_concept, logic.expr('c-dog')) self.assertEqual(index_set.indices, [logic.expr('c-size'), logic.expr('c-color'), 'dog']) self.assertEqual(index_set.required_indices, [logic.expr('c-size')]) self.assertEqual(index_set.slots, [['size', logic.expr('c-size')], ['color', logic.expr('c-color')]]) # Now test various weird cases index_set = p.parse(None, ' !big black !$dog ') self.assertEqual(index_set.indices, ['big', 'black', logic.expr('dog')]) self.assertEqual(index_set.required_indices, ['big', logic.expr('dog')]) # FIXME: Some of these raise SyntaxError because they fail inside # of eval. self.assertRaises(parser.Error, lambda: p.parse(None, '!')) self.assertRaises(SyntaxError, lambda: p.parse(None, '$')) self.assertRaises(SyntaxError, lambda: p.parse(None, '!$$!')) self.assertRaises(SyntaxError, lambda: p.parse(None, '$!$!')) self.assertRaises(SyntaxError, lambda: p.parse('c-dog', '{}')) self.assertRaises(parser.Error, lambda: p.parse('c-dog', '{!}')) self.assertRaises(parser.Error, lambda: p.parse('c-dog', '{foo} {foo}')) self.assertEqual(p.parse(None, ''), parser.IndexSet()) self.assertEqual(p.parse(None, ' '), parser.IndexSet())
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_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_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_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_icp_with_concepts(self): """Slightly more complicated tests with ICP index sets that contain terminals and concepts. """ kb = logic.PropKB() p = parser.IndexedConceptParser(kb) kb.tell(logic.expr('ISA(c-red, c-color)')) kb.tell(logic.expr('ISA(c-green, c-color)')) kb.tell(logic.expr('ISA(c-blue, c-color)')) kb.tell(logic.expr('ISA(c-purple, c-color)')) p.add_phrasal_pattern(logic.expr('c-red'), 'red') p.add_phrasal_pattern(logic.expr('c-green'), 'green') p.add_phrasal_pattern(logic.expr('c-blue'), 'blue') p.add_phrasal_pattern(logic.expr('c-purple'), 'purple') p.add_index_set('c-color', '$c-red $c-green $c-blue $c-purple') results1 = p.parse('red') self.assertEqual(len(results1), 1) self.assertEqual(results1[0].target_concept, logic.expr('c-color')) results2 = p.parse('red green blue purple') self.assertEqual(len(results2), 1) self.assertEqual(results2[0].target_concept, logic.expr('c-color')) self.assertTrue(results2[0].score > results1[0].score) # Setup a little hierarchy, C -> B -> A. kb.tell(logic.expr('ISA(c-b, c-a)')) kb.tell(logic.expr('ISA(c-c, c-b)')) p.add_phrasal_pattern(logic.expr('c-a'), 'a') p.add_phrasal_pattern(logic.expr('c-b'), 'b') p.add_phrasal_pattern(logic.expr('c-c'), 'c') p.add_index_set('c-1', '$c-a') p.add_index_set('c-2', '$c-b') p.add_index_set('c-3', '$c-c') r1 = p.parse('a') r2 = p.parse('b') r3 = p.parse('c') self.assertEqual(len(r1), 1) self.assertEqual(len(r2), 2) self.assertEqual(len(r3), 3) # Most specific result should always have the highest score and # appear first, followed by less specific results. self.assertEqual(map(lambda r: r.target_concept, r1), [logic.expr('c-1')]) self.assertEqual( map(lambda r: r.target_concept, r2), [logic.expr('c-2'), logic.expr('c-1')]) self.assertEqual( map(lambda r: r.target_concept, r3), [logic.expr('c-3'), logic.expr('c-2'), logic.expr('c-1')])
def test_simple_icp3(self): """Test indexset parsing.""" kb = logic.PropKB() p = parser.IndexedConceptParser(kb) kb.tell(logic.expr('ISA(c-red, c-color)')) kb.tell(logic.expr('ISA(c-green, c-color)')) kb.tell(logic.expr('ISA(c-blue, c-color)')) p.add_phrasal_pattern(logic.expr('c-red'), 'red') p.add_phrasal_pattern(logic.expr('c-green'), 'green') p.add_phrasal_pattern(logic.expr('c-blue'), 'blue') p.add_index_set('c-color', 'color $c-red $c-green $c-blue') results1 = p.parse('color') self.assertEqual(len(results1), 1) self.assertEqual(results1[0].target_concept, logic.expr('c-color')) results2 = p.parse('color red green blue') self.assertEqual(len(results2), 1) self.assertEqual(results2[0].target_concept, logic.expr('c-color')) self.assertTrue(results2[0].score > results1[0].score) p.add_index_set('c-john', '!john boy') results = p.parse('boy') self.assertEqual(len(results), 0) results1 = p.parse('john') self.assertEqual(len(results1), 1) self.assertEqual(results1[0].target_concept, logic.expr('c-john')) results2 = p.parse('john boy') self.assertEqual(len(results2), 1) self.assertEqual(results2[0].target_concept, logic.expr('c-john')) self.assertTrue(results2[0].score > results1[0].score) kb.tell(logic.expr('ISA(c-purple, c-color)')) p.add_phrasal_pattern(logic.expr('c-purple'), 'purple') # Tricky! Note that we're adding a second indexset to c-color, # and this one has a required concept. p.add_index_set('c-color', '!$c-purple blah') # If we have one token from the new indexset but not the required # token, it should not parse at all. results = p.parse('blah') self.assertEqual(len(results), 0) # If we have the required token, it should parse. results = p.parse('purple') self.assertEqual(len(results), 1) self.assertEqual(results[0].target_concept, logic.expr('c-color')) # If we have a token from the old indexset, we don't need the # required token from the new indexset. results = p.parse('red') self.assertEqual(len(results), 1) self.assertEqual(results[0].target_concept, logic.expr('c-color'))
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_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_descriptions(self): """Test descriptions.""" kb = logic.PropKB() kb.tell(logic.expr('ISA(Mammal, Animal)')) kb.tell(logic.expr('ISA(Cat, Mammal)')) kb.tell(logic.expr('ISA(Petunia, Cat)')) kb.tell(logic.expr('ISA(Dog, Animal)')) kb.tell(logic.expr('ISA(Nine, Dog)')) kb.define_fluent(logic.expr('Color'), inherited=True) kb.define_fluent(logic.expr('Size'), inherited=True) kb.tell(logic.expr('Size(Cat, Small)')) kb.tell(logic.expr('Color(Petunia, Black)')) kb.tell(logic.expr('Size(Dog, Large)')) kb.tell(logic.expr('Color(Gretchen, Black)')) kb.tell(logic.expr('IsEdible(Animal, true)')) kb.tell(logic.expr('Color(Animal, Purple)')) d = logic.Description('Cat', {'Size': 'Small'}) self.assertEqual( d.find_all(kb), [logic.expr('Cat'), logic.expr('Petunia')]) d = logic.Description('Cat') self.assertEqual( d.find_all(kb), [logic.expr('Cat'), logic.expr('Petunia')]) d = logic.Description('Cat', {'Size': 'Small', 'Color': 'Black'}) self.assertEqual(d.find_all(kb), [logic.expr('Petunia')]) d = logic.Description('Cat', { 'Size': 'Small', 'Color': 'Black', 'Age': '35' }) self.assertEqual(d.find_all(kb), []) d = logic.Description('Animal', {'Color': 'Black'}) self.assertEqual(d.find_all(kb), [logic.expr('Petunia')]) d = logic.Description('Animal', {'Color': 'Black'}) query = logic.expr('Color')(d, logic.expr('?c')) self.assertAllBindingsEqual(kb.ask_all(query), [{'?c': 'Black'}]) query = logic.expr('IsEdible')(d, logic.expr('?c')) self.assertAllBindingsEqual(kb.ask_all(query), [{'?c': 'true'}]) self.assertEqual(d.has_slot('Color'), True) self.assertEqual(d.has_slot(logic.expr('Color')), True) self.assertEqual(d.has_slot('Size'), False) self.assertEqual(d.has_slot(logic.expr('Size')), False) self.assertEqual(d.slot_value('Color'), 'Black') self.assertRaises(KeyError, lambda: d.slot_value('Size')) d = logic.Description('Cat', {'IsEdible': 'false'}) self.assertEqual(kb.slot_value(d, 'IsEdible'), logic.expr('false')) self.assertEqual(kb.slot_value(d, 'Color'), logic.expr('Purple'))
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_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_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_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_icp_slot_filling(self): """Slightly more complicated tests with ICP index sets that contain terminals and concepts. """ kb = logic.PropKB() p = parser.IndexedConceptParser(kb) kb.tell(logic.expr('ISA(c-red, c-color)')) kb.tell(logic.expr('ISA(c-green, c-color)')) kb.tell(logic.expr('ISA(c-big, c-size)')) kb.tell(logic.expr('ISA(c-small, c-size)')) kb.tell(logic.expr('$constraint(c-dog, color, c-color)')) kb.tell(logic.expr('$constraint(c-dog, size, c-size)')) p.add_phrasal_pattern(logic.expr('c-red'), 'red') p.add_phrasal_pattern(logic.expr('c-green'), 'green') p.add_phrasal_pattern(logic.expr('c-big'), 'big') p.add_phrasal_pattern(logic.expr('c-small'), 'small') p.add_index_set('c-dog', '{color} !{size} !dog') results = p.parse('dog') self.assertEqual(len(results), 0) results = p.parse('big red') self.assertEqual(len(results), 0) results = p.parse('big red dog') self.assertEqual(len(results), 1) self.assertParseEqual( results, [logic.Description('c-dog', { 'size': 'c-big', 'color': 'c-red' })]) results = p.parse('big dog') self.assertEqual(len(results), 1) self.assertParseEqual(results, [logic.Description('c-dog', {'size': 'c-big'})]) # Now multiple slots of the same type. kb.tell(logic.expr('$constraint(c-thing, slot-a, c-size)')) kb.tell(logic.expr('$constraint(c-thing, slot-b, c-size)')) p.add_index_set('c-thing', '{slot-a} {slot-b}') results = p.parse('big small') self.assertParseEqual(results, [ logic.Description('c-thing', { 'slot-a': 'c-big', 'slot-b': 'c-small' }) ])
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)')), [{}])