opencog / atomspace

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

Implement ComposeLink #573

Closed ngeiswei closed 6 years ago

ngeiswei commented 8 years ago

Implement https://en.wikipedia.org/wiki/Function_composition in Atomese (I mean as Atomese primitive, although it could be implemented in Atomese as well!).

This can simplify some atomese code. For instance the following (defined here http://wiki.opencog.org/wikihome/index.php/Event_boundary_recognition#INVOKING_EVENT_BOUNDARY_RECOGNITION_CODE_VIA_GSN.E2.80.99S)

DefineLink
    DefinedSchemaNode “getRobotCurrentSeriesPredictabilityDiscontinuitySeries”
    LambdaLink
        ListLink
            TypedVariableLink
                VariableNode "$T"
                TypeNode "TimeNode"
            TypedVariableLink
                VariableNode "$N"
                TypeNode "NumberNode"
        ExecutionOutputLink
            GroundedSchemaNode “py:calculateDiscontinuities”
            ExecutionOutputLink 
                DefinedSchemaNode “getRobotCurrentSeriesPredictability”
                ListLink
                    VariableNode "$T"
                    VariableNode "$N"

could be replaced by

DefineLink
    DefinedSchemaNode “getRobotCurrentSeriesPredictabilityDiscontinuitySeries”
    ComposeLink
        GroundedSchemaNode “py:calculateDiscontinuities”
        DefinedSchemaNode “getRobotCurrentSeriesPredictability”
linas commented 8 years ago

ComposeLink already exists, its called PutLink ... it works, it does type-checking. It only performs the composition, it does not execute or evaluate the result of the composition.

linas commented 8 years ago

http://wiki.opencog.org/w/PutLink

linas commented 8 years ago

It was called Put instead of Compose because ... I dunno. It was thought of as "opposite of get" during the mailing list discussions. I am implementing MapLink right now, which is kind-of "un-compose". Here: #568

ngeiswei commented 8 years ago

I've added a wiki page about it http://wiki.opencog.org/wikihome/index.php/CompositeLink

linas commented 8 years ago

OK, right. Compose is used to define new functions. Put is used to beta-reduce. The distinction is somewhat subtle, though. I wonder if we should maybe extend PutLink so that, when the arguments are functions with variables in them, the result would be a composition of the two. Not clear if this over-complextifies the PutLink...

ngeiswei commented 8 years ago

I positively think that would over-complexify PutLink.

linas commented 8 years ago

I dunno. Maybe, maybe not. Conceptually, they are both doing exactly the same thing. The current PutLink implementation only allows closed sentences, while your ComposeLink definition only allows open sentences. The only difference between open and closed is that one is grounded and one is not, and I imagine that there will be ambiguous situations, where you might not be sure if you are working with a grounded form or an open form, and you want a link type that is usable with either case, that will work no matter what.

ngeiswei commented 8 years ago

@linas I don't think they are the same thing. Let's use some minimal example using GSNs f and g.

Composition (in math):

(g . f)(x)

Corresponding application (in math):

g(f(x))

In Atomese the composite function would look like:

ComposeLink
   GSN g
   GSN f

and if one applies argument A to it, it would look like:

ExecutionOutputLink
   ComposeLink
      GSN g
      GSN f
   Node A

While the application version would look like:

LambdaLink
   VariableNode "$X"
   ExecutionOutputLink
      GSN g
      ExecutionOutputLink
         GSN f
         VariableNode "$X"

And if one applies argument A to it, it would like:

   ExecutionOutputLink
      GSN g
      ExecutionOutputLink
         GSN f
         Node A

Here I've made a simplification and could drop the LambdaLink, but that's not the point.

So I'm curious how you would use PutLink to define (g . f).

linas commented 8 years ago

PutLink does this: given f(x) and a, then PutLink returns f(a)

If a just happens to be g(z) then PutLink of f(x) and a is actually PutLink f(x) and g(z) which is then just f(g(z))

What PutLink does is purely symbolic. It just substitutes one thing into another. It does not evaluate/execute the final result. It does NOT automatically wrap results in a lambda. That is up to you. However, it does do type checking: it does make sure that the type of "a" matches the allowed types for x in f(x). Not sure, but I think it probably already checks that the output type of g(z) matches the type of x in f(x). If types don't match, nothing is done.

linas commented 6 years ago

Closing. I think PutLink resolved all issues here.

ngeiswei commented 6 years ago

Agreed, I'm only waiting to complete the URE-based pattern miner prototype to remove ComposeLink from the code base.