Пролог как устранить левую рекурсию

Я написал DCG (прилагательная фраза и предложная фраза) в прологе, когда я попытался запустить его, введя ip([every,boy,loved,some,girl]), он отображается вне локального стека. Я понял, что что-то не так с nbar. Кто-нибудь может мне помочь? Большое спасибо.

 %tree
 treeP(Term):-
     % Print the tree assuming indentation 0
     treeP(0,Term),
     % Tidy up with linefeed
     nl.

 treeP(_N,Tree):-
     % Tree is just a variable
     var(Tree),!,
     write(Tree).

 treeP(N,[Tree|Trees]):-
     proper_list([Tree|Trees]),!,
     write('['),
     N1 is N+1,
     treePNEL(N1,[Tree|Trees]),
     write(']').

 treeP(N,Tree):-
     % Nonatomic case
     Tree=..[Functor,Argument|Arguments],
     !,
     % Write the functor and opening parenthesis
     write(Functor),write('('),
     % Set N1 to new indentation for arguments
     atom_length(Functor,M), N1 is N+M+1,
     % Pretty-print the arguments
     treePNEL(N1,[Argument|Arguments]),
     % Write right parenthesis
     write(')').

 treeP(_N,Tree):-
     % Noncompound case
     write(Tree).

 treePNEL(N,[Tree1,Tree2|Trees]):-
     treeP(N,Tree1),
     % Go to correct position for further printing
     nl, tab(N),
     treePNEL(N,[Tree2|Trees]).

 treePNEL(N,[Tree]):-
     treeP(N,Tree).

 ip(Sentence):-
     setof(IP,
             ip(IP,Sentence,[]),
             IP),
     treeP(IP).


ip(SSem) --> np(NPSem), ibar(IbarSem),
    {var_replace(NPSem,NPSem1),
     beta(NPSem1@IbarSem,SSem)}.

ibar(VPSem) --> i(MvdVbL),vp(VPSem,MvdVbL).

i([]) --> [].
i([]) --> [Aux],{isAux(Aux)}.
i([Verb]) --> [InflVerb],{pastInfl(Verb,InflVerb),isVerb(Verb)}.
pastInfl(see,saw).
pastInfl(love,loved).

vp(VbarSem,MvdVbL) --> vbar(VbarSem,MvdVbL).
vbar(VbarSem,MvdVbL) --> v(VSem,MvdVbL), np(NPSem),
    {var_replace(VSem,VSem1),
     beta(VSem1@NPSem,VbarSem)}.

v(lbd(s, lbd(x,s@lbd(y,Fla))),[]) --> [Verb],
    {isVerb(Verb),Fla=..[Verb,x,y]}.

v(lbd(s,lbd(x,s@lbd(y,Fla))),[MvdVb])--> [],
    {Fla=..[MvdVb,x,y]}.

np(NbarSem) --> nbar(NbarSem).
nbar(NbarSem) --> adj(AdjSem),nbar(NbarSem1),
    {var_replace(AdjSem,AdjSem1),beta(AdjSem1@NbarSem1,NbarSem)}.
nbar(NbarSem) --> det(DetSem),nbar(NbarSem1),
    {var_replace(DetSem,DetSem1),beta(DetSem1@NbarSem1,NbarSem)}.
nbar(NSem) --> n(NSem).


nbar(NbarSem) --> nbar(NbarSem1),pp(PPSem),
    {var_replace(PPSem,PPSem1),beta(PPSem1@NbarSem1,NbarSem)}.
nbar(NSem) --> n(NSem).
pp(PPSem) --> pbar(PPSem).
pbar(NbarSem) --> po(PPSem),np(NbarSem1),
    {var_replace(PPSem,PPSem1),beta(PPSem1@NbarSem1,NbarSem)}.

isVerb(love).
n(lbd(x,boy(x))) --> [boy].
n(lbd(x,girl(x))) --> [girl].
det(lbd(q,lbd(p,exists(x,(q@x & p@x))))) --> [some].
det(lbd(q,lbd(p,forall(x,(q@x -> p@x))))) --> [every].

nbar(NbarSem) --> adj(AdjSem),nbar(NbarSem1)

nbar(NbarSem) --> det(DetSem),nbar(NbarSem1)

nbar(NbarSem) --> nbar(NbarSem1),pp(PPSem)


person Britishgoat    schedule 06.12.2016    source источник
comment
когда я пытался его запустить... какой именно запрос вы ввели?   -  person lurker    schedule 06.12.2016
comment
Я ввел ip([каждый,мальчик,любимый,какой-то,девушка]).   -  person Britishgoat    schedule 06.12.2016


Ответы (1)


Таблицы реализованы в последних версиях SWI-Prolog. Объявляя предикаты (или нетерминалы) с помощью левой рекурсии как табличные предикаты (или нетерминалы), вы можете сохранить их определения. За подробностями обращайтесь:

http://www.swi-prolog.org/pldoc/man?section=table

person Paulo Moura    schedule 06.12.2016