OverviewFilesCommitsIssuesDocsReleasesPeers

hypercore-kb / opencog-kb / language-learning / layers / multilevel-disambiguation.scm

386 lines · scm ref:
;
; multilevel-disambiguation.scm
;
; Show multiple levels of structure working together,
; and demonstrate when disambiguation FAILS - indicating
; the need to SEARCH for more context or ASK for clarification.
;
; Key insight: Vagueness detection is itself valuable!
;
; ZERO HARDCODING: All evidence scores are COMPUTED from corpus
; statistics via PMI and cluster membership. No numbers are invented.
; Evidence dimensions emerge from the data, not from pre-labeling.
;

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

;; Load shared infrastructure
(load "../lib/counting.scm")

(display "═══════════════════════════════════════════════════════════════════\n")
(display "   MULTI-LEVEL DISAMBIGUATION & VAGUENESS DETECTION                \n")
(display "   (All evidence scores computed -- zero hardcoding)               \n")
(display "═══════════════════════════════════════════════════════════════════\n\n")

;; ═══════════════════════════════════════════════════════════════════
;; CORPUS: Build statistics from text
;; ═══════════════════════════════════════════════════════════════════

(display "Building corpus statistics...\n\n")

(define corpus '(
  ;; Financial bank contexts
  "the customer deposited money at the bank"
  "she withdrew cash from the bank account"
  "the bank approved the loan application"
  "he deposited the check at the bank"
  "the teller at the bank counted the money"
  "the bank charges interest on the loan"
  "she transferred funds from the bank"
  "the bank manager approved the deposit"

  ;; River bank contexts
  "the fisherman sat on the bank of the river"
  "the river eroded the sandy bank"
  "mud covered the bank along the river"
  "the duck swam to the bank"
  "trees grew on the river bank"
  "she walked along the bank by the water"
  "the bank was muddy after the flood"
  "he fished from the bank of the stream"

  ;; Animal/nature contexts
  "the penguin swam across the cold water"
  "penguins live near the ocean shore"
  "the penguin dove into the deep water"
  "the bird flew to the tree by the river"

  ;; Movement contexts
  "she walked to the store across the street"
  "he went to the office for the meeting"
  "they drove to the park near the lake"
  "the child ran home from school"

  ;; Additional mixed contexts
  "the bank building stood by the river"
  "money was deposited into the account"
  "the river flooded the surrounding area"
  "mud and sediment collected along the shore"
  "the fisherman cast his line into the water"
))

;; Compute all statistics
(define counts (count-cooccurrences corpus 2))
(define word-counts (car counts))
(define pair-counts (cdr counts))

;; Discover clusters
(define all-clusters
  (cluster-by-pmi-similarity word-counts pair-counts 0.10))
(define multi-clusters
  (filter (lambda (c) (> (length c) 1)) all-clusters))
(define named-clusters
  (name-clusters-by-medoid multi-clusters word-counts pair-counts))

(display "  Discovered clusters:\n\n")
(display-clusters named-clusters)
(newline)

;; ═══════════════════════════════════════════════════════════════════
;; DISAMBIGUATION FUNCTION
;; ═══════════════════════════════════════════════════════════════════

(define (disambiguate-and-show sentence)
  "Disambiguate 'bank' in a sentence, showing all computed evidence."
  (let* ((evidence (compute-frame-evidence sentence named-clusters
                                            word-counts pair-counts))
         (vagueness (compute-vagueness evidence))
         (context-words (filter (lambda (w) (not (string=? w "bank")))
                                (tokenize-content sentence))))

    ;; Show per-word PMI evidence
    (display "  WORD-LEVEL EVIDENCE (PMI with 'bank'):\n")
    (for-each
      (lambda (w)
        (let ((pmi (compute-pmi word-counts pair-counts w "bank")))
          (when (> pmi -999.0)
            (format #t "    PMI(~a, bank) = ~,2f\n" w pmi))))
      context-words)
    (newline)

    ;; Show per-word cluster membership
    (display "  CLUSTER-LEVEL EVIDENCE (which cluster each context word activates):\n")
    (for-each
      (lambda (w)
        (for-each
          (lambda (nc)
            (when (member w (cdr nc) string=?)
              (format #t "    '~a' -> [~a]-cluster\n" w (car nc))))
          named-clusters))
      context-words)
    (newline)

    ;; Show aggregate cluster evidence
    (display "  AGGREGATE EVIDENCE (sum of PMIs per cluster):\n")
    (display-evidence evidence)
    (newline)

    ;; Show result
    (let* ((best (if (null? evidence) (cons "UNKNOWN" 0.0) (car evidence)))
           (total-ev (apply + (map (lambda (e) (abs (cdr e))) evidence))))

      (format #t "  TOTAL EVIDENCE: ~,2f\n" total-ev)
      (format #t "  VAGUENESS: ~,3f\n\n" vagueness)

      (display "  ┌────────────────────────────────────────────────────────────┐\n")
      (cond
        ((< vagueness 0.1)
         (format #t "  │  RESULT: bank = [~a] sense" (car best))
         (display (make-string (max 1 (- 35 (string-length (car best)))) #\space))
         (display "│\n")
         (display "  │  CONFIDENCE: HIGH (low vagueness, strong evidence)       │\n")
         (display "  │  ACTION: Accept interpretation                           │\n"))
        ((< vagueness 0.3)
         (format #t "  │  RESULT: bank = [~a] sense (moderate)" (car best))
         (display (make-string (max 1 (- 26 (string-length (car best)))) #\space))
         (display "│\n")
         (display "  │  CONFIDENCE: MODERATE                                    │\n")
         (display "  │  ACTION: Accept but flag uncertainty                     │\n"))
        (else
         (display "  │  VAGUENESS DETECTED                                      │\n")
         (display "  │  CONFIDENCE: LOW (insufficient evidence)                 │\n")
         (display "  │  ACTION: SEARCH for more context or ASK for clarification│\n")))
      (display "  └────────────────────────────────────────────────────────────┘\n\n"))))

;; ═══════════════════════════════════════════════════════════════════
;; EXAMPLE 1: High confidence disambiguation
;; ═══════════════════════════════════════════════════════════════════

(display "╔═══════════════════════════════════════════════════════════════════╗\n")
(display "║  EXAMPLE 1: 'I deposited money at the bank by the river'         ║\n")
(display "╚═══════════════════════════════════════════════════════════════════╝\n\n")

(disambiguate-and-show "deposited money at the bank by the river")

;; ═══════════════════════════════════════════════════════════════════
;; EXAMPLE 2: Context helps
;; ═══════════════════════════════════════════════════════════════════

(display "╔═══════════════════════════════════════════════════════════════════╗\n")
(display "║  EXAMPLE 2: 'The penguin swam to the bank'                       ║\n")
(display "╚═══════════════════════════════════════════════════════════════════╝\n\n")

(disambiguate-and-show "the penguin swam to the bank")

;; ═══════════════════════════════════════════════════════════════════
;; EXAMPLE 3: LOW confidence - genuine ambiguity
;; ═══════════════════════════════════════════════════════════════════

(display "╔═══════════════════════════════════════════════════════════════════╗\n")
(display "║  EXAMPLE 3: 'She walked to the bank'                             ║\n")
(display "╚═══════════════════════════════════════════════════════════════════╝\n\n")

(disambiguate-and-show "she walked to the bank")

;; ═══════════════════════════════════════════════════════════════════
;; EXAMPLE 4: Even more ambiguous
;; ═══════════════════════════════════════════════════════════════════

(display "╔═══════════════════════════════════════════════════════════════════╗\n")
(display "║  EXAMPLE 4: 'I went to the bank'                                 ║\n")
(display "╚═══════════════════════════════════════════════════════════════════╝\n\n")

(disambiguate-and-show "went to the bank")

;; ═══════════════════════════════════════════════════════════════════
;; THE VAGUENESS METRIC
;; ═══════════════════════════════════════════════════════════════════

(display "═══════════════════════════════════════════════════════════════════\n")
(display "THE VAGUENESS METRIC\n")
(display "═══════════════════════════════════════════════════════════════════\n\n")

(display "Define: VAGUENESS = 1 - |best - second| / (|best| + |second|)\n\n")

(display "  0.0 = maximally clear (large gap between best and second)\n")
(display "  1.0 = maximally vague (top clusters tied)\n\n")

;; Compute vagueness for all examples
(display "  Sentence                                    | Evidence | Vagueness\n")
(display "  ────────────────────────────────────────────┼──────────┼──────────\n")

(for-each
  (lambda (sent)
    (let* ((ev (compute-frame-evidence sent named-clusters word-counts pair-counts))
           (total-ev (apply + (map (lambda (e) (abs (cdr e))) ev)))
           (vagueness (compute-vagueness ev)))
      (format #t "  ~43a | ~8,2f | ~,3f~a\n"
              sent total-ev vagueness
              (cond ((< vagueness 0.1) " (low)")
                    ((< vagueness 0.3) " (moderate)")
                    (else " (high)")))))
  '("deposited money at the bank by the river"
    "the penguin swam to the bank"
    "the fisherman sat on the bank"
    "she walked to the bank"
    "went to the bank"
    "the bank"))

(newline)

(display "INTERPRETATION:\n")
(display "  Vagueness < 0.1  ->  Disambiguate confidently\n")
(display "  Vagueness 0.1-0.3 -> Disambiguate but flag uncertainty\n")
(display "  Vagueness > 0.3  ->  SEARCH for context or ASK\n\n")

;; ═══════════════════════════════════════════════════════════════════
;; CONTEXT SEARCH STRATEGY
;; ═══════════════════════════════════════════════════════════════════

(display "═══════════════════════════════════════════════════════════════════\n")
(display "CONTEXT SEARCH STRATEGY\n")
(display "═══════════════════════════════════════════════════════════════════\n\n")

(display "When VAGUENESS > threshold, SEARCH for disambiguating context:\n\n")

(display "STRATEGY 1: Look at surrounding sentences\n")
(display "───────────────────────────────────────────\n")
(display "  Expand the context window. More words = more cluster evidence.\n\n")

(display "  Example: 'I went to the bank' alone is vague.\n")
(display "  With context: 'The fisherman sat by the river. I went to the bank.'\n\n")

;; Demonstrate context expansion
(display "  Disambiguation of 'went to the bank' ALONE:\n")
(let* ((ev (compute-frame-evidence "went to the bank" named-clusters
                                    word-counts pair-counts))
       (vagueness (compute-vagueness ev)))
  (display "    ")
  (display-evidence ev)
  (format #t "    Vagueness: ~,3f\n\n" vagueness))

(display "  With expanded context 'fisherman sat the river went to the bank':\n")
(let* ((ev (compute-frame-evidence
             "fisherman sat the river went to the bank"
             named-clusters word-counts pair-counts))
       (vagueness (compute-vagueness ev)))
  (display "    ")
  (display-evidence ev)
  (format #t "    Vagueness: ~,3f\n\n" vagueness))

(display "  Context words ('fisherman', 'river') provide cluster evidence\n")
(display "  that resolves the ambiguity.\n\n")

(display "STRATEGY 2: Frame-activating words from nearby sentences\n")
(display "───────────────────────────────────────────────────────────\n")
(display "  Search [-3 sentences, +3 sentences] for words with high PMI\n")
(display "  to any cluster that contains 'bank'.\n")
(display "  These words provide indirect disambiguation evidence.\n\n")

(display "STRATEGY 3: Discourse-level cluster patterns\n")
(display "──────────────────────────────────────────────\n")
(display "  If the document's dominant cluster is [money]-cluster,\n")
(display "  then 'bank' in that document is likely financial.\n")
(display "  Computed by summing cluster evidence across all sentences.\n\n")

(display "STRATEGY 4: If still ambiguous, generate clarifying question\n")
(display "───────────────────────────────────────────────────────────────\n")
(display "  Template: 'When you said [ambiguous word], did you mean\n")
(display "             [cluster-A medoid]-sense or [cluster-B medoid]-sense?'\n\n")

;; ═══════════════════════════════════════════════════════════════════
;; EXAMPLE: Context resolves ambiguity
;; ═══════════════════════════════════════════════════════════════════

(display "═══════════════════════════════════════════════════════════════════\n")
(display "EXAMPLE: Context Search in Action (COMPUTED)\n")
(display "═══════════════════════════════════════════════════════════════════\n\n")

(display "INPUT: 'I went to the bank.'\n\n")

(let* ((ev-alone (compute-frame-evidence "went to the bank"
                                          named-clusters word-counts pair-counts))
       (vag-alone (compute-vagueness ev-alone)))
  (format #t "  Vagueness = ~,3f -> SEARCH CONTEXT\n\n" vag-alone))

;; Context sentences that might surround "I went to the bank"
(define context-sentences '(
  "the fisherman sat on the bank of the river"
  "went to the bank"
  "the duck swam to the bank"
))

(display "CONTEXT FOUND (surrounding sentences from corpus):\n")
(for-each
  (lambda (s) (format #t "  '~a'\n" s))
  context-sentences)
(newline)

;; Assemble expanded context from the actual context sentences
(define expanded-context
  (string-join context-sentences " "))

(display "EXPANDED EVIDENCE (combining sentence + context):\n\n")
(let* ((ev (compute-frame-evidence expanded-context named-clusters
                                    word-counts pair-counts))
       (vagueness (compute-vagueness ev))
       (best (if (null? ev) (cons "UNKNOWN" 0.0) (car ev))))

  (display-evidence ev)
  (newline)

  (display "  ┌────────────────────────────────────────────────────────────┐\n")
  (format #t "  │  RESULT: bank = [~a] sense" (car best))
  (display (make-string (max 1 (- 35 (string-length (car best)))) #\space))
  (display "│\n")
  (cond
    ((< vagueness 0.1)
     (display "  │  CONFIDENCE: HIGH (context resolved the ambiguity)        │\n"))
    ((< vagueness 0.3)
     (display "  │  CONFIDENCE: MODERATE (context helped but some ambiguity) │\n"))
    (else
     (display "  │  CONFIDENCE: LOW (context did not resolve ambiguity)      │\n")))
  (format #t "  │  Vagueness: ~,3f" vagueness)
  (display (make-string (max 1 (- 43 (string-length (format #f "~,3f" vagueness)))) #\space))
  (display "│\n")
  (display "  │                                                            │\n")
  (display "  │  Context words from surrounding sentences provided         │\n")
  (display "  │  cluster evidence that the sentence alone lacked.          │\n")
  (display "  └────────────────────────────────────────────────────────────┘\n\n"))

;; ═══════════════════════════════════════════════════════════════════
;; THE KEY INSIGHT
;; ═══════════════════════════════════════════════════════════════════

(display "═══════════════════════════════════════════════════════════════════\n")
(display "THE KEY INSIGHT: Vagueness Detection is Valuable\n")
(display "═══════════════════════════════════════════════════════════════════\n\n")

(display "  ┌────────────────────────────────────────────────────────────┐\n")
(display "  │                                                            │\n")
(display "  │  Some sentences ARE genuinely ambiguous.                  │\n")
(display "  │                                                            │\n")
(display "  │  This is not a failure of the system -                    │\n")
(display "  │  it's INFORMATION about the sentence.                     │\n")
(display "  │                                                            │\n")
(display "  │  A good system should:                                    │\n")
(display "  │    1. DETECT when disambiguation fails (high vagueness)   │\n")
(display "  │    2. QUANTIFY the uncertainty (vagueness score)         │\n")
(display "  │    3. SEARCH for additional context when needed           │\n")
(display "  │    4. ASK for clarification when search fails             │\n")
(display "  │    5. MAINTAIN multiple interpretations when appropriate  │\n")
(display "  │                                                            │\n")
(display "  │  All evidence scores in this demo are COMPUTED.           │\n")
(display "  │  No numbers were invented. Every value comes from         │\n")
(display "  │  PMI computation on the corpus.                           │\n")
(display "  │                                                            │\n")
(display "  └────────────────────────────────────────────────────────────┘\n\n")

(display "This is what humans do! When we hear 'I went to the bank',\n")
(display "we don't pick one meaning - we WAIT for more context.\n")
(display "If context never comes, we ASK: 'Which bank?'\n\n")

(display "The system should do the same.\n\n")