-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathbond-links.scm
182 lines (157 loc) · 5.69 KB
/
bond-links.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
;
; bond-links.scm
;
; Associate LG link names with word-pairs.
;
; Copyright (c) 2023 Linas Vepstas
;
; ---------------------------------------------------------------------
; OVERVIEW
; --------
; This file provide the "matrix-object" API that associates word-pairs
; with LG link names. The association takes the form
;
; (Edge (Bond "XYZ") (List (Word ...) (Word ...)))
;
; This association is needed for two reasons:
; 1) When LG is asked to perform parses using Atomese data, it needs to
; be provided with LG-style connector names. But that is not the
; native format used during counting in the AtomSpace. Thus, there
; there needs to be a way of translating word-pairs (or word-class
; pairs) into LG connector names.
; 2) We want to keep track of how often each LG link was used in some
; parse. For that, we store counts on the above structure.
;
; There are several issues that arise here.
; A) The LG `dict-atomese` C++ code already does this association, in
; C++, and there's no need for this object. Yet, to use this object,
; it needs to be kept in sync with the C++ code there. Caveat emptor.
; B) The above structure is not quite a classic "matrix" structure, and
; so doesn't quite fit into the conventional matrix API. The
; structure is actually a tensor. We do a force-fit, here, and make
; it work. You've been warned.
;
; ---------------------------------------------------------------------
;
(use-modules (srfi srfi-1))
(use-modules (opencog))
(use-modules (opencog persist))
(use-modules (opencog matrix))
(define-public (make-bond-link-api)
"
make-bond-link-api -- Associate word-pairs and LG connector names.
The matrix consists of (word,word) pairs and the corresponding LG
connector name. Matrix elements have the form
(Edge (Bond \"XYZ\") (List (Word ...) (Word ...)))
where XYZ is the Link Grammar connector (link) name.
For a detailed description, see the `bond-links.scm` file.
"
(define any-left (AnyNode "bond-left"))
(define any-right (AnyNode "bond-right"))
(define (get-left-type) (Type 'WordNode))
(define (get-right-type) (Type 'WordNode))
(define (get-pair-type) (Type 'EdgeLink))
; We do NOT want ANY bonds!
(define bany (BondNode "ANY"))
; Get the pair, if it exists. Reject pairs with (BondNode "ANY")
; edges between them. They are not one of us.
(define (get-pair L-ATOM R-ATOM)
(define pr #f)
(define wp (cog-link 'List L-ATOM R-ATOM))
(if (nil? wp) wp
(for-each
(lambda (EDGE)
(if (not (equal? bany (gar EDGE)))
(set! pr EDGE)))
(cog-incoming-by-type wp 'EdgeLink)))
pr)
; Given integer, return link string. Mapping is
; 0 -> A
; 1 -> B
; 25 -> Z
; 26 -> AA
; 27 -> AB
; This mapping is *identical* to that used in the link-grammar
; C++ code base, `link-names.cc` file, and needs to be kept in
; sync. Failure to do so will result in hard-to-debug errors.
(define (make-id-str nid lst)
; 65 is ASCII capital A
(if (> 0 nid)
(list->string lst)
(make-id-str (- (floor (/ nid 26)) 1)
(cons (integer->char (+ 65 (modulo nid 26))) lst))))
; Anchor where next ID is stored. This location must be kept in
; sync with the link-grammar C++ code base, `link-names.cc` file.
(define idanch (Anchor "*-LG-issued-link-id-*"))
(define (issue-link)
(define nid (cog-count idanch))
(define linkstr (make-id-str nid '()))
(set! nid (+ 1 nid))
; (make-id-str 1064) is "ANY" and we must avoid that.
(if (equal? nid 1064) (set! nid (+ 1 nid)))
; Save and store. May need it again, some other day.
(cog-set-tv! idanch (CountTruthValue 1 0 nid))
(store-atom idanch)
; Return the link string
linkstr)
; Create the pair, if it does not yet exist.
(define (make-pair L-ATOM R-ATOM)
(define pr (get-pair L-ATOM R-ATOM))
(if (not (nil? pr)) pr
(Edge (Bond (issue-link)) (ListLink L-ATOM R-ATOM))))
(define (get-left-element EDGE) (gadr EDGE))
(define (get-right-element EDGE) (gddr EDGE))
(define (get-left-wildcard WORD)
(Edge idanch (ListLink any-left WORD)))
(define (get-right-wildcard WORD)
(Edge idanch (ListLink WORD any-right)))
(define (get-wild-wild)
(Edge idanch (ListLink any-left any-right)))
; Fetch (from the database) all labelled edges.
(define (load-all-bonds)
(define mon (make-rate-monitor))
(fetch-atom idanch)
(load-atoms-of-type 'BondNode)
(for-each
(lambda (BOND)
(mon #f)
(fetch-incoming-by-type BOND 'EdgeLink))
(cog-get-atoms 'BondNode))
; Marginals are located on the anchor
(fetch-incoming-by-type idanch 'EdgeLink)
(mon "Loaded ~D edges in ~D secs; rate=~5F\n"))
(define (describe)
(display (procedure-property make-bond-link-api 'documentation)))
(define (store-aux) (store-atom idanch))
(define (provides meth)
(case meth
((store-aux) store-aux)
(else #f)
))
; Methods on the object
(lambda (message . args)
(apply (case message
((name) (lambda () "LG-Link - word-pair Association"))
((id) (lambda () "bond-link"))
((left-type) get-left-type)
((right-type) get-right-type)
((pair-type) get-pair-type)
((get-pair) get-pair)
((make-pair) make-pair)
((left-element) get-left-element)
((right-element) get-right-element)
((left-wildcard) get-left-wildcard)
((right-wildcard) get-right-wildcard)
((wild-wild) get-wild-wild)
((fetch-pairs) load-all-bonds)
((provides) provides)
((store-aux) store-aux)
((filters?) (lambda () #f))
((help) describe)
((describe) describe)
((obj) (lambda () "make-bond-link-api"))
((base) (lambda () #f))
(else (error "Bad method call on bond-link:" message)))
args))
)
; ---------------------------------------------------------------------