:- module(flexion_slex,[erzeuge_vollformenlexikon/1]).
:- use_module([wortformen]). 

flektiere(Stammform,Vollform) :-
    lex(Stammform,Wortart,_,Flexionsklasse),
    form(Wortart,Formmerkmale),
    beuge(Wortart,Flexionsklasse,Stammform,
          Formmerkmale,Vollform).

beuge(v,Flexionsklasse,Stammform,Form,Vollform) :-
    konjugiere(Flexionsklasse,Stammform,Form,Vollform).
beuge(Wortart,Flexionsklasse,Stammform,Form,Vollform) :-
    (Wortart = n ; Wortart = rn ; Wortart = en),
    dekliniere(Flexionsklasse,Stammform,Form,Vollform).

flexion(Stammform) :-
    ( lex(Stammform,v,_,Flexionsklasse)        % Verbstamm?
    ->  verbflexion(Flexionsklasse,Stammform)
    ; lex(Stammform,Wortart,_,Flexionsklasse), % Nomenstamm?
        member(Wortart,[n,rn,en])
    ->  nomenflexion(Flexionsklasse,Stammform) 
    ; nl, 
        write('Das Stammlexikon hat keinen Eintrag zu: '),
        write(Stammform)
    ).
        
% verbflexion(+Konjugationsklasse,+Stammform)
verbflexion(Konjugationsklasse,Stammform) :-
    form(vfin,Formmerkmale),
    konjugiere(Konjugationsklasse,Stammform,
               Formmerkmale,Vollform),
    write(Formmerkmale),write(': '),write(Vollform),nl,
    fail.              % weitere Formmerkmale suchen
verbflexion(_,_).      % fertig.
% konjugiere(+Konjugationsklasse,+Infinitiv,
%            ?[Pers,Num,Temp,Mod],-Vollform)

% --- Regelmaessige Konjugation (Finite Formen) ---

konjugiere(rg(_),Infinitiv,[Pers,Num,Temp,Mod],Vollf) :-  
    concat(Stamm,'en',Infinitiv),
    endung(rg,[Pers,Num,Temp,Mod],Endung),
    (dentalstamm(Stamm), \+ concat(e,_,Endung)
    -> concat(e,Endung,ErwEndung)  % e-Einschub
    ;  ErwEndung = Endung
    ), concat(Stamm,ErwEndung,Vollf).

dentalstamm(Stamm) :- 
    concat(_,'d',Stamm) ; concat(_,'t',Stamm).

% -- regelmaessige Konjugation --

endung(rg,[1,sg,praes,ind], 'e').
endung(rg,[1,sg,praes,konj],'e').
endung(rg,[1,sg,praet,ind], 'te').
endung(rg,[1,sg,praet,konj],'te').

endung(rg,[1,pl,praes,ind], 'en').
endung(rg,[1,pl,praes,konj],'en').
endung(rg,[1,pl,praet,ind], 'ten').
endung(rg,[1,pl,praet,konj],'ten').

endung(rg,[2,sg,praes,ind], 'st').
endung(rg,[2,sg,praes,konj],'est').
endung(rg,[2,sg,praet,ind], 'test').
endung(rg,[2,sg,praet,konj],'test').

endung(rg,[2,pl,praes,ind], 't').
endung(rg,[2,pl,praes,konj],'et').
endung(rg,[2,pl,praet,ind], 'tet').
endung(rg,[2,pl,praet,konj],'tet').

endung(rg,[3,sg,praes,ind], 't').
endung(rg,[3,sg,praes,konj],'e').
endung(rg,[3,sg,praet,ind], 'te').
endung(rg,[3,sg,praet,konj],'te').

endung(rg,[3,pl,praes,ind], 'en').
endung(rg,[3,pl,praes,konj],'en').
endung(rg,[3,pl,praet,ind], 'ten').
endung(rg,[3,pl,praet,konj],'ten').

konjugiere(urg(_,(V1,V2,V3,V4),Ablautposition),
           Infinitiv,[Pers,Num,Temp,Mod],Vollform) :-
    concat(Stamm,en,Infinitiv),        % Zerlege z.B.
    LaengeVor is Ablautposition - 1,   % anfangen =
    sub_atom(Stamm,0,LaengeVor,_,Vor), % anf|a | ng |en
    infix(Vor,V1,Nach,Stamm),          % Vor|V1|Nach|en
    verbform((Vor,Nach),(V1,V2,V3,V4),
             [Pers,Num,Temp,Mod],Vollform).

% infix(+Vor,+Mitte,-Nach,+Kette) oder s.u.
% infix(+Vor,+Mitte,+Nach,-Kette) 
infix(Vor,Mitte,Nach,Kette) :-
    concat(Vor,Mitte,Praefix),
    concat(Praefix,Nach,Kette).

verbform((Vor,Nach),(V1,V2,_V3,_V4),
         [Pers,Num,praes,ind],Vollform) :-
    ( not(member([Pers,Num],[[2,sg],[3,sg]])),
      infix(Vor,V1,Nach,Stamm)
    ; member([Pers,Num],[[2,sg],[3,sg]]),
      infix(Vor,V2,Nach,Stamm)
    ),
    endung(urg,[Pers,Num,praes,ind],Endung),
    concat(Stamm,Endung,Vollform).

verbform((Vor,Nach),(_V1,_V2,V3,_V4),
         [Pers,Num,praet,ind],Vollform) :-
    infix(Vor,V3,Nach,Stamm),
    endung(urg,[Pers,Num,praet,ind],Endung),
    concat(Stamm,Endung,Vollform).
verbform((Vor,Nach),(_V1,_V2,V3,_V4),
         [Pers,Num,praet,konj],Vollform) :-
    (member(V3,[a,o,u]) -> umlaut(V3,U) ; U = V3),
    infix(Vor,U,Nach,Stamm),
    endung(urg,[Pers,Num,praet,konj],Endung),
    concat(Stamm,Endung,Vollform).

umlaut(a,ä).  umlaut(o,ö).  umlaut(u,ü).   

% -- unregelmaessige Konjugation --
endung(urg,[1,sg,praes,ind], 'e').
endung(urg,[1,sg,praes,konj],'e').
endung(urg,[1,sg,praet,ind], '').
endung(urg,[1,sg,praet,konj],'e').

endung(urg,[2,sg,praes,ind], 'st').
endung(urg,[2,sg,praes,ind], 'est').
endung(urg,[2,sg,praes,konj],'est').
endung(urg,[2,sg,praet,ind], 'st').
endung(urg,[2,sg,praet,ind], 'est').
endung(urg,[2,sg,praet,konj],'st').
endung(urg,[2,sg,praet,konj],'est').

endung(urg,[3,sg,praes,ind], 't').
endung(urg,[3,sg,praes,ind], 'et').
endung(urg,[3,sg,praes,konj],'e').
endung(urg,[3,sg,praet,ind], '').
endung(urg,[3,sg,praet,konj],'e').

endung(urg,[1,pl,praes,ind], 'en').
endung(urg,[1,pl,praes,konj],'en').
endung(urg,[1,pl,praet,ind], 'en').
endung(urg,[1,pl,praet,konj],'en').

endung(urg,[2,pl,praes,ind], 't').
endung(urg,[2,pl,praes,ind], 'et').
endung(urg,[2,pl,praes,konj],'et').
endung(urg,[2,pl,praet,ind], 't').
endung(urg,[2,pl,praet,ind], 'et').
endung(urg,[2,pl,praet,konj],'t').
endung(urg,[2,pl,praet,konj],'et').

endung(urg,[3,pl,praes,ind], 'en').
endung(urg,[3,pl,praes,konj],'en').
endung(urg,[3,pl,praet,ind], 'en').
endung(urg,[3,pl,praet,konj],'en').

erzeuge_vollformenlexikon(Ausgabedatei) :-
   ( tell(Ausgabedatei),
       lex(Stammform,Wortart,Art,Flexionsklasse),
       form(Wortart,Form),
       beuge(Wortart,Flexionsklasse,Stammform,Form,
             Vollform),
       Kategorie =.. [Wortart,Art,Form],
       portray_clause(wort(Stammform,Kategorie,Vollform)),
       fail  % naechste Form oder Stammform 
   ; told,
       format(user,'Vollformen erzeugt und nach 
                   ''~w'' geschrieben.\n', Ausgabedatei)
   ).
% -------------- Nomenflexion ----------------
% dekliniere(+Flex.klasse,+NomSg,?[Num,Kas],-Vollform)
dekliniere(Deklinationsklasse,Stammform,
           Formmerkmale,Vollform) :-
    endung(Deklinationsklasse,Formmerkmale,Endung),
    concat(Stammform,Endung,Vollform).

nomenflexion(Deklinationsklasse,Stammform) :-
    form(n,Formmerkmale),
    dekliniere(Deklinationsklasse,Stammform,
               Formmerkmale,Vollform),
    write(Formmerkmale),write(': '),
    write(Vollform),nl,
    fail.
nomenflexion(_,_).

% endung(+Dekl.klasse,Formmerkmale,-Endung):

endung((Sg,Pl),[Num,Kas],Endung) :-
        ( endung(Sg,[Num,Kas],Endung)
        ; endung(Pl,[Num,Kas],Endung) ).

endung(s1, [sg,nom],'').   % bei mehrsilbigem Stamm mit
endung(s1, [sg,gen],'s').  % unbetonter Endsilbe;
endung(s1, [sg,dat],'').   % bei Vokal(+h)-Auslaut;
endung(s1, [sg,akk],'').   % bei Nominalisierungen

endung(s1e,[sg,nom],'').   % bei Auslauten s,ß,x,tsch,z; 
endung(s1e,[sg,gen],'es'). % bei einsilbigen Nomen; 
endung(s1e,[sg,dat],'').   % bevorzugt bei Auslaut sch,st
endung(s1e,[sg,akk],'').

endung(s2e,[sg,nom],'').   % bei Nomina mit 
endung(s2e,[sg,gen],'en'). % konson. Auslaut
endung(s2e,[sg,dat],'en').
endung(s2e,[sg,akk],'en').

endung(s3, [sg,nom],'').   % alle Femina
endung(s3, [sg,gen],'').
endung(s3, [sg,dat],'').
endung(s3, [sg,akk],'').

endung(p1, [pl,nom],'e').
endung(p1, [pl,gen],'e').
endung(p1, [pl,dat],'en').
endung(p1, [pl,akk],'e').

endung(p2, [pl,nom],'').
endung(p2, [pl,gen],'').
endung(p2, [pl,dat],'n').
endung(p2, [pl,akk],'').

endung(p3, [pl,nom],'n').   endung(p3e,[pl,nom],'en').
endung(p3, [pl,gen],'n').   endung(p3e,[pl,gen],'en').
endung(p3, [pl,dat],'n').   endung(p3e,[pl,dat],'en').
endung(p3, [pl,akk],'n').   endung(p3e,[pl,akk],'en').

