Reputation: 21
I am trying to build a top left parser in prolog for the sentence "The little pigs were safe inside" and I am trying to figure out where I went wrong in my code. (Note: I'm a beginner in prolog and the code I wrote is based on a working example I had)
Can anybody point me in the right direction on this and maybe shine some light on it?
Code:
% The little pigs were safe inside.
% ------------------------------------------------ TERMINALS ------------------------------------------------
leaf(determiner) --> [the].
leaf(adjective) --> [little].
leaf(adjective) --> [safe].
leaf(noun) --> [pigs].
leaf(verb) --> [were].
leaf(adverb) --> [inside].
% ------------------------------------------------ NON-TERMINALS ------------------------------------------------
lcd(noun_phrase,sentence):-!.
lcd(determiner,noun_phrase):-!.
lcd(adjective,adjective_phrase):-!.
lcd(adverb,adjective_phrase):-!.
lcd(verb,verb_phrase):-!.
lc(X,X):-!.
lc(X,Y):-lcd(X,Y),!.
lc(X,Y):-lcd(X,Z),lc(Z,Y).
% ------------------------------------------------ RULES ------------------------------------------------
parse(Nterm,As,[W0|W1],Wn):-
leaf(Pterm,[W0|W1],W1),
lc(Pterm,Nterm),
Ap=..[Pterm,W0],
P=..[Pterm,Nterm,Ap,As,W1,Wn],
call(P).
noun_phrase(Nt,NP,As)-->{lc(sentence,Nt)},parse(verb_phrase, VP),sentence(Nt,sentence(NP,VP),As),!.
noun_phrase(noun_phrase,E,E)-->[].
determiner(Nt,D,As)-->{lc(noun_phrase,Nt)},parse(adjective_phrase,N),noun_phrase(Nt,noun_phrase(D,N),As).
adjective(Nt,A,As)-->{lc(adjective_phrase,Nt)},parse(adjective_phrase,N),adjective_phrase(Nt,adjective_phrase(A,N),As).
adverb(Nt,A,As)-->{lc(adjective_phrase,Nt)},parse(adjective_phrase,N),adjective_phrase(Nt,adjective_phrase(A,N),As).
noun(Nt,N,As)-->{lc(adjective_phrase,Nt)},adjective_phrase(Nt,adjective_phrase(N),As).
adjective_phrase(adjective_phrase,A,A)-->[].
verb(Nt,V,As)-->{lc(verb_phrase,Nt)},parse(noun_phrase,N),verb_phrase(Nt,verb_phrase(V,N),As).
verb(Nt,V,As)-->{lc(verb_phrase,Nt)},verb_phrase(Nt,verb_phrase(V),As).
verb_phrase(verb_phrase,A,A)-->[].
sentence(s,A,A)-->[].
test(S,A):-parse(S,A,[the, little, pigs, were, safe, inside],[]).
Test trace:
trace,test(S,A).
Call: (9) test(_4648, _4650) ? creep
Call: (10) parse(s, _4650, [the, little, pigs, were, safe, inside], []) ? creep
Call: (11) leaf(_5024, [the, little, pigs, were, safe, inside], [little, pigs, were, safe, inside]) ? creep
Exit: (11) leaf(determiner, [the, little, pigs, were, safe, inside], [little, pigs, were, safe, inside]) ? creep
Call: (11) lc(determiner, s) ? creep
Call: (12) lcd(determiner, s) ? creep
Fail: (12) lcd(determiner, s) ? creep
Redo: (11) lc(determiner, s) ? creep
Call: (12) lcd(determiner, _5026) ? creep
Exit: (12) lcd(determiner, noun_phrase) ? creep
Call: (12) lc(noun_phrase, s) ? creep
Call: (13) lcd(noun_phrase, s) ? creep
Fail: (13) lcd(noun_phrase, s) ? creep
Redo: (12) lc(noun_phrase, s) ? creep
Call: (13) lcd(noun_phrase, _5026) ? creep
Exit: (13) lcd(noun_phrase, sentence) ? creep
Call: (13) lc(sentence, s) ? creep
Call: (14) lcd(sentence, s) ? creep
Fail: (14) lcd(sentence, s) ? creep
Redo: (13) lc(sentence, s) ? creep
Call: (14) lcd(sentence, _5026) ? creep
Fail: (14) lcd(sentence, _5026) ? creep
Fail: (13) lc(sentence, s) ? creep
Fail: (12) lc(noun_phrase, s) ? creep
Fail: (11) lc(determiner, s) ? creep
Redo: (11) leaf(_5024, [the, little, pigs, were, safe, inside], [little, pigs, were, safe, inside]) ? creep
Fail: (11) leaf(_5024, [the, little, pigs, were, safe, inside], [little, pigs, were, safe, inside]) ? creep
Fail: (10) parse(s, _4650, [the, little, pigs, were, safe, inside], []) ? creep
Fail: (9) test(_4648, _4650) ? creep
false.
The expected output for this grammar when running the test should be something like:
S = [the, little, pigs, were, safe, inside],A = s(np(d(the), adjp(adj(little), n(pigs))), vp(v(were), adjp(adj(safe), adv(inside)))) .
Upvotes: 0
Views: 89
Reputation: 21
For anyone who might need this later on. Only a few fixes were needed to make this work. Compare the two programs to find the mistakes :)
Solution
% The little pigs were safe inside.
% ------------------------------------------------ TERMINALS ------------------------------------------------
leaf(determiner) --> [the].
leaf(adjective) --> [little].
leaf(adjective) --> [safe].
leaf(noun) --> [pigs].
leaf(verb) --> [were].
leaf(adverb) --> [inside].
% ------------------------------------------------ NON-TERMINALS ------------------------------------------------
lcd(noun_phrase,sentence):-!.
lcd(determiner,noun_phrase):-!.
lcd(verb,verb_phrase):-!.
lcd(adjective,adjective_phrase):-!.
lc(X,X):-!.
lc(X,Y):-lcd(X,Y),!.
lc(X,Y):-lcd(X,Z),lc(Z,Y).
parse(Nterm,As,[W0|W1],Wn):-
leaf(Pterm,[W0|W1],W1),
lc(Pterm,Nterm),
Ap=..[Pterm,W0],
P=..[Pterm,Nterm,Ap,As,W1,Wn],
call(P).
% ------------------------------------------------ RULES ------------------------------------------------
noun_phrase(Nt,NP,As)-->{lc(sentence,Nt)},parse(verb_phrase, VP),sentence(Nt,sentence(NP,VP),As),!.
noun_phrase(noun_phrase,E,E)-->[].
determiner(Nt,D,As)-->{lc(noun_phrase,Nt)},parse(adjective_phrase,N),noun_phrase(Nt,noun_phrase(D,N),As).
adjective_phrase(adjective_phrase,A,A)-->[].
verb(Nt,V,As)-->{lc(verb_phrase,Nt)},parse(adjective_phrase,N),verb_phrase(Nt,verb_phrase(V,N),As).
verb_phrase(verb_phrase,A,A)-->[].
adjective(Nt,A,As)-->{lc(adjective_phrase,Nt)},parse(noun,N),adjective_phrase(Nt,adjective_phrase(A,N),As).
noun(noun,A,A)-->[].
adjective(Nt,A,As)-->{lc(adjective_phrase,Nt)},parse(adverb,Adv),adjective_phrase(Nt,adjective_phrase(A,Adv),As).
adverb(adverb,A,A)-->[].
sentence(sentence,A,A)-->[].
% ------------------------------------------------ TEST ------------------------------------------------
test(sentence,A):-parse(sentence,A,[the, little, pigs, were, safe, inside],[]).
test1(sentence,A):-parse(sentence,A,[the, little, pigs],[]).
Upvotes: 0