opencog / atomspace

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

Remove ImplicationLink from PM BindLink #54

Closed ngeiswei closed 9 years ago

ngeiswei commented 9 years ago

Overview

I think we can make BindLink take 3 arguments (or 2 when no variable restrictions) and remove the ImplicationLink without hurting anything.

Specification

Instead of

BindLink
   <Variables> (optional)
   ImplicationLink
      <Clauses>
      <Rewrite>

we would have

BindLink
   <Variables> (optional)
   <Clauses>
   <Rewrite>

Example

For example, instead of

BindLink
   VariableNode X
   ImplicationLink
      InheritanceLink
         VariableNode X
         ConceptNode "Earth"
      VariableNode X

we would have

BindLink
   VariableNode X
   InheritanceLink
      VariableNode X
      ConceptNode "Earth"
   VariableNode X

(which would return a SetLink of all things that inherit "earth").

It is simpler, why not go for it?

Motivation

  1. The PM is such a fundamental part of the AtomSpace, it has to be as perfect as possible, people are gonna use this zillions of times, we cannot afford any cruft on it.
  2. No more interferences with PLN rules.

    Yours

If you guys approve I'm happy to take care of it.

linas commented 9 years ago

I guess I'm OK w/ it. Maybe @AmeBel or @williampma might see something.

Do you plan to support the old form, for backwards-compat, or do you plan tear up all the unit tests, and all the other scattered code that uses it, to remove it?

amebel commented 9 years ago

I see no problem

ngeiswei commented 9 years ago

OK, I plan to remove the old form, as this will help me to understand whether it was a good idea to begin with.

ngeiswei commented 9 years ago

And also cause it's better to have one way of doing things.

linas commented 9 years ago

Some history: back in the day, the original pattern matcher was written and working before the BindLink was invented. One day, I realized that the bindLink was possible, and would be cool to have, but could not explain it clearly. Only after putting the ImplicationLink in there did the general concept seem to gel into something that seemed acceptable and understandable by everyone on the mailing list (i.e. understood by Ben, who, after understanding it, lost all objections, but also lost all interest. As Ben is wont to do).

I think that the original idea was that someday, in the distant future, the ImplicationLink would be replaced by more PLN rules, but as you see, that idea didn't really work out.

Err.. well, in some weird way, what you are proposing is the "generalization" we were going to do in the future ... I guess we didn't understand what that generalization would be.

williampma commented 9 years ago

The only problem I can see (and I think maybe it is a very minor problem), is that without the ImplicationLink it is impossible to tell if the BindLink has no free variables in it. Currently the only way to tell if an atom has no free variables is if all variables are inside ScopeLink, and BindLink does not inherit from it (ImplicationLink does).

I assume BindLink by definition has no free variables. So without some sort of ScopeLink inside, what is "scoping" the variables? Should BindLink inherit from ScopeLink in the new implementation?

linas commented 9 years ago

To explicitly have no bound variables, I think you could say (VariableList) at the top. Since it's explicitly declaring all the variables, but its empty, then that must mean there are no variables. (the code may be buggy, this is not tested).

williampma commented 9 years ago

@linas I don't fully understand what you just said, but I think you said "if (VariableList) at the top, then no free varaibles".

I guess that would be a hacky work-around that is applicable to BindLink/SatisfactionLink. It certainly cannot be generalized, since according to @bgoertzel

ImplicationLink
   InheritanceLink $x dog
   InheritanceLink $x animal

has no free variables, and there certainly is no VariableList at the top.

I guess if it is required, the free variable check can be changed to check for both ScopeLink and ConcreteLink (or SatisfactionLink?). I just need some consistent way to check for the existence of free variables in code, no matter if they are defined explicitly and implicitly.

linas commented 9 years ago

Whoops, sorry, I meant "bound variables" not "free variables". I'll go back and edit the comments.

On Thu, May 21, 2015 at 10:53 PM, William Ma notifications@github.com wrote:

@linas https://github.com/linas I don't fully understand what you just said, but I think you said "if (VariableList) at the top, then no free varaibles".

I guess that would be a hacky work-around that is applicable to BindLink/SatisfactionLink. It certainly cannot be generalized, since according to @bgoertzel https://github.com/bgoertzel

ImplicationLink InheritanceLink $x dog InheritanceLink $x animal

has no free variables, and there certainly is no VariableList at the top.

I guess if it is required, the free variable check can be changed to check for both ScopeLink and ConcreteLink (or SatisfactionLink?). I just need some consistent way to check for the existence of free variables in code, no matter if they are defined explicitly and implicitly.

— Reply to this email directly or view it on GitHub https://github.com/opencog/atomspace/issues/54#issuecomment-104496420.

linas commented 9 years ago

I just re-read the comments. I'm confused about what you're confused about. So, yes,

ImplicationLink
   InheritanceLink $x dog
   InheritanceLink $x animal

has no free variables; $x is implicitly bound. Exactly the same as

BindLink
    InheritanceLink $x dog
    InheritanceLink $x animal

has no free variables. The above is short-hand for the older format

BindLink
    VariableList $x
    InheritanceLink $x dog
    InheritanceLink $x animal

which explicitly bound up $x. The new default is that, if there are no explicit variable bindings, then all variables are implicitly bound. To un-bind them, to make them free, you would have to say

BindLink
    VariableList <empty list>
    InheritanceLink $x dog
    InheritanceLink $x animal

which defines the list of bound variables to be empty, thus making $x free. The above example is kind-of bizarre, though. It seems to be syntactically valid, on the surface, but semantically insane. The current code would treat $x as if it were a constant, and, since constant terms are always removed and ignored, the above results in an empty BindLink. Which, I dunno,. it might throw or crash. Not sure

linas commented 9 years ago
(InheritanceLink (ConceptNode "fido") (ConceptNode "dog"))

(cog-bind (BindLink
    (VariableList) 
    (ImplicationLink
       (InheritanceLink (VariableNode "$x") (ConceptNode "dog"))
       (InheritanceLink (VariableNode "$x") (ConceptNode "animal")))))

returns the empty set, but

(cog-bind   
(BindLink
    (ImplicationLink
       (InheritanceLink (VariableNode "$x") (ConceptNode "dog"))
       (InheritanceLink (VariableNode "$x") (ConceptNode "animal")))))

returns

(SetLink
   (InheritanceLink
      (ConceptNode "fido")
      (ConceptNode "animal")
   )
)

as expected. So that all works.

williampma commented 9 years ago

Well, I am less talking about what the Pattern Matcher will do the atom, but rather what the URE (for my case, mostly about Backward Chainer) should do when given an atom.

When the BackwardChainer has target

ImplicationLink
   InheritanceLink $x dog
   InheritanceLink $x animal

it is suppose to see that this atom has no free variables, so is uninteresting and therefore no need to BackwardChain on (in terms of variable-fullfillment query). On the other hand, if given

InheritanceLink $x cat

then the BackwardChainer should see this is interesting, and try to BackwardChain to solve to $x.

But according to what you said, even InheritanceLink $x cat is implicitly bound. If there's no free var, then there's no need to BackwardChain for variable fullfillment... Then there will never be variable fullfillment query since all variables are implicitly bound... or are you talking only about the case when stuff are inside BindLink?

At this point, the only way to recognize the difference in the two different input is to check for variables not inside ScopeLink (since C++ cannot understand what is implicit and what is explicit in the atomspace unless some algorithm is provided). I was just referring to the fact that without the ScopeLink (ImplicationLink), the new BindLink has no ScopeLink wrapping it. Though now that I think about, it probably won't matter much since it is unlikely for the URE to have a rule to have a BindLink as one of its implicant/implicand...

bgoertzel commented 9 years ago

Conceptually, it seems BindLink is imperative whereas implicationLink is declarative, and they are the same other wise ... On 22 May 2015 11:16, "Linas Vepštas" notifications@github.com wrote:

(InheritanceLink (ConceptNode "fido") (ConceptNode "dog"))

(cog-bind (BindLink (VariableList) (ImplicationLink (InheritanceLink (VariableNode "$x") (ConceptNode "dog")) (InheritanceLink (VariableNode "$x") (ConceptNode "animal")))))

returns the empty set, but

(cog-bind (BindLink (ImplicationLink (InheritanceLink (VariableNode "$x") (ConceptNode "dog")) (InheritanceLink (VariableNode "$x") (ConceptNode "animal")))))

returns

(SetLink (InheritanceLink (ConceptNode "fido") (ConceptNode "animal") ) )

as expected. So that all works.

— Reply to this email directly or view it on GitHub https://github.com/opencog/atomspace/issues/54#issuecomment-104512826.

ngeiswei commented 9 years ago

Please, don't assume $x is implicitly binded in

ImplicationLink
   InheritanceLink $x dog
   InheritanceLink $x animal

!!!

I think we can tolerate that BindLink has optionally implicit variable bindings cause it is solely used in the pattern matcher. But outside of BindLink don't assume anything is implicit.

Should I re-explain why?

ngeiswei commented 9 years ago

Yes, I would agree, BindLink is imperative, that is why it doesn't need an ImplicationLink. If one wants to define the semantics of (cog-bind (BindLink ...)) with ImplicationLinks that is fine but I see no need of having it in its imperative use.

amebel commented 9 years ago

What is the difference between

ForAllLink 
     $x
     InheritanceLink $x cat

and InheritanceLink $x cat ?

ngeiswei commented 9 years ago

Well the last time I looked at it, it would have been

AverageLink <TV>
   $x
   InheritanceLink $x cat

and the TV on

InheritanceLink <TV> $x cat

would be equal to the TV on the averageLink.

But that doesn't mean that an implicit binding occurs on the inheritanceLink, for instance you should still be able to express something like

ForAllLink
   $x
   OrLink
      InheritanceLink $x cat
      InheritanceLink $x dog

Which would be very different that

ForAllLink
   $x
   OrLink
      AverageLink
         $implicit_x
         InheritanceLink $implicit_x cat
      AverageLink
         $implicit_x
         InheritanceLink $implicit_x dog

The implicit binding in question would not be on an average quantifier anyway, but a lambda one (a function constructor).

williampma commented 9 years ago

Well, ImplicationLink <- AverageLink <- ForAllLink <- ScopeLink, so they are all clearly "scoped" and to me all those binding are all very "explicit" coding-vise. That's what ScopeLink is, right? It's some sort of LambdaLink according to the description.

The only thing in danger of becoming implicit is the new notation

BindLink
   <Variables> (optional)
   <Clauses>
   <Rewrite>

because the ScopeLink is missing. BindLink <- SatisfactionLink <- ConcreteLink <- OrderedLink so it is not "scoped". There's a variable list but the lambda is missing.

Now, suppose ImplicationLink is not a ScopeLink/LambdaLink (which is not the case). @ngeiswei seems to be saying

ImplicationLink
   InheritanceLink $x dog
   InheritanceLink $x animal

has no binding (it doesn't look "explicit" and Nil was saying it is not "implicit" either) and therefore $x is a free variable? So a variable-fullfillment query will need to solve for $x?

ngeiswei commented 9 years ago

Well, I don't approve neither AverageLink <- ForAllLink nor ImplicationLink <- AverageLink.

BindLink should inherit ScopeLink (actually if I were to design it I wouldn't have had any BindLink to begin with, just a predicate for the finding valid groundings + a schema for rewriting, and have cog-bind take those, but anywaaayyyy, that's another debate).

And yes, in

ImplicationLink
   InheritanceLink $x dog
   InheritanceLink $x animal

$x is a free variable.

amebel commented 9 years ago

@ngeiswei excuse my ignorance but couldn't get the explanation on,

ForAllLink
   $x
   OrLink
      AverageLink
         $implicit_x
         InheritanceLink $implicit_x cat
      AverageLink
         $implicit_x
         InheritanceLink $implicit_x dog

all i see is something like Forall X: Y^2, which i don't know how to interpret

linas commented 9 years ago

Wow. What a ball of confusion. Its is fundamentally impossible for $x to be a free variable in

ImplicationLink
   InheritanceLink $x dog
   InheritanceLink $x animal

That would result in complete non-sense. I think we need to go back to the textbook and review the concepts of free and bound ...

linas commented 9 years ago

What I was going to say was this: I finally understand what GetLink and PutLink are, and BindLink can be written as a combination of GetLink and PutLink -- and vice versa: Getlink can be written as a special case of BindLink and PutLink is identical to what i have been calling BetaRedexLink. The wiki page here explains it all: http://wiki.opencog.org/w/PutLink

bgoertzel commented 9 years ago

Well. If we get rid of the notion of implicit quantification, then $x is unbound in

ImplicationLink InheritanceLink $x dog InheritanceLink $x animal

but the above is just an incomplete fragment that must be wrapped in some link binding $x ...

ben

On Fri, May 22, 2015 at 10:57 PM, Linas Vepštas notifications@github.com wrote:

Wow. What a ball of confusion. Its is fundamentally impossible for $x to be a free variable in

ImplicationLink InheritanceLink $x dog InheritanceLink $x animal

That would result in complete non-sense. I think we need to go back to the textbook and review the concepts of free and bound ...

— Reply to this email directly or view it on GitHub https://github.com/opencog/atomspace/issues/54#issuecomment-104712868.

Ben Goertzel, PhD http://goertzel.org

"The reasonable man adapts himself to the world: the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man." -- George Bernard Shaw

bgoertzel commented 9 years ago

Yes... you got it ... ;)

On Fri, May 22, 2015 at 11:01 PM, Linas Vepštas notifications@github.com wrote:

What I was going to say was this: I finally understand what GetLink and PutLink are, and BindLink can be written as a combination of GetLink and PutLink -- and vice versa: Getlink can be written as a special case of BindLink and PutLink is identical to what i have been calling BetaRedexLink. The wiki page here explains it all: http://wiki.opencog.org/w/PutLink

— Reply to this email directly or view it on GitHub https://github.com/opencog/atomspace/issues/54#issuecomment-104714027.

Ben Goertzel, PhD http://goertzel.org

"The reasonable man adapts himself to the world: the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man." -- George Bernard Shaw

linas commented 9 years ago

Nil: fyi, to avoid git merge collisions -- I am re-organizing the code in the atoms/bind directory, now that I understand the put/get concept. I'll check in results in 6-8 hours.

ngeiswei commented 9 years ago

@AmeBel, regarding

ForAllLink <forall_TV>
   $x
   OrLink
      AverageLink
         $implicit_x
         InheritanceLink $implicit_x cat
      AverageLink
         $implicit_x
         InheritanceLink $implicit_x dog

$x does not appear in the body of the quantification, but that still has a PLN interpretation, which is that the TV of the body (OrLink ...) has a probability described by forall_TV of being in the interval [1 - epsilon, 1].

The ForAllLink wiki page is missing the PLN interpretation, I should remedy that.

amebel commented 9 years ago

@ngeiswei thanks

ngeiswei commented 9 years ago

Woohoo! Beautiful way of handling PutLink/GetLink and tying it to BindLink. Well done, Linas!

linas commented 9 years ago

Should we find a better name for BindLink -- maybe RewriteLink ?

Recall: the old name for BindLink was LambdaLink; the name was changed because I could vaguely understand that variable binding and pattern matching were not the same thing. Due to historical accident/confusion, the bind only worked with ImplicationLink. Now that it is gone (i.e now that we understand that variable binding and pattern matching and rewriting are three different things), then a better name is needed.

ngeiswei commented 9 years ago

I've corrected the remaining wikipages accordingly (thanks @linas for having taken care of the BindLink page!). I consider this issue can be closed.

linas commented 9 years ago

thanks for doing this. Maintenance cleanup like this help clarify what it is that we are doing.I have high hopes for interstnig future directions, as a result