opencog / atomspace

The OpenCog (hyper-)graph database and graph rewriting system
https://wiki.opencog.org/w/AtomSpace
Other
818 stars 232 forks source link

Flexible transient execution #2752

Open linas opened 4 years ago

linas commented 4 years ago

The scheme bindings (and the python bindings, too, I guess) have a certain core subset of functions that are very commonly used, and should be converted to Atomese. For example,

(cog-incoming-set (SomeAtom))

could be written as

(cog-execute! (IncomingOf (SomeAtom)))

This is "a good thing" as it reduces the amount of custom scheme (or python) code needed -- the cog-execute! becomes the one place to do all the work.

The "bad thing" is that this implies that (IncomingOf (SomeAtom)) is a valid Atom, to be stored in the AtomSpace. It is a bit of a waste to store it -- it clogs up RAM, when the "typical" user probably just wanted to get the incoming set, and nothing more. This can be solved by inventing a new cog-execute-transient! function, that works like so:

(cog-execute-transient! (SomeExecutableAtom (SomeOtherAtom)))

It will create an instance of SomeExecutableAtom, then run it (passing in SomeOtherAtom as an argument) and then return the result as a LinkValue (per issue #2530) The SomeExecutableAtom will NOT be placed in any AtomSpace! Thus, it disappears right after being used.

This is particularly desirable for things like the cogserver, and atomspace-to-atomspace communications, where we just want to run some commands remotely, and get answers back (see, for example both https://github.com/opencog/atomspace-cog and also see https://github.com/opencog/atomspace/blob/master/opencog/persist/sexpr/Commands.h )

linas commented 4 years ago

Pretty much all of the commands in https://github.com/opencog/atomspace/blob/master/opencog/persist/sexpr/Commands.h can be converted to atomese. Here's a quick sketch.

(cog-incoming-set (Atom))
 ->
(cog-execute! (IncomingOf  (Atom)))

The IncomingOfLink should maybe(?) be a type of JoinLink

(cog-incoming-by-type " + Sexpr::encode_atom(h)
      + " '" + nameserver().getTypeName(t) + ")\n";
->
(cog-execute! (IncomingOf (Atom) (TypeNode 'type)))

For a general fetch...

(cog-get-atoms 'Node #t)   ;; or #f for no subtyes
->
(cog-execute! (Join??? (TypeNode 'type)))
(cog-execute! (JoinNotSubtype (TypeNode 'type)))

Some kind of JoinLink. Maybe existing JoinLink does this already?

(cog-keys->alist (Atom))
->
(cog-execute! (KeysOf (Atom))

Can this be more join-link like ...??

(cog-value (Atom) (Key))
->
(cog-execute! (ValueOf (Atom) (Key))

All of these suffer from the same two problems:

So maybe the performance tradeoff is not that big a deal?

ditto

(cog-set-values!  (Atom) ...) -> (SetValueOf ...)
(cog-set-tv!  (Atom) ...)

(cog-node 'Type + string)
->
(cog-execute! (Exists .. yuck !!!!)
linas commented 1 year ago

SetValue and SetTV were implemented in #2540 (before this issue was raised)

linas commented 1 year ago

So this is mostly about a flexibility vs. performance tradeoff. Just how much of a performance hit is there? It might be minor.

The other tricky part is that the ProxyNode's key off the built-in callbacks in the BackingStore, and in the StorageNode API, and this blurs some of that. We already have FetchValueOf and StoreValueLinkand this set could be broadend. All this suggests that the StorageNode API can be replaced by a suitable collection of BlahBlahOfLink that "do the desired thing", whatever that thing is, instead of adding yet-another callback into BackingStore.h ... ?

Can this work? It's a pretty major redesign...