OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-agents commits / 811dfe5

Remove crud from the end of the example.
811dfe5cef684ec1c999bbcffda653475ffe0db9
by Linas Vepštas <linasvepstas@gmail.com> · 2024-05-03T13:29:44.000Z

Changed files (1) +6 -170

examples/pair-count.scm +6 -170
……@@ -259,7 +259,7 @@
259259;
260260; https://github.com/opencog/sensory/raw/master/examples/file-read.scm
261261;
262; Repeated here.
262; The last part of that demo is repeated here.
263263
264264; Opening the text stream will create a ValueStream. It needs to be
265265; placed where the parser can find it. Anywhere will do, as long as the
……@@ -284,174 +284,10 @@
284284; That's it. Now wire it all together:
285285(cog-execute! (edge-filter parse-stream edge-counter))
286286
287; --------------------------------------------------------------
288; Return a text parser that counts edges on a stream. The
289; `txt-stream` must be an Atom that can serve as a source of text.
290; Typically, `txt-stream` will be
291; (ValueOf (Concept "some atom") (Predicate "some key"))
292; and the Value there will be a LinkStream from some file or
293; other text source.
294;
295; These sets up a processing pipeline in Atomese, and returns that
296; pipeline. The actual parsing all happens in C++ code, not in scheme
297; code. The scheme here is just to glue the pipeline together.
298(define (make-parser txt-stream)
299 ;
300 ; Pipeline steps, from inside to out:
301 ; * LGParseBonds tokenizes a sentence, and then parses it.
302 ; * The PureExecLink makes sure that the parsing is done in a
303 ; sub-AtomSpace so that the main AtomSpace is not garbaged up.
304 ;
305 ; The result of parsing is a list of pairs. First item in a pair is
306 ; the list of words in the sentence; the second is a list of the edges.
307 ; Thus, each pair has the form
308 ; (LinkValue
309 ; (LinkValue (Word "this") (Word "is") (Word "a") (Word "test"))
310 ; (LinkValue (Edge ...) (Edge ...) ...))
311 ;
312 ; The outer Filter matches this, so that (Glob "$edge-list") is
313 ; set to the LinkValue of Edges.
314 ;
315 ; The inner Filter loops over the list of edges, and invokes a small
316 ; pipe to increment the count on each edge.
317 ;
318 ; The counter is a non-atomic pipe of (SetValue (Plus 1 (GetValue)))
319 ;
320 (define NUML (Number 4))
321 (define DICT (LgDict "any"))
322
323 ; Increment the count on one edge.
324 (define (incr-cnt edge)
325 (SetValue edge (Predicate "count")
326 (Plus (Number 0 0 1)
327 (FloatValueOf edge (Predicate "count") (FloatValueOf (Number 0 0 0))))))
328
329 ; Given a list (an Atomese LinkValue list) of parse results,
330 ; extract the edges and increment the count on them.
331 (define (count-edges parsed-stuff)
332 (Filter
333 (Rule
334 ; (Variable "$edge")
335 (TypedVariable (Variable "$edge") (Type 'Edge))
336 (Variable "$edge")
337 (incr-cnt (Variable "$edge")))
338 parsed-stuff))
339
340 ; Parse text in a private space.
341 (define (parseli phrali)
342 (PureExecLink (LgParseBonds phrali DICT NUML)))
343
344 ; Given an Atom `phrali` holding text to be parsed, get that text,
345 ; parse it, and increment the counts on the edges.
346 (define (filty phrali)
347 (Filter
348 (Rule
349 ; Type decl
350 (Glob "$x")
351 ; Match clause - one per parse.
352 (LinkSignature
353 (Type 'LinkValue) ; the wrapper for the pair
354 (Type 'LinkValue) ; the word-list
355 (LinkSignature ; the edge-list
356 (Type 'LinkValue) ; edge-list wrapper
357 (Glob "$edge-list"))) ; all of the edges
358 ; Pipeline to apply to the resulting match.
359 (count-edges (Glob "$edge-list"))
360 )
361 (parseli phrali)))
362
363 ; Return the parser.
364 (filty txt-stream)
365)
366
367; --------------------------------------------------------------
368; Demo wrapper showing how to use the above: Parse a string.
369; PLAIN-TEXT should be a scheme string.
370;
371; Verify this works as follows:
372; (obs-txt "this is a test")
373; (cog-report-counts)
374; Note the abundance of WordNodes listed in the report.
375; (cog-get-atoms 'WordNode)
376; Cleanup after use:
377; (for-each cog-extract-recursive! (cog-get-atoms 'WordNode))
378; (extract-type 'WordNode)
379(define (obs-txt PLAIN-TEXT)
380
381 ; We don't need to create this over and over; once is enough.
382 (define txt-stream (ValueOf (Concept "foo") (Predicate "some place")))
383 (define parser (make-parser txt-stream))
384
385 (define phrali (Phrase PLAIN-TEXT))
386 (cog-set-value! (Concept "foo") (Predicate "some place") phrali)
387
388 (cog-execute! parser)
389
390 ; Remove the phrase-link, return the list of edges.
391 (cog-set-value! (Concept "foo") (Predicate "some place") #f)
392 (cog-extract-recursive! phrali)
393)
287; Note the actual flow is different from the how this is written, above.
288; First, the parse stream flows to the edge-filter, and then the
289; edge-counter runs. Some twiddling about in scheme could straighten
290; this out into a "natural" direction, but there does not seem to be
291; much point to re-engineering this.
394292
395293; --------------------------------------------------------------
396; Demo wrapper: Parse contents of a file.
397(define (obs-file FILE-NAME)
398
399 ; We don't need to create this over and over; once is enough.
400 (define txt-stream (ValueOf (Concept "foo") (Predicate "some place")))
401 (define parser (make-parser txt-stream))
402
403 (define phrali (Open (Type 'TextFileStream)
404 (Sensory (string-append "file://" FILE-NAME))))
405
406 (cog-execute!
407 (SetValue (Concept "foo") (Predicate "some place") phrali))
408
409 ; Parse only first line of file:
410 ; (cog-execute! parser)
411
412 ; Loop over all lines.
413 (define (looper) (cog-execute! parser) (looper))
414
415 ; At end of file, exception will be thrown. Catch it.
416 (catch #t looper
417 (lambda (key . args) (format #t "The end ~A\n" key)))
418
419 (cog-extract-recursive! phrali)
420)
421
422; --------------------------
423; Issues.
424; Parses arrive as LinkValues. We want to apply a function to each.
425; How? Need:
426; 4) IncrementLink just like cog-inc-value!
427; or is it enough to do atomic lock?
428; Make SetValue exec under lock. ... easier said than done.
429; risks deadlock.
430;
431; cog-update-value calls
432; Ideally, call asp->increment_count(h, key, fvp->value()));
433
434; Below works but is a non-atomic increment.
435(define ed (Edge (Bond "ANY") (List (Word "words") (Word "know"))))
436(define (doinc)
437 (cog-execute!
438 (SetValue ed (Predicate "count")
439 (Plus (Number 0 0 1)
440 (FloatValueOf ed (Predicate "count") (Number 0 0 0))))))
441
442; Here's a demo of what file-access looks like.
443(cog-execute!
444 (SetValue (Concept "foo") (Predicate "some place")
445 (FileRead "file:///tmp/demo.txt")))
446
447; Wait ...
448(define txt-stream-gen
449 (ValueOf (Concept "foo") (Predicate "some place")))
450
451; (cog-execute! (LgParseBonds txt-stream-gen DICT NUML))
452
453; (load "count-agent.scm")
454; (obs-txt "Some kind of sentence to process, hell yeah!")
455; (obs-file "/tmp/demo.txt")
456; (cog-report-counts)
457; (cog-get-atoms 'WordNode)