New Upstream Snapshot - gap-design

Ready changes

Summary

Merged new upstream version: 1.7+git20230112.1.de06555+ds (was: 1.7+ds).

Resulting package

Built on 2023-01-19T09:47 (took 13m28s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots gap-design

Lintian Result

Diff

diff --git a/.codecov.yml b/.codecov.yml
new file mode 100644
index 0000000..198a32a
--- /dev/null
+++ b/.codecov.yml
@@ -0,0 +1,19 @@
+coverage:
+  precision: 2
+  round: down
+  range: "70...100"
+
+  status:
+    project: no
+    patch: yes
+    changes: no
+
+comment:
+  layout: "header, diff, changes, tree"
+  behavior: default
+
+ignore:
+  - "PackageInfo.g"
+  - "init.g"
+  - "read.g"
+  - "tst/**"  # ignore test harness code
diff --git a/README.md b/README.md
index 2b992a5..3ae7132 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ DESIGN is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version. For details, see 
-<http://www.gnu.org/licenses/gpl.html>.
+<https://www.gnu.org/licenses/gpl.html>.
 
 Please reference your use of the DESIGN package in a published work
 as follows:
diff --git a/debian/changelog b/debian/changelog
index 651418e..060f3e3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+gap-design (1.7+git20230112.1.de06555+ds-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Thu, 19 Jan 2023 09:37:01 -0000
+
 gap-design (1.7+ds-3) unstable; urgency=medium
 
   [Jerome Benoit]
diff --git a/debian/patches/debianization.patch b/debian/patches/debianization.patch
index 75baeb9..0ce3164 100644
--- a/debian/patches/debianization.patch
+++ b/debian/patches/debianization.patch
@@ -6,9 +6,11 @@ Forwarded: not-needed
 Author: Jerome Benoit <calculus@rezozer.net>
 Last-Update: 2019-04-25
 
---- a/PackageInfo.g
-+++ b/PackageInfo.g
-@@ -25,7 +25,7 @@
+Index: gap-design.git/PackageInfo.g
+===================================================================
+--- gap-design.git.orig/PackageInfo.g
++++ gap-design.git/PackageInfo.g
+@@ -25,7 +25,7 @@ ArchiveURL      := Concatenation( ~.Sour
  
  ArchiveFormats := ".tar.gz", 
  
@@ -17,8 +19,10 @@ Last-Update: 2019-04-25
  
  Persons := [
    rec(
---- a/doc/manual.tex
-+++ b/doc/manual.tex
+Index: gap-design.git/doc/manual.tex
+===================================================================
+--- gap-design.git.orig/doc/manual.tex
++++ gap-design.git/doc/manual.tex
 @@ -8,7 +8,7 @@
  %%
  %F  gapmacro . . . . . . . . . . . . . . . .  read the GAP macro package
@@ -28,8 +32,10 @@ Last-Update: 2019-04-25
  %
  %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
---- a/doc/make_doc
-+++ b/doc/make_doc
+Index: gap-design.git/doc/make_doc
+===================================================================
+--- gap-design.git.orig/doc/make_doc
++++ gap-design.git/doc/make_doc
 @@ -4,32 +4,44 @@
  #W  make_doc          make Example Package documentation          Greg Gamble
  ##
diff --git a/doc/design.tex b/doc/design.tex
index 0f8e0a9..287af13 100644
--- a/doc/design.tex
+++ b/doc/design.tex
@@ -20,12 +20,15 @@ The {\DESIGN} package is Copyright {\copyright} Leonard H. Soicher
 2003--2019.  {\DESIGN} is part of a wider project, which received EPSRC
 funding under grant GR/R29659/01, to provide a web-based resource for
 design theory; see \URL{http://designtheory.org} and \cite{Dotw}.
+The development of {\DESIGN} is currently supported by EPSRC grant
+EP/M022641/1 (CoDiMa: a Collaborative Computational Project in the area
+of Computational Discrete Mathematics).
 
 {\DESIGN} is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version. For details, see 
-\URL{http://www.gnu.org/licenses/gpl.html}
+\URL{https://www.gnu.org/licenses/gpl.html}
 
 Please reference your use of the {\DESIGN} package in a published work
 as follows:
@@ -45,7 +48,7 @@ to install the package locally or are installing an upgrade of {\DESIGN}
 to an existing installation of {\GAP} (see the main {\GAP} reference
 section "ref:Installing a GAP Package").  If you do need to download
 {\DESIGN}, you can find archive files for the package in various formats
-at \URL{http://www.gap-system.org/Packages/design.html}, and then your
+at \URL{https://www.gap-system.org/Packages/design.html}, and then your
 archive file of choice should be downloaded and unpacked in the `pkg'
 subdirectory of an appropriate GAP root directory (see the main {\GAP}
 reference section "ref:GAP Root Directories").
diff --git a/doc/manual.bib b/doc/manual.bib
index 133a57f..5aef656 100644
--- a/doc/manual.bib
+++ b/doc/manual.bib
@@ -50,7 +50,7 @@ journal	= "Discrete Math.",
 volume  = "306",
 year    = "2006",
 pages   = "3014--3027", 
-note	= "\URL{http://dx.doi.org/10.1016/j.disc.2004.10.027}",
+note	= "\URL{https://doi.org/10.1016/j.disc.2004.10.027}",
 }
 
 @article{BaCh,
@@ -92,7 +92,7 @@ journal	= "Bull. London Math. Soc.",
 volume  = "39",
 year    = "2007",
 pages   = "559--564", 
-note	= "\URL{http://dx.doi.org/10.1112/blms/bdm034}",
+note	= "\URL{https://doi.org/10.1112/blms/bdm034}",
 }
 
 @article{McSo,
@@ -102,7 +102,7 @@ journal	= "European J. Combinatorics",
 volume  = "28",
 year    = "2007",
 pages   = "567--571",
-note    = "\URL{http://dx.doi.org/10.1016/j.ejc.2005.02.003}",
+note    = "\URL{https://doi.org/10.1016/j.ejc.2005.02.003}",
 }
 
 @article{Soi1,
@@ -113,7 +113,7 @@ journal	= "J. Comb. Theory, Ser. A",
 volume  = "117",
 year    = "2010",
 pages   = "799--809",
-note    = "\URL{http://dx.doi.org/10.1016/j.jcta.2010.03.005}",
+note    = "\URL{https://doi.org/10.1016/j.jcta.2010.03.005}",
 }
 
 @manual{Grape,
@@ -158,6 +158,6 @@ journal = "J. Symbolic Comput.",
 volume = "60",
 pages = "94--112",
 year = "2014",
-doi = "http://dx.doi.org/10.1016/j.jsc.2013.09.003",
+doi = "https://doi.org/10.1016/j.jsc.2013.09.003",
 }
 
diff --git a/doc/manual.example-1.tst b/doc/manual.example-1.tst
new file mode 100644
index 0000000..f15a4a4
--- /dev/null
+++ b/doc/manual.example-1.tst
@@ -0,0 +1,72 @@
+gap> H:=CyclicGroup(IsPermGroup,20);
+Group([ (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) ])
+gap> D:=BlockDesigns(rec(v:=21,blockSizes:=[4,5],
+>       tSubsetStructure:=rec(t:=2,lambdas:=[1]),
+>       requiredAutSubgroup:=H ));;
+gap> Length(D);
+1
+gap> D:=D[1];;
+gap> BlockSizes(D);
+[ 4, 5 ]
+gap> BlockNumbers(D);
+[ 20, 9 ]
+gap> Size(AutGroupBlockDesign(D));
+80
+gap> Dstar:=TDesignFromTBD(D,2,4);;
+gap> AllTDesignLambdas(Dstar);
+[ 105, 20, 3 ]
+gap> IsSimpleBlockDesign(Dstar);
+false
+gap> Size(AutGroupBlockDesign(Dstar));
+80
+gap> near_resolutions:=PartitionsIntoBlockDesigns(rec(
+>    blockDesign:=Dstar,
+>    v:=21,blockSizes:=[4],
+>    tSubsetStructure:=rec(t:=0,lambdas:=[5]),
+>    blockIntersectionNumbers:=[[ [0] ]],
+>    requiredAutSubgroup:=SylowSubgroup(H,5) ));;
+gap> Length(near_resolutions);
+2
+gap> List(near_resolutions,x->Size(x.autGroup));
+[ 5, 20 ]
+gap> Print(Dstar,"\n");
+rec(
+  isBlockDesign := true,
+  v := 21,
+  blocks := [ [ 1, 2, 4, 15 ], [ 1, 2, 4, 15 ], [ 1, 2, 4, 15 ],
+      [ 1, 3, 14, 20 ], [ 1, 3, 14, 20 ], [ 1, 3, 14, 20 ], [ 1, 5, 9, 13 ],
+      [ 1, 5, 9, 17 ], [ 1, 5, 13, 17 ], [ 1, 6, 11, 16 ], [ 1, 6, 11, 21 ],
+      [ 1, 6, 16, 21 ], [ 1, 7, 8, 10 ], [ 1, 7, 8, 10 ], [ 1, 7, 8, 10 ],
+      [ 1, 9, 13, 17 ], [ 1, 11, 16, 21 ], [ 1, 12, 18, 19 ],
+      [ 1, 12, 18, 19 ], [ 1, 12, 18, 19 ], [ 2, 3, 5, 16 ], [ 2, 3, 5, 16 ],
+      [ 2, 3, 5, 16 ], [ 2, 6, 10, 14 ], [ 2, 6, 10, 18 ], [ 2, 6, 14, 18 ],
+      [ 2, 7, 12, 17 ], [ 2, 7, 12, 21 ], [ 2, 7, 17, 21 ], [ 2, 8, 9, 11 ],
+      [ 2, 8, 9, 11 ], [ 2, 8, 9, 11 ], [ 2, 10, 14, 18 ], [ 2, 12, 17, 21 ],
+      [ 2, 13, 19, 20 ], [ 2, 13, 19, 20 ], [ 2, 13, 19, 20 ],
+      [ 3, 4, 6, 17 ], [ 3, 4, 6, 17 ], [ 3, 4, 6, 17 ], [ 3, 7, 11, 15 ],
+      [ 3, 7, 11, 19 ], [ 3, 7, 15, 19 ], [ 3, 8, 13, 18 ], [ 3, 8, 13, 21 ],
+      [ 3, 8, 18, 21 ], [ 3, 9, 10, 12 ], [ 3, 9, 10, 12 ], [ 3, 9, 10, 12 ],
+      [ 3, 11, 15, 19 ], [ 3, 13, 18, 21 ], [ 4, 5, 7, 18 ], [ 4, 5, 7, 18 ],
+      [ 4, 5, 7, 18 ], [ 4, 8, 12, 16 ], [ 4, 8, 12, 20 ], [ 4, 8, 16, 20 ],
+      [ 4, 9, 14, 19 ], [ 4, 9, 14, 21 ], [ 4, 9, 19, 21 ], [ 4, 10, 11, 13 ],
+      [ 4, 10, 11, 13 ], [ 4, 10, 11, 13 ], [ 4, 12, 16, 20 ],
+      [ 4, 14, 19, 21 ], [ 5, 6, 8, 19 ], [ 5, 6, 8, 19 ], [ 5, 6, 8, 19 ],
+      [ 5, 9, 13, 17 ], [ 5, 10, 15, 20 ], [ 5, 10, 15, 21 ],
+      [ 5, 10, 20, 21 ], [ 5, 11, 12, 14 ], [ 5, 11, 12, 14 ],
+      [ 5, 11, 12, 14 ], [ 5, 15, 20, 21 ], [ 6, 7, 9, 20 ], [ 6, 7, 9, 20 ],
+      [ 6, 7, 9, 20 ], [ 6, 10, 14, 18 ], [ 6, 11, 16, 21 ],
+      [ 6, 12, 13, 15 ], [ 6, 12, 13, 15 ], [ 6, 12, 13, 15 ],
+      [ 7, 11, 15, 19 ], [ 7, 12, 17, 21 ], [ 7, 13, 14, 16 ],
+      [ 7, 13, 14, 16 ], [ 7, 13, 14, 16 ], [ 8, 12, 16, 20 ],
+      [ 8, 13, 18, 21 ], [ 8, 14, 15, 17 ], [ 8, 14, 15, 17 ],
+      [ 8, 14, 15, 17 ], [ 9, 14, 19, 21 ], [ 9, 15, 16, 18 ],
+      [ 9, 15, 16, 18 ], [ 9, 15, 16, 18 ], [ 10, 15, 20, 21 ],
+      [ 10, 16, 17, 19 ], [ 10, 16, 17, 19 ], [ 10, 16, 17, 19 ],
+      [ 11, 17, 18, 20 ], [ 11, 17, 18, 20 ], [ 11, 17, 18, 20 ] ],
+  autGroup := Group( [ ( 2,14,10,18)( 3, 7,19,15)( 4,20, 8,12)( 5,13,17, 9),
+      ( 1,17, 5, 9)( 2,10,14, 6)( 4,16,12,20)( 7,15,19,11),
+      ( 1,18,19,12)( 2,11, 8, 9)( 3, 4,17, 6)( 5,10,15,20)( 7,16,13,14) ] ),
+  blockSizes := [ 4 ],
+  isBinary := true,
+  allTDesignLambdas := [ 105, 20, 3 ],
+  isSimple := false )
diff --git a/doc/manual.example-10.tst b/doc/manual.example-10.tst
new file mode 100644
index 0000000..1e3f44a
--- /dev/null
+++ b/doc/manual.example-10.tst
@@ -0,0 +1,15 @@
+gap> D:=[ BlockDesign(3, [[1,2],[1,3]]),
+>      BlockDesign(3, [[1,2],[1,2],[2,3]]) ];;
+gap> designs:=rec(list:=D, pairwiseNonisomorphic:=true);;
+gap> BlockDesignsToXMLFile("example.xml",designs,[],"example");
+gap> BlockDesignsFromXMLFile("example.xml");
+rec(
+  infoXML := "<info>\n<software>\n[ DESIGN-1.7, GRAPE-4.8.2, GAPDoc-1.6.2, GAP\
+-4.10.1 ]\n</software>\n</info>",
+  list :=
+    [
+      rec( blocks := [ [ 1, 2 ], [ 1, 3 ] ], id := "example-0",
+          isBinary := true, isBlockDesign := true, v := 3 ),
+      rec( blocks := [ [ 1, 2 ], [ 1, 2 ], [ 2, 3 ] ], id := "example-1",
+          isBinary := true, isBlockDesign := true, v := 3 ) ],
+  pairwiseNonisomorphic := true )
diff --git a/doc/manual.example-2.tst b/doc/manual.example-2.tst
new file mode 100644
index 0000000..7592e19
--- /dev/null
+++ b/doc/manual.example-2.tst
@@ -0,0 +1,74 @@
+gap> TDesignLambdas(5,24,8,1);
+[ 759, 253, 77, 21, 5, 1 ]
+gap> TDesignLambdaMin(5,24,8);
+1
+gap> TDesignLambdaMin(2,12,4);
+3
+gap> TDesignLambdas(2,12,4,3);
+[ 33, 11, 3 ]
+gap> TDesignIntersectionTriangle(2,12,4,3);
+[ [ 33, 22, 14 ], [ 11, 8 ], [ 3 ] ]
+gap> TDesignLambdas(2,12,4,2);
+fail
+gap> TDesignIntersectionTriangle(2,12,4,2);
+fail
+gap> SteinerSystemIntersectionTriangle(5,24,8);
+[ [ 759, 506, 330, 210, 130, 78, 46, 30, 30 ],
+  [ 253, 176, 120, 80, 52, 32, 16, 0 ], [ 77, 56, 40, 28, 20, 16, 16 ],
+  [ 21, 16, 12, 8, 4, 0 ], [ 5, 4, 4, 4, 4 ], [ 1, 0, 0, 0 ], [ 1, 0, 0 ],
+  [ 1, 0 ], [ 1 ] ]
+gap> TDesignIntersectionTriangle(5,24,8,1);
+[ [ 759, 506, 330, 210, 130, 78 ], [ 253, 176, 120, 80, 52 ],
+  [ 77, 56, 40, 28 ], [ 21, 16, 12 ], [ 5, 4 ], [ 1 ] ]
+gap> TDesignBlockMultiplicityBound(5,16,7,5);
+2
+gap> TDesignBlockMultiplicityBound(2,36,6,1);
+0
+gap> TDesignBlockMultiplicityBound(2,36,6,2);
+2
+gap> TDesignBlockMultiplicityBound(2,15,5,2);
+0
+gap> TDesignBlockMultiplicityBound(2,15,5,4);
+2
+gap> TDesignBlockMultiplicityBound(2,11,4,6);
+3
+gap> ResolvableTDesignBlockMultiplicityBound(5,12,6,1);
+1
+gap> ResolvableTDesignBlockMultiplicityBound(2,21,7,3);
+0
+gap> TDesignBlockMultiplicityBound(2,21,7,3);
+1
+gap> ResolvableTDesignBlockMultiplicityBound(2,12,4,3);
+1
+gap> TDesignBlockMultiplicityBound(2,12,4,3);
+2
+gap> OARunMultiplicityBound(81,14,3,3);
+1
+gap> OARunMultiplicityBound(81,15,3,3);
+0
+gap> OARunMultiplicityBound(36,[18,1,1],[2,3,6],2);
+1
+gap> OARunMultiplicityBound(72,7,6,2);
+2
+gap> OARunMultiplicityBound(72,8,6,2);
+1
+gap> x:=Indeterminate(Rationals,1);
+x_1
+gap> m:=[0,0,0,0,0,0,0,1];;
+gap> lambdavec:=TDesignLambdas(6,14,7,4);
+[ 1716, 858, 396, 165, 60, 18, 4 ]
+gap> B:=BlockIntersectionPolynomial(x,m,lambdavec);
+1715*x_1^6-10269*x_1^5+34685*x_1^4-69615*x_1^3+84560*x_1^2-56196*x_1+15120
+gap> Factors(B);
+[ 1715*x_1-1715,
+  x_1^5-1222/245*x_1^4+3733/245*x_1^3-6212/245*x_1^2+5868/245*x_1-432/49 ]
+gap> Value(B,1);
+0
+gap> m:=[0,0,0,0,0,0,0,1];;
+gap> lambdavec:=TDesignLambdas(6,14,7,4);
+[ 1716, 858, 396, 165, 60, 18, 4 ]
+gap> BlockIntersectionPolynomialCheck(m,lambdavec);
+true
+gap> m:=[1,0,0,0,0,0,0,1];;
+gap> BlockIntersectionPolynomialCheck(m,lambdavec);
+false
diff --git a/doc/manual.example-3.tst b/doc/manual.example-3.tst
new file mode 100644
index 0000000..35fc716
--- /dev/null
+++ b/doc/manual.example-3.tst
@@ -0,0 +1,244 @@
+gap> BlockDesign( 2, [[1,2],[1],[1,2]] );
+rec( isBlockDesign := true, v := 2, blocks := [ [ 1 ], [ 1, 2 ], [ 1, 2 ] ] )
+gap> D:=BlockDesign(7, [[1,2,4]], Group((1,2,3,4,5,6,7)));
+rec( isBlockDesign := true, v := 7,
+  blocks := [ [ 1, 2, 4 ], [ 1, 3, 7 ], [ 1, 5, 6 ], [ 2, 3, 5 ],
+      [ 2, 6, 7 ], [ 3, 4, 6 ], [ 4, 5, 7 ] ],
+  autSubgroup := Group([ (1,2,3,4,5,6,7) ]) )
+gap> AllTDesignLambdas(D);
+[ 7, 3, 1 ]
+gap> D:=AGPointFlatBlockDesign(2,4,1);
+rec( isBlockDesign := true, v := 16,
+  blocks := [ [ 1, 2, 3, 4 ], [ 1, 5, 9, 13 ], [ 1, 6, 11, 16 ],
+      [ 1, 7, 12, 14 ], [ 1, 8, 10, 15 ], [ 2, 5, 12, 15 ], [ 2, 6, 10, 14 ],
+      [ 2, 7, 9, 16 ], [ 2, 8, 11, 13 ], [ 3, 5, 10, 16 ], [ 3, 6, 12, 13 ],
+      [ 3, 7, 11, 15 ], [ 3, 8, 9, 14 ], [ 4, 5, 11, 14 ], [ 4, 6, 9, 15 ],
+      [ 4, 7, 10, 13 ], [ 4, 8, 12, 16 ], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ],
+      [ 13, 14, 15, 16 ] ],
+  autSubgroup := Group([ (5,9,13)(6,10,14)(7,11,15)(8,12,16),
+      (2,5,6)(3,9,11)(4,13,16)(7,14,12)(8,10,15),
+      (1,5)(2,6)(3,7)(4,8)(9,13)(10,14)(11,15)(12,16),
+      (3,4)(7,8)(9,13)(10,14)(11,16)(12,15) ]),
+  pointNames := [ [ 0*Z(2), 0*Z(2) ], [ 0*Z(2), Z(2)^0 ], [ 0*Z(2), Z(2^2) ],
+      [ 0*Z(2), Z(2^2)^2 ], [ Z(2)^0, 0*Z(2) ], [ Z(2)^0, Z(2)^0 ],
+      [ Z(2)^0, Z(2^2) ], [ Z(2)^0, Z(2^2)^2 ], [ Z(2^2), 0*Z(2) ],
+      [ Z(2^2), Z(2)^0 ], [ Z(2^2), Z(2^2) ], [ Z(2^2), Z(2^2)^2 ],
+      [ Z(2^2)^2, 0*Z(2) ], [ Z(2^2)^2, Z(2)^0 ], [ Z(2^2)^2, Z(2^2) ],
+      [ Z(2^2)^2, Z(2^2)^2 ] ] )
+gap> AllTDesignLambdas(D);
+[ 20, 5, 1 ]
+gap> D:=PGPointFlatBlockDesign(3,2,1);
+rec( isBlockDesign := true, v := 15,
+  blocks := [ [ 1, 2, 3 ], [ 1, 4, 5 ], [ 1, 6, 7 ], [ 1, 8, 9 ],
+      [ 1, 10, 11 ], [ 1, 12, 13 ], [ 1, 14, 15 ], [ 2, 4, 6 ], [ 2, 5, 7 ],
+      [ 2, 8, 10 ], [ 2, 9, 11 ], [ 2, 12, 14 ], [ 2, 13, 15 ], [ 3, 4, 7 ],
+      [ 3, 5, 6 ], [ 3, 8, 11 ], [ 3, 9, 10 ], [ 3, 12, 15 ], [ 3, 13, 14 ],
+      [ 4, 8, 12 ], [ 4, 9, 13 ], [ 4, 10, 14 ], [ 4, 11, 15 ], [ 5, 8, 13 ],
+      [ 5, 9, 12 ], [ 5, 10, 15 ], [ 5, 11, 14 ], [ 6, 8, 14 ], [ 6, 9, 15 ],
+      [ 6, 10, 12 ], [ 6, 11, 13 ], [ 7, 8, 15 ], [ 7, 9, 14 ],
+      [ 7, 10, 13 ], [ 7, 11, 12 ] ],
+  autSubgroup := Group([ (8,12)(9,13)(10,14)(11,15),
+      (1,2,4,8)(3,6,12,9)(5,10)(7,14,13,11) ]),
+  pointNames := [ <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)> ] )
+gap> AllTDesignLambdas(D);
+[ 35, 7, 1 ]
+gap> W24:=WittDesign(24);;
+gap> AllTDesignLambdas(W24);
+[ 759, 253, 77, 21, 5, 1 ]
+gap> DisplayCompositionSeries(AutomorphismGroup(W24));
+G (3 gens, size 244823040)
+ \ M(24)
+1 (0 gens, size 1)
+gap> W10:=WittDesign(10);;
+gap> AllTDesignLambdas(W10);
+[ 30, 12, 4, 1 ]
+gap> DisplayCompositionSeries(AutomorphismGroup(W10));
+G (4 gens, size 1440)
+ \ Z(2)
+S (4 gens, size 720)
+ \ Z(2)
+S (3 gens, size 360)
+ \ A(6) ~ A(1,9) = L(2,9) ~ B(1,9) = O(3,9) ~ C(1,9) = S(2,9) ~ 2A(1,9) = U(2,\
+9)
+1 (0 gens, size 1)
+gap> D:=BlockDesign(4,[[1,3],[2,3,4],[3,4]]);;
+gap> dualD:=DualBlockDesign(D);
+rec( isBlockDesign := true, v := 3,
+  blocks := [ [ 1 ], [ 1, 2, 3 ], [ 2 ], [ 2, 3 ] ],
+  pointNames := [ [ 1, 3 ], [ 2, 3, 4 ], [ 3, 4 ] ] )
+gap> DualBlockDesign(dualD).blocks;
+[ [ 1, 2 ], [ 2, 3, 4 ], [ 2, 4 ] ]
+gap> D:=PGPointFlatBlockDesign(2,2,1);
+rec( isBlockDesign := true, v := 7,
+  pointNames := [ <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)> ],
+  blocks := [ [ 1, 2, 3 ], [ 1, 4, 5 ], [ 1, 6, 7 ], [ 2, 4, 6 ],
+      [ 2, 5, 7 ], [ 3, 4, 7 ], [ 3, 5, 6 ] ] )
+gap> AllTDesignLambdas(D);
+[ 7, 3, 1 ]
+gap> C:=ComplementBlocksBlockDesign(D);
+rec( isBlockDesign := true, v := 7,
+  blocks := [ [ 1, 2, 4, 7 ], [ 1, 2, 5, 6 ], [ 1, 3, 4, 6 ], [ 1, 3, 5, 7 ],
+      [ 2, 3, 4, 5 ], [ 2, 3, 6, 7 ], [ 4, 5, 6, 7 ] ],
+  pointNames := [ <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)>,
+      <vector space of dimension 1 over GF(2)> ] )
+gap> AllTDesignLambdas(C);
+[ 7, 4, 2 ]
+gap> D:=BlockDesigns(rec(v:=11,blockSizes:=[5],
+>       tSubsetStructure:=rec(t:=2,lambdas:=[2])))[1];
+rec( isBlockDesign := true, v := 11,
+  blocks := [ [ 1, 2, 3, 4, 5 ], [ 1, 2, 9, 10, 11 ], [ 1, 3, 6, 7, 9 ],
+      [ 1, 4, 7, 8, 10 ], [ 1, 5, 6, 8, 11 ], [ 2, 3, 6, 8, 10 ],
+      [ 2, 4, 6, 7, 11 ], [ 2, 5, 7, 8, 9 ], [ 3, 4, 8, 9, 11 ],
+      [ 3, 5, 7, 10, 11 ], [ 4, 5, 6, 9, 10 ] ],
+  tSubsetStructure := rec( t := 2, lambdas := [ 2 ] ), isBinary := true,
+  isSimple := true, blockSizes := [ 5 ], blockNumbers := [ 11 ], r := 5,
+  autGroup := Group([ (2,4)(3,5)(7,11)(8,9), (1,3)(2,5)(7,9)(10,11),
+      (1,5,3)(6,11,7)(8,10,9), (1,10,5,2,11,3)(4,9,7)(6,8) ]) )
+gap> AllTDesignLambdas(D);
+[ 11, 5, 2 ]
+gap> DP:=DeletedPointsBlockDesign(D,[5,8]);
+rec( isBlockDesign := true, v := 9,
+  blocks := [ [ 1, 2, 3, 4 ], [ 1, 2, 7, 8, 9 ], [ 1, 3, 5, 6, 7 ],
+      [ 1, 4, 6, 8 ], [ 1, 5, 9 ], [ 2, 3, 5, 8 ], [ 2, 4, 5, 6, 9 ],
+      [ 2, 6, 7 ], [ 3, 4, 7, 9 ], [ 3, 6, 8, 9 ], [ 4, 5, 7, 8 ] ],
+  pointNames := [ 1, 2, 3, 4, 6, 7, 9, 10, 11 ] )
+gap> PairwiseBalancedLambda(DP);
+2
+gap> D:=BlockDesign(7,[[1,2,4],[1,2,4]],Group((1,2,3,4,5,6,7)));
+rec( isBlockDesign := true, v := 7,
+  blocks := [ [ 1, 2, 4 ], [ 1, 2, 4 ], [ 1, 3, 7 ], [ 1, 3, 7 ],
+      [ 1, 5, 6 ], [ 1, 5, 6 ], [ 2, 3, 5 ], [ 2, 3, 5 ], [ 2, 6, 7 ],
+      [ 2, 6, 7 ], [ 3, 4, 6 ], [ 3, 4, 6 ], [ 4, 5, 7 ], [ 4, 5, 7 ] ],
+  autSubgroup := Group([ (1,2,3,4,5,6,7) ]) )
+gap> DeletedBlocksBlockDesign(D,[[2,3,5],[2,3,5],[4,5,7]]);
+rec( isBlockDesign := true, v := 7,
+  blocks := [ [ 1, 2, 4 ], [ 1, 2, 4 ], [ 1, 3, 7 ], [ 1, 3, 7 ],
+      [ 1, 5, 6 ], [ 1, 5, 6 ], [ 2, 6, 7 ], [ 2, 6, 7 ], [ 3, 4, 6 ],
+      [ 3, 4, 6 ], [ 4, 5, 7 ] ] )
+gap> D:=BlockDesign(7,[[1,2,4],[1,2,4]],Group((1,2,3,4,5,6,7)));
+rec( isBlockDesign := true, v := 7,
+  blocks := [ [ 1, 2, 4 ], [ 1, 2, 4 ], [ 1, 3, 7 ], [ 1, 3, 7 ],
+      [ 1, 5, 6 ], [ 1, 5, 6 ], [ 2, 3, 5 ], [ 2, 3, 5 ], [ 2, 6, 7 ],
+      [ 2, 6, 7 ], [ 3, 4, 6 ], [ 3, 4, 6 ], [ 4, 5, 7 ], [ 4, 5, 7 ] ],
+  autSubgroup := Group([ (1,2,3,4,5,6,7) ]) )
+gap> AddedPointBlockDesign(D,[[2,3,5],[2,3,5],[4,5,7]],"infinity");
+rec( isBlockDesign := true, v := 8,
+  blocks := [ [ 1, 2, 4 ], [ 1, 2, 4 ], [ 1, 3, 7 ], [ 1, 3, 7 ],
+      [ 1, 5, 6 ], [ 1, 5, 6 ], [ 2, 3, 5, 8 ], [ 2, 3, 5, 8 ], [ 2, 6, 7 ],
+      [ 2, 6, 7 ], [ 3, 4, 6 ], [ 3, 4, 6 ], [ 4, 5, 7 ], [ 4, 5, 7, 8 ] ],
+  pointNames := [ 1, 2, 3, 4, 5, 6, 7, "infinity" ] )
+gap> D:=BlockDesign(7,[[1,2,4]],Group((1,2,3,4,5,6,7)));
+rec( isBlockDesign := true, v := 7,
+  blocks := [ [ 1, 2, 4 ], [ 1, 3, 7 ], [ 1, 5, 6 ], [ 2, 3, 5 ],
+      [ 2, 6, 7 ], [ 3, 4, 6 ], [ 4, 5, 7 ] ],
+  autSubgroup := Group([ (1,2,3,4,5,6,7) ]) )
+gap> AddedBlocksBlockDesign(D,D.blocks);
+rec( isBlockDesign := true, v := 7,
+  blocks := [ [ 1, 2, 4 ], [ 1, 2, 4 ], [ 1, 3, 7 ], [ 1, 3, 7 ],
+      [ 1, 5, 6 ], [ 1, 5, 6 ], [ 2, 3, 5 ], [ 2, 3, 5 ], [ 2, 6, 7 ],
+      [ 2, 6, 7 ], [ 3, 4, 6 ], [ 3, 4, 6 ], [ 4, 5, 7 ], [ 4, 5, 7 ] ] )
+gap> D:=BlockDesigns(rec(v:=11,blockSizes:=[5],
+>       tSubsetStructure:=rec(t:=2,lambdas:=[2])))[1];
+rec( isBlockDesign := true, v := 11,
+  blocks := [ [ 1, 2, 3, 4, 5 ], [ 1, 2, 9, 10, 11 ], [ 1, 3, 6, 7, 9 ],
+      [ 1, 4, 7, 8, 10 ], [ 1, 5, 6, 8, 11 ], [ 2, 3, 6, 8, 10 ],
+      [ 2, 4, 6, 7, 11 ], [ 2, 5, 7, 8, 9 ], [ 3, 4, 8, 9, 11 ],
+      [ 3, 5, 7, 10, 11 ], [ 4, 5, 6, 9, 10 ] ],
+  tSubsetStructure := rec( t := 2, lambdas := [ 2 ] ), isBinary := true,
+  isSimple := true, blockSizes := [ 5 ], blockNumbers := [ 11 ], r := 5,
+  autGroup := Group([ (2,4)(3,5)(7,11)(8,9), (1,3)(2,5)(7,9)(10,11),
+      (1,5,3)(6,11,7)(8,10,9), (1,10,5,2,11,3)(4,9,7)(6,8) ]) )
+gap> AllTDesignLambdas(D);
+[ 11, 5, 2 ]
+gap> DD:=DerivedBlockDesign(D,6);
+rec( isBlockDesign := true, v := 10,
+  blocks := [ [ 1, 3, 6, 8 ], [ 1, 5, 7, 10 ], [ 2, 3, 7, 9 ],
+      [ 2, 4, 6, 10 ], [ 4, 5, 8, 9 ] ],
+  pointNames := [ 1, 2, 3, 4, 5, 7, 8, 9, 10, 11 ] )
+gap> AllTDesignLambdas(DD);
+[ 5, 2 ]
+gap> DD:=DerivedBlockDesign(D,D.blocks[6]);
+rec( isBlockDesign := true, v := 5,
+  blocks := [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 2, 3 ], [ 2, 4 ],
+      [ 2, 5 ], [ 3, 4 ], [ 3, 5 ], [ 4, 5 ] ],
+  pointNames := [ 2, 3, 6, 8, 10 ] )
+gap> AllTDesignLambdas(DD);
+[ 10, 4, 1 ]
+gap> D:=BlockDesigns(rec(v:=11,blockSizes:=[5],
+>       tSubsetStructure:=rec(t:=2,lambdas:=[2])))[1];
+rec( isBlockDesign := true, v := 11,
+  blocks := [ [ 1, 2, 3, 4, 5 ], [ 1, 2, 9, 10, 11 ], [ 1, 3, 6, 7, 9 ],
+      [ 1, 4, 7, 8, 10 ], [ 1, 5, 6, 8, 11 ], [ 2, 3, 6, 8, 10 ],
+      [ 2, 4, 6, 7, 11 ], [ 2, 5, 7, 8, 9 ], [ 3, 4, 8, 9, 11 ],
+      [ 3, 5, 7, 10, 11 ], [ 4, 5, 6, 9, 10 ] ],
+  tSubsetStructure := rec( t := 2, lambdas := [ 2 ] ), isBinary := true,
+  isSimple := true, blockSizes := [ 5 ], blockNumbers := [ 11 ], r := 5,
+  autGroup := Group([ (2,4)(3,5)(7,11)(8,9), (1,3)(2,5)(7,9)(10,11),
+      (1,5,3)(6,11,7)(8,10,9), (1,10,5,2,11,3)(4,9,7)(6,8) ]) )
+gap> AllTDesignLambdas(D);
+[ 11, 5, 2 ]
+gap> RD:=ResidualBlockDesign(D,6);
+rec( isBlockDesign := true, v := 10,
+  blocks := [ [ 1, 2, 3, 4, 5 ], [ 1, 2, 8, 9, 10 ], [ 1, 4, 6, 7, 9 ],
+      [ 2, 5, 6, 7, 8 ], [ 3, 4, 7, 8, 10 ], [ 3, 5, 6, 9, 10 ] ],
+  pointNames := [ 1, 2, 3, 4, 5, 7, 8, 9, 10, 11 ] )
+gap> AllTDesignLambdas(RD);
+[ 6, 3 ]
+gap> RD:=ResidualBlockDesign(D,D.blocks[6]);
+rec( isBlockDesign := true, v := 6,
+  blocks := [ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 3, 6 ], [ 1, 4, 5 ],
+      [ 1, 5, 6 ], [ 2, 3, 5 ], [ 2, 4, 6 ], [ 2, 5, 6 ], [ 3, 4, 5 ],
+      [ 3, 4, 6 ] ], pointNames := [ 1, 4, 5, 7, 9, 11 ] )
+gap> AllTDesignLambdas(RD);
+[ 10, 5, 2 ]
+gap> D:=BlockDesigns(rec(v:=10, blockSizes:=[3,4],
+>          tSubsetStructure:=rec(t:=2,lambdas:=[1])))[1];
+rec( isBlockDesign := true, v := 10,
+  blocks := [ [ 1, 2, 3, 4 ], [ 1, 5, 6, 7 ], [ 1, 8, 9, 10 ], [ 2, 5, 10 ],
+      [ 2, 6, 8 ], [ 2, 7, 9 ], [ 3, 5, 9 ], [ 3, 6, 10 ], [ 3, 7, 8 ],
+      [ 4, 5, 8 ], [ 4, 6, 9 ], [ 4, 7, 10 ] ],
+  tSubsetStructure := rec( t := 2, lambdas := [ 1 ] ), isBinary := true,
+  isSimple := true, blockSizes := [ 3, 4 ], blockNumbers := [ 9, 3 ],
+  autGroup := Group([ (5,6,7)(8,9,10), (2,3)(5,7)(8,10),
+      (2,3,4)(5,7,6)(8,9,10), (2,3,4)(5,9,6,8,7,10), (2,6,9,3,7,10)(4,5,8) ])
+ )
+gap> PairwiseBalancedLambda(D);
+1
+gap> Dstar:=TDesignFromTBD(D,2,3);
+rec( isBlockDesign := true, v := 10,
+  blocks := [ [ 1, 2, 3 ], [ 1, 2, 4 ], [ 1, 3, 4 ], [ 1, 5, 6 ],
+      [ 1, 5, 7 ], [ 1, 6, 7 ], [ 1, 8, 9 ], [ 1, 8, 10 ], [ 1, 9, 10 ],
+      [ 2, 3, 4 ], [ 2, 5, 10 ], [ 2, 5, 10 ], [ 2, 6, 8 ], [ 2, 6, 8 ],
+      [ 2, 7, 9 ], [ 2, 7, 9 ], [ 3, 5, 9 ], [ 3, 5, 9 ], [ 3, 6, 10 ],
+      [ 3, 6, 10 ], [ 3, 7, 8 ], [ 3, 7, 8 ], [ 4, 5, 8 ], [ 4, 5, 8 ],
+      [ 4, 6, 9 ], [ 4, 6, 9 ], [ 4, 7, 10 ], [ 4, 7, 10 ], [ 5, 6, 7 ],
+      [ 8, 9, 10 ] ],
+  autGroup := Group([ (5,6,7)(8,9,10), (2,3)(5,7)(8,10), (2,3,4)(5,7,6)(8,9,
+        10), (2,3,4)(5,9,6,8,7,10), (2,6,9,3,7,10)(4,5,8) ]) )
+gap> AllTDesignLambdas(Dstar);
+[ 30, 9, 2 ]
diff --git a/doc/manual.example-4.tst b/doc/manual.example-4.tst
new file mode 100644
index 0000000..d9ee08b
--- /dev/null
+++ b/doc/manual.example-4.tst
@@ -0,0 +1,79 @@
+gap> IsBlockDesign(5);
+false
+gap> IsBlockDesign( BlockDesign(2,[[1],[1,2],[1,2]]) );
+true
+gap> IsBinaryBlockDesign( BlockDesign(2,[[1],[1,2],[1,2]]) );
+true
+gap> IsBinaryBlockDesign( BlockDesign(2,[[1],[1,2],[1,2,2]]) );
+false
+gap> IsSimpleBlockDesign( BlockDesign(2,[[1],[1,2],[1,2]]) );
+false
+gap> IsSimpleBlockDesign( BlockDesign(2,[[1],[1,2],[1,2,2]]) );
+true
+gap> IsConnectedBlockDesign( BlockDesign(2,[[1],[2]]) );
+false
+gap> IsConnectedBlockDesign( BlockDesign(2,[[1,2]]) );
+true
+gap> D:=BlockDesign(3,[[1,2],[1,3],[2,3],[2,3]]);
+rec( isBlockDesign := true, v := 3,
+  blocks := [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 3 ] ] )
+gap> BlockDesignPoints(D);
+[ 1 .. 3 ]
+gap> D:=BlockDesign(3,[[1,2],[1,3],[2,3],[2,3]]);
+rec( isBlockDesign := true, v := 3,
+  blocks := [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 3 ] ] )
+gap> NrBlockDesignPoints(D);
+3
+gap> D:=BlockDesign(3,[[1,2],[1,3],[2,3],[2,3]]);
+rec( isBlockDesign := true, v := 3,
+  blocks := [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 3 ] ] )
+gap> BlockDesignBlocks(D);
+[ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 3 ] ]
+gap> D:=BlockDesign(3,[[1,2],[1,3],[2,3],[2,3]]);
+rec( isBlockDesign := true, v := 3,
+  blocks := [ [ 1, 2 ], [ 1, 3 ], [ 2, 3 ], [ 2, 3 ] ] )
+gap> NrBlockDesignBlocks(D);
+4
+gap> BlockSizes( BlockDesign(3,[[1],[1,2,2],[1,2,3],[2],[3]]) );
+[ 1, 3 ]
+gap> D:=BlockDesign(3,[[1],[1,2,2],[1,2,3],[2],[3]]);
+rec( isBlockDesign := true, v := 3,
+  blocks := [ [ 1 ], [ 1, 2, 2 ], [ 1, 2, 3 ], [ 2 ], [ 3 ] ] )
+gap> BlockSizes(D);
+[ 1, 3 ]
+gap> BlockNumbers(D);
+[ 3, 2 ]
+gap> ReplicationNumber(BlockDesign(4,[[1],[1,2],[2,3,3],[4,4]]));
+2
+gap> ReplicationNumber(BlockDesign(4,[[1],[1,2],[2,3],[4,4]]));
+fail
+gap> D:=BlockDesigns(rec(v:=10, blockSizes:=[3,4],
+>          tSubsetStructure:=rec(t:=2,lambdas:=[1])))[1];
+rec( isBlockDesign := true, v := 10,
+  blocks := [ [ 1, 2, 3, 4 ], [ 1, 5, 6, 7 ], [ 1, 8, 9, 10 ], [ 2, 5, 10 ],
+      [ 2, 6, 8 ], [ 2, 7, 9 ], [ 3, 5, 9 ], [ 3, 6, 10 ], [ 3, 7, 8 ],
+      [ 4, 5, 8 ], [ 4, 6, 9 ], [ 4, 7, 10 ] ],
+  tSubsetStructure := rec( t := 2, lambdas := [ 1 ] ), isBinary := true,
+  isSimple := true, blockSizes := [ 3, 4 ], blockNumbers := [ 9, 3 ],
+  autGroup := Group([ (5,6,7)(8,9,10), (2,3)(5,7)(8,10),
+      (2,3,4)(5,7,6)(8,9,10), (2,3,4)(5,9,6,8,7,10), (2,6,9,3,7,10)(4,5,8) ])
+ )
+gap> PairwiseBalancedLambda(D);
+1
+gap> D:=BlockDesign(3,[[1],[1,2,2],[1,2,3],[2],[3]]);;
+gap> TSubsetLambdasVector(D,0);
+[ 5 ]
+gap> TSubsetLambdasVector(D,1);
+[ 3, 4, 2 ]
+gap> TSubsetLambdasVector(D,2);
+[ 3, 1, 1 ]
+gap> TSubsetLambdasVector(D,3);
+[ 1 ]
+gap> AllTDesignLambdas(PGPointFlatBlockDesign(3,2,1));
+[ 35, 7, 1 ]
+gap> P:=PGPointFlatBlockDesign(2,3,1);; # projective plane of order 3
+gap> AffineResolvableMu(P);
+fail
+gap> A:=ResidualBlockDesign(P,P.blocks[1]);; # affine plane of order 3
+gap> AffineResolvableMu(A);
+1
diff --git a/doc/manual.example-5.tst b/doc/manual.example-5.tst
new file mode 100644
index 0000000..5411c22
--- /dev/null
+++ b/doc/manual.example-5.tst
@@ -0,0 +1,85 @@
+gap> D:=DualBlockDesign(AGPointFlatBlockDesign(2,3,1));;
+gap> BlockDesignBlocks(D);
+[ [ 1, 2, 3, 4 ], [ 1, 5, 6, 7 ], [ 1, 8, 9, 10 ], [ 2, 5, 8, 11 ],
+  [ 2, 7, 9, 12 ], [ 3, 5, 10, 12 ], [ 3, 6, 9, 11 ], [ 4, 6, 8, 12 ],
+  [ 4, 7, 10, 11 ] ]
+gap> PointBlockIncidenceMatrix(D);
+[ [ 1, 1, 1, 0, 0, 0, 0, 0, 0 ], [ 1, 0, 0, 1, 1, 0, 0, 0, 0 ],
+  [ 1, 0, 0, 0, 0, 1, 1, 0, 0 ], [ 1, 0, 0, 0, 0, 0, 0, 1, 1 ],
+  [ 0, 1, 0, 1, 0, 1, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0, 1, 1, 0 ],
+  [ 0, 1, 0, 0, 1, 0, 0, 0, 1 ], [ 0, 0, 1, 1, 0, 0, 0, 1, 0 ],
+  [ 0, 0, 1, 0, 1, 0, 1, 0, 0 ], [ 0, 0, 1, 0, 0, 1, 0, 0, 1 ],
+  [ 0, 0, 0, 1, 0, 0, 1, 0, 1 ], [ 0, 0, 0, 0, 1, 1, 0, 1, 0 ] ]
+gap> D:=DualBlockDesign(AGPointFlatBlockDesign(2,3,1));;
+gap> BlockDesignBlocks(D);
+[ [ 1, 2, 3, 4 ], [ 1, 5, 6, 7 ], [ 1, 8, 9, 10 ], [ 2, 5, 8, 11 ],
+  [ 2, 7, 9, 12 ], [ 3, 5, 10, 12 ], [ 3, 6, 9, 11 ], [ 4, 6, 8, 12 ],
+  [ 4, 7, 10, 11 ] ]
+gap> ConcurrenceMatrix(D);
+[ [ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 ],
+  [ 1, 3, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1 ],
+  [ 1, 1, 3, 1, 1, 1, 0, 0, 1, 1, 1, 1 ],
+  [ 1, 1, 1, 3, 0, 1, 1, 1, 0, 1, 1, 1 ],
+  [ 1, 1, 1, 0, 3, 1, 1, 1, 0, 1, 1, 1 ],
+  [ 1, 0, 1, 1, 1, 3, 1, 1, 1, 0, 1, 1 ],
+  [ 1, 1, 0, 1, 1, 1, 3, 0, 1, 1, 1, 1 ],
+  [ 1, 1, 0, 1, 1, 1, 0, 3, 1, 1, 1, 1 ],
+  [ 1, 1, 1, 0, 0, 1, 1, 1, 3, 1, 1, 1 ],
+  [ 1, 0, 1, 1, 1, 0, 1, 1, 1, 3, 1, 1 ],
+  [ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 0 ],
+  [ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 3 ] ]
+gap> D:=DualBlockDesign(AGPointFlatBlockDesign(2,3,1));;
+gap> BlockDesignBlocks(D);
+[ [ 1, 2, 3, 4 ], [ 1, 5, 6, 7 ], [ 1, 8, 9, 10 ], [ 2, 5, 8, 11 ],
+  [ 2, 7, 9, 12 ], [ 3, 5, 10, 12 ], [ 3, 6, 9, 11 ], [ 4, 6, 8, 12 ],
+  [ 4, 7, 10, 11 ] ]
+gap> InformationMatrix(D);
+[ [ 9/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, 0, 0 ],
+  [ -1/4, 9/4, -1/4, -1/4, -1/4, 0, -1/4, -1/4, -1/4, 0, -1/4, -1/4 ],
+  [ -1/4, -1/4, 9/4, -1/4, -1/4, -1/4, 0, 0, -1/4, -1/4, -1/4, -1/4 ],
+  [ -1/4, -1/4, -1/4, 9/4, 0, -1/4, -1/4, -1/4, 0, -1/4, -1/4, -1/4 ],
+  [ -1/4, -1/4, -1/4, 0, 9/4, -1/4, -1/4, -1/4, 0, -1/4, -1/4, -1/4 ],
+  [ -1/4, 0, -1/4, -1/4, -1/4, 9/4, -1/4, -1/4, -1/4, 0, -1/4, -1/4 ],
+  [ -1/4, -1/4, 0, -1/4, -1/4, -1/4, 9/4, 0, -1/4, -1/4, -1/4, -1/4 ],
+  [ -1/4, -1/4, 0, -1/4, -1/4, -1/4, 0, 9/4, -1/4, -1/4, -1/4, -1/4 ],
+  [ -1/4, -1/4, -1/4, 0, 0, -1/4, -1/4, -1/4, 9/4, -1/4, -1/4, -1/4 ],
+  [ -1/4, 0, -1/4, -1/4, -1/4, 0, -1/4, -1/4, -1/4, 9/4, -1/4, -1/4 ],
+  [ 0, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, 9/4, 0 ],
+  [ 0, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, -1/4, 0, 9/4 ] ]
+gap> D:=DualBlockDesign(AGPointFlatBlockDesign(2,3,1));;
+gap> BlockDesignBlocks(D);
+[ [ 1, 2, 3, 4 ], [ 1, 5, 6, 7 ], [ 1, 8, 9, 10 ], [ 2, 5, 8, 11 ],
+  [ 2, 7, 9, 12 ], [ 3, 5, 10, 12 ], [ 3, 6, 9, 11 ], [ 4, 6, 8, 12 ],
+  [ 4, 7, 10, 11 ] ]
+gap> BlockDesignEfficiency(D);
+rec( A := 33/41,
+  CEFpolynomial := x_1^11-9*x_1^10+147/4*x_1^9-719/8*x_1^8+18723/128*x_1^7-106\
+47/64*x_1^6+138159/1024*x_1^5-159813/2048*x_1^4+2067201/65536*x_1^3-556227/655\
+36*x_1^2+89667/65536*x_1-6561/65536, Dpowered := 6561/65536,
+  Einterval := [ 3/4, 3/4 ] )
+gap> BlockDesignEfficiency(D,10^(-4),true);
+rec( A := 33/41,
+  CEFpolynomial := x_1^11-9*x_1^10+147/4*x_1^9-719/8*x_1^8+18723/128*x_1^7-106\
+47/64*x_1^6+138159/1024*x_1^5-159813/2048*x_1^4+2067201/65536*x_1^3-556227/655\
+36*x_1^2+89667/65536*x_1-6561/65536, Dpowered := 6561/65536,
+  Einterval := [ 3/4, 3/4 ], MV := 3/4 )
+gap> x:=Indeterminate(Rationals,1);
+x_1
+gap> f:=(x+3)*(x^2-3);
+x_1^3+3*x_1^2-3*x_1-9
+gap> L:=DESIGN_IntervalForLeastRealZero(f,-5,5,10^(-3));
+[ -3, -3 ]
+gap> L:=DESIGN_IntervalForLeastRealZero(f,-2,5,10^(-3));
+[ -14193/8192, -7093/4096 ]
+gap> List(L,Float);
+[ -1.73254, -1.73169 ]
+gap> L:=DESIGN_IntervalForLeastRealZero(f,0,5,10^(-3));
+[ 14185/8192, 7095/4096 ]
+gap> List(L,Float);
+[ 1.73157, 1.73218 ]
+gap> L:=DESIGN_IntervalForLeastRealZero(f,0,5,10^(-5));
+[ 454045/262144, 908095/524288 ]
+gap> List(L,Float);
+[ 1.73204, 1.73205 ]
+gap> L:=DESIGN_IntervalForLeastRealZero(f,2,5,10^(-5));
+[  ]
diff --git a/doc/manual.example-6.tst b/doc/manual.example-6.tst
new file mode 100644
index 0000000..d25897e
--- /dev/null
+++ b/doc/manual.example-6.tst
@@ -0,0 +1,19 @@
+gap> D:=PGPointFlatBlockDesign(2,3,1);; # projective plane of order 3
+gap> Size(AutGroupBlockDesign(D));
+5616
+gap> D1:=BlockDesign(3,[[1],[1,2,3],[2]]);;
+gap> D2:=BlockDesign(3,[[1],[1,2,3],[3]]);;
+gap> IsIsomorphicBlockDesign(D1,D2);
+true
+gap> D3:=BlockDesign(4,[[1],[1,2,3],[3]]);;
+gap> IsIsomorphicBlockDesign(D2,D3);
+false
+gap> # block designs with different numbers of points are not isomorphic
+gap> D1:=BlockDesign(3,[[1],[1,2,3],[2]]);;
+gap> D2:=BlockDesign(3,[[1],[1,2,3],[3]]);;
+gap> D3:=BlockDesign(4,[[1],[1,2,3],[3]]);;
+gap> BlockDesignIsomorphismClassRepresentatives([D1,D2,D3]);
+[ rec( isBlockDesign := true, v := 4, blocks := [ [ 1 ], [ 1, 2, 3 ], [ 3 ] ],
+      isBinary := true ),
+  rec( isBlockDesign := true, v := 3, blocks := [ [ 1 ], [ 1, 2, 3 ], [ 2 ] ],
+      isBinary := true ) ]
diff --git a/doc/manual.example-7.tst b/doc/manual.example-7.tst
new file mode 100644
index 0000000..dd9ed31
--- /dev/null
+++ b/doc/manual.example-7.tst
@@ -0,0 +1,55 @@
+gap> DL:=BlockDesigns(rec(
+>    v:=15,blockSizes:=[3],
+>    tSubsetStructure:=rec(t:=2,lambdas:=[1]),
+>    requiredAutSubgroup:=
+>       Group((1,2,3,4,5)(6,7,8,9,10)(11,12,13,14,15))));;
+gap> List(DL,AllTDesignLambdas);
+[ [ 35, 7, 1 ], [ 35, 7, 1 ], [ 35, 7, 1 ] ]
+gap> List(DL,D->Size(AutGroupBlockDesign(D)));
+[ 20160, 5, 60 ]
+gap> parclasses:=List(DL,D->
+>    BlockDesigns(rec(
+>       blockDesign:=D,
+>       v:=15,blockSizes:=[3],
+>       tSubsetStructure:=rec(t:=1,lambdas:=[1]))));
+[ [ rec( isBlockDesign := true, v := 15,
+          blocks := [ [ 1, 2, 6 ], [ 3, 4, 8 ], [ 5, 7, 14 ], [ 9, 12, 15 ],
+              [ 10, 11, 13 ] ],
+          tSubsetStructure := rec( t := 1, lambdas := [ 1 ] ),
+          isBinary := true, isSimple := true, blockSizes := [ 3 ],
+          blockNumbers := [ 5 ], r := 1,
+          autSubgroup := Group([ (2,6)(3,11)(4,10)(5,14)(8,13)(12,15),
+              (2,6)(4,8)(5,12)(7,9)(10,13)(14,15),
+              (2,6)(3,12)(4,9)(7,14)(8,15)(11,13),
+              (3,12,5)(4,15,7)(8,9,14)(10,11,13),
+              (1,6,2)(3,4,8)(5,7,14)(9,12,15)(10,11,13),
+              (1,8,11,2,3,10)(4,13,6)(5,15,14,9,7,12) ]) ) ],
+  [ rec( isBlockDesign := true, v := 15,
+          blocks := [ [ 1, 7, 12 ], [ 2, 8, 13 ], [ 3, 9, 14 ],
+              [ 4, 10, 15 ], [ 5, 6, 11 ] ],
+          tSubsetStructure := rec( t := 1, lambdas := [ 1 ] ),
+          isBinary := true, isSimple := true, blockSizes := [ 3 ],
+          blockNumbers := [ 5 ], r := 1,
+          autSubgroup := Group([ (1,5,4,3,2)(6,10,9,8,7)(11,15,14,13,12) ]) )
+     ],
+  [ rec( isBlockDesign := true, v := 15, blocks := [ [ 1, 2, 6 ], [ 3, 10, 13
+                 ], [ 4, 11, 12 ], [ 5, 7, 15 ], [ 8, 9, 14 ] ],
+          tSubsetStructure := rec( t := 1, lambdas := [ 1 ] ),
+          isBinary := true, isSimple := true, blockSizes := [ 3 ],
+          blockNumbers := [ 5 ], r := 1,
+          autSubgroup := Group([ (1,2)(3,5)(7,10)(8,9)(11,12)(13,15),
+              (1,11,8)(2,12,9)(3,13,10)(4,14,6)(5,15,7) ]) ),
+      rec( isBlockDesign := true, v := 15,
+          blocks := [ [ 1, 8, 11 ], [ 2, 9, 12 ], [ 3, 10, 13 ],
+              [ 4, 6, 14 ], [ 5, 7, 15 ] ],
+          tSubsetStructure := rec( t := 1, lambdas := [ 1 ] ),
+          isBinary := true, isSimple := true, blockSizes := [ 3 ],
+          blockNumbers := [ 5 ], r := 1,
+          autSubgroup := Group([ (1,2)(3,5)(7,10)(8,9)(11,12)(13,15),
+              (1,3,4,2)(6,9,8,10)(11,13,14,12),
+              (1,3,5,2,4)(6,8,10,7,9)(11,13,15,12,14),
+              (1,11,8)(2,12,9)(3,13,10)(4,14,6)(5,15,7) ]) ) ] ]
+gap> List(parclasses,Length);
+[ 1, 1, 2 ]
+gap> List(parclasses,L->List(L,parclass->Size(parclass.autSubgroup)));
+[ [ 360 ], [ 5 ], [ 6, 60 ] ]
diff --git a/doc/manual.example-8.tst b/doc/manual.example-8.tst
new file mode 100644
index 0000000..bf864c3
--- /dev/null
+++ b/doc/manual.example-8.tst
@@ -0,0 +1,25 @@
+gap> List([1..6],k->Length(SemiLatinSquareDuals(4,k))); # weak
+[ 2, 10, 40, 164, 621, 2298 ]
+gap> List([1..6],k->Length(SemiLatinSquareDuals(4,k,"default","default",4))); # strong
+[ 2, 11, 46, 201, 829, 3343 ]
+gap> SemiLatinSquareDuals(6,3,"default",[0,1],0);
+[ rec( isBlockDesign := true, v := 36,
+      blocks := [ [ 1, 8, 15, 22, 29, 36 ], [ 1, 9, 16, 23, 30, 32 ],
+          [ 1, 12, 14, 21, 28, 35 ], [ 2, 9, 17, 24, 25, 34 ],
+          [ 2, 11, 18, 22, 27, 31 ], [ 2, 12, 16, 19, 29, 33 ],
+          [ 3, 10, 14, 24, 29, 31 ], [ 3, 11, 16, 20, 25, 36 ],
+          [ 3, 12, 13, 23, 26, 34 ], [ 4, 7, 14, 23, 27, 36 ],
+          [ 4, 8, 17, 21, 30, 31 ], [ 4, 9, 18, 19, 26, 35 ],
+          [ 5, 7, 15, 20, 30, 34 ], [ 5, 8, 13, 24, 28, 33 ],
+          [ 5, 10, 18, 21, 25, 32 ], [ 6, 7, 17, 22, 26, 33 ],
+          [ 6, 10, 13, 20, 27, 35 ], [ 6, 11, 15, 19, 28, 32 ] ],
+      tSubsetStructure := rec( t := 1, lambdas := [ 3 ] ), isBinary := true,
+      isSimple := true, blockSizes := [ 6 ], blockNumbers := [ 18 ], r := 3,
+      autSubgroup := <permutation group of size 72 with 3 generators>,
+      pointNames := [ [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ],
+          [ 1, 6 ], [ 2, 1 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 2, 5 ],
+          [ 2, 6 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], [ 3, 5 ],
+          [ 3, 6 ], [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ], [ 4, 5 ],
+          [ 4, 6 ], [ 5, 1 ], [ 5, 2 ], [ 5, 3 ], [ 5, 4 ], [ 5, 5 ],
+          [ 5, 6 ], [ 6, 1 ], [ 6, 2 ], [ 6, 3 ], [ 6, 4 ], [ 6, 5 ],
+          [ 6, 6 ] ] ) ]
diff --git a/doc/manual.example-9.tst b/doc/manual.example-9.tst
new file mode 100644
index 0000000..d6ba15b
--- /dev/null
+++ b/doc/manual.example-9.tst
@@ -0,0 +1,101 @@
+gap> DL:=BlockDesigns(rec(
+>    v:=15,blockSizes:=[3],
+>    tSubsetStructure:=rec(t:=2,lambdas:=[1]),
+>    requiredAutSubgroup:=
+>       Group((1,2,3,4,5)(6,7,8,9,10)(11,12,13,14,15))));;
+gap> List(DL,D->Size(AutGroupBlockDesign(D)));
+[ 20160, 5, 60 ]
+gap> PL:=PartitionsIntoBlockDesigns(rec(
+>       blockDesign:=DL[1],
+>       v:=15,blockSizes:=[3],
+>       tSubsetStructure:=rec(t:=1,lambdas:=[1])));
+[ rec(
+      partition := [ rec( isBlockDesign := true, v := 15, blocks := [ [ 1, 2,
+                      6 ], [ 3, 4, 8 ], [ 5, 7, 14 ], [ 9, 12, 15 ],
+                  [ 10, 11, 13 ] ] ),
+          rec( isBlockDesign := true, v := 15, blocks :=
+                [ [ 1, 3, 11 ], [ 2, 4, 12 ], [ 5, 6, 8 ], [ 7, 13, 15 ],
+                  [ 9, 10, 14 ] ] ),
+          rec( isBlockDesign := true, v := 15, blocks :=
+                [ [ 1, 4, 14 ], [ 2, 5, 15 ], [ 3, 10, 12 ], [ 6, 7, 11 ],
+                  [ 8, 9, 13 ] ] ),
+          rec( isBlockDesign := true, v := 15, blocks :=
+                [ [ 1, 5, 10 ], [ 2, 9, 11 ], [ 3, 14, 15 ], [ 4, 6, 13 ],
+                  [ 7, 8, 12 ] ] ),
+          rec( isBlockDesign := true, v := 15, blocks :=
+                [ [ 1, 7, 9 ], [ 2, 8, 10 ], [ 3, 5, 13 ], [ 4, 11, 15 ],
+                  [ 6, 12, 14 ] ] ),
+          rec( isBlockDesign := true, v := 15, blocks :=
+                [ [ 1, 8, 15 ], [ 2, 13, 14 ], [ 3, 6, 9 ], [ 4, 7, 10 ],
+                  [ 5, 11, 12 ] ] ),
+          rec( isBlockDesign := true, v := 15, blocks :=
+                [ [ 1, 12, 13 ], [ 2, 3, 7 ], [ 4, 5, 9 ], [ 6, 10, 15 ],
+                  [ 8, 11, 14 ] ] ) ],
+      autGroup := Group([ (1,10)(2,11)(3,8)(6,13)(7,14)(12,15),
+          (1,13)(2,11)(3,14)(4,5)(6,10)(7,8),
+          (1,13,7)(2,11,5)(6,10,14)(9,12,15),
+          (2,11,5,15,4,9,12)(3,10,8,14,7,13,6) ]) ),
+  rec( partition := [ rec( isBlockDesign := true, v := 15,
+              blocks := [ [ 1, 2, 6 ], [ 3, 4, 8 ], [ 5, 7, 14 ],
+                  [ 9, 12, 15 ], [ 10, 11, 13 ] ] ),
+          rec( isBlockDesign := true, v := 15,
+              blocks := [ [ 1, 3, 11 ], [ 2, 4, 12 ], [ 5, 6, 8 ],
+                  [ 7, 13, 15 ], [ 9, 10, 14 ] ] ),
+          rec( isBlockDesign := true, v := 15,
+              blocks := [ [ 1, 4, 14 ], [ 2, 5, 15 ], [ 3, 10, 12 ],
+                  [ 6, 7, 11 ], [ 8, 9, 13 ] ] ),
+          rec( isBlockDesign := true, v := 15,
+              blocks := [ [ 1, 5, 10 ], [ 2, 13, 14 ], [ 3, 6, 9 ],
+                  [ 4, 11, 15 ], [ 7, 8, 12 ] ] ),
+          rec( isBlockDesign := true, v := 15,
+              blocks := [ [ 1, 7, 9 ], [ 2, 8, 10 ], [ 3, 14, 15 ],
+                  [ 4, 6, 13 ], [ 5, 11, 12 ] ] ),
+          rec( isBlockDesign := true, v := 15,
+              blocks := [ [ 1, 8, 15 ], [ 2, 9, 11 ], [ 3, 5, 13 ],
+                  [ 4, 7, 10 ], [ 6, 12, 14 ] ] ),
+          rec( isBlockDesign := true, v := 15,
+              blocks := [ [ 1, 12, 13 ], [ 2, 3, 7 ], [ 4, 5, 9 ],
+                  [ 6, 10, 15 ], [ 8, 11, 14 ] ] ) ],
+      autGroup := Group([ (1,15)(2,9)(3,4)(5,7)(6,12)(10,13),
+          (1,12)(2,9)(3,5)(4,7)(6,15)(8,14),
+          (1,14)(2,5)(3,8)(6,7)(9,12)(10,13),
+          (1,8,10)(2,5,15)(3,14,13)(4,9,12) ]) ) ]
+gap> List(PL,resolution->Size(resolution.autGroup));
+[ 168, 168 ]
+gap> PL:=PartitionsIntoBlockDesigns(rec(
+>       blockDesign:=DL[2],
+>       v:=15,blockSizes:=[3],
+>       tSubsetStructure:=rec(t:=1,lambdas:=[1])));
+[  ]
+gap> PL:=PartitionsIntoBlockDesigns(rec(
+>       blockDesign:=DL[3],
+>       v:=15,blockSizes:=[3],
+>       tSubsetStructure:=rec(t:=1,lambdas:=[1])));
+[  ]
+gap> L:=BlockDesigns(rec(v:=9,blockSizes:=[3],
+>          tSubsetStructure:=rec(t:=2,lambdas:=[1])));;
+gap> D:=L[1];;
+gap> MakeResolutionsComponent(D);
+gap> D;
+rec( isBlockDesign := true, v := 9,
+  blocks := [ [ 1, 2, 3 ], [ 1, 4, 5 ], [ 1, 6, 7 ], [ 1, 8, 9 ],
+      [ 2, 4, 6 ], [ 2, 5, 8 ], [ 2, 7, 9 ], [ 3, 4, 9 ], [ 3, 5, 7 ],
+      [ 3, 6, 8 ], [ 4, 7, 8 ], [ 5, 6, 9 ] ],
+  tSubsetStructure := rec( t := 2, lambdas := [ 1 ] ), isBinary := true,
+  isSimple := true, blockSizes := [ 3 ], blockNumbers := [ 12 ], r := 4,
+  autGroup := Group([ (1,2)(5,6)(7,8), (1,3,2)(4,8,7)(5,6,9), (1,2)(4,7)(5,9),
+      (1,2)(4,9)(5,7)(6,8), (1,4,8,6,9,2)(3,5,7) ]),
+  resolutions := rec( list := [ rec( partition :=
+                [ rec( isBlockDesign := true, v := 9,
+                      blocks := [ [ 1, 2, 3 ], [ 4, 7, 8 ], [ 5, 6, 9 ] ] ),
+                  rec( isBlockDesign := true, v := 9,
+                      blocks := [ [ 1, 4, 5 ], [ 2, 7, 9 ], [ 3, 6, 8 ] ] ),
+                  rec( isBlockDesign := true, v := 9,
+                      blocks := [ [ 1, 6, 7 ], [ 2, 5, 8 ], [ 3, 4, 9 ] ] ),
+                  rec( isBlockDesign := true, v := 9,
+                      blocks := [ [ 1, 8, 9 ], [ 2, 4, 6 ], [ 3, 5, 7 ] ] ) ],
+              autGroup := Group(
+                [ (2,3)(4,5)(6,7)(8,9), (1,3,2)(4,8,7)(5,6,9),
+                  (1,8,9)(2,4,6)(3,7,5), (1,2)(5,6)(7,8), (1,2)(4,7)(5,9),
+                  (1,2,9,6,8,4)(3,7,5) ]) ) ], pairwiseNonisomorphic := true,
+      allClassesRepresented := true ) )
diff --git a/doc/parameters.tex b/doc/parameters.tex
index 66034d1..4b188ea 100644
--- a/doc/parameters.tex
+++ b/doc/parameters.tex
@@ -9,7 +9,7 @@
 \def\nauty{\it nauty}
 \def\Aut{{\rm Aut}\,}
 \def\x{\times}
-\Chapter{Information from block design parameters}
+\Chapter{Information from design parameters}
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \Section{Information from $t$-design parameters}
@@ -192,6 +192,65 @@ gap> TDesignBlockMultiplicityBound(2,12,4,3);
 2
 \endexample
 
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\Section{Information from (mixed) orthogonal array parameters}
+
+For positive integers $N,k,s,t$, with $t\le k$, an *orthogonal array*
+\index{orthogonal array}
+OA$(N,k,s,t)$ is an $N\times k$ array, in which the entries come from a
+set of *symbols* of size $s>1$, with the property that in any $N\times t$
+subarray, every possible $t$-tuple of symbols occurs as a row equally
+often (which must be $N/s^t$ times).
+
+For positive integers $N,k_1,\ldots,k_w,s_1,\ldots,s_w,t$, a *mixed
+orthogonal array* 
+\index{mixed orthogonal array}
+OA$(N,s_1^{k_1},\ldots,s_w^{k_w},t)$ is an $N\times k$
+array, where $t\le k:=k_1+\cdots +k_w$, in which the entries in the first
+$k_1$ columns come from a set of symbols of size $s_1>1$, the entries
+in the next $k_2$ columns come from a set of symbols of size $s_2>1$,
+and so on, with the property that in any $N\times t$ subarray, every
+possible $t$-tuple of symbols occurs as a row equally often.
+Clearly, a mixed orthogonal array OA$(N,s^k,t)$ is the same thing as an
+orthogonal array OA$(N,k,s,t)$.  
+
+The rows of an orthogonal array or mixed orthogonal array are called *runs*. 
+The *multiplicity* of a run is the number of times it appears as a row
+in the array.
+
+
+\>OARunMultiplicityBound( <N>, <k>, <s>, <t> )
+
+Suppose <N> is a positive integer, and <k> and <s> are non-empty lists
+of the same length, $w$ say, of positive integers, <t> is a positive
+integer $\le$ `Sum(<k>)', and each entry of <s> is at least 2.
+Then this function returns an upper bound on the multiplicity of any
+run in a mixed orthogonal array 
+OA$(N,s[1]^{k[1]},...,s[w]^{k[w]},t)$.
+In particular, if the value $0$ is returned, then this implies that a
+mixed orthogonal array with the given parameters does not exist.
+If <k> is given as an integer, it is replaced by `[<k>]', and
+if <s> is given as an integer, it is replaced by `[<s>]'.
+
+We do not claim that the returned upper bound $m$ is achieved; that
+is, there may well not exist a mixed orthogonal array with the given
+parameters having a run with multiplicity $m$.
+
+\beginexample
+gap> OARunMultiplicityBound(81,14,3,3);
+1
+gap> OARunMultiplicityBound(81,15,3,3);
+0
+gap> OARunMultiplicityBound(36,[18,1,1],[2,3,6],2);
+1
+gap> OARunMultiplicityBound(72,7,6,2);
+2
+gap> OARunMultiplicityBound(72,8,6,2);
+1
+\endexample
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \Section{Block intersection polynomials}
 
diff --git a/lib/blockdesign.g b/lib/blockdesign.g
index 77f0f08..8697bed 100644
--- a/lib/blockdesign.g
+++ b/lib/blockdesign.g
@@ -1,6 +1,6 @@
 ############################################################################
 ##
-##    blockdesign.g             Design 1.7 Package          Leonard Soicher
+##    blockdesign.g             Design 1.8 Package          Leonard Soicher
 ##
 ##
 # Functions to study, construct and classify (sub)block designs 
@@ -8,7 +8,7 @@
 # block designs with given properties.
 # At present there is limited support for non-binary block designs.
 # 
-# Copyright (C) 2003-2019 Leonard H. Soicher
+# Copyright (C) 2003-2023 Leonard H. Soicher
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -175,7 +175,7 @@ BindGlobal("BlockIntersectionPolynomialCheck",function(m,lambdavec)
 # has a non-negative value whenever x is an integer. 
 # Returns true if all this is so; else false is returned.
 #
-local c,x,B,D,i;
+local c,x,B,D,i,xmin,closestintxmin;
 if not IsList(m) or not IsList(lambdavec) then
    Error("usage: BlockIntersectionPolynomialCheck( <List>, <List> )");
 fi;
@@ -200,8 +200,13 @@ elif c[Length(c)]<0 or c[1]<0 or Length(c) mod 2 = 0 then
    # B has negative leading coef or B(0)<0 or B has odd degree.
    return false;
 elif Length(c)=1 then
-   # B is a constant positive polynomial
+   # B is a constant positive polynomial.
    return true;
+elif Length(c)=3 then
+   # B is a quadratic with positive leading term.
+   xmin:=-c[2]/(2*c[3]); #  B has minimum value at xmin. 
+   closestintxmin:=BestQuoInt(NumeratorRat(xmin),DenominatorRat(xmin));
+   return Value(B,closestintxmin)>=0;
 fi;
 # Now apply the bound in [Soicher, MCompSci Thesis] to the absolute
 # values of the zeros of B.  See also:  
@@ -892,6 +897,93 @@ fi;
 return blockmultiplicitybound(t,v,k,lambda);
 end);
 
+BindGlobal("OARunMultiplicityBound",function(N,k,s,t)
+#
+# Suppose N is a positive integer, and k and s are non-empty
+# lists of the same length, w say, of positive integers, 
+# with each element of s >1, and t is a positive integer <= Sum(k). 
+#
+# Then this function returns an upper bound on the multiplicity of 
+# any run in a mixed orthogonal array OA(N,s[1]^k[1],...,s[w]^k[w],t). 
+#
+# If k is given as an integer, it is replaced by [k].
+# If s is given as an integer, it is replaced by [s].
+#
+local runmultiplicitybound,S,i,j;
+
+runmultiplicitybound:=function(N,S,t)
+#
+# This function does most of the work.
+# S is a nonempty list whose length is the number of factors, and 
+# with S[i] being the number of symbols for the i-th factor.
+#
+local lambdavec,m,i,j,C,c,nr,kk,mixed;
+lambdavec:=[N];
+kk:=Length(S); # number of factors
+mixed:=ForAny(S,x->x<>S[1]);
+for i in [1..t] do
+   # determine lambdavec[i+1]
+   if not mixed then
+      lambdavec[i+1]:=N/S[1]^i;
+   else
+      lambdavec[i+1]:=0;
+      C:=Combinations([1..kk],i);
+      for c in C do
+         nr:=Product(S{c});
+         if N mod nr <> 0 then
+            return 0;
+         else
+            lambdavec[i+1]:=lambdavec[i+1]+N/nr;
+         fi;
+      od;
+      lambdavec[i+1]:=lambdavec[i+1]/Binomial(kk,i);
+   fi;
+od;
+if t=1 then
+   return Minimum(List(S,x->N/x));
+fi;
+# Now  Length(S) >= t >= 2. 
+if t mod 2 <> 0 then
+   return Minimum(List([1..kk],
+      i->runmultiplicitybound(N/S[i],S{Difference([1..kk],[i])},t-1)));
+fi;
+# Now t>=2 is even.
+# Determine the bound using block intersection polynomials.
+m:=ListWithIdenticalEntries(kk+1,0);
+m[kk+1]:=1;
+while BlockIntersectionPolynomialCheck(m,lambdavec) do
+   m[kk+1]:=m[kk+1]+1;
+od;
+return m[kk+1]-1;
+end;
+
+if IsPosInt(k) then
+   k:=[k];
+fi;
+if IsPosInt(s) then
+   s:=[s];
+fi;
+if not (IsPosInt(N) and IsList(k) and IsList(s) and IsPosInt(t)) then
+   Error("usage: OARunMultiplicityBound( <PosInt>, <PosInt> or <List>, <PosInt> or <List>, <PosInt> )");
+fi;
+if ForAny(k,x->not IsPosInt(x)) or t>Sum(k) then
+   Error("<k> must be a list of positive integers, with Sum(<k>) >= <t>");
+fi;
+if ForAny(s,x->not IsInt(x) or x<2) then
+   Error("each element of <s> must be an integer > 1");
+fi;
+if Length(s)<>Length(k) then
+   Error("<s> and <k> must have equal length");
+fi;
+S:=[];
+for i in [1..Length(s)] do
+   for j in [1..k[i]] do
+      Add(S,s[i]);
+   od;
+od;
+return runmultiplicitybound(N,S,t);
+end);
+
 BindGlobal("ResolvableTDesignBlockMultiplicityBound",function(t,v,k,lambda)
 
 local multbound,r,lambdavec,m,lower,upper,mid;
diff --git a/tst/testall.tst b/tst/testall.tst
index fb505af..9f8526e 100644
--- a/tst/testall.tst
+++ b/tst/testall.tst
@@ -102,6 +102,16 @@ gap> ResolvableTDesignBlockMultiplicityBound(2,12,4,3);
 1
 gap> TDesignBlockMultiplicityBound(2,12,4,3);
 2
+gap> OARunMultiplicityBound(81,14,3,3);
+1
+gap> OARunMultiplicityBound(81,15,3,3);
+0
+gap> OARunMultiplicityBound(36,[18,1,1],[2,3,6],2);
+1
+gap> OARunMultiplicityBound(72,7,6,2);
+2
+gap> OARunMultiplicityBound(72,8,6,2);
+1
 gap> x:=Indeterminate(Rationals,1);
 x_1
 gap> m:=[0,0,0,0,0,0,0,1];;

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/share/gap/pkg/design/htm/indxO.htm

No differences were encountered in the control files

More details

Full run details