Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault when I fail to declare variable in SatisfactionLink inside LambdaLink #2768

Open
luketpeterson opened this issue Sep 29, 2020 · 4 comments

Comments

@luketpeterson
Copy link

luketpeterson commented Sep 29, 2020

The following Scheme code crashes the process running OpenCog (guile in my case)

.. code-block:: scheme

(use-modules (opencog) (opencog exec))

(EvaluationLink
    (PredicateNode "_obj")
    (ListLink
        (ConceptNode "make")
        (ConceptNode "pottery")))

(DefineLink
    (DefinedPredicateNode "can_be_made?")
    (LambdaLink
        (Variable "test_object")
        (SatisfactionLink
            (AndLink
                (EvaluationLink
                    (PredicateNode "_obj")
                    (ListLink
                        (ConceptNode "make")
                        (Variable "predicate_object")
                    ) )        
                (EqualLink
                    (Variable "test_object")
                    (Variable "predicate_object")
                ) ) ) ) )

(cog-evaluate!
    (Evaluation
        (DefinedPredicate "can_be_made?")
        (ConceptNode "pottery")
    ) )

I can work around the issue by declaring (Variable "predicate_object") in the SatisfactionLink. Regardless of whether the undeclared variable is valid, I would expect an error and not a crash.

I don't know how I access the relevant OpenCog / Atomspace version. I am running the OpenCog Docker images, which are based on Ubuntu 18.04.4 LTS.

@linas
Copy link
Member

linas commented Feb 9, 2021

I tried the above, and I don't get a crash, I get a different error (which should not occur)

ice-9/boot-9.scm:1669:16: In procedure raise-exception:
Throw to key `C++-EXCEPTION' with args `("cog-evaluate!" "Transient space memleak! (/home/linas/src/novamente/src/atomspace-git/opencog/atomspace/Transient.cc:89)\nFunction args:\n((EvaluationLink\n  (DefinedPredicateNode \"can_be_made?\")\n  (ConceptNode \"pottery\"))\n)")'.

@linas
Copy link
Member

linas commented Feb 9, 2021

Digging just a bit deeper, it appears that there's some inf-loop in there, which, for me, is terminated after exceeding the max count ...

@linas
Copy link
Member

linas commented Feb 9, 2021

Oh. Hah. The inf loop is due to the variables being untyped. So, somewhere during matching, it decides that it should explore the DefinedPredicateNode as a possible grounding. So it expands the definition. Then somehow its decides its runnable, so it tries to run it, which just causes it to loop.

At the moment, its not obvious to me why, exactly, it tried to loop. However, this is a generic problem of untyped variables: during pattern matching, the worst-case assumption is to try to match everything, which is both a performance hit, and often leads to obscure bugs like this.

The following works:

(DefineLink
    (DefinedPredicateNode "can_be_made?")
    (LambdaLink
        (Variable "test_object")   ;; Note, I left this untyped. That's fine. Its the return value.
        (SatisfactionLink
            ; Force the search to look only for ConceptNodes.
            (TypedVariable (Variable "predicate_object") (Type 'ConceptNode))
            (AndLink
                (EvaluationLink
                    (PredicateNode "_obj")
                    (ListLink
                        (ConceptNode "make")
                        (Variable "predicate_object")
                    ) )
                (EqualLink
                    (Variable "test_object")
                    (Variable "predicate_object")
                ) ) ) ) )

@linas
Copy link
Member

linas commented Feb 9, 2021

Oh, ahh Hmm I have to eat some of my words. The following also works:

(DefineLink
    (DefinedPredicateNode "can_be_made?")
    (LambdaLink
        (Variable "test_object") 
        (SatisfactionLink
            (Variable "predicate_object") 
            (AndLink
                (EvaluationLink
                    (PredicateNode "_obj")
                    (ListLink
                        (ConceptNode "make")
                        (Variable "predicate_object")
                    ) )
                (EqualLink
                    (Variable "test_object")
                    (Variable "predicate_object")
                ) ) ) ) )

You are right -- the definition for the (Variable "predicate_object") should not have been needed, and the SatisfactionLink should have worked exactly the same way with and without this definition. So that's weird.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants