% Metaregeln zur Erzeugung von Satzregeln für einfache Sätze
% aus Komplementrahmen von Verben.              CIS, H.Leiß, 1.3.2017

/* Wenn man nur die Anordnung der Konstitutenten sehen will,
   kann man die Expansion der Kategorienabkuerzungen unterdrücken,
   in dem man 

       expandiereSubjCat([Pers,Num],Rahmen,SubjRahmen)
       expandiere([Pers,Num],VFIN,VINF,RahmenPraed2,Cats)

   so ändert (vgl. jeweils die erste Klausel unten), daß sich 

       SubjRahmen = Rahmen  
       Cats       = RahmenPraed2

   ergibt (was natürlich nicht zu Parsen erlaubt).
*/
   
:- op(1100,xfx,'-+->'). % neues Infix-Relationssymbol

ersetze_metaregeln :- tell('saetze.pl'), 
    (A -+-> B),     % Instanz von (A -+-> B) beweisen
    portray_clause((A --> B)), % und als DCG-Regel 
    nl, fail.       % in 'saetze.pl' schreiben
ersetze_metaregeln :- told. % Datei schliessen.

% Metaregel für einfache Ja/Nein-Fragen und vz/vl-Sätze:

(s([Def,si],[Temp,Mod,Vst]) -+-> Konstituenten) :-
    ( Vst=ve, Def=qu  % Def=def: Konditionalsaetze, weglassen
    ; Vst=vz, Def=def
    ; Vst=vl, Def=def % Relativsaetze s.u.
    ),
    tempusauswahl(Temp),
    rahmenauswahl(Rahmen),     % Auswahl für Teilgrammatik!
    adverbialauswahl(Advs),    % Auswahl für Teilgrammatik!     
    praedikatsteile(VFIN,VINF, % = Praedikatsteile
                    Rahmen,Pers,Num,Temp,Mod,aktiv),
    expandiereSubjCat([Pers,Num],Rahmen,SubjRahmen),
    felderverteilung(SubjRahmen,Advs,Vst,Kurzkonstituenten),
    expandiere([Pers,Num],VFIN,VINF,Kurzkonstituenten,Cats),
    listToTuple(Cats,Konstituenten).

% Metaregel für einfache Relativsätze: 

% Ersetze in s.def.vl die np am Anfang durch pron.rel mit Gen,Num:
(s([rel(Gen,Num),si],[Temp,Mod,vl]) -+-> Konstituenten) :-
    (s([def,si],[Temp,Mod,vl]) -+-> (np([Pers,Gen,Num,_Fig],[Kas]),Rest)),
    Konstituenten = (pron([rel],[Pers,Gen,Num,Kas]),Rest).
    
% Metaregel für einfache daß-Sätze und untergeordnete Fragesätze: 

(s([Def,si],[Temp,Mod,vl]) -+-> Conj, s([def,si],[Temp,Mod,vl])) :-
    ( Def = daß, Conj = ([dass];[daß])
    ; Def = qu,  Conj = [ob]
    ).

% Metaregel für einfache zu-Infinitive: (Hack!)

(s([infzu,si],[praes,-,-]) -+-> Konstituenten) :-
    rahmenauswahl([Subj|Objs]),% Auswahl für Teilgrammatik!
    adverbialauswahl(Advs),    % Auswahl für Teilgrammatik!     
    praedikatsteile(VFIN,VINF, % = Praedikatsteile
                    [Subj|Objs],Pers,Num,fut1,ind,aktiv),
    felderverteilung(Objs,Advs,ve,[vfin|Konst]),
    reverse(Konst,[Inf|KonstRev]),
    reverse(KonstZu,[Inf,[zu]|KonstRev]),
    expandiere([Pers,Num],VFIN,VINF,KonstZu,Cats),
    listToTuple(Cats,Konstituenten).
    
% Metaregeln, die durch Ersetzen von -+-> zu DCG-Regeln werden:

% Korrelat für Subjekt- und Objektsätze:
(kor(daß)  -+-> [es]).

% Pronominaladverbiale als Korrelate: (sollten dann aber keine adv([Art],[]) sein)
(kor(temp) -+-> [dann]).
(kor(kaus) -+-> [deshalb]).
(kor(lok)  -+-> [dort]).
(kor(mod)  -+-> [so]).
(kor(inst) -+-> [damit]).

% Auswahl von Verbarten, für die Satzregeln erzeugt werden sollen:

rahmenauswahl(Rahmen) :- 
    member(Rahmen,           % Beispielverben: siehe syntax16.wrd
           [[nom],           % intransitive
            [nom,refl(akk)], % reflexive
            [nom,akk],       % transitve
%            [nom,dat],       % andere zweistellige
%            [nom,auf,dat],   % zweist. mit Präpositionalobjekt
            [nom,auf,akk],   % (Aufg. 10.1 f)
            [nom,daß],       % mit Objektsatz
%            [nom,ob],        % mit interrog.Objektsatz
%            [nom,refl(akk),ob], % reflexiv mit interrog.Objektsatz
            [daß,akk]       % zweistellig mit Subjektsatz
%            [nom,dat,akk]    % dreistellig (Aufgabe 10.1 f)
           ]). 

tempusauswahl(Temp) :-
    member(Temp,[praes,perf]). % ohne fut1,praet,plqm,fut2

adverbialauswahl([]).             % keine Adverbiale
adverbialauswahl([advp]).         % ein Adverbial+Korrelat
% adverbialauswahl([advp,advp]).  % zwei Adverbiale


% Prädikatsteile und daran abgelesene Merkmale (i.a. von Vst abhängig):    
% praedikatsteile/8: belegt VFIN und Liste VINF 

praedikatsteile(v([Rahmen],[Pers,Num,Mod,praes]),[[]],
                Rahmen,Pers,Num,praes,Mod,aktiv).
praedikatsteile(v([Rahmen],[Pers,Num,Mod,praet]),[[]],
                Rahmen,Pers,Num,praet,Mod,aktiv).
praedikatsteile(v([haben],[3,Num,Mod,praes]),
                [v([Rahmen],[part2])],
                Rahmen,3,Num,perf,Mod,aktiv).  
praedikatsteile(v([haben],[3,Num,Mod,praet]),
                [v([Rahmen],[part2])],
                Rahmen,3,Num,plqm,Mod,aktiv).  
praedikatsteile(v([werden],[3,Num,Mod,praes]),
                [v([Rahmen],[inf])],
                Rahmen,3,Num,fut1,Mod,aktiv).
praedikatsteile(v([werden],[3,Num,Mod,praes]),
                [v([Rahmen],[part2]), v([haben],[inf])],
                Rahmen,3,Num,fut2,Mod,aktiv).

% mit Modalverben: (falsch bei vl)

praedikatsteile(v([modal],[Pers,Num,Mod,praes]),
                [v([Rahmen],[inf])],
                Rahmen,Pers,Num,praes,Mod,aktiv).
praedikatsteile(v([modal],[Pers,Num,Mod,praet]),
                [v([Rahmen],[inf])],
                Rahmen,Pers,Num,praet,Mod,aktiv).
praedikatsteile(v([haben],[3,Num,Mod,praes]),
                [v([Rahmen],[inf]),v([modal],[inf])],
                Rahmen,3,Num,perf,Mod,aktiv).  
praedikatsteile(v([haben],[3,Num,Mod,praet]),
                [v([Rahmen],[inf]),v([modal],[inf])],
                Rahmen,3,Num,plqm,Mod,aktiv).  
praedikatsteile(v([werden],[3,Num,Mod,praes]),
                [v([Rahmen],[inf]),v([modal],[inf])],
                Rahmen,3,Num,fut1,Mod,aktiv).
praedikatsteile(v([werden],[3,Num,Mod,praes]),
                [v([haben],[inf]), v([Rahmen],[inf]),
                 v([modal],[inf])],                
                Rahmen,3,Num,fut2,Mod,aktiv).

% Permutationen von Argumenten und Adverbialen:

felderverteilung(Rahmen,Advs,Vst,Kurzkonstituenten) :-
    felder(Rahmen,Advs,Vst,Vor,Mitte,Nach),
    append(Vor,Mitte,Satzanfang),
    verbstellung(Satzanfang,Vst,RahmenPraed), 
    append(RahmenPraed,Nach,Kurzkonstituenten).

% felder(+Rahmen,+Vst,-Vorfeld,-Mitttelfeld,-Nachfeld)

felder(Rahmen,Advs,Vst,Vor,Mitte,Nach) :-
    praepObjekte(Rahmen,RahmenPraep), % an,akk -> an(akk)
    append(RahmenPraep,Advs,RahmenAdvs),
    permutation(RahmenAdvs,Perm),     % i.a. zu viel, teuer!
    nachfeld(Perm,VorMitte,Nach),
    ( Vst=vz -> length(Vor,1) ; length(Vor,0) ),
    append(Vor,Mitte,VorMitte).

praepObjekte([X,Y|Zs],[Pr|PZs]) :-
    ( praeposition(X,Y),
        Pr =.. [X,Y], praepObjekte(Zs,PZs)
    ; praepObjekte([Y|Zs],PZs), Pr=X
    ), !.
praepObjekte([X],[X]).
praepObjekte([],[]).

% daß-Sätze oder Adverbiale evtl.ins Nachfeld, Korrelat im Mittelfeld:
nachfeld([daß|ArgsPraed],[([];kor(daß))|ArgsPraed],[daß]).
% nachfeld([daß|ArgsPraed],[kor(daß)|ArgsPraed],[]).
nachfeld([daß|ArgsPraed],[kor(daß)|Mittelf],Nachf) :-
    !, nachfeld(ArgsPraed,Mittelf,Nachf).
nachfeld([advp|ArgsPraed],[([];kor(Dim))|ArgsPraed],
         [(advp([Dim],[]), {Dim\=neg})]).
nachfeld([advp|ArgsPraed],[(advp([Dim],[]),{Dim\=neg})|Mittelf],Nachf) :-
    !, nachfeld(ArgsPraed,Mittelf,Nachf).

nachfeld([A|ArgsPraed],[A|ArgsPraed2],Nachfeld) :-
    nachfeld(ArgsPraed,ArgsPraed2,Nachfeld).
nachfeld([],[],[]).

% Besetzung der Satzklammern durch Verbteile (mit optionaler Negation):

verbstellung(Args,ve,ArgsPraed) :-
    append([vfin|Args],[neg,vinf],ArgsPraed).
verbstellung([Arg|Args],vz,ArgsPraed) :-
    append([Arg,vfin|Args],[neg,vinf],ArgsPraed).
verbstellung(Args,vl,ArgsPraed) :-
    append(Args,[neg,vinf,vfin],ArgsPraed).

% Expansion von Kategorienabkürzungen:

expandiereSubjCat([_Pers,_Num],Rahmen, Rahmen) :-
    fail, !. % fail := expandieren, true := nicht expandieren

expandiereSubjCat([Pers,Num],[Subj|Objs],[SubjE|Objs]) :-
    expandiereCat(Subj,SubjE),
    kongruenz_sfin(SubjE,[Pers,Num,nom]).

expandiereCat(nom, np([_,_,_,_],[nom])) :- !.
expandiereCat(akk, np([_,_,_,_],[akk])) :- !.
expandiereCat(dat, np([_,_,_,_],[dat])) :- !. % dat-NPs: nur Pron
expandiereCat(daß, s([daß,_],_Form)) :- !.
expandiereCat(ob,  s([qu,_], _Form)) :- !.
expandiereCat(neg, ([] ; adv([neg],[]))) :- !.
expandiereCat(advp,(advp([Art],[]), {Art\=neg})) :- !.
expandiereCat((X;Y),(XE;YE)) :-
    !, expandiereCat(X,XE), expandiereCat(Y,YE).
expandiereCat(PrKas, ([Pr], Cat)) :-
    PrKas =.. [Pr,Kas],
    praeposition(Pr,Kas),
    !, expandiereCat(Kas, Cat).
expandiereCat(X,X) :- !.  % (Vereinfachung) 

% Präpositionen ohne adverbiale Bedeutung (für Präpositionalobjekte):
praeposition(in,akk).  praeposition(an,akk).
praeposition(auf,akk). praeposition(um,akk).
praeposition(für,akk). praeposition(an, dat). 
praeposition(mit,dat). praeposition(vor,dat).
praeposition(von,dat). praeposition(auf,dat). 

kongruenz_sfin(np([Pers,_Gen,Num,_Fig],[Kas]),[Pers,Num,Kas]).
kongruenz_sfin(s([daß,_Fig],[_,_,vl]),[3,sg,nom]).

% Expansion der Komplementabkürzungen relativ zu den
% Finitheismerkmalen Fin und den Verbteilen Vfin,Vinf:

expandiere(Fin,Vfin,Vinf,[vfin|Args],[Vfin|Kats]) :-
    !, expandiere(Fin,Vfin,Vinf,Args,Kats).
expandiere(Fin,Vfin,Vinf,[vinf|Args],VinfKats) :-
    !, expandiere(Fin,Vfin,Vinf,Args,Kats),
    append(Vinf,Kats,VinfKats).

expandiere(Fin,Vfin,Vinf,[Arg|Args],[Arg|Kats]) :- 
    fail, !, % fail=expandieren, true=nicht expandieren
    expandiere(Fin,Vfin,Vinf,Args,Kats). 

expandiere(Fin,Vfin,Vinf,[Arg|Args],[Kat|Kats]) :-
    !, expandiereCat(Fin,Arg,Kat), 
    expandiere(Fin,Vfin,Vinf,Args,Kats).
expandiere(_Fin,_Vfin,_Vinf,[],[]).

% expandiereCat/3: Finitheitsmerkmale ins Reflexivpronomen
expandiereCat([Pers,Num], refl(akk),
    pron([refl],[Pers,Num,akk])) :- !.
expandiereCat([_Pers,_Num], X,C) :- expandiereCat(X,C).

% Umwandlung einer Liste in ein Tupel:
listToTuple(X,_) :- var(X), !, fail.
listToTuple([Cat1,Cat2|Cats],(Cat1,Konstituenten)) :-
    listToTuple([Cat2|Cats],Konstituenten).
listToTuple([Cat],Cat).
listToTuple([],[]).
