OverviewFilesCommitsIssuesDocsReleasesPeers

hypercore-kb / opencog-kb / language-learning / chatbot / test-matrix-learner.scm

181 lines · scm ref:
;
; test-matrix-learner.scm - Test the matrix-based learner
;
; Same 7-layer test as test-selflearn.scm but using atomspace-matrix-learner.scm
;

(use-modules (opencog))
(use-modules (ice-9 rdelim))
(use-modules (ice-9 format))

(primitive-load "atomspace-matrix-learner.scm")

;; Load knowledge files (tracks as manual observations)
(define (load-knowledge filename)
  (display (format #f "Loading ~a...\n" filename))
  (let ((port (open-input-file filename))
        (count 0))
    (let loop ((line (read-line port)))
      (if (eof-object? line)
          (begin (close-port port)
                 (display (format #f "  Processed ~a lines\n" count)))
          (begin
            (let ((trimmed (string-trim-both line)))
              (unless (or (string-null? trimmed)
                          (string-prefix? "#" trimmed))
                (process-text-manual! trimmed)
                (set! count (+ count 1))))
            (loop (read-line port)))))))

;; ═══════════════════════════════════════════════════════════════════
;; LAYER TESTS
;; ═══════════════════════════════════════════════════════════════════

(define (test-layer-1)
  "Layer 1: Counting"
  (let ((words (length (get-all-words)))
        (pairs (length (*pair-stars* 'get-all-elts))))
    (display (format #f "  Words: ~a  Pairs: ~a\n" words pairs))
    (display (format #f "  Bootstrap cost: ~a manual observations\n" *manual-observations*))
    (and (> words 0) (> pairs 0))))

(define (test-layer-2)
  "Layer 2: Association - MI computed via matrix module"
  (let* ((test-words '("keypair" "anproto" "grep" "atomspace"))
         (results (filter-map
                    (lambda (w)
                      (let ((assocs (get-associations w 3)))
                        (and (not (null? assocs))
                             (cons w (map cdr assocs)))))
                    test-words)))
    (for-each
      (lambda (r)
        (display (format #f "  ~a → ~a\n" (car r) (string-join (cdr r) ", "))))
      results)
    (display (format #f "  Bootstrap cost: ~a manual observations\n" *manual-observations*))
    (not (null? results))))

(define (test-layer-3)
  "Layer 3: Structure - discovered relations"
  (let ((evals (length (cog-get-atoms 'EvaluationLink #t))))
    (display (format #f "  EvaluationLinks: ~a\n" evals))
    (for-each
      (lambda (w)
        (let ((contains (safe-string-list (query-contains w))))
          (when (not (null? contains))
            (display (format #f "  ~a contains: ~a\n" w (string-join contains ", "))))))
      '("atomspace" "keypair" "anproto" "message" "signature"))
    (display (format #f "  Bootstrap cost: ~a manual observations\n" *manual-observations*))
    (> evals 0)))

(define (test-layer-4)
  "Layer 4: Response"
  (let ((questions '("what is keypair" "what is anproto" "what is atomspace"))
        (pass #t))
    (for-each
      (lambda (q)
        (let ((answer (respond q)))
          (display (format #f "  Q: ~a\n  A: ~a\n" q answer))
          (when (string-prefix? "I don't know" answer)
            (set! pass #f))))
      questions)
    (display (format #f "  Bootstrap cost: ~a manual observations\n" *manual-observations*))
    pass))

(define (test-layer-5)
  "Layer 5: Self-awareness"
  (let ((self-questions '("what is grep" "what is atomspace" "what is wirecore"))
        (pass #t))
    (for-each
      (lambda (q)
        (let ((answer (respond q)))
          (display (format #f "  Q: ~a\n  A: ~a\n" q answer))
          (when (string-prefix? "I don't know" answer)
            (set! pass #f))))
      self-questions)
    (display (format #f "  Bootstrap cost: ~a manual observations\n" *manual-observations*))
    pass))

(define (test-layer-6)
  "Layer 6: Tool reasoning"
  (let ((test-words '("keypair" "signature" "signing" "verify"))
        (plans-formed 0))
    (for-each
      (lambda (w)
        (display (format #f "  Reasoning about '~a':\n" w))
        (let ((plan (reason-search-plan w)))
          (if plan
              (begin
                (display (format #f "    Plan: ~a\n" (assoc-ref plan 'reasoning)))
                (set! plans-formed (+ plans-formed 1)))
              (display "    BLOCKED - cannot form plan\n"))))
      test-words)
    (display (format #f "  Plans formed: ~a/~a\n" plans-formed (length test-words)))
    (display (format #f "  Bootstrap cost: ~a manual observations\n" *manual-observations*))
    (> plans-formed 0)))

;; ═══════════════════════════════════════════════════════════════════
;; MAIN
;; ═══════════════════════════════════════════════════════════════════

(define (run-matrix-test)
  (display "\n")
  (display "════════════════════════════════════════════════════════════\n")
  (display "  MATRIX LEARNER TEST: 7 Layers (opencog matrix module)\n")
  (display "════════════════════════════════════════════════════════════\n\n")

  ;; Bootstrap
  (display "BOOTSTRAP: Loading manual knowledge\n")
  (load-knowledge "data/self-knowledge.txt")
  (load-knowledge "data/anproto-knowledge.txt")

  ;; Batch MI computation (the matrix way)
  (display "\nCOMPUTING MI (batch)...\n")
  (recompute-mi!)

  ;; Structure discovery
  (display "\nDISCOVERING STRUCTURES...\n")
  (discover-all-structures!)

  (display (format #f "\n~a\n" (show-stats)))

  ;; Test each layer
  (let ((results '()))
    (define (run-layer n name test-fn)
      (display (format #f "\n── Layer ~a: ~a ──\n" n name))
      (let ((pass (test-fn)))
        (set! results (cons (list n name pass) results))
        (display (format #f "  Result: ~a\n" (if pass "PASS" "FAIL")))))

    (run-layer 1 "Counting" test-layer-1)
    (run-layer 2 "Association" test-layer-2)
    (run-layer 3 "Structure" test-layer-3)
    (run-layer 4 "Response" test-layer-4)
    (run-layer 5 "Self-awareness" test-layer-5)
    (run-layer 6 "Tool reasoning" test-layer-6)

    ;; Summary
    (display "\n════════════════════════════════════════════════════════════\n")
    (display "  MATRIX LEARNER TEST SUMMARY\n")
    (display "════════════════════════════════════════════════════════════\n\n")

    (for-each
      (lambda (r)
        (display (format #f "  Layer ~a (~a): ~a\n"
                         (car r) (cadr r)
                         (if (caddr r) "PASS" "FAIL"))))
      (reverse results))

    (display (format #f "\n  Total bootstrap cost: ~a manual observations\n" *manual-observations*))
    (display (format #f "\n  AtomSpace:\n"))
    (display (format #f "    ConceptNodes:    ~a\n" (length (cog-get-atoms 'ConceptNode #t))))
    (display (format #f "    EdgeLinks:       ~a\n" (length (cog-get-atoms 'EdgeLink #t))))
    (display (format #f "    EvaluationLinks: ~a\n" (length (cog-get-atoms 'EvaluationLink #t))))
    (display (format #f "    Total words:     ~a\n" (length (get-all-words))))

    (display "\n════════════════════════════════════════════════════════════\n")
    (display "  END\n")
    (display "════════════════════════════════════════════════════════════\n")))

(run-matrix-test)