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:

```    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.

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.

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.

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

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
TypeNode "ConceptNode"
NumberNode 3
NumberNode -1
```

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

```SignatureLink
TypeNode "ConceptNode"
NumberNode 4
NumberNode 5
```

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

```SignatureLink
TypeNode "PredicateNode"
NumberNode 2
NumberNode 3
TypeNode "ConceptNode"
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
```

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
```

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

```TypeSet
TypeChoice
Type "ConceptNode"
Type "NumberNode"
TypeChoice
Type "PredicateNode"
Type "ConceptNode"
```

is exactly the same as saying

```TypeChoice
Type "ConceptNode"
```

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
Type "ConceptNode"
Type "NumberNode"
Interval
Number "2"
Number "-1"
```

A list of two or more EvaluationLinks:

``` TypeSet
Evaluation
Type "PredicateNode"
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"