Cat::CombinatorialClass – the category of combinatorial classes

Cat::CombinatorialClass represents the category of combinatorial classes, that is, the category of sets that can be enumerated, counted, …

→ Examples

Categories

Cat::BaseCategory

Details:

Entries

"domtype"

The MuPAD  domain of the object belonging to the class. Since a combinatorial class can be a façade domain, it can be different from dom.

Basic Methods

isA – membership testing

Cat::CombinatorialClass::isA(x, <size s, constraints c>)

Checks if the object x belongs to the combinatorial class. If optional s or c are given, checks further if x has size s and satisfies the constraints.

Apart from sequences, any MuPAD object x shall be accepted as input. On the other hand isA is allowed to raise type errors about the size and constraints.

The return value is a boolean (DOM_BOOL). TRUE and FALSE shall be guaranted answers. In case the membership testing is too costly (if not infeasible), isA may return the MuPAD value UNKNOWN. The default implementation is to always return UNKNOWN.

This function plays a role which is closely related to the testtype mechanism. However it is more general, because of the optional size and constraints arguments, and because an UNKNOWN answer is allowed. Cat::CombinatorialClass provides a default implementation of testtype which uses isA. An UNKNOWN answer is then translated into TRUE; indeed, the most common use case is type checking of arguments: there, when we can't decide whether an input argument, we want to accept it.

size – size of an object

Cat::CombinatorialClass::size(dom x)

Returns the size of an object of the class.

count – number of objects

Cat::CombinatorialClass::count(<size s, constraints c>)

Returns the number of objects of the class. If the class is infinite then s must be given. In this case count returns the number of objects of the class of the size s. Moreover, if c is given, returns the number of objects of the class of the size s satisfying the extra constraints c.

The category provides a default implementation using generator.

countApproximate – approximate number of objects

Cat::CombinatorialClass::countApproximate(<size s, constraints c>)

Returns the order of magnitude of the result of count(...).

The only quality requirement is that it should return infinity if and only if count returns infinity. The main purpose is for heuristic decisions depending on the order of magnitude of the size of the combinatorial class.

The category provides a default implementation using count if the later is non trivial.

list – list of the objects

Cat::CombinatorialClass::list(<size s, constraints c>)

Returns whether the combinatorial class is finite, or UNKNOWN.

The category provides a default implementation using countApproximate if the later is defined.

list – list of the objects

Cat::CombinatorialClass::list(<size s, constraints c>)

Returns the list of objects of the class. If the class is infinite then s must be given. In this case list returns the list of objects of the class of the size s. Moreover, if c is given, returns the list of objects of the class of the size s satisfying the extra constraints c.

If cl is a combinatorial class, the call cl(size) is a shortcut for cl::list(size). Note that this shortcut should be reserved at the interactive level an not during programming.

The category provides a default implementation using generator.

generator – generator for the objects

Cat::CombinatorialClass::generator(<size s, constraints c>)

Returns a generator for the objects of the class. If s or c is given, returns a generator for the objects of the class of the size s satisfying the extra constraints c.

This category provides the following methods that can be used as default implementations of cl::generator for cl a class in this category:

So for example, to set cl::generator to cl::generatorFromList requires the implementation of cl::list.

first – first object

Cat::CombinatorialClass::first(<size s, constraints c>)

Returns the first object of the class. If s or c is given, returns the first object of the class of the size s satisfying the extra constraints c.

last – last object

Cat::CombinatorialClass::last(<size s, constraints c>)

Returns the last object of the class. If s or c is given, returns the last object of the class of the size s satisfying the extra constraints c.

Next – next object

Cat::CombinatorialClass::Next(dom o, <size s, constraints c>)

Returns the next object of the class. If s or c is given, returns the next object of the class of the size s satisfying the extra constraints c.

previous – previous object

Cat::CombinatorialClass::previous(dom o, <size s, constraints c>)

Returns the previous object of the class. If s or c is given, returns the previous object of the class of the size s satisfying the extra constraints c.

rank – rank object

Cat::CombinatorialClass::rank(dom o, <size s, constraints c>)

Returns the rank of the object o in the list of the objects belonging to the class. If s or c is given, returns the rank of the object o in the list of the object of the class of the size s satisfying the extra constraints c.

unrank – unrank object

Cat::CombinatorialClass::unrank(nonnegative integer n, <size s, constraints c>)

Returns the n-th object of the class. If s or c is given, returns the n-th object of the class of the size s satisfying the extra constraints c.

random – random object

Cat::CombinatorialClass::random(<size s, constraints c>)

Returns a random object of the class. If s or c is given, returns a random object of the class of the size s satisfying the extra constraints c.

_less – comparison of two objects

Cat::CombinatorialClass::_less(dom o1, dom o2)

Whenever it is possible, this method compares the objects o1 and o2 and returns TRUE if o1 is smaller than o2.

This method is optional.

generatingSeries – the generating series of the class

Cat::CombinatorialClass::generatingSeries(variable z)

The generating series of a class math is defined as

math,

where math is the set of objects in math of size math. Thus the coefficient of math in the generating series math is the number of objects of size math. Whenever it is possible, this method returns an expression for the generating series.

Default Count/List Methods

The following methods are provided to help writing a combinatorial class. They are not supposed to be called directly, they are here rather to provide default implementations to other methods.

Note that these default implementations can be very inefficient in time or space compared to ad-hoc implementations.

countFromGenerator – count the number of objects using generation

Cat::CombinatorialClass::countFromGenerator(<size s, constraints c>)

Returns the number of objects of the class. The counting is done by generating all the objects step by step.

This is the default implementation for the count method if nothing else is provided.

listFromGenerator – list the number of objects using generation

Cat::CombinatorialClass::listFromGenerator(<size s, constraints c>)

Returns the list of objects of the class. This is done by generating all the objects step by step, using size-doubling arrays to avoid the reallocation of the list at each step.

This is the default implementation for the list method if nothing else is provided.

Default Generator Implementations

The following methods can be used to provide default implementations for cl::generator with cl a combinatorial class. This category tries, in the following order, to use these implementations when the necessary functions are defined:

If none of the preceding methods has been successful because the necessary methods are not provided in cl, an error is raised at the first call of cl::generator. This also applies to the first call of cl::count or cl::list if they are using a default implementation via generator.

generatorFromNext – generator for the objects using first and Next

Cat::CombinatorialClass::generatorFromNext(<size s, constraints c>)

Returns a generator for the objects of the class. This is done by calling Next at each step, which is usually a relatively good implementation with respect to time and space.

This is the default implementation for the generator methods if first and Next are provided.

generatorFromPrevious – generator for the objects using last and previous

Cat::CombinatorialClass::generatorFromPrevious(<size s, constraints c>)

Returns a generator for the objects of the class. This is done by calling previous at each step, which is usually a relatively good implementation with respect to time and space.

generatorFromUnrank – generator for the objects using unrank

Cat::CombinatorialClass::generatorFromUnrank(<size s, constraints c>)

Returns a generator for the objects of the class. This is done by calling unrank at each step, which is usually a relatively good implementation with respect to time and space.

generatorFromList – generator for the objects using list

Cat::CombinatorialClass::generatorFromList(<size s, constraints c>)

Returns a generator for the objects of the class. This is done by expanding the list when the generator is constructed.

This is the fallback implementation of generator if noting better is possible. This is very inefficient with respect to memory space.

Example 1:

Suppose that you want to define the combinatorial class of the binary vectors. The size is the length of the vector. It is easy to write a Next function considering that a vector is a binary expansion of a number. This is done by searching the first math and replacing the initial sequence math by math. Here is a way to do this:

    nextBinExp := proc(lst)

        local pos;

    begin

       if (pos := contains(lst, 0)) <> 0 then

           [ 0$(pos-1), 1, op(lst, pos+1..nops(lst))]

       else FAIL

       end_if; 

    end:

    nextBinExp([1, 1, 0, 1, 0, 1, 1, 0]);

math

We can use this to build a combinatorial class. We have to define isA for the type checking and first and Next for generation :

domain ZeroOneVectors

    inherits Dom::BaseDomain;

    category Cat::CombinatorialClass, Cat::FacadeDomain(DOM_LIST);

 

    isA := // Type checking.

    proc(obj         : Type::AnyType,

        size = FAIL : Type::Union(Type::NonNegInt, DOM_FAIL)) : DOM_BOOL

    begin

        if domtype(obj) <> DOM_LIST then return(FALSE); end_if;

        if {op(obj)} minus {0,1} <> {} then return(FALSE); end_if;

        if args(0) = 1 then return(TRUE);

        else

            bool(nops(obj) = size);

        end_if;

    end_proc;

 

    size  := proc(v : dom) : Type::NonNegInt begin nops(v); end_proc;

 

    first := proc(size : Type::NonNegInt) : dom

             begin

                 [ 0 $ size ];

             end_proc;

 

    Next := proc(lst : dom) : Type::Union(DOM_FAIL, dom)

                local pos;

            begin

                if (pos := contains(lst, 0)) <> 0 then

                    [ 0$(pos-1), 1, op(lst, pos+1..nops(lst))]

                else FAIL

                end_if; 

            end_proc;

end_domain:

The type checking is working:

testtype([1, 0, 1], ZeroOneVectors);

testtype([1, 0, 2], ZeroOneVectors)

math

math

The method list is provided by Cat::CombinatorialClass via the default implementation using generator:

ZeroOneVectors::list(3)

math

together with the method generator:

g := ZeroOneVectors::generator(2):

g(), g(), g(), g(), g()

math

The following useful shortcut is also defined

ZeroOneVectors(3)

math

A default implementation is provided for the count method:

ZeroOneVectors::count(4)

math

However, this is very slow since it simply generates all the elements and counts them:

ZeroOneVectors::count(10);

time(ZeroOneVectors::count(10))

math

math

Whenever possible, it is better to implement the count method:

ZeroOneVectors::count := i -> 2^i:

ZeroOneVectors::count(10);

time(ZeroOneVectors::count(10))

math

math