Download src/snapkitty/ltms/LTMS.hs from Snapkitty/snapkitty-clojure-lisp-bridge: direct link, hf CLI and curl.
- Browser
- Download file 11.5 kB
-
https://huggingface.co/Snapkitty/snapkitty-clojure-lisp-bridge/resolve/main/src/snapkitty/ltms/LTMS.hs
- Command line
-
hf download hf://Snapkitty/snapkitty-clojure-lisp-bridge/src/snapkitty/ltms/LTMS.hs
-
curl -L -o LTMS.hs https://huggingface.co/Snapkitty/snapkitty-clojure-lisp-bridge/resolve/main/src/snapkitty/ltms/LTMS.hs
11.5 kB
| -- SKC-LISP: Layered Truth Maintenance System (LTMS) β Haskell Implementation | |
| -- Knowledge layer: Type-safe symbolic reasoning | |
| -- Author: Ahmad Parr (ahmedparr93@gmail.com) | |
| -- Integration: Snapkitty LISP Bridge knowledge engine | |
| module Snapkitty.LTMS.LTMS where | |
| import Data.Time | |
| import Data.List (sortBy, sortOn) | |
| import Data.Ord (Down(..)) | |
| import Data.Map (Map) | |
| import qualified Data.Map as Map | |
| import Data.Set (Set) | |
| import qualified Data.Set as Set | |
| import Control.Monad (when) | |
| import GHC.Generics | |
| import Text.Printf | |
| -- ============================================================================ | |
| -- DATA STRUCTURES | |
| -- ============================================================================ | |
| -- A Fact: asserts a value from a source with confidence + priority | |
| data Fact = Fact | |
| { value :: String | |
| , source :: String | |
| , timestamp :: UTCTime | |
| , confidence :: Double -- 0.0 to 1.0 | |
| , priority :: Int -- higher = wins conflicts | |
| } deriving (Show, Eq, Generic) | |
| -- A Sense: one interpretation of a concept | |
| data Sense = Sense | |
| { gloss :: String -- human-readable meaning | |
| , contextPred :: Maybe (Context -> Bool) -- predicate: "applies in this context?" | |
| , confidence :: Double -- how confident we are in this sense | |
| } deriving (Show, Eq) | |
| -- A Concept: word/term with multiple possible meanings | |
| data Concept = Concept | |
| { name :: String | |
| , senses :: [Sense] | |
| } deriving (Show, Eq) | |
| -- Context: a key-value map for disambiguating senses | |
| type Context = Map.Map String String | |
| -- A Rule: head :- body within a module | |
| data Rule = Rule | |
| { ruleHead :: String | |
| , ruleBody :: String | |
| , ruleModule :: String | |
| , rulePriority :: Int | |
| } deriving (Show, Eq) | |
| -- Module statistics: for tracking complexity | |
| data ModuleStats = ModuleStats | |
| { module :: String | |
| , ruleCount :: Int | |
| , maxRules :: Int -- hard limit (80) | |
| , lastUpdated :: UTCTime | |
| } deriving (Show, Eq) | |
| -- Result of hybrid query: symbolic proof vs embedding fallback | |
| data HybridResult a | |
| = Symbolic a Double -- proof + confidence (1.0 for logical proof) | |
| | Embedding a Double -- embedding retrieval + confidence | |
| | Failed | |
| deriving (Show, Eq) | |
| -- ============================================================================ | |
| -- 1. CONFLICT RESOLUTION | |
| -- Higher priority wins, then higher confidence | |
| -- ============================================================================ | |
| resolveConflict :: [Fact] -> Maybe Fact | |
| resolveConflict [] = Nothing | |
| resolveConflict fs = Just $ head $ sortBy cmp fs | |
| where | |
| cmp a b = compare (Down (priority a), Down (confidence a)) | |
| (Down (priority b), Down (confidence b)) | |
| -- Query the winning fact for a value | |
| getBelief :: [Fact] -> String -> Maybe (Fact, Double) | |
| getBelief facts val = | |
| case resolveConflict (filter (\f -> value f == val) facts) of | |
| Nothing -> Nothing | |
| Just f -> Just (f, confidence f) | |
| -- ============================================================================ | |
| -- 2. OUTDATED DETECTION | |
| -- Exponential decay: Conf(t) = Conf(0) * exp(-0.0001 * age_in_seconds) | |
| -- ============================================================================ | |
| -- Half-life: time for confidence to drop to 50% | |
| halfLifeSeconds :: Double | |
| halfLifeSeconds = log 2.0 / 0.0001 -- ~6931 seconds | |
| -- Compute decayed confidence at a given time | |
| decayedConfidence :: Fact -> UTCTime -> Double | |
| decayedConfidence f now = | |
| let age = realToFrac $ diffUTCTime now (timestamp f) :: Double | |
| decayed = confidence f * exp (-0.0001 * age) | |
| in decayed | |
| -- Check if a fact is outdated (confidence < 15%) | |
| isOutdated :: Fact -> UTCTime -> Bool | |
| isOutdated f now = decayedConfidence f now < 0.15 | |
| -- Prune outdated facts | |
| pruneOutdated :: [Fact] -> UTCTime -> [Fact] | |
| pruneOutdated facts now = filter (not . flip isOutdated now) facts | |
| -- ============================================================================ | |
| -- 3. AMBIGUOUS CONCEPTS | |
| -- ============================================================================ | |
| -- Register a concept with multiple senses | |
| createConcept :: String -> [String] -> Concept | |
| createConcept nm glosses = | |
| Concept nm [Sense gloss Nothing 1.0 | gloss <- glosses] | |
| -- Find senses that apply in a context | |
| disambiguate :: Concept -> Context -> [Sense] | |
| disambiguate c ctx = | |
| filter (\s -> case contextPred s of | |
| Nothing -> True | |
| Just pred -> pred ctx) | |
| (senses c) | |
| -- Get the best (highest confidence) sense in context | |
| bestSense :: Concept -> Context -> Maybe Sense | |
| bestSense c ctx = | |
| case sortOn (Down . confidence) (disambiguate c ctx) of | |
| [] -> Nothing | |
| (s:_) -> Just s | |
| -- ============================================================================ | |
| -- 4. MAINTAINABILITY GUARD | |
| -- Hard limit: 80 rules per module (prevents knowledge explosion) | |
| -- ============================================================================ | |
| -- Add a rule to a module (fails if limit exceeded) | |
| addRule :: ModuleStats -> Rule -> Either String ModuleStats | |
| addRule stats rule = | |
| if ruleCount stats >= maxRules stats | |
| then Left $ printf "Module %s has reached rule limit (%d rules)" | |
| (LTMS.module stats) | |
| (ruleCount stats) | |
| else Right $ stats { ruleCount = ruleCount stats + 1 } | |
| -- Suggest refactoring when module > 70% full | |
| needsRefactor :: ModuleStats -> Bool | |
| needsRefactor stats = | |
| let percent = fromIntegral (ruleCount stats) / fromIntegral (maxRules stats) :: Double | |
| in percent > 0.7 | |
| -- Module complexity percentage (0-100) | |
| complexityPercent :: ModuleStats -> Double | |
| complexityPercent stats = | |
| (fromIntegral (ruleCount stats) / fromIntegral (maxRules stats)) * 100.0 | |
| -- ============================================================================ | |
| -- 5. HYBRID / NON-RULE KNOWLEDGE | |
| -- Symbolic proof β Embedding fallback β Failure | |
| -- ============================================================================ | |
| -- Pure symbolic prover (stub: just checks if fact exists) | |
| proveSymbolic :: String -> [Fact] -> Maybe Fact | |
| proveSymbolic goal facts = | |
| case filter (\f -> value f == goal) facts of | |
| [] -> Nothing | |
| (f:_) -> Just f | |
| -- Embedding retrieval (stub: returns Nothing, can be extended to query vector DB) | |
| embeddingRetrieve :: String -> Maybe (String, Double) | |
| embeddingRetrieve _goal = Nothing -- placeholder | |
| -- Hybrid query: try symbolic first, then embedding | |
| hybridQuery :: String -> [Fact] -> HybridResult Fact | |
| hybridQuery goal facts = | |
| case proveSymbolic goal facts of | |
| Just f -> Symbolic f 1.0 | |
| Nothing -> case embeddingRetrieve goal of | |
| Just (_res, conf) -> Embedding (Fact goal "embedding" (unsafePerformIO getCurrentTime) conf 0) conf | |
| Nothing -> Failed | |
| -- ============================================================================ | |
| -- QUERY & ASSERTION API | |
| -- ============================================================================ | |
| -- Get all facts for a value (before conflict resolution) | |
| getAllFacts :: [Fact] -> String -> [Fact] | |
| getAllFacts facts val = filter (\f -> value f == val) facts | |
| -- Get facts from a specific source | |
| factsBySource :: [Fact] -> String -> [Fact] | |
| factsBySource facts src = filter (\f -> source f == src) facts | |
| -- ============================================================================ | |
| -- SUBSUMPTION & TAXONOMIES | |
| -- ============================================================================ | |
| -- Represent is-a relationships as facts | |
| data Subsumption = Subsumption | |
| { subSpecific :: String | |
| , subGeneral :: String | |
| , subConfidence :: Double | |
| } deriving (Show, Eq) | |
| -- Get all ancestors of a concept (transitive closure of is-a) | |
| ancestors :: [Subsumption] -> String -> Set.Set String | |
| ancestors subs concept = go concept Set.empty | |
| where | |
| go current visited | |
| | Set.member current visited = visited | |
| | otherwise = | |
| let visited' = Set.insert current visited | |
| parents = [subGeneral s | s <- subs, subSpecific s == current] | |
| in Set.unions $ visited' : [go p visited' | p <- parents] | |
| -- ============================================================================ | |
| -- INSPECTION & DEBUGGING | |
| -- ============================================================================ | |
| -- Pretty print a fact | |
| factSummary :: Fact -> String | |
| factSummary f = | |
| printf "Fact: %s\n Source: %s\n Confidence: %d%%\n Priority: %d" | |
| (value f) | |
| (source f) | |
| (round $ confidence f * 100 :: Int) | |
| (priority f) | |
| -- Pretty print a concept | |
| conceptSummary :: Concept -> String | |
| conceptSummary c = | |
| printf "Concept: %s\n Senses: %d" | |
| (name c) | |
| (length $ senses c) | |
| -- Module report | |
| moduleReport :: [ModuleStats] -> String | |
| moduleReport stats = | |
| unlines $ | |
| [ printf "%s: %d/%d rules (%.1f%%)" | |
| (LTMS.module s) (ruleCount s) (maxRules s) (complexityPercent s) | |
| | s <- stats | |
| ] ++ | |
| [ "" ] ++ | |
| [ printf "Needs refactor (>70%%): %s" | |
| (unwords [LTMS.module s | s <- stats, needsRefactor s]) | |
| ] | |
| -- ============================================================================ | |
| -- TESTS | |
| -- ============================================================================ | |
| runLTMSTests :: IO () | |
| runLTMSTests = do | |
| putStrLn "=== LTMS Tests (Haskell) ===\n" | |
| now <- getCurrentTime | |
| -- Test 1: Conflict resolution | |
| putStrLn "Test 1: Conflict resolution" | |
| let fact1 = Fact "color-car" "source-a" now 0.8 10 | |
| fact2 = Fact "color-car" "source-b" now 0.9 5 | |
| facts = [fact1, fact2] | |
| case resolveConflict facts of | |
| Just winner -> putStrLn $ "β Winner: " ++ source winner ++ " (confidence " ++ show (confidence winner) ++ ")" | |
| Nothing -> putStrLn "β No winner found" | |
| putStrLn "" | |
| -- Test 2: Outdated detection | |
| putStrLn "Test 2: Outdated detection" | |
| let oldTime = addUTCTime (-10 * 60) now -- 10 minutes ago | |
| oldFact = Fact "old-value" "old-source" oldTime 0.5 1 | |
| if isOutdated oldFact now | |
| then putStrLn "β Old fact marked as outdated" | |
| else putStrLn "β Old fact not detected" | |
| putStrLn "" | |
| -- Test 3: Concepts & disambiguation | |
| putStrLn "Test 3: Concepts & disambiguation" | |
| let bankConcept = createConcept "bank" ["financial institution", "river bank", "pile of snow"] | |
| putStrLn $ "β Bank concept has " ++ show (length $ senses bankConcept) ++ " senses" | |
| putStrLn "" | |
| -- Test 4: Module complexity | |
| putStrLn "Test 4: Module complexity guard" | |
| let stats = ModuleStats "main" 1 80 now | |
| putStrLn $ printf "β Main module: %.1f%% full" (complexityPercent stats) | |
| putStrLn "" | |
| -- Test 5: Hybrid query | |
| putStrLn "Test 5: Hybrid query with fallback" | |
| let skyFact = Fact "sky-color" "observation" now 0.95 100 | |
| facts' = [skyFact] | |
| case hybridQuery "sky-color" facts' of | |
| Symbolic f _ -> putStrLn $ "β Query result: " ++ value f ++ " (symbolic)" | |
| Embedding f _ -> putStrLn $ "β Query result: " ++ value f ++ " (embedding)" | |
| Failed -> putStrLn "β Query failed" | |
| putStrLn "" | |
| putStrLn "=== LTMS Tests Complete ===\n" | |
| -- Helper to get current time for tests | |
| unsafePerformIO :: IO a -> a | |
| unsafePerformIO = System.IO.Unsafe.unsafePerformIO | |