Closed ngeiswei closed 6 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.
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
I've added a wiki page about it http://wiki.opencog.org/wikihome/index.php/CompositeLink
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...
I positively think that would over-complexify PutLink.
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.
@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).
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.
Closing. I think PutLink resolved all issues here.
Agreed, I'm only waiting to complete the URE-based pattern miner prototype to remove ComposeLink
from the code base.
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)
could be replaced by