% Discourse 2009 go :- retractall(tel(_)), assert(tel(1)), %blank slate DRS = drs([], []), S = [ [ik,zie,een,rode,kat], [ik,zie,een,blauwe,mat], [de,kat,zit,op,de,mat] ], analyse(S, DRS). gomuis :- retractall(tel(_)), assert(tel(1)), %blank slate DRS = drs([], []), S = [ [in,het,midden,van,het,hartje,van,het,binnenste,van,het,muiskleurig,gebergte,woonde,de,weerwolf], ['hij', 'was', 'groot', 'en', 'verschrikkelijk'], ['zijn', 'ogen', 'sproeiden', 'vuur', 'en', 'zijn', 'tong', 'had', 'karteltjes'], ['hij', 'had', 'lange', 'witte', 'scherpe', 'tanden'], ['iedere', 'avond', 'stiet', 'hij', 'een', 'gebrul', 'uit'], %waarvan ['het', 'hele', 'muiskleurige', 'gebergte', 'sidderde'], ['dat', 'is', 'de', 'weerwolf']], analyse(S, DRS). go(S) :- retractall(tel(_)), assert(tel(1)), %blank slate DRS = drs([], []), analyse([S], DRS). goprince :- retractall(tel(_)), assert(tel(1)), DRS = drs([], []), S = [[once, when, i, was, six, years, old], [i, saw, a, magnificent, picture, in, a, book], [called, true, stories, from, nature], [about, the, primeval, forest]], %It was a picture of a boa constrictor in the act of swallowing an animal. Here is a copy of the drawing. analyse(S, DRS). % Groep 1: Lexicon %lex(word, VariablesToEat, Features). %Features: % - eat, find, bind % - part of speech (det, pron, neg, prep, adj, noun, verb) % - after, before, next (difference between before and next is that next % only matches the word directly next to it) % - male, female, neuter % - plural, singular % - animate % % All features take one argument. The argument is anonymous (_) if it is about % the word itself, or it specifies a constraint for eat/find/bind. % pos(tempadv, [X], [adv(T), eat(X), verb(X), bind(T)], T). %introduce new reference time pos(adv, [X], [adv(T), eat(X), adv(X)], T). pos(adv, [X], [adv(T), eat(X), adj(X)], T). pos(adj, [X], [adj(T), eat(X), next(X)], T). pos(adj, [X], [adj(T), eat(X), adj(X)], T). pos(noun, [], [noun(T)], T). pos(noun, [X], [noun(T), eat(X), next(X), noun(X)], T). %eg. picture book = picture -> book pos(aninoun, [], [noun(T), animate(T)], T). pos(prep, [X,Y], [prep(T), eat(X), eat(Y), before(X), next(Y)], T). %preposition modifies its two closest neighbors pos(verb1, [X], [eat(X), before(X), verb(T), noun(X)], T). pos(verb2, [X,Y], [eat(X), eat(Y), before(X), verb(T), noun(X), noun(Y)], T). pos(aniverb2, [X,Y], [eat(X), eat(Y), before(X), verb(T), animate(X), noun(Y)], T). % lexclass(tempadv, [once, when]). lexclass(adj, [six, old, magnificent, true, primeval]). lexclass(noun, [years, picture, book, stories, nature, forest, act, swallowing, copy, drawing]). lexclass(aninoun, [boa,constrictor,animal]). lexclass(verb1, []). lexclass(verb2, [is, was, called]). lexclass(aniverb2, [is, was, saw]). lexclass(prep, [in, of, on, at, under, above, from, about]). % lex(i, [], [pron(T), find(_), animate(T), male(T)], T). lex(i, [], [pron(T), find(_), animate(T), female(T)], T). lex(a, [X], [det(T), bind(T), eat(X), next(X)], T). lex(the, [X], [det(T), find(_), eat(X), next(X)], T). lex(A, B, C, D) :- word(A,B,C,D). lex(Word, Vars, Feat, Id) :- lexclass(POS, Words), member(Word, Words), pos(POS, Vars, Feat, Id). lex(ik, [], [pron(T), find(Y), animate(Y), male(Y)], T). lex(ik, [], [pron(T), find(Y), animate(Y), female(Y)], T). lex(zie, [X, Y], [eat(X), eat(Y), before(X), verb(T), animate(X), noun(Y)], T). lex(een, [X], [det(T), eat(X), bind(_Y), next(X), takefeat(X)], T). %, takefeat(X)]). lex(rode, [X], [eat(X), adj(T), noun(X), next(X)], T). lex(kat, [], [noun(Y), animate(Y), male(Y)], Y). lex(blauwe, [X], [adj(T), eat(X), noun(X), next(X)], T). lex(zit, [X], [eat(X), before(X), verb(T)], T). lex(niet, [X], [eat(X), before(X), verb(X), neg(T)], T). lex(mat, [], [noun(T), male(T)], T). lex(op, [X,Y], [prep(T), eat(X), eat(Y), before(X), next(Y), verb(X)], T). lex(in, [X, Y], [prep(T), eat(X), eat(Y), verb(X), prep(Y), after(Y)], T). lex(het, [X], [det(T), find(_Y), eat(X), next(X), takefeat(X)], T). %, takefeat(X)]). lex(midden, [], [noun(T), neuter(T)], T). lex(van, [X,Y], [prep(T), eat(X), eat(Y), noun(X), before(X), prep(Y), after(Y)], T). lex(van, [X,Y], [prep(T), eat(X), eat(Y), next(Y), noun(X), before(X)], T). lex(hartje, [], [noun(T), neuter(T)], T). lex(binnenste, [], [noun(T), neuter(T)], T). lex(muiskleurig, [X], [adj(T), eat(X), next(X), noun(X)], T). lex(gebergte, [], [noun(X), neuter(X)], X). lex(woonde, [X], [verb(T), singular(T), past(T), eat(X), noun(X), animate(X)], T). lex(de, [X], [det(T), find(_), eat(X), next(X), male(X), takefeat(X)], T). lex(de, [X], [det(T), find(_), eat(X), next(X), female(X)], T). %, takefeat(X)]). lex(de, [X], [det(T), find(_), eat(X), next(X), plural(X)], T). %, takefeat(X)]). lex(weerwolf, [], [noun(X), animate(X), male(X)], X). % hij was groot en verschrikkelijk word(hij,[],[find(X),pronoun(This), male(X),animate(X)],This). word(was,[X,Y],[verb(This),pastTense(This),singular(This), eat(X),eat(Y)],This). word(groot,[],[ adj(This)],This). word(en,[X,Y],[npconj(This),eat(X),eat(Y),before(X),after(Y)],This). % een 'en' zoals in een opsomming word(verschrikkelijk,[],[ adj(This)],This). % zijn ogen sproeiden vuur en zijn tong had karteltjes word(zijn,[X],[pronoun(This),eat(X),noun(X),find(Y),male(Y)],This). word(ogen,[],[ noun(This),plural(This),inanimate(This)],This). word(sproeiden,[X,Y],[verb(This),plural(This),pastTense(This),eat(X),eat(Y), noun(Y)], This). word(vuur,[],[noun(This),inanimate(This),singular(This),neuter(This)],This). word(en,[X,Y],[conn(This),eat(X),eat(Y), before(X), after(Y), verb(X),verb(Y)], This). % een 'en' die twee complete zinnen verbindt word(tong,[],[noun(This),inanimate(This),singular(This),female(This)],This). word(had,[X,Y],[verb(This), singular(This),pastTense(This),eat(X),eat(Y), noun(Y)],This). word(karteltjes,[],[noun(This),plural(This)],This). % hij had lange witte scherpe tanden en word(lange,[X],[adj(This),eat(X),next(X),takefeat(X)],This). word(witte,[X],[adj(This),eat(X),next(X),takefeat(X)],This). word(scherpe,[X],[adj(This),eat(X),next(X),takefeat(X)],This). word(tanden,[],[ noun(This),plural(This),inanimate(This)],This). % iedere avond om zes uur stiet hij een gebrul uit waarvan het hele muiskleurige gebergte sidderde word(iedere,[X,Y],[univ(This), noun(X), next(X), eat(X), takefeat(X), verb(Y), eat(Y)], This). word(avond,[],[noun(This),inanimate(This),singular(This),male(This)],This). word(om,[X,Y],[eat(X),after(X),noun(X), verb(Y),eat(Y)], _This). word(zes,[X],[num(This),eat(X),noun(X),after(X),takefeat(X)],This). word(uur,[],[noun(This),neuter(This),inanimate(This)],This). word(stiet,[X,Y,Z],[verb(This),pastTense(This),singular(This),eat(X),eat(Y),eat(Z),animate(X),noun(Y),particle(Z)],This). word(een,[X],[det(This), bind(This),eat(X),noun(X),singular(X)],This). word(gebrul,[],[noun(This),singular(This),neuter(This),inanimate(This)],This). % deze 'uit' hoort bij 'stiet' (uitstoten) % ik maak er daarom een particle van en geen preposition % zie http://en.wikipedia.org/wiki/Preposition_and_postposition#Particles % -- Jeroen word(uit,[],[particle(This)],This). word(waarvan,[X,Y],[pronoun(X),verb(X),eat(X),eat(Y)],_This). % 'waarvan' is een betrekkelijk voornaamwoord word(hele,[X],[ adj(This),eat(X),noun(X),takefeat(X)],This). word(muiskleurige,[X],[adj(This) ,noun(X),takefeat(X), eat(X)],This). word(sidderde,[X],[ verb(This),pastTense(This),singular(This),noun(X),eat(X)],This). % dat is de weerwolf word(dat,[X],[pronoun(This),noun(X),find(X)],This). word(is, [X,Y],[verb(This),presentTense(This),singular(This),noun(X),eat(X),eat(Y)],This). :- dynamic tel/1. analyse([], _DRS). analyse([Sentence | Rest], DRS) :- interpret(Sentence, Meaning, DRS), writeln('Interpretation: '), writelist(Meaning), nl, %generatie check? docontext(Meaning, Meaning, DRS, drs(Ref, Cond)), writeln('Sentence: '), writeln(Sentence), nl, writeln('Meaning: '), writelist(Meaning), nl, writeln('Context: '), % 'pretty-print' DRS writeln(Ref), writeln('--------------'), writelist(Cond), nl, analyse(Rest, drs(Ref, Cond)). writelist([]). writelist([Head | Tail]) :- writeln(Head), writelist(Tail). % Groep 2 interpret(S, M, DRS):- def(S, M), eat(M, R1, M, M, det), eat(M, R2, R1, M, adj), eat(M, R3, R2, M, verb), eat(M, R4, R3, M, prep), eat(M, R5, R4, M, _), write('Not eaten: '), writeln(R5), find(M, M, DRS). % Get word definitions and assign unique word IDs def([], []). def([H|T], [lex(H, A2, A3, Tel)|M]) :- lex(H, A2, A3, Tel), tel(Tel), NewTel is Tel + 1, retractall(tel(_)), assert(tel(NewTel)), def(T, M). eat([], F, F, _, _). eat([lex(_,_,Feat, Id) | Tail], RFood, F, Meaning, Type) :- eat(Tail, Food, F, Meaning, Type), ((var(Type) ; (P =.. [Type, Id], memb(P, Feat))) -> doeat(Feat, Id, Food, RFood, Meaning) ; RFood = Food). memb(A, [H|T]) :- A == H ; memb(A,T). doeat(Feat, Id, Food, RRFood, Meaning) :- ((select(eat(X), Feat, Rest), var(X)) -> doeat(Rest, Id, Food, RFood, Meaning), %find all constraints specified for the referent we need to find: findall(C, getconstraint(C, X, Rest), Constraints), %instantiate X with word satisfying constraints (select(takefeat(_), Constraints, RConstraints) -> getFood(X, Id, RConstraints, RFood, TFood), % get features from word that was eaten member(lex(_,_,XFeat, X), Food), append(Feat, XFeat, RFeat), % put those features in the current word select(lex(W,V,Feat,Id), TFood, Tmp), RRFood = [lex(W,V,RFeat,Id) | Tmp] ; getFood(X, Id, Constraints, RFood, RRFood)) ; RRFood = Food). getconstraint(C, X, Feat) :- member(C, Feat), C =.. [_Pred, Y], X == Y. getFood(X, Id, Constraints, Meaning, Rest) :- % if there is a before constraint, reverse to match closest word first: (member(before(_), Constraints) -> reverse(Meaning, RM), select(lex(_, _, Feats, FoodId), RM, RF), reverse(RF, Rest) ; select(lex(_, _, Feats, FoodId), Meaning, Rest)), forall(member(C, Constraints), checkconstraint(C, Feats, Id, FoodId)), \+ Id = FoodId, %don't eat yourself. % don't eat something which has already been eaten: (causes problems with current lexicon) %\+ (member(lex(_,_,F,_), Meaning), member(eat(I), F), I == FoodId), X = FoodId. checkconstraint(C, Feats, Id, FoodId) :- (C = before(_), FoodId < Id) ; (C = after(_), FoodId > Id) ; % words directly next to each other (C = next(_), FoodId =:= Id + 1) ; ( \+ C = after(_), \+ C = before(_), \+ C = next(_), member(C, Feats)). %get properties from word that was eaten, and look in DRS for matching %conditions find([], _, _). find([lex(W1,_,Feat, Id) | Tail], Meaning, DRS) :- find(Tail, Meaning, DRS), (select(find(X), Feat, Rest) -> (select(eat(Y), Feat, _) -> % eg. the -> cat, get constraints from cat. member(lex(W,_,Feat2, Y), Meaning), %find all constraints specified for the referent we need to find: findall(C, getconstraint(C, Y, Feat2), Constraints) ; % eg. he, get constraints from own features. W = W1, findall(C, getconstraint(C, X, Rest), Constraints)), %instantiate X with referent satisfying constraints, %or if that fails, it will get bound later. try((findRef(X, W, Id, Constraints, DRS), % no two findings in sentence should be identical: %\+ (member(A, Rest), % A = lex(_,_,F1,_), % member(find(C), F1), % nonvar(C), C = X), true)) ; true). % try calling Pred, but succeed anyway if it fails try(Pred) :- call(Pred). try(_Pred). % find a suitable referent findRef(X, W, Id, Constraints, drs(Ref, Cond)) :- member(X, Ref), %instantiation happens here! P =.. [W, Y], %the word/predicate is already in the DRS (member(P, Cond) -> X = Y, % do not find myself: \+ X = Id ; % we have a word and some constraints, look in conditions if it % contains a word/predicate which satisfies those conditions checkref(Constraints, Cond, X), \+ X = Id). % maybe look into past meanings as well? (previous sentences) % (should be something more sophisticated: % een kat .... de kat <-- look for kat(X) in DRS % de man .... hij <-- look for male referent in DRS) % when a referent has already been found in a sentence, % assume we need to find a *different* referent: % een kat en een mat <- Ex,y cat(x) ^ mat(y) ^ not(x = y) findRef(X, W, Id, Constraints, drs(_Ref, Cond)) :- member(imp(DRS1, DRS2), Cond), (findRef(X, W, Id, Constraints, DRS1) ; findRef(X, W, Id, Constraints, DRS2)). findRef(X, W, Id, Constraints, drs(_Ref, Cond)) :- member(not(DRS), Cond), findRef(X, W, Id, Constraints, DRS). % take a DRS condition and see if it satisfies the constraints according to lexicon: checkref([], _Cond, _Ref). checkref([C | Tail], Cond, Ref) :- checkref(Tail, Cond, Ref), member(P, Cond), P =.. [W, Ref], lex(W,_,Feat,_), member(C, Feat). % Groep 3: context model gocontext :- retractall(tel(_)), assert(tel(1)), DRS = drs([], []), Meaning = [lex(hij, [], [find(1), pronoun(1), male(1), singular(1), animate(1)], 1), lex(had, [1, 3], [verb(2), pastTense(2), eat(1), eat(3), singular(1), noun(1), before(1), noun(3), after(3)], 2), lex(lange, [4], [adj(3), eat(4), noun(4), next(4), same_features(3, 4)], 3), lex(witte, [5], [adj(4), eat(5), noun(5), next(5), same_features(4, 5)], 4), lex(scherpe, [6], [adj(5), eat(6), noun(6), next(6), same_features(5, 6)], 5), lex(tanden, [], [noun(6), plural(6), inanimate(6)], 6), lex(en, [2, 18], [conn(7), eat(2), eat(18)], 7), lex(iedere, [9, 13], [univ(8), eat(9), noun(9), next(9), singular(9), same_features(8, 9), verb(13), eat(13)], 8), lex(avond, [], [noun(9), inanimate(9), singular(9), male(9)], 9), lex(om, [8, 11], [prep(10), eat(8), before(8), noun(8), eat(11), noun(11), after(11)], 10), lex(zes, [12], [det(11), eat(12), noun(12), next(12), same_features(11, 12)], 11), lex(uur, [], [noun(12), neuter(12), inanimate(12)], 12), lex(stiet, [14, 15, 17], [verb(13), pastTense(13), eat(14), eat(15), eat(17), singular(14), animate(14), noun(15), after(15), particle(17)], 13), lex(hij, [], [find(14), noun(14), male(14), singular(14), animate(14)], 14), lex(een, [16], [det(15), bind(15), eat(16), next(16), noun(16), singular(16), same_features(15, 16)], 15), lex(gebrul, [], [noun(16), singular(16), neuter(16), inanimate(16)], 16), lex(uit, [], [particle(17)], 17) , lex(waarvan, [10, 23], [prep(18), eat(10), eat(23), prep(10), verb(23)], 18), lex(het, [20], [det(19), find(19), eat(20), next(20), neuter(20), same_features(19, 20)], 19), lex(hele, [21], [adj(20), eat(21), noun(21), next(21), same_features(20, 21)], 20), lex(muiskleurige, [22], [adj(21), noun(22), next(22), same_features(21, 22), eat(22)], 21) , lex(gebergte, [], [noun(22), neuter(22), singular(22)], 22), lex(sidderde, [19], [verb(23), pastTense(23), singular(19), before(19), noun(19), eat(19)], 23)], /* Meaning = [ lex(in, [14, 4], [prep(1), eat(14), eat(4), verb(14), prep(4), after(4)], 1), lex(het, [3], [det(2), find(2), eat(3), next(3), neuter(3), same_features(2, 3)], 2), lex(midden, [], [noun(3), neuter(3)], 3), lex(van, [2, 7], [prep(4), eat(2), eat(7), noun(2), prep(7), before(2), after(7)], 4) , lex(het, [6], [det(5), find(5), eat(6), next(6), neuter(6), same_features(5, 6)], 5) , lex(hartje, [], [noun(6), neuter(6)], 6) , lex(van, [5, 10], [prep(7), eat(5), eat(10), noun(5), prep(10), before(5), after(10)], 7) , lex(het, [9], [det(8), find(8), eat(9), next(9), neuter(9), same_features(8, 9)], 8) , lex(binnenste, [], [noun(9), neuter(9)], 9) , lex(van, [8, 11], [prep(10), eat(8), eat(11), noun(8), noun(11), before(8), after(11)], 10) , lex(het, [12], [det(11), find(11), eat(12), next(12), neuter(12), same_features(11, 12)], 11) , lex(muiskleurig, [13], [adj(12), eat(13), noun(13), next(13), same_features(12, 13)], 12) , lex(gebergte, [], [noun(13), neuter(13), singular(13)], 13) , lex(woonde, [15], [verb(14), singular(14), past(14), eat(15), noun(15), animate(15)], 14) , lex(de, [16], [det(15), find(15), eat(16), noun(16), next(16), male(16), same_features(15, 16)], 15) , lex(weerwolf, [], [noun(16), animate(16), male(16)], 16)], */ docontext(Meaning, Meaning, DRS, NewDRS), writeln(NewDRS). gocontext1 :- M=[lex(hij, [], [find(1), noun(1), male(1), singular(1), animate(1)], 1), lex(was, [1, 4], [verb(2), pastTense(2), eat(1), eat(4), singular(1), noun(1), before(1), prep(4), after(4)], 2), lex(groot, [], [noun(3)], 3), lex(en, [3, 5], [npconj(4), eat(3), eat(5), noun(3), before(3), noun(5), after(5)], 4), lex(verschrikkelijk, [], [noun(5)], 5)], docontext(M,M,drs([2, 5, 8, 11, 15], [in(15, 2), midden(2), van(2, 5), hartje(5), van(5,8), binnenste(8), van(8, 11), gebergte(11), muiskleurig(11), woonde(15),weerwolf(15)]),ND), writeln(ND). %bind new referents dobind([], _, DRS, DRS). dobind([lex(Word, Vars, Feats, Id) | Rest], M, drs(Ref, Cond), drs(NewRef, Cond)) :- dobind(Rest, M, drs(Ref, Cond), drs(R, Cond)), ((member(bind(V), Feats) ; (member(find(V), Feats), var(V))) -> V = Id, %Add variable to M: member(lex(Word, Vars, Feats, Id), M), %Add new variable to Ref: union(R, [V], NewRef) ; % ?! nonvar(Ref), NewRef = R). % wrapper docontext(Meaning, Meaning, DRS, NewDRS) :- dobind(Meaning, Meaning, DRS, Tmp), Tmp = drs(Ref, Cond), %handle negation ((select(lex(_, _, C, _), Meaning, Rest), member(neg(_), C)) -> docontext(Rest, Rest, drs([], []), drs(NewRef, TempCond)), subtract(TempCond, Cond, NewCond), NewDRS = drs(Ref, [not(drs(NewRef, NewCond)) | Cond]) ; % handle sentence conjunction ((select(lex(_, _, D, _), Meaning, _Rest), member(conn(_), D)) -> append(A, [lex(_,_,D,_)|B], Meaning), docontext(A, A, DRS, drs(NewRef1, TempCond1)), docontext(B, B, DRS, drs(NewRef2, TempCond2)), % merge DRSes union(NewRef1, NewRef2, NewRef3), union(NewRef3, Ref, NewRef), union(TempCond1, TempCond2, TempCond3), union(TempCond3, Cond, NewCond), NewDRS = drs(NewRef, NewCond) ; % handle universal quantification ((select(lex(_, _, E, _), Meaning, Rest), member(univ(_), E)) -> select(eat(A), E, ER), %variable select(eat(B), ER, _), %sentence select(lex(W,_V,_F,A), Rest, RRest), %one-word hack for variable: Pred =.. [W, A], DRS1 = drs([A], [Pred]), %AM = [lex(W,V,F,A)], %plus more words? %eg. iedere donkere avond %docontext(AM, AM, drs([],[]), DRS1), docontext(RRest, RRest, drs([],[]), DRS2), DRS2 = drs(Ref2, Cond2), subtract(Ref2, Ref, NRef2), union(Cond, [forall(DRS1, drs(NRef2, Cond2))], NewCond), NewDRS = drs(Ref, NewCond) ; %normal sentence, stop recursing context(Meaning, Meaning, Tmp, NewDRS)))). context([], _, NewDRS, NewDRS). context([lex(Word, Vars, Feats, Id) | Rest], M, drs(Ref, Cond), Result) :- % add conditions to DRS % normal words, ie., neither a determiner or pronoun, has arguments: (\+ (member(det(_), Feats) ; member(npconj(_), Feats) ; member(pronoun(_), Feats) ; Vars = []) -> % handle NP conjunctions and copula (member(eat(X), Feats), member(lex(_,_,XFeats,X), M), member(npconj(X), XFeats) -> select(eat(A), XFeats, XRest), select(eat(B), XRest, _), (Vars = [Y, X] -> XVars1 = [Y, A], XVars2 = [Y, B] ; XVars1 = [A, Y], XVars2 = [B, Y]), ((deref(XVars1, M, DerefVars1), deref(XVars2, M, DerefVars2)) -> Pred1 =.. [Word | DerefVars1], Pred2 =.. [Word | DerefVars2], union(Ref, DerefVars1, Tmp), union(Tmp, DerefVars2, NewRef) ; %copula, verb has no meaning member(lex(Word1, _,_, A), M), member(lex(Word2, _,_, B), M), Pred1 =.. [Word1, Y], Pred2 =.. [Word2, Y], union(Ref, [Y], NewRef)), union(Cond, [Pred1, Pred2], NewCond) ; %resolve word IDs to discourse referents (deref(Vars, M, DerefVars) -> Pred =.. [Word | DerefVars], union(Ref, DerefVars, NewRef) ; %copula, verb has no meaning % eg. hij was groot: % get ref from 'hij', condition from 'groot' select(eat(A), Feats, XRest), select(eat(B), XRest, _), member(lex(_W,_,AF,A), M), member(lex(Word,_,_,B), M), member(bind(A), AF), Pred =.. [Word, A], union(Ref, [A], NewRef)), union(Cond, [Pred], NewCond)), context(Rest, M, drs(NewRef, NewCond), Result) ; %handle determiners ((member(det(_), Feats) ; member(pronoun(_), Feats)) -> (member(find(F), Feats) ; member(bind(F), Feats)), %recurse until word which hasn't eaten (noun) findconditions(F, Feats, M, Preds), union(Cond, Preds, NewCond), context(Rest, M, drs(Ref, NewCond), Result) ; % a word which hasn't eaten anything but is % eaten directly by a verb should bind a new referent % and be added as condition. ((member(lex(_,_,VFeat,_), M), member(eat(Id), VFeat), (member(verb(_), VFeat) ; member(prep(_), VFeat))) -> Pred =.. [Word, Id], union(Cond, [Pred], NewCond), union(Ref, [Id], NewRef), context(Rest, M, drs(NewRef, NewCond), Result) ; % other words without arguments are ignored: context(Rest, M, drs(Ref, Cond), Result)))). % eg. de -> rode -> kat should yield [kat, rode] findconditions(_F, Feats, _Meaning, []) :- \+ member(eat(_X), Feats). findconditions(F, Feats, Meaning, [Pred | Tail]) :- member(eat(X), Feats), select(lex(AteWord, _, NFeats, X), Meaning, Rest), Pred =.. [AteWord, F], findconditions(F, NFeats, Rest, Tail). % dereference word IDs to their original discourse referents % (ie., word ID from when referent was introduced) deref([], _Meaning, []). deref([V | Vars], Meaning, [R | RVars]) :- deref(Vars, Meaning, RVars), %find word referred to: select(lex(_, _, Feats, V), Meaning, Rest), %either the discourse referent has been found: (member(find(R), Feats) ; %or it has or will be bound: member(bind(R), Feats) ; % implicit bind: bare nouns (member(lex(_,_, Feats2, _), Meaning), member(eat(V), Feats2), member(verb(_), Feats2), R = V) ; %recurse (determiner contains find/bind). (\+ member(bind(_), Feats), \+ member(find(_), Feats), ((member(verb(_), Feats) ; member(prep(_), Feats) ; member(npconj(_), Feats) ; member(adv(_), Feats)) -> % resolve verb to one of its arguments %(which argument is part of ambiguity of language...) member(eat(Foo), Feats) ; %backwards: eg. kat -> rode -> de member(lex(_,_, Feats2, Foo), Meaning), member(eat(V), Feats2)), % prevent cycles by passing Rest, ie., without the word we just tried: deref([Foo], Rest, [R]))).