OverviewFilesCommitsIssuesDocsReleasesPeers

hypercore-kb / opencog-kb / language-learning / experiments / learn-demo.scm

118 lines · scm ref:
;
; learn-demo.scm -- Simple language learning demo
;
(use-modules (opencog) (opencog exec) (opencog sensory))
(use-modules (opencog lg))
(use-modules (srfi srfi-1))

(display "=== Language Learning Demo ===\n\n")

; Sample text to learn from
(define sample-text "
The cat sat on the mat.
The dog ran in the park.
A cat chased the dog.
The mat was on the floor.
A dog sat on the mat.
")

; Write to temp file
(call-with-output-file "/tmp/learn-text.txt"
  (lambda (port) (display sample-text port)))

(display "Sample text:\n")
(display sample-text)
(display "\n")

; Setup file reader
(define file-node (TextFile "file:///tmp/learn-text.txt"))
(cog-execute! (SetValue file-node (Predicate "*-open-*") (Type 'StringValue)))

; Create text stream
(cog-execute!
  (SetValue (Anchor "learn pipe") (Predicate "text source")
    (DontExec (ValueOf file-node (Predicate "*-stream-*")))))

(define txt-stream (ValueOf (Anchor "learn pipe") (Predicate "text source")))

; Parse with Link Grammar
(display "Parsing sentences with Link Grammar...\n\n")

(define parser
  (Filter
    (Rule
      (TypedVariable (Variable "$x") (Type 'StringStream))
      (Variable "$x")
      (LgParseBonds (Variable "$x") (LgDict "en") (Number 1)))
    txt-stream))

; Storage for word-pair counts
(define pair-counts (make-hash-table))

(define (count-pair w1 w2)
  (let* ((key (string-append w1 "|" w2))
         (current (hash-ref pair-counts key 0)))
    (hash-set! pair-counts key (+ current 1))))

; Extract word pairs from parse result
(define (extract-pairs result)
  (when (and result (not (null? result)))
    (let ((linkages (cog-value->list result)))
      (for-each
        (lambda (linkage)
          (when (and linkage (not (null? linkage)))
            (let ((parts (cog-value->list linkage)))
              (when (>= (length parts) 2)
                (let ((bonds-val (list-ref parts 1)))
                  (when bonds-val
                    (let ((bonds (cog-value->list bonds-val)))
                      (for-each
                        (lambda (bond)
                          (when (cog-atom? bond)
                            (let ((out (cog-outgoing-set bond)))
                              (when (>= (length out) 2)
                                (let ((word-list (list-ref out 1)))
                                  (when (cog-atom? word-list)
                                    (let ((words (cog-outgoing-set word-list)))
                                      (when (= (length words) 2)
                                        (let ((w1 (cog-name (car words)))
                                              (w2 (cog-name (cadr words))))
                                          (count-pair w1 w2))))))))))
                        bonds))))))))
        linkages))))

; Process 5 sentences
(display "Processing sentences:\n")
(do ((i 0 (+ i 1)))
    ((>= i 5))
  (let ((result (cog-execute! parser)))
    (format #t "  Sentence ~a parsed\n" (+ i 1))
    (extract-pairs result)))

; Display results
(display "\n=== Word Pair Counts (from Link Grammar bonds) ===\n\n")

; Convert to list and sort
(define pair-list (hash-map->list cons pair-counts))
(define sorted-pairs
  (sort pair-list (lambda (a b) (> (cdr a) (cdr b)))))

; Show top pairs
(format #t "Found ~a unique word pairs\n\n" (length sorted-pairs))
(display "Top word pairs (sorted by frequency):\n")
(for-each
  (lambda (pair)
    (let* ((words (string-split (car pair) #\|))
           (w1 (car words))
           (w2 (cadr words))
           (count (cdr pair)))
      (format #t "  ~15a -- ~15a : ~a\n" w1 w2 count)))
  (take sorted-pairs (min 20 (length sorted-pairs))))

(display "\n=== Interpretation ===\n")
(display "High-frequency pairs reveal grammatical patterns:\n")
(display "  - 'the' connects to nouns (cat, dog, mat, park, floor)\n")
(display "  - Subjects connect to verbs (cat-sat, dog-ran)\n")
(display "  - 'on' connects to 'the' and nouns\n")
(display "\nWith more text, MI computation reveals deeper structure.\n")