1. Using generators

As usual, for shortening the notations, we export the library combinat:

  export(combinat):

We leave it as exercise to the reader to try the following examples, and guess what each of the constructed generator actually does:

  g:=generators::fromRange(1..4):

  g := generators::fromNext(0,_plus,1):

  g := generators::fromUnrank(r->if r < 4 then r^2 else FAIL end_if, 4):

  g := generators::map(generators::fromNext(0, _plus, 1), id^2):

  g := generators::concat(generators::fromList([a,b,c]),

                        generators::fromList([1,2,3])):

  g := generators::cartesian(generators::fromList([a,b]),

                     generators::fromList([1,2])):

  g := generators::fromRange(1..5):

  f := generators::powerset(g, 3):

  g := generators::select(generators::fromRange(1..100), isprime):

  g := generators::pipe(generators::fromRange(1..4),

                      n -> generators::repeater(n,n)):

Lists of n integers such that 1<=l[i]<=n.

  codeGen :=

proc(n)

begin

    if n=0 then

        generators::singleton([]);

    else

        generators::pipe

        (codeGen(n-1),

         (list,n) -> generators::map

                 (generators::fromRange(1..n),

                  (i, list)->append(list,i),

                  list),

         n

        );

    end_if;

end_proc: