Spaces:
Running
Running
File size: 7,234 Bytes
47b17cc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | :- 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).
|