The TypeIntersectionLink (also called TypeSetLink, a synonymous name) is a type constructor for grouping together multiple typing properties into one unit. Currently, its primary use is to variadic (variable-length) lists for glob matching with GlobNode. It allows a type specifier to be combined with a length, so that for a match to occur, both the type specification and the length constraint must hold.
More generally, it can be used to compute the intersection of type specifications. See Wikipedia Intersection Type for a general overview.
The TypeIntersectionLink 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.
The name "TypeSet" is a synonym that requires less ... typing.
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:
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
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.
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.
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.
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.
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.
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"