import jsgf class NLU: #Natural Language Understanding """ Moduł odpowiedzialny za analizę tekstu. W wyniku jego działania tekstowa reprezentacja wypowiedzi użytkownika zostaje zamieniona na jej reprezentację semantyczną, najczęściej w postaci ramy. Wejście: Tekst Wyjście: Akt użytkownika (rama) """ def __init__(self, acts, arguments, book_grammar): self.acts = acts self.arguments = arguments self.book_grammar = book_grammar def get_dialog_act(self, rule): slots = [] self.get_slots(rule.expansion, slots) return {'act': rule.grammar.name, 'slots': slots} def get_slots(self, expansion, slots): if expansion.tag != '': slots.append((expansion.tag, expansion.current_match)) return for child in expansion.children: self.get_slots(child, slots) if not expansion.children and isinstance(expansion, jsgf.NamedRuleRef): self.get_slots(expansion.referenced_rule.expansion, slots) def analyze(self, text): """ Analiza Tekstu wprowadzonego przez użytkownika i zamiana na akt (rama) """ print("Analiza Tekstu: " + text) act = "(greetings()&request(name))" print("Akt to: " + act) #przerobienie na wektor act_vector = [[0],[1,0]] #1 wektor to greetings, a 2 wektor to request z argumentem "name" print("Zamiana na: ") print(act_vector) return act_vector def test_nlu(self, utterance): matched = self.book_grammar.find_matching_rules(utterance) print(matched) if matched: return self.get_dialog_act(matched[0]) else: return {'act': 'null', 'slots': []} class DST: #Dialogue State Tracker """ Moduł odpowiedzialny za śledzenie stanu dialogu. Przechowuje informacje o tym jakie dane zostały uzyskane od użytkownika w toku prowadzonej konwersacji. Wejście: Akt użytkownika (rama) Wyjście: Reprezentacja stanu dialogu (rama) """ def __init__(self, acts, arguments): self.acts = acts self.arguments = arguments self.frame_list= [] def store(self, rama): """ Dodanie nowego aktu do listy """ print("\nDodanie do listy nowej ramy: ") print(rama) self.frame_list.append(rama) def transfer(self): print("Przekazanie dalej listy ram: ") print(self.frame_list) return self.frame_list class DP: """ Moduł decydujący o wyborze kolejnego aktu, który ma podjąć system prowadząc rozmowę. Wejście: Reprezentacja stanu dialogu (rama) Wyjście: Akt systemu (rama) """ def __init__(self, acts, arguments): self.acts = acts self.arguments = arguments def choose_tactic(self, frame_list): """ Obieranie taktyki na podstawie aktów usera. Bardzo ważna jest kolejność dodawanych do frame_list wartości. """ act_vector = [0, 0] return act_vector class NLG: """ Moduł, który tworzy reprezentację tekstową aktu systemowego wybranego przez taktykę dialogu. Wejście: Akt systemu (rama) Wyjście: Tekst """ def __init__(self, acts, arguments): self.acts = acts self.arguments = arguments def change_to_text(self, act_vector): """ Funkcja zamieniająca akt systemu na tekst rozumiany przez użytkownika. """ if(act_vector == [0, 0]): return "Cześć, mam na imię Janet" return "Nie rozumiem" class Janet: def __init__(self): self.acts={ 0: "greetings", 1: "request", } self.arguments={ 0: "name" } self.nlg = NLG(self.acts, self.arguments) self.dp = DP(self.acts, self.arguments) self.dst = DST(self.acts, self.arguments) self.nlu = NLU(self.acts, self.arguments, jsgf.parse_grammar_file('book.jsgf')) def test(self, command): out = self.nlu.test_nlu(command) return out def process(self, command): act = self.nlu.analyze(command) self.dst.store(act) dest_act = self.dp.choose_tactic(self.dst.transfer()) return self.nlg.change_to_text(dest_act) janet = Janet() print(janet.test('chciałbym się umówić na wizytę do Piotra Pająka na jutro')) #Testowy print na start while(1): print('\n') text = input("Wpisz tekst: ") print(janet.test(text))