OverviewFilesCommitsIssuesDocsReleasesPeers

hypercore-kb / opencog-kb / language-learning / chatbot / vagueness.scm

201 lines · scm ref:
;
; vagueness.scm - Uncertainty tracking
;
; Vagueness = 1 / (1 + evidence)
;
; HIGH vagueness → uncertain, need more information
; LOW vagueness → confident, can proceed
;
; Tracks:
;   - Per-word vagueness (how well do we know this word?)
;   - Per-topic vagueness (how well do we know this area?)
;   - Overall vagueness (what's our weakest knowledge?)
;

(use-modules (opencog))
(use-modules (ice-9 format))
(use-modules (srfi srfi-1))

;; ═══════════════════════════════════════════════════════════════════
;; VAGUENESS COMPUTATION
;; ═══════════════════════════════════════════════════════════════════

(define (compute-vagueness evidence-count)
  "Vagueness = 1 / (1 + evidence)"
  (/ 1.0 (+ 1.0 evidence-count)))

(define (vagueness-level v)
  "Categorize vagueness level"
  (cond
    ((< v 0.1) 'CONFIDENT)
    ((< v 0.3) 'MODERATE)
    ((< v 0.5) 'UNCERTAIN)
    (else 'VERY-UNCERTAIN)))

;; ═══════════════════════════════════════════════════════════════════
;; WORD VAGUENESS
;; ═══════════════════════════════════════════════════════════════════

(define (word-vagueness word)
  "How uncertain are we about this word?"
  (let ((node (find-word word)))
    (if (not node)
        1.0  ; Unknown word = maximum vagueness
        (let* ((word-count (get-word-count node))
               (assoc-count (length (layer1-associations word 10)))
               (cluster (layer2-get-cluster word))
               ;; Evidence from multiple layers
               (layer1-evidence word-count)
               (layer2-evidence (if cluster 5 0))  ; Bonus for being clustered
               (total-evidence (+ layer1-evidence layer2-evidence assoc-count)))
          (compute-vagueness total-evidence)))))

(define (show-word-vagueness word)
  "Display vagueness analysis for a word"
  (let* ((v (word-vagueness word))
         (level (vagueness-level v))
         (node (find-word word)))
    (if (not node)
        (format #f "'~a': UNKNOWN (vagueness=1.0)" word)
        (let ((count (get-word-count node))
              (assocs (length (layer1-associations word 10)))
              (cluster (layer2-get-cluster word)))
          (format #f "'~a': ~a (v=~,2f)\n  seen: ~a times\n  associations: ~a\n  cluster: ~a"
                  word level v count assocs (or cluster "none"))))))

;; ═══════════════════════════════════════════════════════════════════
;; CLUSTER/TOPIC VAGUENESS
;; ═══════════════════════════════════════════════════════════════════

(define (cluster-vagueness cluster-id)
  "How uncertain are we about this cluster?"
  (let ((members (layer2-get-members cluster-id)))
    (if (null? members)
        1.0
        (let* ((member-vagueness (map word-vagueness members))
               (avg-vagueness (/ (apply + member-vagueness) (length members)))
               ;; More members = more confident
               (size-bonus (compute-vagueness (length members))))
          (* avg-vagueness size-bonus)))))

;; ═══════════════════════════════════════════════════════════════════
;; OVERALL KNOWLEDGE MAP
;; ═══════════════════════════════════════════════════════════════════

(define (knowledge-map)
  "Map of what we know and don't know"
  (let* ((words (get-all-words))
         (word-v (map (lambda (w) (cons w (word-vagueness w))) words))
         (sorted (sort word-v (lambda (a b) (> (cdr a) (cdr b))))))
    sorted))

(define (most-uncertain n)
  "Get N most uncertain words"
  (take (knowledge-map) (min n (length (get-all-words)))))

(define (most-certain n)
  "Get N most certain words"
  (take (reverse (knowledge-map)) (min n (length (get-all-words)))))

(define (show-knowledge-gaps)
  "Display what we're most uncertain about"
  (let ((uncertain (most-uncertain 10)))
    (if (null? uncertain)
        "No knowledge yet"
        (string-join
          (cons "Most uncertain (highest vagueness):"
                (map (lambda (p)
                       (format #f "  ~a: ~,2f (~a)"
                               (car p) (cdr p) (vagueness-level (cdr p))))
                     uncertain))
          "\n"))))

(define (show-knowledge-strengths)
  "Display what we're most confident about"
  (let ((certain (most-certain 10)))
    (if (null? certain)
        "No knowledge yet"
        (string-join
          (cons "Most confident (lowest vagueness):"
                (map (lambda (p)
                       (format #f "  ~a: ~,2f (~a)"
                               (car p) (cdr p) (vagueness-level (cdr p))))
                     certain))
          "\n"))))

;; ═══════════════════════════════════════════════════════════════════
;; OVERALL VAGUENESS
;; ═══════════════════════════════════════════════════════════════════

(define (overall-vagueness)
  "Average vagueness across all knowledge"
  (let ((words (get-all-words)))
    (if (null? words)
        1.0
        (let ((vagueness-sum (apply + (map word-vagueness words))))
          (/ vagueness-sum (length words))))))

(define (show-overall-vagueness)
  "Display overall knowledge state"
  (let* ((words (get-all-words))
         (total (length words))
         (v (overall-vagueness))
         (confident (length (filter (lambda (w) (< (word-vagueness w) 0.3)) words)))
         (uncertain (length (filter (lambda (w) (> (word-vagueness w) 0.5)) words))))
    (format #f "Overall: ~,2f (~a)\n  ~a words known\n  ~a confident (<0.3)\n  ~a uncertain (>0.5)"
            v (vagueness-level v) total confident uncertain)))

;; ═══════════════════════════════════════════════════════════════════
;; QUERY GENERATION (what should we learn next?)
;; ═══════════════════════════════════════════════════════════════════

(define (suggest-learning-targets)
  "Suggest what to learn next based on vagueness"
  (let ((uncertain (most-uncertain 5)))
    (if (null? uncertain)
        "No suggestions - need initial data"
        (string-join
          (cons "Consider learning more about:"
                (map (lambda (p)
                       (let* ((word (car p))
                              (cluster (layer2-get-cluster word)))
                         (format #f "  '~a' - ~a"
                                 word
                                 (if cluster
                                     (format #f "in cluster ~a, needs more associations" cluster)
                                     "not yet clustered"))))
                     uncertain))
          "\n"))))

;; ═══════════════════════════════════════════════════════════════════
;; SENTENCE VAGUENESS
;; ═══════════════════════════════════════════════════════════════════

(define (sentence-vagueness text)
  "How well do we understand this sentence?"
  (let* ((words (tokenize text))
         (vagueness-scores (map word-vagueness words)))
    (if (null? vagueness-scores)
        1.0
        ;; Use max vagueness - we're only as good as our weakest understanding
        (apply max vagueness-scores))))

(define (analyze-sentence text)
  "Analyze understanding of a sentence"
  (let* ((words (tokenize text))
         (word-analysis
           (map (lambda (w)
                  (cons w (word-vagueness w)))
                words))
         (overall (sentence-vagueness text))
         (weakest (if (null? word-analysis)
                      '("" . 1.0)
                      (car (sort word-analysis (lambda (a b) (> (cdr a) (cdr b))))))))
    (format #f "Sentence vagueness: ~,2f (~a)\nWeakest: '~a' (~,2f)\nWords: ~a"
            overall (vagueness-level overall)
            (car weakest) (cdr weakest)
            (string-join
              (map (lambda (p) (format #f "~a:~,2f" (car p) (cdr p)))
                   word-analysis)
              " "))))