File size: 5,202 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
:- module(binding, [check_binding/3, classify_dp/3]).

:- use_module(lexicon).

%% ==========================================================================
%% MLAF Grammar Engine — Government & Binding Theory
%%
%% Implements Principles A, B, C:
%%   Principle A: Anaphors must be bound in local domain
%%   Principle B: Pronouns must be FREE in local domain
%%   Principle C: R-expressions must be free everywhere
%%
%% Current 11-gesture vocabulary:
%%   - Pronouns (I, You, He, We, They) -> Principle B
%%   - R-expressions (food, water, book) -> Principle C
%%   - Framework extensible for reflexives (Principle A)
%% ==========================================================================

%% --- classify_dp(+GestureID, -DPType, -Principle) ---
%% Classifies a DP node by its binding type.

classify_dp(GestureID, pronoun, principle_b) :-
    lex(GestureID, _, _, Feats),
    member(anaphor=no, Feats),
    member(pronominal=yes, Feats),
    !.

classify_dp(GestureID, r_expression, principle_c) :-
    lex(GestureID, _, _, Feats),
    member(anaphor=no, Feats),
    member(pronominal=no, Feats),
    !.

classify_dp(GestureID, anaphor, principle_a) :-
    lex(GestureID, _, _, Feats),
    member(anaphor=yes, Feats),
    member(pronominal=no, Feats),
    !.

classify_dp(_, unknown, none).

%% --- check_binding(+GestureIDs, +BindingDomain, -Violations) ---
%% GestureIDs: list of gesture IDs in the sentence
%% BindingDomain: local (clause-level) or global (discourse-level)
%% Violations: list of violation(Principle, ID, Message) or empty list

check_binding(GestureIDs, local, Violations) :-
    findall(
        violation(Principle, ID, Message),
        (
            member(ID, GestureIDs),
            lex(ID, _, _, _),
            binding_violation(ID, GestureIDs, local, Principle, Message)
        ),
        Violations
    ).

check_binding(GestureIDs, global, Violations) :-
    findall(
        violation(Principle, ID, Message),
        (
            member(ID, GestureIDs),
            lex(ID, _, _, _),
            binding_violation(ID, GestureIDs, global, Principle, Message)
        ),
        Violations
    ).

%% --- binding_violation(+ID, +AllIDs, +Domain, -Principle, -Message) ---
%% Checks if a specific DP violates binding principles.

%% Principle A: Anaphor must be bound in local domain
%% (no anaphors in current vocabulary, but framework ready)
binding_violation(ID, AllIDs, local, principle_a, Message) :-
    classify_dp(ID, anaphor, principle_a),
    %% Check if there's a c-commanding antecedent in the local domain
    \+ has_local_antecedent(ID, AllIDs),
    lex(ID, Form, _, _),
    atomic_list_concat(['Anaphor ', Form, ' must be bound in its local domain'], Message).

%% Principle B: Pronoun must be FREE in local domain
%% In single-clause sentences with different referents, pronouns are fine.
%% Violation occurs if a pronoun is coindexed with a local c-commanding DP.
binding_violation(ID, AllIDs, local, principle_b, Message) :-
    classify_dp(ID, pronoun, principle_b),
    has_local_binder(ID, AllIDs),
    lex(ID, Form, _, _),
    atomic_list_concat(['Pronoun ', Form, ' must be free in its local domain'], Message).

%% Principle C: R-expression must be free everywhere
binding_violation(ID, AllIDs, _, principle_c, Message) :-
    classify_dp(ID, r_expression, principle_c),
    has_any_binder(ID, AllIDs),
    lex(ID, Form, _, _),
    atomic_list_concat(['R-expression ', Form, ' must not be bound'], Message).

%% --- Binding domain helpers ---

%% An anaphor has a local antecedent if another DP with matching features
%% appears before it (c-commands it) in the same clause.
has_local_antecedent(ID, AllIDs) :-
    lex(ID, _, _, Feats),
    member(person=P, Feats),
    member(number=N, Feats),
    member(OtherID, AllIDs),
    OtherID \= ID,
    lex(OtherID, _, _, OtherFeats),
    member(person=P, OtherFeats),
    member(number=N, OtherFeats),
    %% Must appear before (c-command approximation via linear order)
    appears_before(OtherID, ID, AllIDs).

%% A pronoun has a local binder if another DP with identical reference
%% c-commands it in the same clause (simplified: same person+number, appears before)
has_local_binder(ID, AllIDs) :-
    lex(ID, _, _, Feats),
    member(person=P, Feats),
    member(number=N, Feats),
    member(case=nom, Feats),
    %% Subject pronoun bound by another subject = violation
    member(OtherID, AllIDs),
    OtherID \= ID,
    lex(OtherID, _, _, OtherFeats),
    member(person=P, OtherFeats),
    member(number=N, OtherFeats),
    member(case=nom, OtherFeats),
    appears_before(OtherID, ID, AllIDs).

%% R-expression bound anywhere — requires explicit coreference.
%% In our vocabulary, binding violation only fires when the same gesture
%% ID appears twice (duplicate R-expression) or when a pronoun and
%% R-expression share the same referential index (future extension).
has_any_binder(ID, AllIDs) :-
    %% Same gesture ID appearing more than once signals coreference
    member(OtherID, AllIDs),
    OtherID == ID,
    appears_before(OtherID, ID, AllIDs).

%% --- Linear order helper ---

appears_before(X, Y, List) :-
    nth0(IX, List, X),
    nth0(IY, List, Y),
    IX < IY.