TypeSetLink

From OpenCog
Jump to: navigation, search

The TypeSetLink is a type constructor for grouping together multiple typing properties into one unit. Currently, its primary use is in conjunction with IntervalLink, to specify and constrain variadic (variable-length) lists. One such use is illustrated in GlobNode, to construct variable-length matching, and another in deep types, to specify variadic lists.

The TypeSetLink is a type constructor, defining a new type out of a set of type definitions which must all hold true simultaneously. Thus, it might have been called "TypeAndLink". Most of the examples show variadic behavior; however, this is not the only use, as the intersection of sets of types is also possible.

Variadic collections

The TypeSetLink can be used to specify a variadic collection of atom types. For example, collection of either two or three ConceptNodes can be written as:

    TypeSet
        Interval
            Number  2
            Number  3
        Type "ConceptNode"

The only purpose served here is to group the IntervalLink together with the TypeNode, to create a composite type, having the properties of specifying both a length interval and an Atom type. That is, the TypeSetLink is a type constructor.

Variadic and type intersection

Although TypeSet is type intersection, it is implicitly assumed that any type, such as

Type "ConceptNode"

is a variadic type with interval

Interval
  Number 1
  Number 1

and mentioning a new interval overwrites such that default. Thus TypeSet can be used both as variadic and type intersection constructor without introducing ambiguities.

Variadic globbing

The GlobNode is a kind of VariableNode that is inherently variadic, allowing a grounding by zero or more Atoms. The TypeSetLink can be used to alter and constrain the grounding. For example, the following specifies a GlobNode that can be grounded by a ConceptNode, two or three times (only):

TypedVariable
    Glob   "$foo"
    TypeSet
        Interval
            Number  2
            Number  3
        Type "ConceptNode"

The above expression states that the GlobNode "$foo" must match a list of ConceptNodes of length two or length three, but no other lengths. It is implicit in the GlobNode that it always works with lists; thus an explicit declaration of a ListLink is not required.

Variadic lists

The TypeSetLink can be used to specify variable-length list arguments in the following manner:

Signature
   Evaluation
      Type "PredicateNode"
      List
         TypeSet 
             Type "ConceptNode"
             Interval
                 Number 3
                 Number -1

The above would be the signature of any EvaluationLink that required three or more ConceptNode's in it's argument list. Observe that the value of "-1" was used to represent unboundedness: The minimum length of the list is three, but the maximum length is unbounded.

Another way to say the same thing would be to write

Signature
   Evaluation
      Type "PredicateNode"
      List
         Type "ConceptNode"
         Type "ConceptNode"
         Type "ConceptNode"
         TypeSet 
             Type "ConceptNode"
             Interval
                 Number 0
                 Number -1

which explicitly lists three ConceptNodes at the start, followed by zero or more additional ConceptNodes.

Compare this to the simpler specification below, which asks for exactly two ConceptNodes in the argument list.

Signature
   Evaluation
      Type "PredicateNode"
      List
         Type "ConceptNode"
         Type "ConceptNode"

The above could also be written in the perverse, but completely valid fashion:

Signature
   Evaluation
      Type "PredicateNode"
      List
         TypeSet 
             Type "ConceptNode"
             Interval
                 Number 2
                 Number 2

The above states that the ListLink must contain two and exactly two ConceptNodes.

See the wiki pages for SignatureLink, ArrowLink and TypedAtomLink for examples of where these constructions are useful, in practice.

Variadic sets

There is no particular reason to restrict the use of the IntervalLink to specify the length of lists: it could also be used to specify the size of sets, or of other Link types. For example:

SignatureLink
   AndLink
      TypeSetLink 
          TypeNode "ConceptNode"
          IntervalLink
              NumberNode 3
              NumberNode -1

specifies an AndLink that must contain three or more ConceptNodes. Similarly,

SignatureLink
   SetLink
      TypeSetLink 
          TypeNode "ConceptNode"
          IntervalLink
              NumberNode 4
              NumberNode 5

specifies a SetLink that must contain exactly 4 or 5 ConceptNodes. These can be combined:

SignatureLink
   SetLink
      TypeSetLink 
          TypeNode "PredicateNode"
          IntervalLink
              NumberNode 2
              NumberNode 3
      TypeSetLink 
          TypeNode "ConceptNode"
          IntervalLink
              NumberNode 4
              NumberNode 5

states that something must be a SetLink that contains 2 or 3 PredicateNodes, and also contains 4 or 5 ConceptNodes.

Variadic functions

The TypeSetLink can be combined with the ArrowLink to specify variadic functions. For example, the type of PlusLink and TimesLink is

Arrow
    TypeSet
        Type "NumberNode"
        Interval
            Number 1
            Number -1
    Type "NumberNode"

That is, these two links are functions that take a list of one or more NumberNodes as input, and return a NumberNode as output. (This is a bit of an oversimplification: the PlusLink and TimesLink also allow variables (for symbolic algebra) and numeric Values (for Value formulas) as arguments.)

Type ranges (intersection and union)

A range of types can be specified by using the TypeSetLink with the TypeInhNode and the TypeCoInhNode, to form a conjunction. Thus, for example, to force the variable "$foo" to be a SetLink, an UnorderedLink, or any type in between, one could write

TypedVariable
    Variable "$foo"
    TypeSet
        TypeInh "UnorderedLink"
        TypeCoInh "SetLink"

The above requires that "$foo" have at least the type UnorderedLink, but nothing derived from SetLink. Recall that the SetLink is a special case of the UnorderedLink. At the time of this writing, there are no other types in between UnorderedLink and SetLink, so the above is completely equivalent to

TypedVariable
    Variable "$foo"
    TypeChoice
        Type "UnorderedLink"
        Type "SetLink"

In general, TypeSetLink performs an intersection of any specified ranges. For example,

TypeSet
    TypeChoice
        Type "ConceptNode"
        Type "NumberNode"
        Type "UnorderedLink"
        Type "EvaluationLink"
    TypeChoice
        Type "PredicateNode"
        Type "ConceptNode"
        Type "EvaluationLink"
        Type "ListLink"

is exactly the same as saying

TypeChoice
    Type "ConceptNode"
    Type "EvaluationLink"

Recall that TypeChoiceLink is effectively behaving as a set-union, for types.

More examples

Below are some additional examples, repeating what was said above, but providing specific examples:

A list of 2 or more numbers:

 TypeSet
     Type "NumberNode"
     Interval
         Number "2"
         Number "-1"

A list of two or more number/concept nodes, mixed up in arbitrary order:

 TypeSet
     TypeChoice
         Type "NumberNode" 
         Type "ConceptNode"
     Interval
         Number "2"
         Number "-1"

A list of two or more number nodes, only, or a list of concept nodes, only (no mixing allowed):

 TypeChoice
     TypeSet
         Type "NumberNode" 
         Interval
             Number "2"
             Number "-1"
     TypeSet
         Type "ConceptNode" 
         Interval
             Number "2"
             Number "-1"

A list of alternating concept-number pairs of arbitrary length (but even-numbered; the two must alternate one-for-one Concept-Number-Concept-Number-...)

 TypeSet
     Signature
         Type "ConceptNode" 
         Type "NumberNode"
     Interval
         Number "2"
         Number "-1"

In the above, SignatureLink is acting like a bracket, specifying a list of two types. The ListLink cannot be used for bracketing, because it already has a different meaning, when mixed in with type declarations, as the next example shows.

A list of two or more ListLinks, with each ListLink being concept-number:

 TypeSet
     ListLink
         Type "ConceptNode" 
         Type "NumberNode"
     Interval
         Number "2"
         Number "-1"

A list of two or more EvaluationLinks:

 TypeSet
     Evaluation
         Type "PredicateNode" 
         ListLink
             Type "ConceptNode"
             Type "ConceptNode"
     Interval
         Number "2"
         Number "-1"

A list of two or more "is-inside-of" EvaluationLinks:

 TypeSet
     Evaluation
         PredicateNode "is-inside-of" 
         ListLink
             Type "ConceptNode"
             Type "ConceptNode"
     Interval
         Number "2"
         Number "-1"