FormulaStream
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 FormulaStream provides future FloatValues.
- The FormulaTruthValue provides future SimpleTruthValues; these are just vectors of length 2.
- The FutureStream provides generic future values, wrapped as LinkValues.
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.