<div class="notebook open-fullscreen"> <div class="nb-cell program" data-background="true" data-singleline="true" name="p1"> % swish helper :-style_check(-discontiguous). :-style_check(-singleton). :- use_rendering(mathjax). </div> <div class="nb-cell markdown" name="md1"> # Materialien zu Kapitel 3 ## Implementing Cooper Storage Repräsentationen: indexed binding operators werden mit dem Prädikat =bo/2= dargestellt, das erste Argument =Quant= ist die quantifizierte NP, das zweite Argument =Ind= eine Prologvariable. stores werden durch Listen dargestellt, deren Kopf ein Lambda-Ausdruck ist. Der (möglicherweise leere) Rest der Liste enthält binding operators. </div> <div class="nb-cell program" name="p3"> % representing binding operators: bo(QUant,Ind). % representing stores example [walk(X),bo(lam(P,all(Y,imp(boxer(Y),app(P,X)))),X)] </div> <div class="nb-cell markdown" name="md2"> Keine Veränderung der Regeln in `englishGrammar.pl`: </div> <div class="nb-cell program" data-background="true" name="p4"> % syntactic rules t([sem:T])--> s([coord:no,sem:S]), {combine(t:T,[s:S])}. s([coord:no,sem:Sem])--> np([coord:_,num:Num,gap:[],sem:NP]), vp([coord:_,inf:fin,num:Num,gap:[],sem:VP]), {combine(s:Sem,[np:NP,vp:VP])}. np([coord:no,num:sg,gap:[],sem:NP])--> det([mood:decl,type:_,sem:Det]), n([coord:_,sem:N]), {combine(np:NP,[det:Det,n:N])}. vp([coord:no,inf:I,num:Num,gap:G,sem:VP])--> tv([inf:I,num:Num,sem:TV]), np([coord:_,num:_,gap:G,sem:NP]), {combine(vp:VP,[tv:TV,np:NP])}. n([coord:no,sem:N])--> noun([sem:Noun]), {combine(n:N,[noun:Noun])}. % lexical rules det([mood:M,type:Type,sem:Det])--> {lexEntry(det,[syntax:Word,mood:M,type:Type])}, Word, {semLex(det,[type:Type,sem:Det])}. noun([sem:Sem])--> {lexEntry(noun,[symbol:Sym,syntax:Word])}, Word, {semLex(noun,[symbol:Sym,sem:Sem])}. tv([inf:Inf,num:Num,sem:Sem])--> {lexEntry(tv,[symbol:Sym,syntax:Word,inf:Inf,num:Num])}, Word, {semLex(tv,[symbol:Sym,sem:Sem])}. </div> <div class="nb-cell markdown" name="md3"> Keine Veränderung der lexikaischen Einträge in `englishLexicon.pl`: </div> <div class="nb-cell program" data-background="true" name="p5"> lexEntry(det,[syntax:[every],mood:decl,type:uni]). lexEntry(det,[syntax:[a],mood:decl,type:indef]). lexEntry(noun,[symbol:person,syntax:[person]]). lexEntry(noun,[symbol:animal,syntax:[boxer]]). lexEntry(tv,[symbol:like,syntax:[likes],inf:fin,num:sg]). </div> <div class="nb-cell markdown" name="md4"> Einführung der Storages in `semLexStorage.pl`: </div> <div class="nb-cell program" data-background="true" name="p6"> semLex(noun,M):- M = [symbol:Sym, sem:[lam(X,Formula)]], my_compose(Formula,Sym,[X]). % compare: noun macro in semLexLambda.pl: %semLex(noun,M):- % M = [symbol:Sym, % sem:lam(X,Formula)], % my_compose(Formula,Sym,[X]). semLex(det,M):- M = [type:uni, sem:[lam(P,lam(Q,all(X,imp(app(P,X),app(Q,X)))))]]. semLex(det,M):- M = [type:indef, sem:[lam(P,lam(Q,some(X,and(app(P,X),app(Q,X)))))]]. semLex(tv,M):- M = [symbol:Sym, sem:[lam(K,lam(Y,app(K,lam(X,Formula))))]], my_compose(Formula,Sym,[Y,X]). </div> <div class="nb-cell markdown" name="md5"> Neue semantische Regeln: `semRulesCooper.pl` </div> <div class="nb-cell program" data-background="true" name="p7"> % semantische Regel für VP -> V NP in semRulesCooper.pl combine(vp:[app(A,B)|S],[tv:[A],np:[B|S]]). % compare: semantische Regel für VP -> V NP in semRulesLambda.pl % combine(vp:app(A,B),[tv:A,np:B]). % semantische Regel für NP -> D N in semRulesCooper.pl % Warum gibt es zwei Regeln? combine(np:[lam(P,app(P,X)),bo(app(A,B),X)|S],[det:[A],n:[B|S]]). combine(np:[app(A,B)|S],[det:[A],n:[B|S]]). % compare: semantische Regel für NP -> D N in semRulesLambda.pl % combine(np:app(A,B),[det:A,n:B]). combine(n:A,[noun:A]). % semantische Regel für S -> NP VP in semRulesCooper.pl combine(s:S,[np:[A|S1],vp:[B|S2]]):- appendLists(S1,S2,S3), sRetrieval([app(A,B)|S3],Retrieved), betaConvert(Retrieved,S). %% compare: semantische Regel für S -> NP VP in semRulesLambda.pl %combine(s:app(A,B),[np:A,vp:B]). combine(t:Converted,[s:Sem]):- betaConvert(Sem,Converted). </div> <div class="nb-cell markdown" name="md6"> `cooperStorage.pl` lädt einige Hilfsprädikate aus `comsemPredicates.pl` und einige Prädikate der vergangengen Sitzungen: </div> <div class="nb-cell program" data-background="true" data-singleline="true" name="p8"> % predicates earlier introduced: % % from comsemPredicates.pl: /*======================================================================== Appending two lists ========================================================================*/ appendLists([],List,List). appendLists([X|Tail1],List,[X|Tail2]):- appendLists(Tail1,List,Tail2). /*======================================================================== List membership ========================================================================*/ memberList(X,[X|_]). memberList(X,[_|Tail]):- memberList(X,Tail). /*======================================================================== Selecting (i.e. removing) a member of a list ========================================================================*/ selectFromList(X,[X|L],L). selectFromList(X,[Y|L1],[Y|L2]):- selectFromList(X,L1,L2). /*======================================================================== compose predicate argument structure ========================================================================*/ my_compose(Term,Symbol,ArgList):- Term =.. [Symbol|ArgList]. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % from alphaConversion.pl: /*======================================================================== Alpha Conversion (introducing substitutions) ========================================================================*/ alphaConvert(F1,F2):- alphaConvert(F1,[],[]-_,F2). /*======================================================================== Alpha Conversion ========================================================================*/ alphaConvert(X,Sub,Free1-Free2,Y):- var(X), ( memberList(sub(Z,Y),Sub), X==Z, !, Free2=Free1 ; Y=X, Free2=[X|Free1] ). alphaConvert(Expression,Sub,Free1-Free2,some(Y,F2)):- nonvar(Expression), Expression = some(X,F1), alphaConvert(F1,[sub(X,Y)|Sub],Free1-Free2,F2). alphaConvert(Expression,Sub,Free1-Free2,all(Y,F2)):- nonvar(Expression), Expression = all(X,F1), alphaConvert(F1,[sub(X,Y)|Sub],Free1-Free2,F2). alphaConvert(Expression,Sub,Free1-Free2,lam(Y,F2)):- nonvar(Expression), Expression = lam(X,F1), alphaConvert(F1,[sub(X,Y)|Sub],Free1-Free2,F2). alphaConvert(Expression,Sub,Free1-Free3,que(Y,F3,F4)):- nonvar(Expression), Expression = que(X,F1,F2), alphaConvert(F1,[sub(X,Y)|Sub],Free1-Free2,F3), alphaConvert(F2,[sub(X,Y)|Sub],Free2-Free3,F4). alphaConvert(F1,Sub,Free1-Free2,F2):- nonvar(F1), \+ F1 = some(_,_), \+ F1 = all(_,_), \+ F1 = lam(_,_), \+ F1 = que(_,_,_), my_compose(F1,Symbol,Args1), alphaConvertList(Args1,Sub,Free1-Free2,Args2), my_compose(F2,Symbol,Args2). /*======================================================================== Alpha Conversion (listwise) ========================================================================*/ alphaConvertList([],_,Free-Free,[]). alphaConvertList([X|L1],Sub,Free1-Free3,[Y|L2]):- alphaConvert(X,Sub,Free1-Free2,Y), alphaConvertList(L1,Sub,Free2-Free3,L2). /*======================================================================== Alphabetic Variants ========================================================================*/ alphabeticVariants(Term1,Term2):- alphaConvert(Term1,[],[]-Free1,Term3), alphaConvert(Term2,[],[]-Free2,Term4), Free1==Free2, numbervars(Free1,0,N), numbervars(Term3,N,M), numbervars(Term4,N,M), Term3=Term4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % from betaConversion: /*======================================================================== Beta-Conversion (introducing stack) ========================================================================*/ % ?- betaConvert(app(lam(U,app(U,mia)),lam(X,smoke(X))),Converted). % introduce empty stack betaConvert(X,Y):- betaConvert(X,Y,[]). /*======================================================================== Beta-Conversion (comment-in for tracing) ========================================================================*/ %betaConvert(X,_,S):- % nl, write('Expre: '), print(X), % nl, write('Stack: '), print(S), nl, % fail. /*======================================================================== Beta-Conversion (core stuff) ========================================================================*/ % expression is a variable => do nothing betaConvert(X,Y,[]):- var(X), !, Y=X. % expression is application => push argument to stack betaConvert(Expression,Result,Stack):- nonvar(Expression), Expression = app(Functor,Argument), %% To suppress alpha-conversion: alphaConvert(Functor,Converted), %% comment-out this line % Functor=Converted, %% comment-in this line betaConvert(Converted,Result,[Argument|Stack]), !. % expression is abstraction + stack is not empty => pop argument from stack betaConvert(Expression,Result,[X|Stack]):- nonvar(Expression), Expression = lam(X,Formula), betaConvert(Formula,Result,Stack), !. % other expression => break down complex expression betaConvert(Formula,Result,[]):- nonvar(Formula), !, my_compose(Formula,Functor,Formulas), betaConvertList(Formulas,ResultFormulas), my_compose(Result,Functor,ResultFormulas). betaConvert(Exp,app(Exp,Y),[X]):- %% Impossible to perform application. betaConvert(X,Y). /*======================================================================== Beta-Convert a list ========================================================================*/ betaConvertList([],[]). betaConvertList([Formula|Others],[Result|ResultOthers]):- betaConvert(Formula,Result), betaConvertList(Others,ResultOthers). </div> <div class="nb-cell markdown" name="md7"> `cooperStorage.pl` übernimmt die Rolle von `lambda.pl` und stellt die Prädikate =sRetrieval/2= und =filterAlphabeticVariants/2= zur Verfügung. =sRetrieval/2= übernimmt die Auflösung des Stores: </div> <div class="nb-cell program" data-background="true" name="p9"> sRetrieval([S],S). sRetrieval([Sem|Store],S):- selectFromList(bo(Q,X),Store,NewStore), sRetrieval([app(Q,lam(X,Sem))|NewStore],S). </div> <div class="nb-cell query" name="q2"> sRetrieval([app(lam(X,walk(X)),Z),bo(lam(P,all(Y,imp(boxer(Y),app(P,Y)))),Z)],Ret), betaConvert(Ret,Beta), printInfix(Ret), printInfix(Beta). </div> <div class="nb-cell query" name="q1"> sRetrieval([app(lam(U,app(U,Z4)),app(lam(V,lam(W,app(V,lam(X,drink(W,X))))),lam(Y,app(Y,Z5)))),bo(app(lam(P,lam(Q,all(R,imp(app(P,R),app(Q,R))))),lam(S,boxer(S))),Z4),bo(app(lam(A,lam(B,some(C,and(app(A,C),app(B,C))))),lam(D,beverage(D))),Z5)],Ret), betaConvert(Ret,Beta), printInfix(Beta). </div> <div class="nb-cell markdown" name="md11"> **Aufgabe:** Ändere den Code so, dass auf dem Bildschirm ausgegeben wird, welcher indizierte Bindungsoperator als nächstes verwendet wird. </div> <div class="nb-cell markdown" name="md8"> =filterAlphabeticVariants/2= löscht alphabetische Varianten aus einer Liste von Formeln. </div> <div class="nb-cell program" data-background="true" name="p11"> filterAlphabeticVariants(L1,L2):- selectFromList(X,L1,L3), memberList(Y,L3), alphabeticVariants(X,Y), !, filterAlphabeticVariants(L3,L2). filterAlphabeticVariants(L,L). </div> <div class="nb-cell query" name="q3"> filterAlphabeticVariants([lam(P,walk(P)),lam(Q,walk(Q))],Res). </div> <div class="nb-cell markdown" name="md9"> Das zentrale Prädikat ist =cooperStorage/2=: </div> <div class="nb-cell program" data-background="true" name="p12"> cooperStorage:- readLine(Sentence), setof(Sem,t([sem:Sem],Sentence,[]),Sems1), filterAlphabeticVariants(Sems1,Sems2), % comment this line our and the next in to test without alphabetic variant elimination % Sems1=Sems2, printRepresentations(Sems2). cooperStorage(Sentence,Sems2):- setof(Sem,t([sem:Sem],Sentence,[]),Sems1), filterAlphabeticVariants(Sems1,Sems2). /*======================================================================== Test Suite Predicates ========================================================================*/ cooperStorageTestSuite:- nl, write('>>>>> COOPER STORAGE ON SENTENCE TEST SUITE <<<<< '), nl, sentence(Sentence,Readings), format('~nSentence: ~p (~p readings)',[Sentence,Readings]), cooperStorage(Sentence,Sems), printRepresentations(Sems), fail. cooperStorageTestSuite. </div> <div class="nb-cell markdown" name="md10"> Mit =info/0= lassen sich Informationen zu den einzelnen Prädikaten ausgeben </div> <div class="nb-cell program" data-background="true" data-singleline="true" name="p13"> info:- format('~n> ------------------------------------------------------------------- <',[]), format('~n> cooperStorage.pl, by Patrick Blackburn and Johan Bos <',[]), format('~n> <',[]), format('~n> ?- cooperStorage. - parse a typed-in sentence <',[]), format('~n> ?- cooperStorage(S,F). - parse a sentence and return formulas <',[]), format('~n> ?- cooperStorageTestSuite. - run the test suite <',[]), format('~n> ?- infix. - switches to infix display mode <',[]), format('~n> ?- prefix. - switches to prefix display mode <',[]), format('~n> ?- info. - shows this information <',[]), format('~n> ------------------------------------------------------------------- <',[]), format('~n~n',[]). </div> <div class="nb-cell query" name="q4"> info. </div> <div class="nb-cell markdown" name="md12"> Die Prädikate von `cooperStorage.pl`lassen sich nicht auf einer Swish-Seite ausführen. Sie müssen lokal ausgeführt werden. </div> <div class="nb-cell program" data-background="true" data-singleline="true" name="p10"> % printInfix/1: druckt eine in Präfix-Form gegebene Formel in Infix-Form. printInfix(X):- numbervars(X,1,_End,[]),printInfix1(X). printInfix1(X):- var(X), write(X),!. printInfix1(not(X)):- write('~'), write('('), printInfix1(X), write(')'),!. printInfix1(and(X,Y)):- write('('), printInfix1(X), write(' & '), printInfix1(Y), write(')'),!. printInfix1(or(X,Y)):- write('('), printInfix1(X), write(' v '), printInfix1(Y), write(')'),!. printInfix1(imp(X,Y)):- write('('), printInfix1(X), write(' > '), printInfix1(Y), write(')'),!. printInfix1(eq(X,Y)):- write('('), printInfix1(X), write(' = '), printInfix1(Y), write(')'),!. printInfix1(some(X, F)):- write('some ('), write_term(X,[numbervars(true)]), write(' '), printInfix1(F), write(')'),!. printInfix1(all(X, F)):- write('all ('), write_term(X,[numbervars(true)]), write(' '), printInfix1(F), write(')'),!. printInfix1(lam(X, F)):- write('lam '), write_term(X,[numbervars(true)]), write(' '), printInfix1(F),!. printInfix1(app(X,Y)):- write('('), printInfix1(X), write(' @ '), printInfix1(Y), write(')'),!. printInfix1(A):- write(A),!. </div> <div class="nb-cell program" data-background="true" data-singleline="true" name="p2"> % Student exercise profile :- set_prolog_flag(occurs_check, error). % disallow cyclic terms :- set_prolog_stack(global, limit(8 000 000)). % limit term space (8Mb) :- set_prolog_stack(local, limit(2 000 000)). % limit environment space </div> </div>