:- op(500,yfx,&), op(600,yfx,'\/'),
    op(600,xfx,'=>'), op(600,xfx,'<=>').

kleinschreibung(Wort,Klein) :-
    atom(Wort),
    name(Wort,[C|Chars]),
    (member(C,"ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜ")
    ->  K is C+32,           
        name(Klein,[K|Chars])
    ; Klein = Wort).

sem([en(Art,Form), Vollform],LamTerm) :-
    wort(Stammform, en(Art,Form), Vollform),
    kleinschreibung(Stammform,EN),
    LamTerm = lam(P,P*EN).

sem([n(Art,Form),Vollform],LamTerm) :-
    wort(Stammform, n(Art,Form), Vollform),
    kleinschreibung(Stammform,Stamm),
    Formel =.. [Stamm,X],
    LamTerm = lam(X,Formel).
   
sem([rn(Art,Form), Vollform],LamTerm) :-
    wort(Stammform, rn(Art,Form), Vollform),
    kleinschreibung(Stammform,Stamm),
    Formel =.. [Stamm,X,Y],
    LamTerm = lam(X,lam(Y,Formel)).

sem([v([nom,akk],Form),Vollform],LamTerm) :-
    kleinschreibung(Vollform,VollformKl),
    wort(Stammform,v([nom,akk],Form),VollformKl),
    Formel =.. [Stammform,X,Y],
    LamTerm = lam(X,lam(Y,Formel)).
   
sem([n(Art,Form),[rn(Art,Form),Vollform]],LamTerm) :-
    wort(Stammform, rn(Art,Form), Vollform),
    kleinschreibung(Stammform,Stamm),
    Formel =.. [Stamm,X],
    LamTerm = lam(X,Formel).
   
sem([det([quant],_Form),_Vollform],
    lam(N,lam(P,all(X,N*X => P*X)))).

sem([det([indef],_Form),_Vollform],
    lam(N,lam(P,ex(X,N*X & P*X)))).

sem([det([def],[_,pl,_]),Vollform],
    lam(N,lam(P, anzahl(X,N*X & P*X,Zahl)))) :-
    anzahl(Vollform,Zahl), !.
sem([det([def], [_,sg,_]),_Vollform],
    lam(N,lam(P,
    ex(Y,all(X,eq(X,Y) <=> N*X) & P*Y)))).

sem([det([qu], _Form),_Vollform],
    lam(N,lam(P,qu(X,N*X & P*X)))).  

sem([a([als(nom)],[komp]),kleiner],
    lam(X,lam(Y,(X < Y)))). % Fehlermeldung?
sem([a([als(nom)],[komp]),größer],
    lam(X,lam(Y,(X > Y)))).

sem([pron([rel],_Form),_Rel], lam(P,lam(X,P*X))).
sem([pron([qu],_Form),_Pron], lam(P,qu(X,P*X))).

sem([poss([rel],[_Gen,_Num,gen]),_Poss],
    lam(RN,lam(P,lam(Y,ex(X,RN*X*Y & P*X))))).
    % nur bei RNsg 
sem([np([_,3,_],[_,_]),
       Det, [n(Art,Form),Vf]], SemNP) :-
    sem(Det,SemDet),
    Vf \= km, sem([n(Art,Form),Vf],SemN),
    normalize(SemDet * SemN,SemNP).

sem([np([def,3,Gen],[Num,Kas]),
       [en([Gen],[Num,Kas]),EN]], SemNP) :-
    sem([en([Gen],[Num,Kas]),EN],SemNP).
sem([np([def,3,Gen],[Num,_Kas]),
       [det([def],_),_],
       [en([Gen],[Num,nom]),EN]],
    SemNP) :-
    !, sem([en([Gen],[Num,nom]),EN],SemNP).
sem([np([def,3,Gen],[Num,Kas]), 
       [det([def],_),_],
       [n([Gen],[Num,Kas]),N],
       [en([Gen2],[Num,nom]),EN]], SemNP) :-
    !, sem([n([Gen],[Num,Kas]),N],SemN),
    sem([en([Gen2],[Num,nom]),EN],SemEN),
    normalize(lam(P,SemEN*SemN & SemEN*P),SemNP).

sem([np([Def,3,Gen],[Num,Kas]),
      [pron([DefP],[Gen,Num,Kas]),Pron]],
    SemNP) :-
    ( DefP = rel, Def = rel(Gen,Num)
    ; DefP = qu, Def = qu ),
    sem([pron([DefP],[Gen,Num,Kas]),Pron],
        SemNP).

sem([np([rel(Gen2,Num2),3,Gen],[sg,Kas]),
       [poss([rel],[Gen2,Num2,gen]),Poss],
       [rn([Gen],[sg,Kas]),RN]],
    SemNP) :-
    sem([poss([rel],[Gen2,Num2,gen]),Poss],
        SemPoss),
    sem([rn([Gen],[sg,Kas]),RN],SemRN),
    normalize(SemPoss*SemRN,SemNP).

sem([np([_,3,_],[_,_]),
       [det([def],_),Zahlatom],[n(_,_),km]],
    lam(P,P*Zahl)) :-
    anzahl(Zahlatom,Zahl). % Ausnahme: Maß

sem([np([_,3,_],[_,_]),
       Det,[rn(Art,Form),RN],NPgen], Sem) :-
    sem(Det,SemDet),   
    sem([rn(Art,Form),RN],SemRN),
    sem(NPgen,SemNPgen),
    SemN = lam(X,SemNPgen*lam(Y,(SemRN*X)*Y)),
    normalize(SemDet*SemN,Sem).

sem([s([_Def],[_,_,vz]),
      NP1, [v([nom,akk],[3,Num,_,ind]),V], NP2],
    SemS)
:-  sem(NP1,SemNP1), sem(NP2,SemNP2),
    sem([v([nom,akk],[3,Num,_,ind]),V], SemV),
    NP1 = [np([_,3,_],[Num1,Kas1])|_Konst], 
    (Kas1 = nom, Num1 = Num,
        Sem = SemNP1 * lam(X,SemNP2 *
                          lam(Y,SemV * X * Y))
    ; Kas1 = akk,
        Sem = SemNP1 * lam(Y,SemNP2 *
                          lam(X,SemV * X * Y))
    ), normalize(Sem,SemS).
       
sem([s([qu],[_,ind,ve]),
      [v([nom,akk],[3,Num,_,ind]),V], NP1, NP2],
    SemS)
:-
    sem(NP1,SemNP1),
    sem([v([nom,akk],[3,Num,_,ind]),V], SemV),
    sem(NP2,SemNP2),
    NP1 = [np(_,[Num1,Kas1])|_Konstituenten], 
    (Kas1 = nom, Num1 = Num,
        Sem = SemNP1 * lam(X,SemNP2 *
                          lam(Y,SemV * X * Y))
    ; Kas1 = akk,
        Sem = SemNP1 * lam(Y,SemNP2 *
                          lam(X,SemV * X * Y))
    ), normalize(Sem,SemS).
       
sem([s([qu],[_,ind,ve]),
      [v([sein],[3,Num,_,ind]),_V], NP1, NP2],
    SemS)
:-
    NP1 = [np(_,[Num,nom])|_Konst1],
    NP2 = [np([Def2,3,_],[Num,nom])|_Konst2], 
    sem(NP1,SemNP1),
    sem(NP2,SemNP2), (Def2 = indef ; Def2 = def), 
    Sem = SemNP1*lam(X,SemNP2*lam(Y,eq(X,Y))),
    normalize(Sem,SemS).

sem([s([qu],[_,ind,ve]),
      [v([sein],[3,Num,_,ind]),_], NP1, AP],
    SemS)
:-
    NP1 = [np(_,[Num,nom])|_Konst1],
    AP  = [ap([],[komp])|_Konst2], 
    sem(NP1,SemNP1),
    sem(AP,SemAP),
    normalize(SemNP1*SemAP, SemS).

sem([s([rel(GenR,NumR)],[Tmp,ind,vl]),
      NP1,
      NP2, 
      [v([nom,akk],[3,Num,Tmp,ind]),V]],
    SemS)
:-
    NP1 = [np([rel(GenR,NumR),3,GenR],[_,Kas1])|_], 
    sem(NP1,SemNP1),
    sem([v([nom,akk],[3,Num,Tmp,ind]),V], SemV),
    sem(NP2,SemNP2),
    (Kas1 = nom,
        Sem = SemNP1 * lam(X,SemNP2 *
                          lam(Y,SemV * X * Y))
    ; Kas1 = akk,
        Sem = SemNP1 * lam(Y,SemNP2 *
                          lam(X,SemV * X * Y))
    ),
    normalize(Sem,SemS).
       
sem([s([rel(GenR,NumR)],[Temp,ind,vl]),
      NP1, AP, [v([sein],[3,Num,Temp,ind]),_]],
    SemS)
:-
    NP1 = [np([rel(GenR,NumR),3,_],[Num,nom])|_],
    AP  = [ap([],[komp])|_Konst2], 
    sem(NP1,SemNP1),
    sem(AP,SemAP),
    normalize(SemNP1*SemAP, SemS).

sem([s([rel(GenR,NumR)],[Temp,ind,vl]),
      NP1, NP2, [v([sein],[3,Num,Temp,ind]),_V]],
    SemS)
:-
    NP1 = [np([rel(GenR,NumR),3,_],[Num,nom])|_],
    NP2 = [np([Def2,3,_],[Num,nom])|_Konst2], 
    sem(NP1,SemNP1),
    sem(NP2,SemNP2), (Def2 = indef ; Def2 =def),
    Sem = SemNP1*lam(X,SemNP2*lam(Y,eq(X,Y))),
    normalize(Sem,SemS).

sem([np([_Def,3,Gen],[Num,Kas]),
       DET,
       [n([Gen],[Num,Kas]), N],
       [s([rel(Gen,Num)],[_,_,vl]),REL,NP,TV]],
    LamTerm)
:-
    sem(DET,SemDET),
    sem([n([Gen],[Num,Kas]),N],SemN),
    sem([s([rel(Gen,Num)],[_,_,vl]),REL,NP,TV],
        SemSREL),
    SemNREL = lam(X,(SemN * X) & (SemSREL * X)),
    normalize(SemDET * SemNREL, LamTerm).
        
sem([ap([],[komp]),
       [a([als(nom)],[komp]),Adj], als, NP], 
    SemAP)
:-  sem([a([als(nom)],[komp]),Adj], SemAdj),
    NP = [np([_,3,_],[_,nom])|_],
    sem(NP,SemNP),
    normalize(lam(X,SemNP*lam(Y,SemAdj*X*Y)),
              SemAP).    
       
sem([np([rel(Gen2,Num2),3,Gen],[pl,Kas]),
       [poss([rel],[Gen2,Num2,gen]),_Poss],
       [rn([Gen],[pl,Kas]),RN]],
    SemNP) :-
    SemPoss = lam(R,lam(P,lam(Y,
                 all(X,R*X*Y => P*X)))),
    sem([rn([Gen],[pl,Kas]),RN],SemRN),
    normalize(SemPoss*SemRN,SemNP).

