Spaces:
Running
Running
| :- module(compositional, [ | |
| compose_sentence/3, | |
| semantic_type/2, | |
| semantic_repr/2, | |
| lambda_apply/3 | |
| ]). | |
| :- use_module(lexicon). | |
| :- use_module(xbar). | |
| %% ========================================================================== | |
| %% MLAF Grammar Engine β Compositional Semantics | |
| %% | |
| %% Implements the Principle of Compositionality (Frege's Principle) from | |
| %% Partee, ter Meulen & Wall, Ch 13: | |
| %% | |
| %% "The meaning of a complex expression is a function of the meanings | |
| %% of its parts and of the way they are syntactically combined." | |
| %% | |
| %% Formally: there exists a homomorphism h from the syntactic algebra | |
| %% <E_s, F_1..F_n> to the semantic algebra <E_m, G_1..G_n> such that | |
| %% for every syntactic rule F_i, there is a corresponding semantic rule G_i. | |
| %% | |
| %% Type System (Montague, PTQ): | |
| %% e β entities (individuals) | |
| %% t β truth values (propositions) | |
| %% <a, b> β functions from type a to type b | |
| %% | |
| %% Semantic Representations: | |
| %% Pronouns: type e, denotation = constant (i, you, he, she, we, they) | |
| %% Trans. Verbs: type <e, <e, t>>, denotation = lambda x.lambda y.verb(y,x) | |
| %% Intrans. Verbs: type <e, t>, denotation = lambda x.verb(x) | |
| %% Nouns: type e, denotation = constant (food, water, book, ...) | |
| %% | |
| %% Lambda Calculus: | |
| %% lambda(Var, Body) β abstraction | |
| %% apply(Fn, Arg) β application (beta reduction) | |
| %% pred(Name, Args) β predicate (after full reduction) | |
| %% ========================================================================== | |
| %% --- Semantic Types --- | |
| semantic_type(subject_i, e). | |
| semantic_type(subject_you, e). | |
| semantic_type(subject_he, e). | |
| semantic_type(subject_she, e). | |
| semantic_type(subject_we, e). | |
| semantic_type(subject_they, e). | |
| semantic_type(verb_want, arrow(e, arrow(e, t))). | |
| semantic_type(verb_eat, arrow(e, arrow(e, t))). | |
| semantic_type(verb_see, arrow(e, arrow(e, t))). | |
| semantic_type(verb_grab, arrow(e, arrow(e, t))). | |
| semantic_type(verb_drink, arrow(e, arrow(e, t))). | |
| semantic_type(verb_go, arrow(e, t)). | |
| semantic_type(verb_stop, arrow(e, t)). | |
| semantic_type(object_food, e). | |
| semantic_type(object_water, e). | |
| semantic_type(object_book, e). | |
| semantic_type(object_apple, e). | |
| semantic_type(object_ball, e). | |
| semantic_type(object_house, e). | |
| %% --- Semantic Representations (Lexical Entries) --- | |
| %% Pronouns: constant denotations | |
| semantic_repr(subject_i, entity(i)). | |
| semantic_repr(subject_you, entity(you)). | |
| semantic_repr(subject_he, entity(he)). | |
| semantic_repr(subject_she, entity(she)). | |
| semantic_repr(subject_we, entity(we)). | |
| semantic_repr(subject_they, entity(they)). | |
| %% Transitive verbs: lambda x . lambda y . verb(y, x) | |
| %% (object first per currying: V applied to Obj gives <e,t>, then applied to Subj gives t) | |
| semantic_repr(verb_want, lambda(x, lambda(y, pred(want, [y, x])))). | |
| semantic_repr(verb_eat, lambda(x, lambda(y, pred(eat, [y, x])))). | |
| semantic_repr(verb_see, lambda(x, lambda(y, pred(see, [y, x])))). | |
| semantic_repr(verb_grab, lambda(x, lambda(y, pred(grab, [y, x])))). | |
| semantic_repr(verb_drink, lambda(x, lambda(y, pred(drink,[y, x])))). | |
| %% Intransitive verbs: lambda x . verb(x) | |
| semantic_repr(verb_go, lambda(x, pred(go, [x]))). | |
| semantic_repr(verb_stop, lambda(x, pred(stop, [x]))). | |
| %% Nouns: constant denotations | |
| semantic_repr(object_food, entity(food)). | |
| semantic_repr(object_water, entity(water)). | |
| semantic_repr(object_book, entity(book)). | |
| semantic_repr(object_apple, entity(apple)). | |
| semantic_repr(object_ball, entity(ball)). | |
| semantic_repr(object_house, entity(house)). | |
| %% ========================================================================== | |
| %% LAMBDA CALCULUS β Beta Reduction | |
| %% ========================================================================== | |
| %% lambda_apply(+Function, +Argument, -Result) | |
| %% Beta reduction: (lambda X . Body)(Arg) = Body[X := Arg] | |
| lambda_apply(lambda(Var, Body), Arg, Result) :- | |
| substitute(Var, Arg, Body, Result). | |
| lambda_apply(Expr, _, Expr) :- | |
| \+ functor(Expr, lambda, 2). | |
| %% substitute(+Var, +Value, +Expr, -Result) | |
| %% Replace all free occurrences of Var with Value in Expr. | |
| substitute(Var, Value, Var, Value) :- !. | |
| substitute(Var, _Value, lambda(Var, Body), lambda(Var, Body)) :- !. | |
| %% Var is bound in this lambda β do not substitute inside | |
| substitute(Var, Value, lambda(OtherVar, Body), lambda(OtherVar, NewBody)) :- | |
| Var \= OtherVar, | |
| substitute(Var, Value, Body, NewBody), !. | |
| substitute(Var, Value, pred(Name, Args), pred(Name, NewArgs)) :- | |
| maplist(substitute(Var, Value), Args, NewArgs), !. | |
| substitute(Var, Value, apply(Fn, Arg), apply(NewFn, NewArg)) :- | |
| substitute(Var, Value, Fn, NewFn), | |
| substitute(Var, Value, Arg, NewArg), !. | |
| substitute(Var, Value, entity(X), entity(NewX)) :- | |
| (X == Var -> NewX = Value ; NewX = X), !. | |
| substitute(_Var, _Value, Atom, Atom) :- | |
| atomic(Atom), !. | |
| substitute(Var, Value, Term, NewTerm) :- | |
| compound(Term), | |
| Term =.. [F | Args], | |
| maplist(substitute(Var, Value), Args, NewArgs), | |
| NewTerm =.. [F | NewArgs]. | |
| %% ========================================================================== | |
| %% COMPOSITIONAL SENTENCE INTERPRETATION | |
| %% ========================================================================== | |
| %% compose_sentence(+GestureIDs, -SemanticForm, -TypeResult) | |
| %% | |
| %% Given a list of gesture IDs, compute the compositional semantic | |
| %% representation by: | |
| %% 1. Looking up each lexical item's semantic representation | |
| %% 2. Applying functional application (lambda calculus) | |
| %% 3. Returning the fully reduced logical form | |
| %% | |
| %% For SVO: Subj + Verb + Obj | |
| %% Step 1: V(Obj) = lambda y . pred(V, [y, obj]) β type <e, t> | |
| %% Step 2: V(Obj)(Subj) = pred(V, [subj, obj]) β type t | |
| %% SVO β transitive | |
| compose_sentence([SubjID, VerbID, ObjID], SemanticForm, TypeResult) :- | |
| lex(SubjID, _, d, _), | |
| lex(VerbID, _, v, VFeats), | |
| member(transitive=yes, VFeats), | |
| lex(ObjID, _, n, _), | |
| !, | |
| semantic_repr(SubjID, SubjSem), | |
| semantic_repr(VerbID, VerbSem), | |
| semantic_repr(ObjID, ObjSem), | |
| %% Step 1: Apply verb to object | |
| lambda_apply(VerbSem, ObjSem, VerbObjSem), | |
| %% Step 2: Apply result to subject | |
| lambda_apply(VerbObjSem, SubjSem, SemanticForm), | |
| TypeResult = t. | |
| %% SV β intransitive | |
| compose_sentence([SubjID, VerbID], SemanticForm, TypeResult) :- | |
| lex(SubjID, _, d, _), | |
| lex(VerbID, _, v, VFeats), | |
| \+ member(transitive=yes, VFeats), | |
| !, | |
| semantic_repr(SubjID, SubjSem), | |
| semantic_repr(VerbID, VerbSem), | |
| %% Apply verb to subject | |
| lambda_apply(VerbSem, SubjSem, SemanticForm), | |
| TypeResult = t. | |
| %% Partial: Subject only | |
| compose_sentence([SubjID], SubjSem, e) :- | |
| lex(SubjID, _, d, _), | |
| !, | |
| semantic_repr(SubjID, SubjSem). | |
| %% Partial: Subject + transitive verb (awaiting object) | |
| compose_sentence([SubjID, VerbID], PartialSem, arrow(e, t)) :- | |
| lex(SubjID, _, d, _), | |
| lex(VerbID, _, v, VFeats), | |
| member(transitive=yes, VFeats), | |
| !, | |
| semantic_repr(VerbID, VerbSem), | |
| %% Can't fully apply yet β return partial: verb needs object | |
| PartialSem = awaiting_object(SubjID, VerbSem). | |
| %% Fallback | |
| compose_sentence(_, unknown, unknown). | |