OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-learn / scm / attic / cluster / cset-merge.scm

182 lines · scm ref:
;
; cset-merge.scm
;
; Merge connectors into classes of connectors -  merge connector sets.
;
; Copyright (c) 2017, 2018, 2021 Linas Vepstas
;
; ---------------------------------------------------------------------
; OVERVIEW
; --------
; The merging of words into word-classes proceeds in two parts. The
; first part is reviewed in `gram-classification.scm` and proceeds by
; comparing words to see if they share similar sets of sections. If they
; do, then the words can be judged to be similar, and merged into a word
; class.  The second part, reviewed here, is to merge connector
; sequences, so that connectors are made from word classes, instead of
; of individual words.
;
; Before any merging, a single section on a single word has the
; general form
;
;     Section
;         WordNode "foo"
;         ConnectorSeq
;             Connector
;                WordNode "bar"
;                ConnectorDir "+"
;             Connector
;                ....
;
; The goal of connector-set merging (aka disjunct-merging) is to
; replace the WordNode's in a Connector by WordClassNode's, and
; thence merge two similar ConnectorSeq's into one.
;
; Based on the analysis in the diary (Language Learning Diary - Part
; Two, subsection "Connector merging" (circa March 2021)) it appears
; that connector merging is commutative with section merging, in that
; if it has been decided that two words should be merged, then merging
; both sections and shapes (and later using the shapes to reconstruct
; sections) gives the same result as merging the connectors, directly.
; If only a fraction is merged, then the same fraction should be applied
; to the connectors, as well.
;
; The core idea is that the decision to merge is carried out elsewhere,
; and the only task remaining is to actually carry out the merge,
; transfering counts, or a fraction of the counts, as determined by
; the decision maker. If this is done, then merge results appear to
; always be self-consistent, thanks to the above-mentioned commutativity
; property.
;
; (An earlier version of this file discussed four different merge
; strategies that were not sel-consistent. That discussion has been
; removed).
;
; Worked example
; --------------
; Two connector sequences can be merged if and only if each one contains
; one of the connectors to be merged, and if all of the other connectors
; are the same.
;
; Let `P: Q+ & R+` be short-hand notation for
;
;     Section
;         WordNode "P"
;         ConnectorSeq
;             Connector
;                WordNode "Q"
;                ConnectorDir "+"
;             Connector
;                WordNode "R"
;                ConnectorDir "+"
;
; Suppose the decision-making process determines that words `S` and `Q`
; can be merged.  Then `P: Q+ & R+` can be merged with `P: S+ & R+`
; because these contain the words in question, and because the conector
; directions agree, and all the other connectors (i.e. `R+`) are
; identical. If it has been determined that only a percentage of `S`
; is to be merged, then that percentage should be applied to the counts
; on the sections, as well.
;
; Note that there are actually two distinct merge tasks: one to be
; performed on Sections, and another on CrossSections.
;
; ---------------------------------------------------------------------

(use-modules (srfi srfi-1))
(use-modules (opencog) (opencog sheaf) (opencog persist))

; ---------------------------------------------------------------
; XXX Incomplete, in development.

(define (matching-sequences CON-A CON-B)
"
  matching-sequences CON-A CON-B -- return matching ConnectorSeqs's

  Find all ConnectorSeq that contain CON-A, and check to see if an
  equivalent ConnectorSeq exists, containing CON-B. If so, create
  a scheme pair containing both. Return a list of these matching pairs.
"
	(filter-map
		(lambda (ASEQ)
			; Is there an equivalent seq with B instead of A?
			(define bseq
				(cog-link 'ConnectorSeq
					(map
						(lambda (CON) (if (equal? CON-A CON) CON-B CON))
						(cog-outgoing-set ASEQ))))
			(if (nil? bseq) #f (cons ASEQ bseq)))

		; All 'ConnectorSeq containing A
		(cog-incoming-by-type CON-A 'ConnectorSeq)))

(define (matching-sections CON-A CON-B)
"
  matching-sections CON-A CON-B -- return matching Sections

  Find all Sections that contain CON-A, and check to see if an
  equivalent Section exists, containing CON-B. If so, create
  a scheme pair containing both. Return a list of these matching pairs.
"
	(concatenate! (map
		(lambda (PR)
			; The two matching sequences.
			(define sequ-a (car PR))
			(define sequ-b (cdr PR))

			; If a Section contains ConnectorSeq A, see if there's
			; an equivalent section containing ConnectorSeq B.
			(filter-map
				(lambda (A-SEC)
					(define b-sec (cog-link 'Section (gar A-SEC) sequ-b))
					(if (nil? b-sec) #f (cons A-SEC b-sec)))
				(cog-incoming-by-type sequ-a 'Section)))

		; A list of matching sequences that contain connectors A and B.
		(matching-sequences CON-A CON-B)))
)


; ---------------------------------------------------------------
; Fetch from storage (load into RAM) all words that appear as members
; of one of the provided word-classes. Return the list of words.
;
; CLS-LST should be a list of word-classes.
;
; In most cases, this is not strictly necessary, as the usual case is
; that all words and word-classes are already in RAM.
;
; XXX this is maybe-dead code, its only used by `fetch-mergable-sections`
; below, which is not used anywhere...
;
(define (fetch-class-words CLS-LST)

	; Return a list without duplicates.
	(delete-dup-atoms
		(concatenate!
			; Loop over all WordClassNodes
			(map
				; This lambda returns a list of words.
				(lambda (CLS)  ; CLS is a WordClasNode
					(fetch-incoming-by-type CLS 'MemberLink)
					; map converts list of MemberLinks into list of words.
					(map
						; MEMB is a MemberLink; the zeroth atom in
						; the MemberLink is the WordNode.
						(lambda (MEMB) (cog-outgoing-atom MEMB 0))
						(cog-incoming-by-type CLS 'MemberLink)))
				CLS-LST)))
)


; ---------------------------------------------------------------
; Example usage
;
; (define cls-lst (cog-get-atoms 'WordClassNode))
; (fetch-mergable-sections cls-lst)
; (get-classified-words) ; verify that they were fetched.
;
; (define wrd (Word "chance"))
; (define secs (cog-incoming-by-type wrd 'Section))
; (define maybe (get-all-sections-in-classes wrd))