Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(PLN) Truth Value updates #2532

Closed
linas opened this issue Mar 27, 2020 · 13 comments
Closed

(PLN) Truth Value updates #2532

linas opened this issue Mar 27, 2020 · 13 comments

Comments

@linas
Copy link
Member

linas commented Mar 27, 2020

This issue lists several ideas for altering how truth values are updated. It's aimed at PLN, one of the current primary consumers of truth values. The goals are (1) simpler, easier-to-use (2) improved performance.

A review of different ways of updating TV's.

GroundedSchema
The first: the current PLN usage, which uses GroundedSchemaNodes as a key work-horse. A typical rule is explicitly declarative:

Bind
     Variables ...
      Body ...
      ExecutionOutput
           GroundedSchema "scm: ..."
           List
                 Target
                  Inputs ...

The GroundedSchema is some scheme snippet that grabs the TV's from the Inputs..., performs some simple arithmetic, and updates the TV on Target. (Its not always "simple arithmetic", but many of the base-cases are.)

This works, and is relatively easy to use. The biggest disadvantage is speed: for simple arithmetic, the CPU-time spent entering/exiting scm is approx 10x greater than the CPU time spent computing the arithmetic formulas. But is this an actual real-world bottleneck for PLN, or is it a drop in the bucket? @ngeiswei ? Is it safe to assume it mostly doesn't matter, and most PLN overhead is lost on chaining, unification, etc.?

PredicateFormula
The PredicateFormulaLink, used with DefinedPredicate allows arithmetic formulas to be specified in Atomese. See examples for a working example. In short, this looks like

Evaluation
    DefinedPredicate  "some name"
    List
        Inputs ...

Where the DefinePredicate is attached to a formula written in Atomese, i.e. with PlusLink, TimesLink, etc. The advantages of this is that the CPU overhead of the GroundedSchema is avoided. The disadvantage is that there is no way to specify a "target": only the TV on the EvaluationLink is modified.

(There are a few "theoretical advantages" to this form: since the formulas are in Atomese, they could be "easily" imported and/or learned: e.g. from MOSES. Also, in principle, atomese formulas could be byte-compiled for performance)

Enhanced ExecutionOutput (proposal)
The goal is to get past the limitation of the previous example. This would alter ExecutionOutput to allow the use of a GPN and or other predicate. The form would be:

ExecutionOutput
    GroundedPredicate "scm: some-formula"
    List
           Target      ;; The atom whose TV will be modified
           Inputs ...  ;; the atoms that will be passed to the formula

Here, only the inputs are passed to the GPN, not the target. The GPN returns some TV, and that TV is inserted into the target. Note that the target is NOT passed to the formula (which seems like the right thing to do, right?)

In place of the GPN, one could use a DefinedPredicate or a PredicateFormula.

Coding this up should be very easy; maybe only a few dozen lines of code.

UpdateTVLink & FormulaTruthValue (to be invented)
The FormulaTruthValue would be a value, that inherits from TruthValue, but instead of storing static numbers, it would instead result in a call to some formula, whenever the strength/confidence was asked for. The UpdateTVLink would be used to install the formula onto an atom.

Example installation of a formula

UpdateTVLink
       Target   ; the atom whose TV will be dynamic
       GroundedPredicate "scm: some-formula"
       Inputs ...

The above has to be done only once. After being done, that formula will be forever-more attached to the Target atom. Accessing the TV on the target atom will cause the formula to be evaluated. Thus, a trivial example usage:

(cog-tv Target)

Normally, cog-tv just grabs the numeric value of the TV on target. For this new case, the attached formula is evaluated.

In place of the GPN, we could have a DefinePredicate, or a PredicateFormula.

The FormulaTruthValue is more-or-less invisible to the end-user; its just a device to hold the predicates, and the inputs.

This is also pretty easy to implement. So @ngeiswei is this useful? Could you use it?

The "could be fun" thing here is that, after installing a bunch of these updaters, they would chain, so you could just poll one atom, and the whole network of formulas feeding that atom get propagated, updated. (Some extra effort would be needed to make sure that we did only lazy evaluation, and had some kind of caching system, to avoid excessive evaluations.)

Generic Update Value
Like the above, but for generic values.

@linas
Copy link
Member Author

linas commented Mar 27, 2020

p.s. after a very short amount of thinking about this, I'm tempted to implement both proposals, mostly because both are really pretty easy, and do not requires a whole bunch of code. I'm starting to conclude that any kind of easy changes that do not require a lot of work, that are limited in scope, are always "good". Its the human-designer version of evolutionary hill-climbing. Always take the easiest path, until you hit a dead-end.

@ngeiswei
Copy link
Member

@linas said

Enhanced ExecutionOutput: ... Note that the target is NOT passed to the formula (which seems like the right thing to do, right?)

Actually the target needs to be passed so that it can be unified with the premises of the inference tree it is trying to expand. It doesn't necessarily need to be the first argument of the formula, but it needs to be somewhere. The target can be thought as the output type of a functional programming language function, and the premises the input types.

@ngeiswei
Copy link
Member

The FormulaTruthValue is an interesting idea. As long as the process of back propagating the TV update can be done in a highly controlled manner as to avoid combinatorial explosion.

@ngeiswei
Copy link
Member

I think, what I just need to get rid of GSN, is a SetTVLink, the equivalent of cog-set-tv!, to trivially translate the Scheme formula into an Atomese formula.

@linas
Copy link
Member Author

linas commented Mar 30, 2020

OK. So syntax of SetTVLink could be identical to UpdateTVLink as described above, right? The difference between the two would then be that SetTVLink evaluates the formula, and installs the resulting constants as the TV, while UpdateTVLink updates the TV every time it is asked for.

(Implementation-wise, in the C++ code, though, they're nearly identical; so I'll implement both. Yes, the Update version has a combinatorial-explosion on back-propagation problem; it risks getting stuck in inf loops. There are three solutions: (1) tell the end-user to not do that. (2) tell the end-user to design formulas that are explosion/loop resistant (3) provide some kind of generic back-propagation-control mechanism for all atomspace users. I have some extremely vague ideas about (3). But that belongs in a separate issue.).

I dislike the names "Set" and "Update", need better names. Maybe "Set" and "Dynamic" ...? "Set" and "Poll" ? "Set" and "Pull"?

Or maybe InstallTVLink instead of SetTVLink? Because the installed formula can be used more than once? (i.e. the TV is updated every time you call cog-evaluate on it?) Or maybe EvaluateTVLink? Invitation to anyone who is reading this: please take some time and imagine some good names for these two things...

@ngeiswei
Copy link
Member

I think SetTVLink is perfectly fine.

For update... ProbeTVLink, PokeTVLink, for what I can think of.

@linas
Copy link
Member Author

linas commented Apr 4, 2020

@ngeiswei I'm almost done implementing the first part of this, and it's clear that SetTVLink and/or SetValueLink looks "almost" like the old ExecutionLink, in that

   (SetTV
      (Concept "bar")
      (DefinedPredicate "has a reddish color")
      (List (Concept "A") (Concept "B"))))

takes, as input, A and B, applies the function "has reddish color", and then places the result onto "bar". This isn't quite what ExecutionLink was supposed to do, but its similar ... and its not what EvaluationLink was supposed to do, its more of a "generalized EvaluationLink" ... do any of Ben's writings anticipate anything like this?

The SetTVLink name is OK, but .... I have a nagging feeling that there is some other, better name somewhere out there.

@linas
Copy link
Member Author

linas commented Apr 4, 2020

On a slightly related note: this works as expected:

(cog-execute!
   (Put
      (Lambda (Variable "$X")
         (Plus (Variable "$X") (Number 1)))
      (Number 1 2 3 4 5)))

but this does not:

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

(cog-execute!
   (Put
      (Lambda (Variable "$X")
         (Plus (Variable "$X") (Number 1)))
      (ValueOf foo key)))

It seems reasonable that the second form should work...

@linas
Copy link
Member Author

linas commented Apr 6, 2020

... Planning to rename SetTV to UpdateTV later today ... that is because the TV is updated, whenever execute is called. This is in contrast to InstallTV which will actually copy the TV itself.. as opposed to copying the values. (there's no difference, if everything is a SimpleTV; but different TV types needs .. more) ... or not. This is very confusing. The alternative is to create a new Atom type for each TV type...

@linas linas mentioned this issue Apr 7, 2020
@linas
Copy link
Member Author

linas commented Apr 7, 2020

Pull req #2543 implements the other half of this -- the concept of dynamically-updatable TV's.

Examples can be found in /examples/atomspace/flows.scm and /examples/atomspace/flow-formulas.scm

TODO:

  • - write wiki pages
  • - write a blog entry for the whole thing.

The wiki pages are:

The blog entry is here: https://blog.opencog.org/2020/04/08/value-flows

@linas linas self-assigned this Apr 7, 2020
@linas
Copy link
Member Author

linas commented Apr 8, 2020

Closing. I wrote a blog entry for this whole thing, here: https://blog.opencog.org/2020/04/08/value-flows/

@linas linas closed this as completed Apr 8, 2020
@bgoertzel
Copy link
Contributor

bgoertzel commented Apr 9, 2020 via email

@linas
Copy link
Member Author

linas commented Apr 9, 2020

Really interesting stuff that I've been wanting for a long time -- thanks Linas!

Ben, -- Welcome. New features are chicken-and-egg ... without demand, they don't get created, without use, they don't get enhanced. Encourage use and demand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants