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

flektiere(Stammform,Vollform) :-
    lex(Stammform,Wortart,_,Flexionsklasse),
    form(Wortart,Formmerkmale),
    ( (Wortart = v,
          konjugiere(Flexionsklasse,Stammform,
                     Formmerkmale,Vollform))
    ; (member(Wortart,[n,rn,en]), 
          dekliniere(Flexionsklasse,Stammform,
                     Formmerkmale,Vollform))
    ).
flexion(Stammform) :-
    (lex(Stammform,_,_,_) % Stammform bekannt?
    -> lex(Stammform,Wortart,_,Flexionsklasse),
        ( (Wortart = v,
              verbflexion(Flexionsklasse,
                          Stammform))
        ; (member(Wortart,[n,rn,en]),
              nomenflexion(Flexionsklasse,
                           Stammform))
        )
    ; nl, % schreibe neue Zeile
        write('Das Stammlexikon enthält 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),
    (dentalstamm(Stamm)
    -> konjugation(rge,[Pers,Num,Temp,Mod],Endung)  
    ;  konjugation(rg, [Pers,Num,Temp,Mod],Endung)
    ),
    concat(Stamm,Endung,Vollf).

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

% -- regelmaessige Konjugation --

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

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

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

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

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

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

% ---- mit e-Erweiterung:

konjugation(rge,[1,sg,praes,ind], 'e').
konjugation(rge,[1,sg,praes,konj],'e').
konjugation(rge,[1,sg,praet,ind], 'ete').
konjugation(rge,[1,sg,praet,konj],'ete').

konjugation(rge,[1,pl,praes,ind], 'en').
konjugation(rge,[1,pl,praes,konj],'en').
konjugation(rge,[1,pl,praet,ind], 'eten').
konjugation(rge,[1,pl,praet,konj],'eten').

konjugation(rge,[2,sg,praes,ind], 'est').
konjugation(rge,[2,sg,praes,konj],'est').
konjugation(rge,[2,sg,praet,ind], 'etest').
konjugation(rge,[2,sg,praet,konj],'etest').

konjugation(rge,[2,pl,praes,ind], 'et').
konjugation(rge,[2,pl,praes,konj],'et').
konjugation(rge,[2,pl,praet,ind], 'etet').
konjugation(rge,[2,pl,praet,konj],'etet').

konjugation(rge,[3,sg,praes,ind], 'et').
konjugation(rge,[3,sg,praes,konj],'e').
konjugation(rge,[3,sg,praet,ind], 'ete').
konjugation(rge,[3,sg,praet,konj],'ete').

konjugation(rge,[3,pl,praes,ind], 'en').
konjugation(rge,[3,pl,praes,konj],'en').
konjugation(rge,[3,pl,praet,ind], 'eten').
konjugation(rge,[3,pl,praet,konj],'eten').
konjugiere(urg(_,(V1,V2,V3),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),
             [Pers,Num,Temp,Mod],Vollform).

infix(Vor,Mitte,Nach,Kette) :-
    concat(Vor,Mitte,Praefix),
    concat(Praefix,Nach,Kette).

verbform((Vor,Nach),(V1,_V2,_V3),
         [Pers,Num,praes,ind],Vfinit) :-
    not(member([Pers,Num],[[2,sg],[3,sg]])),
    infix(Vor,V1,Nach,Stamm),
    konjugation(urg,[Pers,Num,praes,ind],Endung),
    concat(Stamm,Endung,Vfinit).
verbform((Vor,Nach),(V1,_V2,_V3),
         [Pers,Num,praes,ind],Vfinit) :-
    member([Pers,Num],[[2,sg],[3,sg]]),
    umlaut(V1,U),
    infix(Vor,U,Nach,Stamm), 
    konjugation(urg,[Pers,Num,praes,ind],Endung),
    concat(Stamm,Endung,Vfinit).

verbform((Vor,Nach),(_V1,V2,_V3),
         [Pers,Num,praet,ind],Vfinit) :-
    infix(Vor,V2,Nach,Stamm),
    konjugation(urg,[Pers,Num,praet,ind],Endung),
    concat(Stamm,Endung,Vfinit).
verbform((Vor,Nach),(_V1,V2,_V3),
         [Pers,Num,praet,konj],Vfinit) :-
    umlaut(V2,U),
    infix(Vor,U,Nach,Stamm),
    konjugation(urg,[Pers,Num,praet,konj],Endung),
    concat(Stamm,Endung,Vfinit).

umlaut(a,ä). umlaut(o,ö).   umlaut(u,ü).   
% Hilfsweise:
umlaut(i,i). umlaut(ie,ie). umlaut(ei,ei). 
umlaut(e,i). 
% -- unregelmaessige Konjugation --

konjugation(urg,[1,sg,praes,ind], 'e').
konjugation(urg,[1,sg,praes,konj],'e').
konjugation(urg,[1,sg,praet,ind], '').
konjugation(urg,[1,sg,praet,konj],'e').

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

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

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

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

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

% --- Erzeuge Einträge in ein Vollformenlexikon: ---

erzeuge_vollformenlexikon(Ausgabedatei) :-
    tell(Ausgabedatei),
    lex(Stammform,Wortart,Art,Flexionsklasse),
    form(Wortart,Form),
    ( (Wortart = v,
          konjugiere(Flexionsklasse,Stammform,
                     Form,Vollform),
          portray_clause(wort(Stammform,v(Art,Form),
                              Vollform))
      )
    ; (member(Wortart,[n,rn,en]),
          dekliniere(Flexionsklasse,Stammform,
                     Form,Vollform),
          Kategorie =.. [Wortart,Art,Form],
          portray_clause(wort(Stammform,Kategorie,
                              Vollform))
      )
    ),
    fail. % naechste Form oder Stammform 

erzeuge_vollformenlexikon(Ausgabedatei) :-
    told,
    format(user,'Vollformen erzeugt und
                 nach ''~w'' geschrieben', Ausgabedatei),
    nl.
% -------------- Nomenflexion ----------------
% dekliniere(+Flex.klasse,+NomSg,?[Num,Kas],-Vollform)
dekliniere(Deklinationsklasse,Stammform,
           Formmerkmale,Vollform) :-
    deklination(Deklinationsklasse,
                Formmerkmale,Endung),
    concat(Stammform,Endung,Vollform).

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

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

deklination((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(p3, [pl,gen],'n').
endung(p3, [pl,dat],'n').
endung(p3, [pl,akk],'n').

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

