File size: 7,834 Bytes
119e586
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
202
203
204
205
206
207
208
209
210
211
%% SKC-LISP: Layered Truth Maintenance System (LTMS)
%% Knowledge layer: Prolog symbolic reasoning engine
%% Author: Ahmad Parr (ahmedparr93@gmail.com)
%% Integration: Snapkitty LISP Bridge knowledge engine

:- dynamic fact/5.        % fact(Value, Source, Timestamp, Confidence, Priority)
:- dynamic rule/4.        % rule(Head, Body, Module, Priority)
:- dynamic concept/2.     % concept(Name, Senses)
:- dynamic sense/4.       % sense(Concept, Gloss, ContextPred, Confidence)
:- dynamic belief_base/1. % belief_base(Timestamp) for history
:- dynamic module_stats/3. % module_stats(Module, RuleCount, LastUpdated)

%% ============================================================================
%% 1. CONFLICT RESOLUTION
%% ============================================================================
%% When multiple facts claim the same value, pick the winner by:
%% Priority > Confidence > Source recency

resolve_conflict(Value, Winner) :-
    findall(f(Value,S,T,C,P), fact(Value,S,T,C,P), Candidates),
    (Candidates = []
      -> fail
      ;  predsort(compare_facts, Candidates, Sorted),
         Sorted = [Winner|_]).

%% Comparison: higher priority wins, then higher confidence
compare_facts(Order, f(_,_,_,C1,P1), f(_,_,_,C2,P2)) :-
    ( P1 > P2 -> Order = (<)
    ; P1 < P2 -> Order = (>)
    ; C1 > C2 -> Order = (<)
    ; C1 < C2 -> Order = (>)
    ; Order = (=) ).

%% Get the winning value
get_belief(Value, WinningFact) :-
    resolve_conflict(Value, WinningFact).

%% ============================================================================
%% 2. OUTDATED DETECTION
%% ============================================================================
%% Exponential decay: confidence decays over time
%% Decay function: Conf(t) = Conf(0) * exp(-0.0001 * age_in_ms)

is_outdated(fact(_,_,Created,Conf,_), Now) :-
    Decay is Conf * exp(-0.0001 * (Now - Created)),
    Decay < 0.15.

prune_outdated_facts(Now) :-
    findall(f(V,S,T,C,P), fact(V,S,T,C,P), AllFacts),
    forall(member(F, AllFacts),
           (is_outdated(F, Now) -> retract(F) ; true)).

%% Half-life: time for confidence to drop to 50%
compute_half_life(HalfLife) :-
    HalfLife is log(2.0) / 0.0001.  % ~6931 milliseconds = 6.9 seconds

%% ============================================================================
%% 3. AMBIGUOUS CONCEPTS
%% ============================================================================
%% Concepts have multiple senses, each with a context predicate

register_concept(Name, SenseGlosses) :-
    findall(sense(Name, Gloss, _, 1.0), member(Gloss, SenseGlosses), Senses),
    assertz(concept(Name, Senses)).

disambiguate(Concept, Context, Sense) :-
    concept(Concept, Senses),
    member(sense(Concept, Gloss, Pred, Conf), Senses),
    (var(Pred) ; call(Pred, Context)),
    Sense = sense(Concept, Gloss, Pred, Conf).

%% Pick best sense by confidence (or first if all equal)
best_sense(Concept, Context, BestSense) :-
    findall(Sense, disambiguate(Concept, Context, Sense), Candidates),
    (Candidates = []
      -> fail
      ;  sort(Candidates, [BestSense|_])).

%% ============================================================================
%% 4. MAINTAINABILITY GUARD
%% ============================================================================
%% Hard limit: no module can have > 80 rules
%% Prevents knowledge explosion and maintains readable rule sets

assert_rule(Head, Body, Module, Priority) :-
    findall(_, rule(_,_,Module,_), Rules),
    length(Rules, N),
    (N >= 80
      -> throw(error(module_overflow,
                     context(assert_rule/4,
                             "Module " + Module + " has reached rule limit")))
      ;  assertz(rule(Head, Body, Module, Priority)),
         update_module_stats(Module)).

update_module_stats(Module) :-
    (retract(module_stats(Module, _, _)) ; true),
    findall(_, rule(_,_,Module,_), Rules),
    length(Rules, Count),
    get_time(Now),
    assertz(module_stats(Module, Count, Now)).

%% Get module health (rules / max_rules)
module_complexity(Module, Percentage) :-
    module_stats(Module, Count, _),
    Percentage is (Count / 80.0) * 100.

%% Suggest refactoring when > 70% full
suggest_refactor(Module) :-
    module_complexity(Module, P),
    P > 70.0.

%% ============================================================================
%% 5. HYBRID / NON-RULE KNOWLEDGE
%% ============================================================================
%% Fallback to embeddings when symbolic reasoning fails

hybrid_prove(Goal, Result, Confidence) :-
    ( prove_symbolic(Goal, Result)
    -> Confidence = 1.0
    ;  embedding_retrieve(Goal, Result, Confidence)
    ).

prove_symbolic(Goal, Result) :-
    clause(Goal, Body),
    call(Body),
    Result = Goal.

%% Stub for embedding retrieval (connects to vector DB)
embedding_retrieve(Goal, Result, Confidence) :-
    % In production: query Qdrant/WORM ledger for similar embeddings
    % For now: fail gracefully
    fail.

%% ============================================================================
%% ASSERTION & QUERY API
%% ============================================================================

%% Assert a new fact
assert_fact(Value, Source, Confidence, Priority) :-
    get_time(Now),
    Timestamp is floor(Now * 1000),  % milliseconds
    assertz(fact(Value, Source, Timestamp, Confidence, Priority)).

%% Query belief about a value (returns winning fact + confidence)
query(Value, Confidence) :-
    resolve_conflict(Value, f(Value, _, _, Confidence, _)).

%% All known senses of a concept
all_senses(Concept, AllSenses) :-
    concept(Concept, AllSenses).

%% Concept subsumption: is Specific a kind of General?
is_a(Specific, General) :-
    fact(is_a(Specific, General), _, _, _, _).

%% ============================================================================
%% DEBUGGING & INSPECTION
%% ============================================================================

%% List all facts
list_facts :-
    findall(f(V,S,T,C,P), fact(V,S,T,C,P), Facts),
    forall(member(F, Facts), writeln(F)).

%% List all rules by module
list_rules_in_module(Module) :-
    findall(rule(H,B,M,Pr), rule(H,B,Module,Pr), Rules),
    forall(member(R, Rules), writeln(R)).

%% List all concepts
list_concepts :-
    findall(C, concept(C, _), Concepts),
    forall(member(C, Concepts), writeln(C)).

%% Module report
module_report :-
    findall(m(M,Count,Updated), module_stats(M,Count,Updated), Stats),
    forall(member(m(Mod,Count,_), Stats),
           format('~w: ~w/80 rules~n', [Mod, Count])).

%% ============================================================================
%% TESTS
%% ============================================================================

:- initialization(run_ltms_tests).

run_ltms_tests :-
    writeln('=== LTMS Tests ==='),

    % Test 1: Conflict resolution
    writeln('Test 1: Conflict resolution'),
    assert_fact(color(car), source_a, 0.8, 10),
    assert_fact(color(car), source_b, 0.9, 5),
    resolve_conflict(color(car), Winner),
    writeln(Winner), nl,

    % Test 2: Outdated detection
    writeln('Test 2: Outdated detection'),
    get_time(Now),
    OldTime is (Now * 1000) - 10000,
    (is_outdated(fact(old_value, old_source, OldTime, 0.5, 1), Now * 1000)
      -> writeln('✓ Old fact marked as outdated')
      ;  writeln('✗ Old fact not detected')), nl,

    % Test 3: Module limit
    writeln('Test 3: Module complexity guard'),
    (module_complexity(main, P), format('Main module: ~1f% full~n', [P])
      ;  writeln('Main module not yet used')), nl,

    writeln('=== LTMS Tests Complete ===').