210 likes | 338 Views
Natural Language Processing. A few problems from your work ‘append’ program - two lists to one or split one list into two How to write a parser in Prolog , how it works (ref. Paul’s book, page 78-85) Construct parse trees Use of parse trees. Common Problems/Mistakes.
E N D
Natural Language Processing A few problems from your work ‘append’ program - two lists to one or split one list into two How to write a parser in Prolog, how it works (ref. Paul’s book, page 78-85) Construct parse trees Use of parse trees
Common Problems/Mistakes • % an empty set is a subset of any set L subset([], [L]). % what is wrong? • When call ‘not_u_turn’, must make sure that both parameters are not variables. not_u_turn(X,Y):- \+(u_turn(X,Y).
(re-used slide) Manipulating Lists Ex. 5 – Appending 2 lists Write a program append(L1,L2,L3) where L3 is the concatenation of L1 and L2. e.g. append([1,2], [a,b,c],L) returns L = [1,2,a,b,c] Q: how about append(L1, L2, [1,2,3]) ? append([],L,L). append([X|T1],T2,[X|T3]):- append(T1,T2,T3). (in SICStusProlog, append is a builtin)
How many different way ‘append’ program can be called? • append([a], [student], [a,student]). % in/in/in • append([you,are],[in,’2q49’], L). % in/in/out L = [you,are,in,’2q49’] • append([you], L, [you,are,a,student]). % in/out/in L = [are,a,student] • append(L, [student], [i,am,a,student]). % out/in/in L = [i,am,a] • append([you],L1,L2). % in/out/out • append(L1,[you],L2). % out/in/out • append(L1,L2,[i,am,a,student]). % out/out/in
Parsing – work out the structure of a sentence The first step toward to processing language • I like uwe very much subject verb object_phrase noun_phrase adverb I like uwe very much
Why do we need parser? Traditional Parser’s Role: • Check if a sentence syntactically correct • If yes, construct a parse tree for the sentence Non-traditional Role: • Generate possible sentences
Why do we need parse tree? • Help us to understand the meaning of a sentence • Allow us to transform a sentence to other forms: • Machine translation. e.g. ‘I like uwe’ in Japanese, the order is ‘I uwe like’. We need to know both structures in order to translate • Reconstructing a new sentence from an old one. e.g. ‘I like uwe’ can be changed to ‘why do you like uwe’. This is useful for creating a conversation for chatbot.
A Small Example Let’s use this small set of vocabulary { i, you, me, us, uwe, cs_course, robolics_course, like, love, very_much } Next, we define a very basic English grammar shown in the left box. sentence --> subject_phrase, verb, object_phrase. subject_phrase --> subject_pronoun. object_phrase --> object_pronoun, adverb. object_phrase --> noun_phrase, adverb. noun_phrase --> determiner, noun. ‘-->’ means ‘defined as’ and ‘consists of’
A Small Example (cont) subject_pronoun --> [i]. subject_pronoun --> [we]. subject_pronoun --> [you]. object_pronoun --> [you]. object_pronoun --> [me]. object_pronoun --> [us]. determiner --> []. % determiner --> [a]. % determiner --> [the]. noun --> [uwe]. noun --> [cs_course]. noun --> [robotics_course]. adverb --> [very, much]. adverb --> []. verb --> [like]. verb --> [love].
How to write it in Prolog? • Those (in slide 9-10) are already Prolog code ! • ‘-->’ is specially added for writing a parser sentence --> subject_phrase, verb, object_phrase. is equivalent to sentence(L1,Rest):- subject_phrase(L1,L2), verb(L2,L3), object_phrase(L3,Rest). So, we can call ‘sentence([we,love,uwe],[]).’ to check if it it a legal sentence
Having those defined, we can do lots of things: Check if it a legal sentence | ?- sentence([we, love, uwe],[]). yes | ?- sentence([love,you],[]). no | ?- sentence([we, like, you, because], R). R = [because] ? yes | ?- sentence(L,[]). L = [i,like,uwe,very,much] ? ; L = [i,like,uwe] ? ; L = [i,like,cs_course,very,much] ? ; L = [i,like,cs_course] ? ; L = [i,like,robotics_course,very,much] ? ; L = [i,like,robotics_course] ? ; L = [i,like,you,very,much] ? ; L = [i,like,you] ? ; L = [i,like,me,very,much] ? ; L = [i,like,me] ? ; L = [i,like,us,very,much] ? yes | ?- findall(L, sentence(L,[]), All). All = [[i,like,uwe,very,much],[i,like,uwe],[i,like,cs_course,very,much],[i,like,cs_course],[i,like,robotics_course,very,much],[i,like,robotics_course],[i,like,you,very|...],[i,like,you],[i,like|...],[...|...]|...] ? Generate all legal sentences! What is a legal sentence?
In order to generate parse tree we need to change the code (version 2)New Old sentence(s(X, Y, Z)) --> subject_phrase(X), verb(Y), object_phrase(Z). subject_phrase(sp(X)) --> subject_pronoun(X). object_phrase(op(X,Y)) --> noun_phrase(X), adverb(Y). object_phrase(op(X, Y)) --> object_pronoun(X), adverb(Y). noun_phrase(np(Y)) --> noun(Y). prepositional_phrase(pp(X, Y)) --> preposition(X), place_name(Y). sentence --> subject_phrase, verb, object_phrase. subject_phrase --> subject_pronoun. object_phrase --> noun_phrase, adverb. object_phrase --> object_pronoun, adverb. noun_phrase --> noun. prepositional_phrase --> preposition, place_name.
In order to generate parse tree we need to change the code (version 2)New Old preposition(prep(in)) --> [in]. preposition(prep(at)) --> [at]. preposition(prep(from)) --> [from]. place_name(pname(reception)) --> [reception]. place_name(pname(london)) --> [london]. place_name(pname(bristol)) --> [bristol]. place_name(pname(X)) --> [X], { next(X,_,_,_,_) }. subject_pronoun(spn(i)) --> [i]. subject_pronoun(spn(we)) --> [we]. subject_pronoun(spn(you)) --> [you]. object_pronoun(opn(you))--> [you]. object_pronoun(opn(me))--> [me]. object_pronoun(opn(us))--> [us]. %... preposition --> [in]. preposition --> [at]. preposition --> [from]. place_name --> [reception]. place_name --> [london]. place_name --> [bristol]. place_name --> [X], { next(X,_,_,_,_) }. subject_pronoun --> [i]. subject_pronoun --> [we]. subject_pronoun --> [you]. object_pronoun --> [you]. object_pronoun --> [me]. object_pronoun --> [us]. % ………
Test on version 2 – a list of words to a parse tree | ?- sentence(Tree, [i,love,you],[]). Tree = s(sp(spn(i)),vd(love),op(opn(you),ad([]))) ? ; | ?- sentence(Tree, [i,love,you,very,much],[]). Tree = s(sp(spn(i)),vd(love),op(opn(you),ad([very,much]))) ? yes | ?- sentence(T,[i,am,in,bristol],[]). T = s(s_2b([i,am]),pp(prep(in),pname(bristol))) ? | ?- sentence(s(sp(spn(i)),vd(love),op(opn(you),ad([very,much]))), L,K). L = [i,love,you,very,much|K] ? yes % 6 | ?- sentence(s(s_2b([i,am]),pp(prep(in),pname(bristol))), L,[]). L = [i,am,in,bristol] ? • Test on version 2 – a parse tree to a list of word
Add a few more grammar rules for questions question(q(why,do,S)) --> [why, do], sentence(S). question(q(do,S)) --> [do], sentence(S). /* after added the above line, we can handle questions like: */ | ?- question(Tree, [why,do ,you, love,me],[]). Tree = q(why,do,s(sp(spn(you)),vd(love),op(opn(me),ad([])))) ? | ?- question(Tree, [do ,you, like,uwe],[]). Tree = q(do,s(sp(spn(you)),vd(like),op(np(uwe),ad([])))) ?
How to change a sentence to a question beginning with ‘why’? I like uwe Why do you like uwe mapping(s2why, % s(sp(spn(N1)), vd(V), op(np(noun(N2)), ad(X))), q(why,do,s(sp(spn(P1)),vd(V),op(np(noun(N2)),ad(X)))) ) :- mapping_spn(N1, P1).
How to change a sentence to a question beginning with ‘why’? I like you Why do you like me mapping(s2why, % type of mapping s(sp(spn(N1)),vd(V),op(opn(N2),ad(X))), q(why,do,s(sp(spn(P1)),vd(V),op(opn(P2),ad(X)))) ) :- mapping_spn(N1, P1), mapping_opn(N2, P2).
| ?- sentence(T1, [i,like,uwe],[]), mapping(s2why,T1,T2), question(T2, L,[]). L = [why,do,you,like,uwe], T1 = s(sp(spn(i)),vd(like),op(np(noun(uwe)),ad([]))), T2 = q(why,do,s(sp(spn(you)),vd(like),op(np(noun(uwe)),ad([])))) ? yes % 7 converging parse trees Parser Parser | ?- question(Tree, [why,do,you,love,me],[]), mapping(s2why, T, Tree), sentence(T, L, []). L = [i,love,you], T = s(sp(spn(i)),vd(love),op(opn(you),ad([]))), Tree = q(why,do,s(sp(spn(you)),vd(love),op(opn(me),ad([])))) ?
Put them together (file english.pl) test:- repeat, readin(S), gen_reply(S,Ans), write_list(Ans), nl, S = [bye|_]. test:- write(bye),nl. gen_reply(S,Reply):- sentence(Tree1, S, _Rest),!, mapping(s2why,Tree1, Tree2), question(Tree2, Rep,[]), append(Rep, ['?'], Reply). gen_reply(S,Reply):- question(Tree2, S, _Rest),!, mapping(s2q,Tree1, Tree2), sentence(Tree1, Rep,[]), append([yes, ','|Rep], ['!'], Reply). gen_reply([bye|_],[bye ,for, now, '.']). gen_reply(_,[what,'?']). % default case % ‘!’ will be explained in next week
A test example from this simple chatbot | ?- test. |: hi! |: what ? Hi! |: what ? i love you! |: why do you love me ? don't know. |: what ? do you love me? |: yes , i love you ! bye. bye for now .