| … | … | @@ -9,11 +9,14 @@ |
| 9 | 9 | ; This source blocks if there's nothing to be read; else it |
| 10 | 10 | ; returns the next PhraseNode. The SRFI's call this a generator. |
| 11 | 11 | ; For now, see `sensory.scm` module and example. |
| 12 | ; It uses a FileReadNode to loop voer a text file. |
| 12 | 13 | ; 2) (Optional) Some way to split one source into multiple sources. |
| 13 | 14 | ; Maybe this: |
| 14 | 15 | ; https://wiki.opencog.org/w/PromiseLink#Multiplex_Example |
| 15 | 16 | ; but what happens if the readers don't both read ??? |
| 16 | 17 | ; 3) A Filter that takes above and increments pair counts. |
| 18 | ; Done. Its non-atomic, but so what. Perhaps we can live with |
| 19 | ; that, given that sampliing is statistical, anyway. |
| 17 | 20 | ; 4) Execution control. There are two choices: |
| 18 | 21 | ; Pull: infinite loop polls on promise. Source blocks if |
| 19 | 22 | ; no input. |
| … | … | @@ -22,22 +25,32 @@ |
| 22 | 25 | ; Right now, the general infrastructure supports Pull naturally. |
| 23 | 26 | ; There aren't any push demos. |
| 24 | 27 | ; Attention control is easier with Pull. |
| 28 | ; |
| 29 | ; The below demos this design. |
| 30 | ; |
| 31 | ; Open issues: |
| 32 | ; *) Need to call cog-execute! in a loop to loop over whole file. |
| 33 | ; Would be nicer to not have to do this. |
| 34 | ; *) End-of-file results in a throw from parser. This is a side |
| 35 | ; effect. We need some proper end-of-file handling. |
| 25 | 36 | |
| 26 | | |
| 27 | | (define text-blob "this is just a bunch of words you know") |
| 28 | | |
| 29 | | |
| 37 | ; -------------------------------------------------------------- |
| 30 | 38 | ; Return a text parser that counts edges on a stream. The |
| 31 | 39 | ; `txt-stream` must be an Atom that can serve as a source of text. |
| 32 | 40 | ; Typically, `txt-stream` will be |
| 33 | 41 | ; (ValueOf (Concept "some atom") (Predicate "some key")) |
| 34 | 42 | ; and the Value there will be a LinkStream from some file or |
| 35 | 43 | ; other text source. |
| 44 | ; |
| 45 | ; These sets up a processing pipeline in Atomese, and returns that |
| 46 | ; pipeline. The actual parsing all happens in C++ code, not in scheme |
| 47 | ; code. The scheme here is just to glue the pipeline together. |
| 36 | 48 | (define (make-parser txt-stream) |
| 37 | | ; From inside to out: |
| 38 | | ; LGParseBonds tokenizes a sentence, and then parses it. |
| 39 | | ; The PureExecLink makes sure that the parsing is done in a sub-AtomSpace |
| 40 | | ; so that the main AtomSpace is not garbaged up. |
| 49 | ; |
| 50 | ; Pipeline steps, from inside to out: |
| 51 | ; * LGParseBonds tokenizes a sentence, and then parses it. |
| 52 | ; * The PureExecLink makes sure that the parsing is done in a |
| 53 | ; sub-AtomSpace so that the main AtomSpace is not garbaged up. |
| 41 | 54 | ; |
| 42 | 55 | ; The result of parsing is a list of pairs. First item in a pair is |
| 43 | 56 | ; the list of words in the sentence; the second is a list of the edges. |
| … | … | @@ -46,8 +59,13 @@ |
| 46 | 59 | ; (LinkValue (Word "this") (Word "is") (Word "a") (Word "test")) |
| 47 | 60 | ; (LinkValue (Edge ...) (Edge ...) ...)) |
| 48 | 61 | ; |
| 49 | | ; The Filter matches this, so that (Variable "$x") is equated with the |
| 50 | | ; list of Edges. |
| 62 | ; The outer Filter matches this, so that (Glob "$edge-list") is |
| 63 | ; set to the LinkValue of Edges. |
| 64 | ; |
| 65 | ; The inner Filter loops over the list of edges, and invokes a small |
| 66 | ; pipe to increment the count on each edge. |
| 67 | ; |
| 68 | ; The counter is a non-atomic pipe of (SetValue (Plus 1 (GetValue))) |
| 51 | 69 | ; |
| 52 | 70 | (define NUML (Number 4)) |
| 53 | 71 | (define DICT (LgDict "any")) |
| … | … | @@ -86,9 +104,9 @@ |
| 86 | 104 | (Type 'LinkValue) ; the word-list |
| 87 | 105 | (LinkSignature ; the edge-list |
| 88 | 106 | (Type 'LinkValue) ; edge-list wrapper |
| 89 | | (Glob "$x"))) ; all of the edges |
| 90 | | ; Rewrite |
| 91 | | (count-edges (Glob "$x")) |
| 107 | (Glob "$edge-list"))) ; all of the edges |
| 108 | ; Pipeline to apply to the resulting match. |
| 109 | (count-edges (Glob "$edge-list")) |
| 92 | 110 | ) |
| 93 | 111 | (parseli phrali))) |
| 94 | 112 | |
| … | … | @@ -96,8 +114,10 @@ |
| 96 | 114 | (filty txt-stream) |
| 97 | 115 | ) |
| 98 | 116 | |
| 99 | | ; Parse a string. |
| 117 | ; Demo wrapper: Parse a string. |
| 100 | 118 | (define (obs-txt PLAIN-TEXT) |
| 119 | |
| 120 | ; We don't need to create this over and over; once is enough. |
| 101 | 121 | (define txt-stream (ValueOf (Concept "foo") (Predicate "some place"))) |
| 102 | 122 | (define parser (make-parser txt-stream)) |
| 103 | 123 | |
| … | … | @@ -110,8 +130,10 @@ |
| 110 | 130 | (cog-extract-recursive! phrali) |
| 111 | 131 | ) |
| 112 | 132 | |
| 113 | | ; Parse contents of a file. |
| 133 | ; Demo wrapper: Parse contents of a file. |
| 114 | 134 | (define (obs-file FILE-NAME) |
| 135 | |
| 136 | ; We don't need to create this over and over; once is enough. |
| 115 | 137 | (define txt-stream (ValueOf (Concept "foo") (Predicate "some place"))) |
| 116 | 138 | (define parser (make-parser txt-stream)) |
| 117 | 139 | |
| … | … | @@ -148,7 +170,7 @@ |
| 148 | 170 | ; risks deadlock. |
| 149 | 171 | ; |
| 150 | 172 | ; cog-update-value calls |
| 151 | | ; asp->increment_count(h, key, fvp->value())); |
| 173 | ; Ideally, call asp->increment_count(h, key, fvp->value())); |
| 152 | 174 | |
| 153 | 175 | ; Below works but is a non-atomic increment. |
| 154 | 176 | (define ed (Edge (Bond "ANY") (List (Word "words") (Word "know")))) |
| … | … | @@ -158,7 +180,7 @@ |
| 158 | 180 | (Plus (Number 0 0 1) |
| 159 | 181 | (FloatValueOf ed (Predicate "count") (Number 0 0 0)))))) |
| 160 | 182 | |
| 161 | | ; Lets work on file-access now. |
| 183 | ; Here's a demo of what file-access looks like. |
| 162 | 184 | (cog-execute! |
| 163 | 185 | (SetValue (Concept "foo") (Predicate "some place") |
| 164 | 186 | (FileRead "file:///tmp/demo.txt"))) |
| … | … | @@ -170,7 +192,7 @@ |
| 170 | 192 | ; (cog-execute! (LgParseBonds txt-stream-gen DICT NUML)) |
| 171 | 193 | |
| 172 | 194 | ; (load "count-agent.scm") |
| 173 | | ; (obs-txt text-blob) |
| 195 | ; (obs-txt "Some kind of sentence to process, hell yeah!") |
| 174 | 196 | ; (obs-file "/tmp/demo.txt") |
| 175 | 197 | ; (cog-report-counts) |
| 176 | 198 | ; (cog-get-atoms 'WordNode) |