Closed williampma closed 8 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.
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.
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?
Virtual link (evaluatable) are different. Your InheritanceLink are not evaluated after matching.
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
)
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).
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"))
)
Isn't such a clause acceptable in a mulit-clause case?
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).
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.
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...?
Woow!!!!
Why should the inner EqualLink be matched as is?
Because a EqualLink return TV (if evaluated) and InheritanceLink expect an atom.
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)")'.
VariableNode "$A" is certainly unquoted...
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).
Obviously, outch!
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!)
I'll try to fix this, I have several related bugs to hack.
Or not. The crash seems to be hard to reproduce. Opening a new bug.
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.
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 ...
Thanks!
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)
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?