opencog / atomspace

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

Evaluatable in non-logical link inside BindLink clause #132

Closed williampma closed 8 years ago

williampma commented 9 years ago

Just thought I would throw this out there. Doing cog-bind on the following craziness

(BindLink
    (VariableList (stv 1.000000 0.000000)
        (VariableNode "$A") ; [80]
        (VariableNode "$B") ; [92]
        (VariableNode "$C") ; [103]
    )
    (MemberLink (stv 1.000000 1.000000)
        (BindLink (stv 1.000000 0.000000)
            (VariableList (stv 1.000000 0.000000)
                (TypedVariableLink (stv 1.000000 0.000000)
                    (VariableNode "$A") ; [80]
                    (TypeNode "ConceptNode") ; [100]
                ) ; [101]
                (TypedVariableLink (stv 1.000000 0.000000)
                    (VariableNode "$B") ; [92]
                    (TypeNode "ConceptNode") ; [100]
                ) ; [102]
                (TypedVariableLink (stv 1.000000 0.000000)
                    (VariableNode "$C") ; [103]
                    (TypeNode "ConceptNode") ; [100]
                ) ; [104]
            ) ; [105]
            (AndLink (stv 1.000000 0.000000)
                (InheritanceLink (stv 1.000000 0.000000)
                    (VariableNode "$A") ; [80]
                    (VariableNode "$B") ; [92]
                ) ; [106]
                (InheritanceLink (stv 1.000000 0.000000)
                    (VariableNode "$B") ; [92]
                    (VariableNode "$C") ; [103]
                ) ; [107]
                (NotLink (stv 1.000000 0.000000)
                    (EqualLink (stv 1.000000 0.000000)
                        (VariableNode "$A") ; [80]
                        (VariableNode "$C") ; [103]
                    ) ; [108]
                ) ; [109]
            ) ; [110]
            (ExecutionOutputLink (stv 1.000000 0.000000)
                (GroundedSchemaNode "scm: pln-formula-simple-deduction") ; [111]
                (ListLink (stv 1.000000 0.000000)
                    (InheritanceLink (stv 1.000000 0.000000)
                        (VariableNode "$A") ; [80]
                        (VariableNode "$B") ; [92]
                    ) ; [106]
                    (InheritanceLink (stv 1.000000 0.000000)
                        (VariableNode "$B") ; [92]
                        (VariableNode "$C") ; [103]
                    ) ; [107]
                    (InheritanceLink (stv 1.000000 0.000000)
                        (VariableNode "$A") ; [80]
                        (VariableNode "$C") ; [103]
                    ) ; [112]
                ) ; [113]
            ) ; [114]
        ) ; [115]
        (ConceptNode "URE") ; [116]
    ) ; [118]
    (ListLink
        (VariableNode "$A") ; [80]
        (VariableNode "$B") ; [92]
        (VariableNode "$C") ; [103]
    )
)

gives me

ERROR: In procedure cog-bind: Unknown logical connective (MemberLink (stv 1.000000 1.000000)
...

I stumbled upon this when the BC algorithm tried to backward chain an untyped (VariableNode "$stuff") target (from modus ponens rule), which match to everything in the atomspace. Then since the variables inside the interior MemberLink are by current algorithmic definition "free", the MemberLink is added as a target as a "Variable Fullfillment Query", and then generate the above error when trying to ground it.

williampma commented 9 years ago

Hummm.... so

`(1 2 (3 ,(+ 4 5)))
     ⇒ (1 2 (3 9))

but what if we actually want

`(1 2 (3 ,(+ 4 5)))
     ⇒ (1 2 (3 ,(+ 4 5)))

does LISP allow that?

bgoertzel commented 9 years ago

it seems you can nest backquotes and commas

http://stackoverflow.com/questions/7549550/using-two-backquotes-and-commas-common-lisp

in the LISP spirit that "data is code" ...

On Fri, Aug 14, 2015 at 9:21 PM, William Ma notifications@github.com wrote:

Hummm.... so

`(1 2 (3 ,(+ 4 5))) ⇒ (1 2 (3 9))

but what if we actually want

`(1 2 (3 ,(+ 4 5))) ⇒ (1 2 (3 ,(+ 4 5)))

does LISP allow that?

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

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

When Ben talks about quote and unquote, I think he really means quasi-quote and unquote. You cannot wriggle your way out of a quote, but you can unquote your way out of a quasi-quote: http://docs.racket-lang.org/reference/quasiquote.html (this works in scheme just like in racket). https://www.gnu.org/software/guile/manual/html_node/Expression-Syntax.html

Note that regular single-quote ' is quote while the back-tick ` is quasi-quote.

linas commented 9 years ago

So, to answer William's question:

`(1 2 (3 ,(+ 4 5)))   ;;; back-tick is quasi-quote

yields (1 2 (3 9)), whereas

'(1 2 (3 ,(+ 4 5)))    ;;; regular tick is just quote.

yields (1 2 (3 (unquote (+ 4 5))))

linas commented 9 years ago

This suggests the need for three link types: QuoteLink QuasiquoteLink and UnquoteLink -- the UnquoteLink can only work inside a QuasiquoteLink; it is powerless otherwise. Whether we shall someday need a UnquoteSplicingLink is unclear.

bgoertzel commented 9 years ago

Linas,

What you're calling a quasiquote, I used to call a "backquote",

http://www.gnu.org/software/emacs/manual/html_node/elisp/Backquote.html

but yeah it's the same thing...

http://www.phyast.pitt.edu/~micheles/scheme/scheme8.html

So I think we agree, and Cassio concurred with this approach also.... Basically, this is in line with the maxim that every AI system inevitably contains N different hacky versions of a LISP interpreter ;p ...

ben

On Sun, Aug 16, 2015 at 9:59 AM, Linas Vepštas notifications@github.com wrote:

When Ben talks about quote and unquote, I think he really means quasi-quote and unquote. You cannot wriggle your way out of a quote, but you can unquote your way out of a quasi-quote: http://docs.racket-lang.org/reference/quasiquote.html (this works in scheme just like in racket). https://www.gnu.org/software/guile/manual/html_node/Expression-Syntax.html

Note that regular single-quote ' is quote while the back-tick ` is quasi-quote.

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

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

I think only two link types are really required in our current case, though -- Quote and Unquote

In Scheme (as you likely know), quote causes the S-expression quoted to be constructed at compile time, whereas quasiquote causes the S-expression to be constructed at run time

ftp://ftp.cs.utexas.edu/pub/garbage/cs345/schintro-v13/schintro_129.html

So if one isn't concerned about optimization of quoted expressions (via compile-time construction), then one can ignore the quote/quasiquote distinction and effectively just have quasiquote...

So my suggestion is to just have QuoteLink and UnquoteLink, where QuoteLink behaves like Scheme quasiquote and UnquoteLink behaves like Scheme unquote

I think this is what Nil was suggesting a while ago in this thread... and what Cassio suggested in our F2F at the HK office last week...

-- Ben

On Sun, Aug 16, 2015 at 10:06 AM, Linas Vepštas notifications@github.com wrote:

This suggests the need for three link types: QuoteLink QuasiquoteLink and UnquoteLink -- the UnquoteLink can only work inside a QuasiquoteLink; it is powerless otherwise. Whether we shall someday need a UnquoteSplicingLink is unclear.

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

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

ngeiswei commented 9 years ago

Guys, we've got an AbsentLink for when a pattern in not in the atomspace, let's use a PresentLink for when a pattern is in the AtomSpace. You say "it's verbose", I say "fuck that!" :-D. You can always create helper functions to workaround the verbosity, but you cannot hand to the user such a complex badly specified behavior. In its last email Linas said

"The meta-problem with the pattern matcher is that it is not obvious
(to newcomers) that some clauses are being used for matching, and
other clauses are being used for their TV only."

I think he has a point. What isn't good to a newcomers isn't good to us.

Yes most patterns will be populated with PresentLink, on the other hand the use for QuoteLink and the like will drop considerably (only when you need to match variables inside pattern, or maybe I'm missing something).

bgoertzel commented 9 years ago

If we wanted to use PresentLink, we would just have to wrap it around the outer BindLink passed to the PM, right? Then AbsentLink would be used to override this default PresentLink..

So most patterns would not be populated with PresentLink, but would simply be wrapped with PresentLink -- if we wanted to go that way...

On Tue, Aug 18, 2015 at 6:53 PM, ngeiswei notifications@github.com wrote:

Guys, we've got an AbsentLink for when a pattern in not in the atomspace, let's use a PresentLink for when a pattern is in the AtomSpace. You say "it's verbose", I say "fuck that!" :-D. You can always create helper functions to workaround the verbosity, but you cannot hand to the user such a complex badly specified behavior. In its last email Linas said

"The meta-problem with the pattern matcher is that it is not obvious (to newcomers) that some clauses are being used for matching, and other clauses are being used for their TV only."

I think he has a point. What isn't good to a newcomers isn't good to us.

Yes most patterns will be populated with PresentLink, on the other hand the use for QuoteLink and the like will drop considerably (only when you need to match variables inside pattern, or maybe I'm missing something).

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

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

ngeiswei commented 9 years ago

The (old) idea is to have everything evaluatable by default and use PresentLink to tell to search the a pattern. So for instance to define the deduction rule one would write

BindLink
   AndLink
      PresentLink
         ImplicationLink
            VariableNode "$X"
            VariableNode "$Y"
      PresentLink
         ImplicationLink
            VariableNode "$Y"
            VariableNode "$Z"
      NotLink
         EqualLink
            VariableNode "$X"
            VariableNode "$Z"
   ImplicationLink
      VariableNode "$X"
      VariableNode "$Z"

letting aside the formula on the implicand.

ngeiswei commented 9 years ago

PresentLink is the BelongLink I introduced earlier, except the name is cooler, especially cause we've got an AbsentLink...

bgoertzel commented 9 years ago

I guess I still don't see why we need to make that explicit

I mean when we have

ImplicationLink Inheritance $X cat Inheritance $X animal

do you want to say instead

ImplicationLink PresentLink Inheritance $X cat PresentLink Inheritance $X animal

?

On Tue, Aug 18, 2015 at 8:32 PM, ngeiswei notifications@github.com wrote:

PresentLink is the BelongLink I introduced earlier, except the name is cooler, especially cause we've got an AbsentLink...

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

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

On Tue, Aug 18, 2015 at 7:41 AM, bgoertzel notifications@github.com wrote:

I guess I still don't see why we need to make that explicit

I mean when we have

ImplicationLink Inheritance $X cat Inheritance $X animal

do you want to say instead

ImplicationLink PresentLink Inheritance $X cat PresentLink Inheritance $X animal

No, that would be wrong, or almost surely not what you meant. The PresentLink evaluates to true or false: if the pattern matcher finds the thing wrapped by PresentLink, then it replaces it by "true". This would be wrong or weird inside an ImplicationLink. The only things you want above a PresentLink would be AndLink, OrLink, NotLink, SequenctialAndLink, Choice Link.

Sequential just means "you must evaluate in order"; pattern matching can run unordered. ChoiceLink means "pick one and only one".

Anyway, I like PresentLink, it solves a different bit of queasiness I'm getting with the behavior tree concept, that I need to fix today... We may need unquote anyway, at some future date, but PresentLink really emphasizes unambiguously that the marked component is being searched for, rather than evaluated.

linas commented 9 years ago

There is an easy work-around for PresentLink that already exists and is implemented. Its called ChoiceLink. I just tested it, and it works as expected. An arity-N ChoiceLink is true if and only if one (or more) of its outgoing st is in the atomspace (can be grounded in the atomspace). Thus, an arity-1 ChoiceLink is identical to an arity-1 PresentLink: its true if and only if the wrapped atom is present.

I defined PresentLink here: http://wiki.opencog.org/w/PresentLink and I defined it so that it requires all of its terms to be present. thus, PresentLink is like present-and, while ChoiceLink is like present-or. ChoiceLink works today!

Note some additional confusion: PrsentLink resembles SatisfactionLink, in that both are either true or false; but SatisfactionLink binds its variables, while PresentLink leaves them free.

I think the spec in http://wiki.opencog.org/w/PresentLink is sufficiently clear that it can be "easily" implemented. Seems like a good idea.

ngeiswei commented 9 years ago

+1 for n-ary PresentLink.

Maybe having n-ary AbsentLink could be useful as well. In that case NotLink AbsentLink wouldn't be equivalent to PresentLink except for the unary case, but I don't think that would be a problem.

Also you say in the wiki page of PresentLink

"Unlike SatisfactionLink, a PresentLink cannot be used with the cog-bind function. "

Why is that?

Also, do you intend to make PresentLink mandatory? Which involves re-populating all the existing BindLinks and GetLinks with PresentLinks. Or to come up with a convention to avoid doing that?

ngeiswei commented 9 years ago

I guess when PresentLink isn't used then the evaluatable per link conventions could be used... So for instance if one wants to search for the pattern EqualLink $X $Y it would be wrapped in a PresentLink.

linas commented 8 years ago

I think this conversation has reached a conclusion; closing this as a bug report. If there are new issues, please open a new bug report.

BTW, PresentLink is now partly-implemented (in a rather narrow scope) via bug #218