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_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_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_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 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 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_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_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_examples2(self): """Even more tests.""" kb = logic.PropKB() kb.tell(logic.expr('ISA(c-start-over, c-action)')) kb.tell(logic.expr('ISA(c-hog, c-name)')) kb.tell(logic.expr('ISA(c-process, c-thing)')) kb.tell(logic.expr('ISA(c-nine-line, c-process)')) kb.tell(logic.expr('ISA(c-talk-on, c-process)')) kb.tell(logic.expr('$constraint(c-action-request, addressee, c-name)')) kb.tell(logic.expr('$constraint(c-action-request, action, c-action)')) kb.tell(logic.expr('$constraint(c-action-request, object, c-thing)')) p = parser.ConceptualParser(kb) p.add_phrasal_pattern(logic.expr('c-hog'), 'hog') p.add_phrasal_pattern(logic.expr('c-start-over'), 'start [over|again]') p.add_phrasal_pattern(logic.expr('c-start-over'), 'restart') p.add_phrasal_pattern(logic.expr('c-nine-line'), '[nine|9] line') p.add_phrasal_pattern(logic.expr('c-nine-line'), 'nineline') p.add_phrasal_pattern(logic.expr('c-nine-line'), '9line') p.add_phrasal_pattern(logic.expr('c-talk-on'), 'talk on') p.add_phrasal_pattern(logic.expr('c-talk-on'), 'talkon') p.add_phrasal_pattern( logic.expr('c-action-request'), ("?:?addressee ?:[let's|let us|lets|why don't we] " "?action ?:[with|on] ?:the ?object")) self.assertParseEqual(p.parse('hog'), [logic.Description('c-hog')]) self.assertParseEqual(p.parse('9 line'), [logic.Description('c-nine-line')]) self.assertParseEqual(p.parse('start again'), [logic.Description('c-start-over')]) self.assertParseEqual( p.parse("hog, let's start over with the nine-line"), [ logic.Description( 'c-action-request', { 'addressee': 'c-hog', 'action': 'c-start-over', 'object': 'c-nine-line' }) ]) self.assertParseEqual( p.parse("hog, why don't we start over with talk-on"), [ logic.Description( 'c-action-request', { 'addressee': 'c-hog', 'action': 'c-start-over', 'object': 'c-talk-on' }) ]) self.assertParseEqual(p.parse('hog, start over with the nine-line'), [ logic.Description( 'c-action-request', { 'addressee': 'c-hog', 'action': 'c-start-over', 'object': 'c-nine-line' }) ]) self.assertParseEqual(p.parse('restart the nine-line'), [ logic.Description('c-action-request', { 'action': 'c-start-over', 'object': 'c-nine-line' }) ]) self.assertParseEqual(p.parse('restart the 9-line'), [ logic.Description('c-action-request', { 'action': 'c-start-over', 'object': 'c-nine-line' }) ]) self.assertParseEqual(p.parse('restart the 9line'), [ logic.Description('c-action-request', { 'action': 'c-start-over', 'object': 'c-nine-line' }) ])
def test_head_directive(self): """Test :head directive.""" kb = logic.PropKB() kb.tell(logic.expr('ISA(c-animal, c-physobj)')) kb.tell(logic.expr('ISA(c-dog, c-animal)')) kb.tell(logic.expr('ISA(c-cat, c-animal)')) 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('ISA(c-flea-bitten, c-flea-status)')) kb.tell(logic.expr('ISA(c-flea-free, c-flea-status)')) kb.tell(logic.expr('ISA(c-feed, c-action)')) kb.tell(logic.expr('$constraint(c-physobj, color, c-color)')) kb.tell(logic.expr('$constraint(c-physobj, size, c-size)')) kb.tell(logic.expr('$constraint(c-action-request, action, c-action)')) kb.tell( logic.expr( '$constraint(c-action-request, theta-object, c-physobj)')) kb.tell(logic.expr('$constraint(c-dog, flea-status, c-flea-status)')) p = parser.ConceptualParser(kb) p.add_phrasal_pattern(logic.expr('c-physobj'), '<size> <color> <:head>') p.add_phrasal_pattern(logic.expr('c-physobj'), 'thing') p.add_phrasal_pattern(logic.expr('c-cat'), 'cat') p.add_phrasal_pattern(logic.expr('c-dog'), 'dog') p.add_phrasal_pattern(logic.expr('c-dog'), '<flea-status> dog') 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-small'), 'small') p.add_phrasal_pattern(logic.expr('c-small'), 'tiny') p.add_phrasal_pattern(logic.expr('c-big'), 'big') p.add_phrasal_pattern(logic.expr('c-big'), 'large') p.add_phrasal_pattern(logic.expr('c-flea-bitten'), 'itchy') p.add_phrasal_pattern(logic.expr('c-flea-free'), 'happy') p.add_phrasal_pattern(logic.expr('c-feed'), 'feed') p.add_phrasal_pattern(logic.expr('c-action-request'), '<action> <theta-object>') p.add_phrasal_pattern(logic.expr('c-action-request'), '<action> the <theta-object>') self.assertParseEqual(p.parse('big red thing'), [ logic.Description('c-physobj', { 'color': 'c-red', 'size': 'c-big' }) ]) self.assertParseEqual(p.parse('big green thing'), [ logic.Description('c-physobj', { 'color': 'c-green', 'size': 'c-big' }) ]) self.assertParseEqual(p.parse('small red thing'), [ logic.Description('c-physobj', { 'color': 'c-red', 'size': 'c-small' }) ]) self.assertParseEqual(p.parse('small green thing'), [ logic.Description('c-physobj', { 'color': 'c-green', 'size': 'c-small' }) ]) cat_desc = logic.Description('c-cat', { 'color': 'c-green', 'size': 'c-small' }) self.assertParseEqual(p.parse('feed the small green cat'), [ logic.Description('c-action-request', { 'action': 'c-feed', 'theta-object': cat_desc }) ]) green_dog_desc = logic.Description('c-dog', { 'color': 'c-green', 'size': 'c-small' }) self.assertParseEqual(p.parse('feed the small green dog'), [ logic.Description('c-action-request', { 'action': 'c-feed', 'theta-object': green_dog_desc }) ]) green_itchy_dog_desc = logic.Description('c-dog', { 'flea-status': 'c-flea-bitten', 'color': 'c-green', 'size': 'c-small' }) self.assertParseEqual(p.parse('feed the small green itchy dog'), [ logic.Description('c-action-request', { 'action': 'c-feed', 'theta-object': green_itchy_dog_desc }) ])
def test_slot_filling2(self): """More slot filling tests""" kb = logic.PropKB() kb.tell(logic.expr('ISA(c-animal, c-physobj)')) kb.tell(logic.expr('ISA(c-dog, c-animal)')) kb.tell(logic.expr('ISA(c-cat, c-animal)')) 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('ISA(c-feed, c-action)')) kb.tell(logic.expr('$constraint(c-physobj, color, c-color)')) kb.tell(logic.expr('$constraint(c-physobj, size, c-size)')) kb.tell(logic.expr('$constraint(c-action-request, action, c-action)')) kb.tell( logic.expr( '$constraint(c-action-request, theta-object, c-physobj)')) p = parser.ConceptualParser(kb) p.add_phrasal_pattern(logic.expr('c-physobj'), '<size> <color> thing') 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-small'), 'small') p.add_phrasal_pattern(logic.expr('c-small'), 'tiny') p.add_phrasal_pattern(logic.expr('c-big'), 'big') p.add_phrasal_pattern(logic.expr('c-big'), 'large') p.add_phrasal_pattern(logic.expr('c-feed'), 'feed') p.add_phrasal_pattern(logic.expr('c-action-request'), '<action> the <theta-object>') self.assertParseEqual(p.parse_tokens(['big', 'red', 'thing']), [ logic.Description('c-physobj', { 'color': 'c-red', 'size': 'c-big' }) ]) self.assertParseEqual(p.parse('big red thing'), [ logic.Description('c-physobj', { 'color': 'c-red', 'size': 'c-big' }) ]) self.assertParseEqual(p.parse('big green thing'), [ logic.Description('c-physobj', { 'color': 'c-green', 'size': 'c-big' }) ]) self.assertParseEqual(p.parse('small red thing'), [ logic.Description('c-physobj', { 'color': 'c-red', 'size': 'c-small' }) ]) self.assertParseEqual(p.parse('small green thing'), [ logic.Description('c-physobj', { 'color': 'c-green', 'size': 'c-small' }) ]) self.assertParseEqual(p.parse('feed the small green thing'), [ logic.Description( 'c-action-request', { 'action': 'c-feed', 'theta-object': logic.Description('c-physobj', { 'color': 'c-green', 'size': 'c-small' }) }) ])
def test_string_parsing(self): """Test parsing FDL from strings.""" xml = """ <fdl> <lexicon> <lexeme> <!-- Short for 'roger'. --> <spelling>rog</spelling> <part-of-speech>interjection</part-of-speech> <phonemes>r ao jh</phonemes> <phonemes>r ao d</phonemes> </lexeme> <lexeme> <!-- Whatever, this is just a test. --> <spelling>john</spelling> <part-of-speech>noun</part-of-speech> <phonemes>j uh n</phonemes> </lexeme> </lexicon> <frame id='c-action-request'> <parent id='c-utterance' /> <constraint slot='addressee' type='c-name' /> <constraint slot='action' type='c-action' /> <constraint slot='object' type='c-thing' /> <phrase> {addressee} ?:[let's|let us|why don't we] {action} ?:[with|on] ?:the {object} </phrase> </frame> <frame id='c-hog'> <parent id='c-name' /> <phrase>hog</phrase> </frame> <frame id='c-restart'> <parent id='c-action' /> <phrase>[restart|start over]</phrase> </frame> <frame id='c-talkon'> <parent id='c-thing' /> <phrase>[talk on|talkon]</phrase> </frame> <frame id='i-petunia'> <parent id='c-cat' instanceof='true' /> <slot name='color' value='i-gray' /> <generate>Petunia</generate> </frame> </fdl> """ 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) self.assertEqual(fdl_parser.parse_fdl_string(xml), True) self.assertEqual( kb.isa(logic.expr('c-action-request'), logic.expr('c-utterance')), True) self.assertEqual( cp_parser.slot_constraint(logic.expr('c-action-request'), logic.expr('addressee')), logic.expr('c-name')) self.assertEqual( cp_parser.slot_constraint(logic.expr('c-action-request'), logic.expr('action')), logic.expr('c-action')) self.assertEqual( cp_parser.slot_constraint(logic.expr('c-action-request'), logic.expr('object')), logic.expr('c-thing')) self.assertParseEqual(cp_parser.parse('hog'), [logic.Description('c-hog')]) self.assertParseEqual(cp_parser.parse('restart'), [logic.Description('c-restart')]) self.assertParseEqual(cp_parser.parse('start over'), [logic.Description('c-restart')]) self.assertParseEqual(cp_parser.parse('talkon'), [logic.Description('c-talkon')]) self.assertParseEqual(cp_parser.parse('talk on'), [logic.Description('c-talkon')]) 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' }) ]) self.assertAllBindingsEqual(kb.ask_all(logic.expr('ISINSTANCE(?x)')), [{ '?x': 'i-petunia' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('INSTANCEOF(i-petunia, ?x)')), [{ '?x': 'c-cat' }]) self.assertAllBindingsEqual( kb.ask_all(logic.expr('color(i-petunia, ?c)')), [{ '?c': 'i-gray' }]) self.assertEqual('color' in kb.heritable, True) generator = generation.Generator(kb) self.assertEqual(generator.generate(logic.expr('i-petunia')), 'Petunia') self.assertEqual(len(fdl_handler.lexemes), 2) self.assertEqual(fdl_handler.lexemes[0].spelling, 'rog') self.assertEqual(fdl_handler.lexemes[0].part_of_speech, 'interjection') self.assertEqual(fdl_handler.lexemes[0].phonetic_pronunciations, ['r ao jh', 'r ao d']) self.assertEqual(fdl_handler.lexemes[1].spelling, 'john') self.assertEqual(fdl_handler.lexemes[1].part_of_speech, 'noun') self.assertEqual(fdl_handler.lexemes[1].phonetic_pronunciations, ['j uh n'])