Spaces:
Running
Running
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.
|