FormulaStream

From OpenCog

The FormulaStream is a kind of Value that holds a numeric formula within it. Whenever it is polled for it's current numeric value, that formula is automatically executed to obtain those numbers. Functionally, it always returns a FloatValue as the result. FormulaStreams are used to implement arithmetic on dynamically-changing values.

It is part of a trio that provides futures:

The PromiseLink can be used to wrap any executable Atoms such that the value returned by execution is wrapped by a FormulaStream. This is useful to convert a static function (for example, a GroundedSchema or DefinedProcedure) into a dynamically-updating function.

A frozen sample of the stream can be obtained with the StreamValueOfLink. This Link will take a single sample from the stream, and convert it to a FloatValue, thus "freezing" the sampled value forever.

Example

Example usage:

(FormulaStream (TimeLink))

should return

(FormulaStream
   (TimeLink)
   ; Current sample:
   ; (FloatValue 1669175345.451965)
)

Printed at the bottom is the current value obtained from executing TimeLink. That this is indeed the actual value being generated can be seen by getting the value directly:

(define fut (FormulaStream (TimeLink)))

(cog-value->list fut)
(cog-value-ref fut 0)
(cog-value-ref fut 0)
(cog-value-ref fut 0)

Note that the value updates with each access. Note that there is no need to call cog-execute! to get the updated value: the execution to get the update happens automatically, upon access. This is the basic different between static Values and Streams -- Streams are always "live" and flowing.

Multiple Values

The FormulaStream can create vectors of multiple values. For example, a window that is 60 seconds wide:

(define time-window
    (FormulaStream
        (Minus (Time) (Number 30))
        (Time)
        (Plus (Time) (Number 30))))

This window updates with each access.

(cog-value->list time-window)
(cog-value->list time-window)

should print

(1669238302.096752 1669238332.096764 1669238362.0968)

The arguments can be wrapped with a ListLink for convenience:

(define time-alt
    (FormulaStream
        (ListLink
            (Minus (Time) (Number 30))
            (Time)
            (Plus (Time) (Number 30)))))

This does exactly the same thing as above.

Example

The following defines a FormulaStream that computes a new FloatValue based on the FloatValues on (Concept "foo") located at the key (Predicate "some key"). Basically, it just takes whatever FloatValue can be found there, and adds ten to each vector component.

(FormulaStream
    (Plus
        (Number 10)
        (FloatValueOf (Concept "foo") (Predicate "some key"))))

For example:

(cog-set-value! (Concept "foo") (Predicate "some key")
    (FloatValue 1 2 3 4 5))

(define plu-ten
   (FormulaStream
       (Plus
          (Number 10)
          (FloatValueOf (Concept "foo") (Predicate "some key")))))

plu-ten
(cog-value->list plu-ten)

should print

(FloatValue 11 12 13 14 15)

A more detailed exploration can be found in the /examples/atomspace/flow-formulas.scm file.

See also