cardinality

Counting Methods

The second number a report gives is the count of canonical pure, total, parametric implementations a method or constructor admits with everything in scope — what it can access, capture or call. def choose[A](x: A, y: A): A has 2 (x or y). A constructor is counted as the product of its parameters' value spaces: Pair[A](x: A, y: A) has 4 ways to build its product, IntArrBuilder(initialCapacity: Int) is 2^32, and Slice(arr: Array[Any], offset: Int, length: Int) is ω.

This is a different question from the stored-value estimate on the data type: Pair[Int] still holds 2^64 values. A parameter whose space the estimate cannot read whole — a type parameter nobody supplied, a name outside the sources — stays with the shape model, which names it.

The rules below follow Alex Knvl's Counting type inhabitants (24 November 2018). ReferenceInhabitantsSpec is the executable form of the examples.

The rules

ω is a productive cycle: def use[A](x: A, step: A => A): A can return x, step(x), step(step(x)), … — countably many. A cycle with no starting inhabitant is 0, not ω. An enclosing value, a callable producer and a product projection all count as captures, and a type parameter's identity is per binder, so a shadowed A is not an outer A.

What the analysis cannot read is ?, with the reason. The section header sums the reasons into a triage list:

Generic method / constructor implementation cardinalities
  53 signatures: 41 finite · 3 countably infinite · 9 unresolved
  8 unresolved on: unresolved type
  1 unresolved on: given environment not resolved

4  example.Pair.<init>  Pair[A](left: A, right: A)  Light.scala:11  [constructor]
1  example.Accessor.get  get[X, A](fa: (X, A)): A  Accessor.scala:18  [method]
    captures: tupleAccessor

Repeated arguments

Type.Repeated(T) in a method or constructor parameter is a finite, possibly empty sequence of T, not one supplied T: Σ_{n≥0} Xⁿ. Parameter clauses keep their ordering and binder identities. This is a pure, total implementation count, not a stored-value estimate for Scala's Seq representation.

Signature or shape goal Count Reason
def ignore[A](xs: A*): Unit 1 Only the Unit result is observable
def pick[A](x: A)(xs: Nothing*): A 1 xs is necessarily empty
case class Empty(xs: Nothing*) constructor 1 The only field sequence is empty
Sequence-of-A shape goal with no A producer 1 Only Nil
Sequence-of-A shape goal with x: A ω Productive Cons cycle, distinct lengths
def use[A](x: A)(fs: (A => A)*): A ? Arbitrary sequence elimination is outside the fragment
case class Many[A](xs: A*) constructor ? Arbitrary input-sequence transformations are not enumerated

The solver does not enumerate total length tests, safe element selection, mapping, folds or recursive sequence elimination. When a supplied sequence can be present in a non-singleton goal, it reports:

Repeated-argument sequence elimination is unsupported (length tests, selection and folds)

Element types still use the ordinary resolver and environment checks. General Seq[T] names, aliases and collection methods are not resolved by this feature.

What the reference supports that the solver does not

Where the solver is deliberately narrower