# Tests for Exercise Sheet 6
# Python 2 - SS13

import unittest
from tree import Tree
from l6_shift_reduce import parse
from l6_top_down import recognize, TopDownParser



class TestShiftReduce(unittest.TestCase): 

    rules = [ 
        ( 'S', ['NP', 'VP']),
        ('NP', ['D', 'N']),
        ('NP', ['NP', 'PP']),
        ('VP', ['V']),
        ('VP', ['V', 'NP']),
        ('VP', ['VP', 'PP']),
        ('PP', ['P', 'NP']),
        ( 'V', ['arbeitet']),
        ( 'V', ['liest']),
        ( 'N', ['Student']),
        ( 'N', ['Buch']),
        ( 'N', ['Bibliothek']),
        ( 'P', ['in']),
        ( 'D', ['der']),
        ( 'D', ['die']),
        ( 'D', ['das'])
    ]


    def testParseMethod(self):
        parser = parse(['der', 'Student', 'liest', 'das', 'Buch', 'in', 'der', 'Bibliothek'], TestShiftReduce.rules)
        parses = [p for p in parser]
        self.assertEqual(len(parses),2) 
        ref1 = Tree('S', [Tree('NP', [Tree('D', [Tree('der', [])]), Tree('N', [Tree('Student', [])])]), Tree('VP', [Tree('VP', [Tree('V', [Tree('liest', [])]), Tree('NP', [Tree('D', [Tree('das', [])]), Tree('N', [Tree('Buch', [])])])]), Tree('PP', [Tree('P', [Tree('in', [])]), Tree('NP', [Tree('D', [Tree('der', [])]), Tree('N', [Tree('Bibliothek', [])])])])])])
        ref2 = Tree('S', [Tree('NP', [Tree('D', [Tree('der', [])]), Tree('N', [Tree('Student', [])])]), Tree('VP', [Tree('V', [Tree('liest', [])]), Tree('NP', [Tree('NP', [Tree('D', [Tree('das', [])]), Tree('N', [Tree('Buch', [])])]), Tree('PP', [Tree('P', [Tree('in', [])]), Tree('NP', [Tree('D', [Tree('der', [])]), Tree('N', [Tree('Bibliothek', [])])])])])])])
        self.assertTrue(ref1 in parses)      
        self.assertTrue(ref2 in parses)


class TestTopDown(unittest.TestCase): 
    rules = dict([ 
      ( 'S', [['NP', 'VP']]),
      ('NP', [['D', 'N'], ['D', 'N', 'PP']]),
      ('VP', [['V'], ['V', 'PP'], ['V', 'NP'], ['V', 'NP', 'PP']]),
      ('PP', [['P', 'NP']])
    ])

    lexicon = set([
       ( 'V', 'arbeitet'),
       ( 'V', 'liest'),
       ( 'N', 'Student'),
       ( 'N', 'Buch'),
       ( 'N', 'Bibliothek'),
       ( 'P', 'in'),
       ( 'D', 'der'),
       ( 'D', 'die'),
       ( 'D', 'das')
    ]) 

    def test_recognize(self):
        self.assertTrue(recognize(['der', 'Student', 'arbeitet'],TestTopDown.rules,TestTopDown.lexicon))
        self.assertTrue(recognize(['der', 'Student', 'liest', 'das', 'Buch', 'in', 'der', 'Bibliothek'], TestTopDown.rules,TestTopDown.lexicon))
        self.assertFalse(recognize(['der', 'Student', 'arbeitet', 'in', 'Bibliothek'], TestTopDown.rules, TestTopDown.lexicon))
        self.assertFalse(recognize(['der', 'Student', 'liest', 'das'], TestTopDown.rules, TestTopDown.lexicon))

    def test_parser(self):
        parser = TopDownParser(['der', 'Student', 'liest', 'das', 'Buch', 'in', 'der', 'Bibliothek'], TestTopDown.rules,TestTopDown.lexicon)
        parses = [p for p in parser]
        self.assertEqual(len(parses),2)
        ref1 = Tree('S', [Tree('NP', [Tree('D', [Tree('der', [])]), Tree('N', [Tree('Student', [])])]), Tree('VP', [Tree('V', [Tree('liest', [])]), Tree('NP', [Tree('D', [Tree('das', [])]), Tree('N', [Tree('Buch', [])])]), Tree('PP', [Tree('P', [Tree('in', [])]), Tree('NP', [Tree('D', [Tree('der', [])]), Tree('N', [Tree('Bibliothek', [])])])])])])
        ref2 = Tree('S', [Tree('NP', [Tree('D', [Tree('der', [])]), Tree('N', [Tree('Student', [])])]), Tree('VP', [Tree('V', [Tree('liest', [])]), Tree('NP', [Tree('D', [Tree('das', [])]), Tree('N', [Tree('Buch', [])]), Tree('PP', [Tree('P', [Tree('in', [])]), Tree('NP', [Tree('D', [Tree('der', [])]), Tree('N', [Tree('Bibliothek', [])])])])])])])
        self.assertTrue(ref1 in parses)
        self.assertTrue(ref2 in parses)
         

if __name__ == '__main__':
    unittest.main()    
