opencog / atomspace

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

BindLink clause with a single evaluatable #165

Closed williampma closed 8 years ago

williampma commented 9 years ago

Come across this while marking a single (VariableNode $A) clause as "evaluatable" (since if it maps to an "evaluatable", special treatment is need to evaluate the mapped stuff)

guile> (define B 
   (BindLink 
      (VariableList (VariableNode "$A") (VariableNode "$B")) 
      (EqualLink (VariableNode "$A") (VariableNode "$B"))
      (ListLink (VariableNode "$A") (VariableNode "$B"))))

guile> (cog-bind B)
(SetLink
)

ie. a BindLink with a single virtual clause currently is not run and not grounded. Should it? The above query should produce every single atom in the AtomSpace right?

amebel commented 9 years ago

I don't think so, how could (VariableNode "$A") (VariableNode "$B") be ever equal? So on evaluation the virtual-link return false in every possible case and thus the implicand isn't executed.

williampma commented 9 years ago

Humm... no, it is suppose to find a grounding, so if $A and $B ground to the same atom, then the EqualLink will be true, and so the solution will be all atoms in the AtomSpace returned in pair (double) inside ListLink.

amebel commented 9 years ago
guile> (clear)

guile> (define c
   (BindLink 
      (VariableList (VariableNode "$B")) 
      (InheritanceLink (VariableNode "$B") (VariableNode "$B"))
...       (OrderedLink (VariableNode "$B") (VariableNode "$B"))))

guile> (InheritanceLink (ConceptNode "william") (ConceptNode "william"))
(InheritanceLink
   (ConceptNode "william")
   (ConceptNode "william")
)

guile> (InheritanceLink (ConceptNode "chair") (ConceptNode "door"))
(InheritanceLink
   (ConceptNode "chair")
   (ConceptNode "door")
)

guile> (cog-bind c)
(SetLink
   (OrderedLink
      (ConceptNode "william")
      (ConceptNode "william")
   )
)

guile> 

If I got you, then there should be

(OrderedLink
   (ConceptNode "chair")
   (ConceptNode "chair")
)

right? or does the case differs for virtual-links?

williampma commented 9 years ago

Virtual link (evaluatable) are different. Your InheritanceLink are not evaluated after matching.

amebel commented 9 years ago

I am not right either

(define d
   (BindLink 
      (VariableList(VariableNode "$B")) 
      (EqualLink (VariableNode "$B") (VariableNode "$B"))
...       (ListLink (VariableNode "$B") (VariableNode "$B"))))

guile> (cog-bind d)
(SetLink
)
williampma commented 9 years ago

Yeah, currently it won't even run the main PM code when the only clause is virtual.

I changed some condition to make it run on my local copy, but then the default PM path ends up treating the virtual link as non-virtual (via the variable_search path).

williampma commented 8 years ago

Just wondering, should a BindLink clause like the following also be acceptable?

(BindLink
   (VariableList (VariableNode "$A") (VariableNode "$B") (VariableNode "$C"))
   (NotLink
      (EqualLink
         (InheritanceLink (VariableNode "$A") (VariableNode "$B"))
         (InheritanceLink (VariableNode "$B") (VariableNode "$C"))
      )
   )
   (ListLink (VariableNode "$A") (VariableNode "$B") (VariableNode "$C"))
)
amebel commented 8 years ago

Isn't such a clause acceptable in a mulit-clause case?

williampma commented 8 years ago

I haven't seen it. The above clause has two InheritanceLink with variables that need to grounded inside an EqualLink (not outside like in deduction rule).

williampma commented 8 years ago

It doesn't work for multi-clause case neither though. I just tried

(define B (BindLink
   (VariableList (VariableNode "$A") (VariableNode "$B") (VariableNode "$C"))
   (AndLink
      (VariableNode "$A")
      (VariableNode "$B")
      (VariableNode "$C")
      (NotLink
         (EqualLink
            (InheritanceLink (VariableNode "$A") (VariableNode "$B"))
            (InheritanceLink (VariableNode "$B") (VariableNode "$C"))
         )
      )
   )
   (ListLink (VariableNode "$A") (VariableNode "$B") (VariableNode "$C"))
)
(InheritanceLink (ConceptNode "cat") (ConceptNode "dog"))

(cog-bind B) looks to return all combination of atoms, not just those that are inside InheritanceLink. And I think I know why, since PM assumes atoms in evaluatable does not exist yet, it creates the InheritanceLink inside the temporary atomspace on the fly to evaluate the EqualLink.

Maybe this behavior correct, maybe it is not. Not sure.

williampma commented 8 years ago

It gets more complicated with this kind of clause

   (EqualLink
      (InheritanceLink
         (EqualLink (VariableNode "$A") (VariableNode "$B"))
         (ConceptNode "dog")
      )
      (VariableNode "$C")
   )

is this clause virtual?

I would assume it is, and that the outer most EqualLink should be evaluated, while the inner EqualLink should be matched as is. But if everything inside an evaluatable should be treated as "not yet exist" than the inner stuff does not exist and cannot be matched.

So in this case it means the whole clause should be matched as is...?

amebel commented 8 years ago

Woow!!!!

Why should the inner EqualLink be matched as is?

williampma commented 8 years ago

Because a EqualLink return TV (if evaluated) and InheritanceLink expect an atom.

ngeiswei commented 8 years ago

I thought I one could work around B (the first one defined above) by adding the VariableNodes as clauses, but it crashes the pattern matcher

... scheme@(guile-user)> C
$4 = (BindLink (av 0 0 0)
   (VariableList (av 0 0 0)
      (VariableNode "$A")
      (VariableNode "$B")
   )
   (AndLink
      (VariableNode "$A")
      (VariableNode "$B")
      (EqualLink
         (VariableNode "$A")
         (VariableNode "$B")
      )
   )
   (ListLink
      (VariableNode "$A")
      (VariableNode "$B")
   )
)
scheme@(guile-user)> (cog-bind C)
ERROR: In procedure opencog-extension:
ERROR: Throw to key `C++-EXCEPTION' with args `("cog-bind" "The variable (VariableNode \"$A\") ; [2]\n does not appear (unquoted) in any clause! (/home/nilg/OpenCog/atomspace/opencog/atoms/bind/PatternLink.cc:371)")'.
ngeiswei commented 8 years ago

VariableNode "$A" is certainly unquoted...

williampma commented 8 years ago

That was my solution I was trying, by extracting any unique variables inside an evaluatable and put it outside as a clause automatically. This lead to https://github.com/opencog/atomspace/issues/172 which is the same error as you mentioned above.

This is because one of the VariableNode is matched to the BindLink, and then EqualLink try to evaluate it by putting them into _temp_aspace, which crash the BindLink constructor (via Instantiator).

ngeiswei commented 8 years ago

Obviously, outch!

linas commented 8 years ago

For the very first few posts, I think that the answer here is the same as for bug #171 -- the pattern matcher should have thrown an error about 'nvalid syntax'. What you seem to want to do is this:

(define B 
   (BindLink 
      (VariableList (VariableNode "$A") (VariableNode "$B")) 
      (AndLink
          (VariableNode "$A")
          (VariableNode "$B")
          (EqualLink (VariableNode "$A") (VariableNode "$B"))
      )
      (ListLink (VariableNode "$A") (VariableNode "$B"))))

The above should give you what you wanted: all atoms in the atomspace, repeated in a ListLink. (I just tried it ... it segfaults!)

linas commented 8 years ago

I'll try to fix this, I have several related bugs to hack.

linas commented 8 years ago

Or not. The crash seems to be hard to reproduce. Opening a new bug.

linas commented 8 years ago

After the last batch of fixes, this now works as expected:

(define D
(GetLink
   (VariableList (VariableNode "$A") (VariableNode "$B"))
   (AndLink
      (VariableNode "$A")
      (VariableNode "$B")
      (EqualLink (VariableNode "$A") (VariableNode "$B")))))
(define D
(GetLink
   (VariableList (VariableNode "$A") (VariableNode "$B"))
   (AndLink
      (VariableNode "$A")
      (VariableNode "$B")
      (EqualLink (VariableNode "$A") (VariableNode "$B")))))
(cog-execute! D)

This does too:

(define C
(BindLink
   (VariableList (VariableNode "$A") (VariableNode "$B"))
   (AndLink
      (VariableNode "$A")
      (VariableNode "$B")
      (EqualLink (VariableNode "$A") (VariableNode "$B")))
   (ListLink (VariableNode "$A") (VariableNode "$B"))))
(cog-bind! C)

The meaning of these patterns is this:

(define E
(GetLink
   (VariableList (VariableNode "$A") (VariableNode "$B"))
   (AndLink
      (PresentLink (VariableNode "$A"))
      (PresentLink (VariableNode "$B"))
      (EqualLink (VariableNode "$A") (VariableNode "$B")))))

However, since PresentLink is not yet implemented, so(cog-execute! E)` does not yet work (bug #218)

Anyway, comparing B at the to to E here makes it clear that B is not really a valid BindLink, and the pattern matcher should have thrown in this case.

linas commented 8 years ago

I just pushed an explicit check for this in pull request #247. I'm closing this because the discussion got long and confused, and several related bugs were found. I think all of them are now fixed. If you can find stuff that doesn't work, please open a new bug ...

williampma commented 8 years ago

Thanks!