parsingprologdcgfailure-slicenon-termination

Prolog parsing is running out of stack


I have this code

s(W) :- append(W1,W2,W), np(W1), vp(W2).

vp(W) :- append(W1,W2,W), v(W1), np(W2).

np(W) :-
   (  append(W1,W2,W), pn(W1), ph(W2)
   ;  append(W1,W2,W), det(W1), n(W2)
   ).

pn([hans]).

ph([]).

v([beobachtet]).

n([mann]).
n([fernrohr]).

p([mit]).

det([den]).
det([dem]).

when I cast something like np(X). vp(X). or pp(X) get one possible parse and then an out of stack error. when I cast s(X). I don't even get a parse. I know that is because there is some infinite loop running, but I just cant point out at which point it gets looped. i figured it might happen because of using the same names for all my variables, but then I changed them to individual ones and it didn't change anything.

any one got a hint?

thanks in advance!


Solution

  • Reason for out of stack

    Let's look at the following line from your code:

    vp(W) :- append(W1,W2,W), v(W1), np(W2).
    

    Running append(W1, W2, W) in isolation gives the following:

    ?- append(W1, W2, W).
    W1 = [],
    W2 = W ;
    W1 = [_G1108],
    W = [_G1108|W2] ;
    W1 = [_G1108, _G1114],
    W = [_G1108, _G1114|W2] ;
    W1 = [_G1108, _G1114, _G1120],
    W = [_G1108, _G1114, _G1120|W2] .
    

    As you can see, W1 is a list of increasing length. Only for length 1 does it give a solution (since v(W1)). After this first instantiation, W1 gets longer and longer and longer and ..., but v(W1) will not succeed for lists of longer length.

    DCG grammar

    In Prolog you can use DCG notation to create a grammar. Your grammar would look as follows:

    s --> np, vp.
    np --> pn.
    np --> det, n.
    vp --> v, np.
    
    det --> [den].
    det --> [dem].
    
    n --> [mann].
    n --> [fernrohr].
    
    pn --> [hans].
    
    v --> [beobachtet].
    

    Example of use

    ?- phrase(s, S).
    S = [hans, beobachtet, hans] ;
    S = [hans, beobachtet, den, mann] ;
    S = [hans, beobachtet, den, fernrohr] ;
    S = [hans, beobachtet, dem, mann] ;
    S = [hans, beobachtet, dem, fernrohr] ;
    S = [den, mann, beobachtet, hans] ;
    S = [den, mann, beobachtet, den, mann] ;
    S = [den, mann, beobachtet, den, fernrohr] ;
    S = [den, mann, beobachtet, dem, mann] ;
    S = [den, mann, beobachtet, dem, fernrohr] ;
    S = [den, fernrohr, beobachtet, hans] ;
    S = [den, fernrohr, beobachtet, den, mann] ;
    S = [den, fernrohr, beobachtet, den, fernrohr] ;
    S = [den, fernrohr, beobachtet, dem, mann] ;
    S = [den, fernrohr, beobachtet, dem, fernrohr] ;
    S = [dem, mann, beobachtet, hans] ;
    S = [dem, mann, beobachtet, den, mann] ;
    S = [dem, mann, beobachtet, den, fernrohr] ;
    S = [dem, mann, beobachtet, dem, mann] ;
    S = [dem, mann, beobachtet, dem, fernrohr] ;
    S = [dem, fernrohr, beobachtet, hans] ;
    S = [dem, fernrohr, beobachtet, den, mann] ;
    S = [dem, fernrohr, beobachtet, den, fernrohr] ;
    S = [dem, fernrohr, beobachtet, dem, mann] ;
    S = [dem, fernrohr, beobachtet, dem, fernrohr].