SNAPKITTYWEST's picture
push from SNAPKITTYWEST/snapkitty-clojure-lisp-bridge
119e586 verified
Raw History Blame Contribute Delete
7.83 kB
%% 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 ===').