210 likes | 357 Vues
This guide explores common problems and solutions in natural language processing using Prolog. Learn how to append two lists or split a list into two, and delve into writing a parser to construct parse trees. We will cover the role of parse trees in understanding sentence structure, their importance for machine translation, and how to correctly implement them in Prolog. Additionally, we will examine various examples of legal sentences generated from defined grammar, demonstrating how Prolog can be utilized for language processing with effective list manipulation techniques.
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 .