MeetLink

From OpenCog

The MeetLink is used to specify a search pattern that can be satisfied with Atoms found in the AtomSpace. It is nearly identical to the older, deprecated GetLink. It is similar to QueryLink, except that it does not perform any graph re-writing. it is similar to SatisfactionLink, except that, upon execution, it returns a set of atoms, instead of a truth value. It is similar to the SatisfyingSetLink, except that it is imperative: the MeetLink commands: "go and search for all atoms that satisfy this predicate", whereas SatisfyingSetLink is declarative: "here is a set of atoms that satisfy this predicate".

MeetLinks can be combined with PutLinks to implement graph rewriting. See link comparison for other related links.

MeetLink gets its name because it implements the idea of a "meet" of partially ordered sets (it actually does a bit more, as it can apply arbitrary predicates as it does so, and also force term absence, support the AlwaysLink, etc.) It is dual to JoinLink, which implements the join.

Overview

The MeetLink has the general form:

 MeetLink
    <optional variable declarations and type restrictions>
    <clause containing variables>

Alternatively MeetLink can take a LambdaLink to express the variable declarations and the pattern

 MeetLink
   LambdaLink
      <optional variable declarations and type restrictions>
      <clause containing variables>

Upon execution with the cog-execute! function, it returns the set of all possible groundings:

    SetLink
       <atoms that ground the variables>

When there is only one grounding, the SetLink is omitted, and the single grounding is returned. When there are multiple variables in the pattern, these are enclosed in a ListLink; if there is only one variable, the ListLink is omitted.

The MeetLink is essentially identical to the SatisfyingSetLink, except that the SatisfyingSetLink is declarative, whereas the MeetLink is imperative. That is, the MeetLink is used to force a search, right now, of all of the things in the AtomSpace that satisfy it's conditions. By contrast, the SatisfyingSetLink is declarative, and can be used during (PLN) reasoning and/or Markov (Viterbi) parsing: viz: if something satisfies this, then I can conclude this other thing.

Type specifiers are allowed to explicitly bind the variables in a MeetLink, such as TypedVariableLinks and VariableLists. Thus, for example, the following constrains variable A to be

  (MeetLink
     (VariableList
         (TypedVariableLink
             (VariableNode "$A")
             (TypeNode "ConceptNode"))
         (VariableNode "$B"))
     (InheritanceLink
          (VariableNode "$A")
          (VariableNode "$B")))

By default, MeetLink finds all free variables in an expression, and binds them. Thus, if you wish to specify type restrictions for one variable, then you must provide a variable binding for all of the relevant variables; else they will become unbound.

MeetLink is fully implemented; the above example works today. Use cog-execute! to run it; see /examples/guile/simple.scm for an example.

Conversion to GetLink

The GetLink is functionally equivalent to saying

CollectionOfLink
   MeetLink
      ...

This is because the CollectionOfLink takes the QueueValue returned by MeetLink, and converts it into a SetLink, which is the same thing as what GetLink does.

Equivalence to QueryLink

Observe that MeetLink, as descried above, is completely equivalent to

 QueryLink
     <clause containing free variables>
     ListLink
        <the variables>

Observe also that QueryLink is almost equivalent to a MeetLink and a PutLink combined. That is, the form

  QueryLink
     <clauses containing variables>
     <re-write clauses>

is the almost exactly same thing as

  PutLink
     <re-write clauses>
     MeetLink
        <clauses containing variables>

A concrete example should help to illustrate this. Consider the following QueryLink:

QueryLink
   WhizzyLink
       SomeAtom "widget"
       VariableNode "$x"
   FooBarLink
       SomeAtom "thing-a-ma-bob"
       VariableNode "$x"

When the above is executed, it will find all possible groundings for the VariableNode $x, and it would then produce a SetLink containing a FooBarLink for each grounding. Exactly the same effect can be achieved by executing the following:

PutLink
   FooBarLink
       SomeAtom "thing-a-ma-bob"
       VariableNode "$x"
   MeetLink
       WhizzyLink
           SomeAtom "widget"
           VariableNode "$x"
   

When the MeetLink above is run, it will return a SetLink containing all possible groundings for the variable. The PutLink then takes this as an argument, substitutes those groundings for the variable in FooBarLink, and creates a bunch of FooBarLinks with the grounded values in them.

Multiplicity

The above carefully states "almost exactly". So when do they differ? They differ whenever the MeetLink might return several different values, which, inserted into the Put, results in the same final value. In this case, the Meet-Put combination would return multiple identical results, while the QueryLink would return one unique result. Consider, for example

PutLink
   FooBarLink
       SomeAtom "thing-a-ma-bob"
       VariableNode "$x"
   MeetLink
       WhizzyLink
           SomeAtom "widget"
           VariableNode "$x"
           VariableNode "$y"


If the variable $x can be grounded one way, and the variable $y five ways, then the result of executing the PutLink will result in five identical copies of FooBarLink. By contrast

QueryLink
   WhizzyLink
       SomeAtom "widget"
       VariableNode "$x"
       VariableNode "$y"
   FooBarLink
       SomeAtom "thing-a-ma-bob"
       VariableNode "$x"

will result in only one (unique) instance of FooBarLink. And so, except for this difference in multiplicity, QueryLink and Meet-Put both produce the same results.