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).