% DCG-Grammatik (Definite Clause Grammar)
% Nur Pers = 3, daher ignoriert.

startsymbol(s([_Temp])).  % für später

s([Temp]) -->
    np([Gen],[NumNP,KasNP]), vp([KasSubj],[Temp,NumVP]),
    { kongruenz((s([Temp]) -->
                 np([Gen],[NumNP,KasNP]),
                 vp([KasSubj],[Temp,NumVP]))) }.

kongruenz((s([Temp]) -->
           np([Gen],[NumNP,KasNP]),
           vp([KasSubj],[Temp,NumVP]))) :-
    ( Gen = error -> write('\nGenusinkongurenz im Subjekt') ; true),
    ( NumNP = error -> write('\nNumerusinkongurenz im Subjekt') ; true),
    ( KasNP = error -> write('\nKasuskongurenz im Subjekt') ; true),
    ( NumNP = NumVP -> true
    ; write('\nInkongurenz im Numerus von Subjekt und Praedikat')),
    ( KasNP = KasSubj -> true
    ; write('\nInkongurenz im Kasus von Subjekt und Praedikat')).
    
    

s([Temp]) -->
    [es], vp([es],[Temp,sg]).

np([GenNP],[NumNP,KasNP]) -->
    det([GenDet,NumDet,KasDet]),
    n([GenN],[NumN,KasN]),
    { kongruenz((np([GenNP],[NumNP,KasNP]) -->
                 det([GenDet,NumDet,KasDet]),
                 n([GenN],[NumN,KasN])))
    }.

kongruenz((np([GenNP],[NumNP,KasNP]) -->
                 det([GenDet,NumDet,KasDet]),
                 n([GenN],[NumN,KasN]))) :-
    ( GenDet = GenN -> GenNP = GenN ; GenNP = error ),
    ( NumDet = NumN -> NumNP = NumN ; NumNP = error ),
    ( KasDet = KasN -> KasNP = KasN ; KasNP = error ).

vp([nom],[Temp,Num]) -->
    ( v([nom],[Temp,Num])
    ; v([nom,akk],[Temp,Num]), np([_Gen],[_Num,akk])
    ).
vp([es],[Temp,Num]) --> v([es],[Temp,Num]), (adv ; []).

det([Gen,sg,Kas]) -->
    ( [der], { Gen = mask, Kas = nom }
    ; [das], { Gen = neut, (Kas = nom; Kas = akk) }
    ).

det([Gen,pl,Kas]) -->
    ( [die], { (Gen = mask ; Gen = fem ; Gen = neut),
               (Kas = nom ; Kas = akk) }
    ).

n([mask],[Num,Kas]) -->
    ['Programmierer'], { (Num = sg ; Num = pl),
                         (Kas = nom; Kas = akk) }.
n([neut],[sg,Kas]) -->
    ['Programm'], { (Kas = nom; Kas = akk) }.

v([nom],[praes,sg]) --> [steht].
v([nom],[praes,pl]) --> [stehen].
v([nom,akk],[praet,sg]) --> [schrieb].
v([nom,akk],[praet,pl]) --> [schrieben].

v([es],[praes,sg]) --> [regnet].
adv --> [oft] ; [lange].
