class CoveringDesign(SageObject): """ Covering design. INPUT: data -- parameters (v,k,t) size incidence structure (points and blocks) -- default points are $[0,...v-1]$ lower bound for such a design database information: creator, method, timestamp """ def __init__(self, v=0, k=0, t=0, size=0, points=[], blocks=[], low_bd=0, method='', creator='', timestamp=''): """ EXAMPLES: sage: C=CoveringDesign(5,4,3,4,range(5),[[0,1,2,3],[0,1,2,4],[0,1,3,4],[0,2,3,4]],4, 'Lexicographic Covering') sage: print C C(5,4,3) = 4 Method: Lexicographic Covering 0 1 2 3 0 1 2 4 0 1 3 4 0 2 3 4 """ self.__v = v self.__k = k self.__t = t self.__size = size if low_bd > 0: self.__low_bd = low_bd else: self.__low_bd = schonheim(v, k, t) self.__method = method self.__creator = creator self.__timestamp = timestamp self.__incidence_structure = IncidenceStructure(points, blocks) def __repr__(self): """ A print method, giving the parameters and any other information about the covering (but not the blocks). EXAMPLES: sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C (7,3,2)-covering design of size 7 Lower bound: 7 Method: Projective Plane """ repr = '(%d,%d,%d)-covering design of size %d\n' % ( self.__v, self.__k, self.__t, self.__size) repr += 'Lower bound: %d\n' % (self.__low_bd) if self.__creator != '': repr += 'Created by: %s\n' % (self.__creator) if self.__method != '': repr += 'Method: %s\n' % (self.__method) if self.__timestamp != '': repr += 'Submitted on: %s\n' % (self.__timestamp) return repr def __str__(self): """ A print method, displaying a covering design's parameters and blocks. OUTPUT: covering design parameters and blocks, in a readable form EXAMPLES: sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: print C C(7,3,2) = 7 Method: Projective Plane 0 1 2 0 3 4 0 5 6 1 3 5 1 4 6 2 3 6 2 4 5 """ if self.__size == self.__low_bd: # check if the covering is known to be optimal repr = 'C(%d,%d,%d) = %d\n' % (self.__v, self.__k, self.__t, self.__size) else: repr = '%d <= C(%d,%d,%d) <= %d\n' % ( self.__low_bd, self.__v, self.__k, self.__t, self.__size) if self.__creator != '': repr += 'Created by: %s\n' % (self.__creator) if self.__method != '': repr += 'Method: %s\n' % (self.__method) if self.__timestamp != '': repr += 'Submitted on: %s\n' % (self.__timestamp) for i in range(self.__size): for j in range(self.__k): repr = repr + str( self.__incidence_structure.blocks()[i][j]) + ' ' repr += '\n' return repr def is_covering(self): """ Checks that all t-sets are in fact covered. INPUT: putative covering design OUTPUT: True if all t-sets are in at least one block NOTES: This is very slow and wasteful of memory. A faster Cython version will be added soon. EXAMPLES: sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.is_covering() True sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 6]],0, 'not a covering') # last block altered sage: C.is_covering() False """ v = self.__v k = self.__k t = self.__t Svt = Combinations(range(v), t) Skt = Combinations(range(k), t) tset = {} # tables of t-sets: False = uncovered, True = covered for i in Svt: tset[tuple(i)] = False # mark all t-sets covered by each block for a in self.__incidence_structure.blocks(): for z in Skt: y = [a[x] for x in z] tset[tuple(y)] = True for i in Svt: if tset[tuple(i)] == False: # uncovered return False return True # everything was covered def v(self): """ Return v, the number of points in the covering design EXAMPLES: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.v() 7 """ return self.__v def k(self): """ Return k, the size of blocks of the covering design EXAMPLES: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.k() 3 """ return self.__k def t(self): """ Return t, the size of sets which must be covered by the blocks of the covering design EXAMPLES: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.t() 2 """ return self.__t def size(self): """ Return the number of blocks in the covering design EXAMPLES: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.size() 7 """ return self.__size def low_bd(self): """ Return a lower bound for the number of blocks a covering design with these parameters could have. Typically this is the Schonheim bound, but for some parameters better bounds have been shown. EXAMPLES: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.low_bd() 7 """ return self.__low_bd def method(self): """ Return the method used to create the covering design This field is optional, and is used in a database to give information about how coverings were constructed EXAMPLES: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.method() 'Projective Plane' """ return self.__method def creator(self): """ Return the creator of the covering design This field is optional, and is used in a database to give attribution for the covering design It can refer to the person who submitted it, or who originally gave a construction EXAMPLES: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane','Gino Fano') sage: C.creator() 'Gino Fano' """ return self.__creator def timestamp(self): """ Return the time that the covering was submitted to the database EXAMPLES: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane','Gino Fano','1892-01-01 00:00:00') sage: C.timestamp() #Fano had an article in 1892, I don't know the date it appeared '1892-01-01 00:00:00' """ return self.__timestamp def incidence_structure(self): """ Return the incidence structure of a covering design, without all the extra parameters. EXAMPLES: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: D = C.incidence_structure() sage: D.points() [0, 1, 2, 3, 4, 5, 6] sage: D.blocks() [[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]] """ return self.__incidence_structure
class CoveringDesign(SageObject): """ Covering design. INPUT: - ``v,k,t`` -- integer parameters of the covering design. - ``size`` (integer) - ``points`` -- list of points (default points are `[0,...v-1]`). - ``blocks`` - ``low_bd`` (integer) -- lower bound for such a design - ``method, creator, timestamp`` -- database information. """ def __init__(self, v=0, k=0, t=0, size=0, points=[], blocks=[], low_bd=0, method='', creator ='',timestamp=''): """ EXAMPLES:: sage: C=CoveringDesign(5,4,3,4,range(5),[[0,1,2,3],[0,1,2,4],[0,1,3,4],[0,2,3,4]],4, 'Lexicographic Covering') sage: print(C) C(5,4,3) = 4 Method: Lexicographic Covering 0 1 2 3 0 1 2 4 0 1 3 4 0 2 3 4 """ self.__v = v self.__k = k self.__t = t self.__size = size if low_bd > 0: self.__low_bd = low_bd else: self.__low_bd = schonheim(v,k,t) self.__method = method self.__creator = creator self.__timestamp = timestamp self.__incidence_structure = IncidenceStructure(points, blocks) def __repr__(self): """ A print method, giving the parameters and any other information about the covering (but not the blocks). EXAMPLES:: sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C (7,3,2)-covering design of size 7 Lower bound: 7 Method: Projective Plane """ repr = '(%d,%d,%d)-covering design of size %d\n' % (self.__v, self.__k, self.__t, self.__size) repr += 'Lower bound: %d\n' % (self.__low_bd) if self.__creator != '': repr += 'Created by: %s\n' % (self.__creator) if self.__method != '': repr += 'Method: %s\n' % (self.__method) if self.__timestamp != '': repr += 'Submitted on: %s\n' % (self.__timestamp) return repr def __str__(self): """ A print method, displaying a covering design's parameters and blocks. OUTPUT: covering design parameters and blocks, in a readable form EXAMPLES:: sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: print(C) C(7,3,2) = 7 Method: Projective Plane 0 1 2 0 3 4 0 5 6 1 3 5 1 4 6 2 3 6 2 4 5 """ if self.__size == self.__low_bd: # check if the covering is known to be optimal repr = 'C(%d,%d,%d) = %d\n'%(self.__v,self.__k,self.__t,self.__size) else: repr = '%d <= C(%d,%d,%d) <= %d\n'%(self.__low_bd,self.__v,self.__k,self.__t,self.__size); if self.__creator != '': repr += 'Created by: %s\n'%(self.__creator) if self.__method != '': repr += 'Method: %s\n'%(self.__method) if self.__timestamp != '': repr += 'Submitted on: %s\n'%(self.__timestamp) for i in range(self.__size): for j in range(self.__k): repr = repr + str(self.__incidence_structure.blocks()[i][j]) + ' ' repr += '\n' return repr def is_covering(self): """ Checks that all `t`-sets are in fact covered by the blocks of ``self`` .. NOTE:: This is very slow and wasteful of memory. EXAMPLES:: sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.is_covering() True sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 6]],0, 'not a covering') # last block altered sage: C.is_covering() False """ v = self.__v k = self.__k t = self.__t Svt = Combinations(range(v),t) Skt = Combinations(range(k),t) tset = {} # tables of t-sets: False = uncovered, True = covered for i in Svt: tset[tuple(i)] = False # mark all t-sets covered by each block for a in self.__incidence_structure.blocks(): for z in Skt: y = [a[x] for x in z] tset[tuple(y)] = True for i in Svt: if not tset[tuple(i)]: # uncovered return False return True # everything was covered def v(self): """ Return `v`, the number of points in the covering design. EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.v() 7 """ return self.__v def k(self): """ Return `k`, the size of blocks of the covering design EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.k() 3 """ return self.__k def t(self): """ Return `t`, the size of sets which must be covered by the blocks of the covering design EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.t() 2 """ return self.__t def size(self): """ Return the number of blocks in the covering design EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.size() 7 """ return self.__size def low_bd(self): """ Return a lower bound for the number of blocks a covering design with these parameters could have. Typically this is the Schonheim bound, but for some parameters better bounds have been shown. EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.low_bd() 7 """ return self.__low_bd def method(self): """ Return the method used to create the covering design This field is optional, and is used in a database to give information about how coverings were constructed EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: C.method() 'Projective Plane' """ return self.__method def creator(self): """ Return the creator of the covering design This field is optional, and is used in a database to give attribution for the covering design It can refer to the person who submitted it, or who originally gave a construction EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane','Gino Fano') sage: C.creator() 'Gino Fano' """ return self.__creator def timestamp(self): """ Return the time that the covering was submitted to the database EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane','Gino Fano','1892-01-01 00:00:00') sage: C.timestamp() #Fano had an article in 1892, I don't know the date it appeared '1892-01-01 00:00:00' """ return self.__timestamp def incidence_structure(self): """ Return the incidence structure of a covering design, without all the extra parameters. EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C=CoveringDesign(7,3,2,7,range(7),[[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]],0, 'Projective Plane') sage: D = C.incidence_structure() sage: D.ground_set() [0, 1, 2, 3, 4, 5, 6] sage: D.blocks() [[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]] """ return self.__incidence_structure
class CoveringDesign(SageObject): """ Covering design. INPUT: - ``v``, ``k``, ``t`` -- integer parameters of the covering design - ``size`` (integer) - ``points`` -- list of points (default points are `[0, ..., v-1]`) - ``blocks`` - ``low_bd`` (integer) -- lower bound for such a design - ``method``, ``creator``, ``timestamp`` -- database information """ def __init__(self, v=0, k=0, t=0, size=0, points=None, blocks=None, low_bd=0, method='', creator='', timestamp=''): """ EXAMPLES:: sage: C = CoveringDesign(5, 4, 3, 4, range(5), [[0, 1, 2, 3], ....: [0, 1, 2, 4], [0, 1, 3, 4], [0, 2, 3, 4]], 4, ....: 'Lexicographic Covering') sage: print(C) C(5, 4, 3) = 4 Method: Lexicographic Covering 0 1 2 3 0 1 2 4 0 1 3 4 0 2 3 4 """ self.__v = v self.__k = k self.__t = t self.__size = size if low_bd > 0: self.__low_bd = low_bd else: self.__low_bd = schonheim(v, k, t) self.__method = method self.__creator = creator self.__timestamp = timestamp if points is None: points = [] if blocks is None: blocks = [] self.__incidence_structure = IncidenceStructure(points, blocks) def __repr__(self): """ Return the representation of this covering design. This has the parameters but not the blocks. EXAMPLES:: sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: C (7, 3, 2)-covering design of size 7 Lower bound: 7 Method: Projective Plane """ repr = ('(%d, %d, %d)-covering design of size %d\n' % (self.__v, self.__k, self.__t, self.__size)) repr += 'Lower bound: %d\n' % (self.__low_bd) if self.__creator: repr += 'Created by: %s\n' % (self.__creator) if self.__method: repr += 'Method: %s\n' % (self.__method) if self.__timestamp: repr += 'Submitted on: %s\n' % (self.__timestamp) return repr[:-1] def __str__(self): """ Return the string for this covering design. This has the parameters and the blocks in readable form. EXAMPLES:: sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: print(C) C(7, 3, 2) = 7 Method: Projective Plane 0 1 2 0 3 4 0 5 6 1 3 5 1 4 6 2 3 6 2 4 5 """ if self.__size == self.__low_bd: # check if covering is optimal repr = ('C(%d, %d, %d) = %d\n' % (self.__v, self.__k, self.__t, self.__size)) else: repr = ('%d <= C(%d, %d, %d) <= %d\n' % (self.__low_bd, self.__v, self.__k, self.__t, self.__size)) if self.__creator: repr += 'Created by: %s\n' % (self.__creator) if self.__method: repr += 'Method: %s\n' % (self.__method) if self.__timestamp: repr += 'Submitted on: %s\n' % (self.__timestamp) return repr + '\n'.join( ' '.join(str(k) for k in block) for block in self.__incidence_structure.blocks()) def is_covering(self): """ Check all `t`-sets are in fact covered by the blocks of ``self``. .. NOTE:: This is very slow and wasteful of memory. EXAMPLES:: sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: C.is_covering() True sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], ....: [2, 4, 6]], 0, 'not a covering') # last block altered sage: C.is_covering() False """ v = self.__v k = self.__k t = self.__t Svt = Combinations(range(v), t) Skt = Combinations(range(k), t) tset = {} # tables of t-sets: False = uncovered, True = covered for i in Svt: tset[tuple(i)] = False # mark all t-sets covered by each block for a in self.__incidence_structure.blocks(): for z in Skt: y = (a[x] for x in z) tset[tuple(y)] = True for i in Svt: if not tset[tuple(i)]: # uncovered return False return True # everything was covered def v(self): """ Return `v`, the number of points in the covering design. EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: C.v() 7 """ return self.__v def k(self): """ Return `k`, the size of blocks of the covering design EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: C.k() 3 """ return self.__k def t(self): """ Return `t`, the size of sets which must be covered by the blocks of the covering design EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: C.t() 2 """ return self.__t def size(self): """ Return the number of blocks in the covering design EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: C.size() 7 """ return self.__size def low_bd(self): """ Return a lower bound for the number of blocks a covering design with these parameters could have. Typically this is the Schonheim bound, but for some parameters better bounds have been shown. EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: C.low_bd() 7 """ return self.__low_bd def method(self): """ Return the method used to create the covering design. This field is optional, and is used in a database to give information about how coverings were constructed. EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: C.method() 'Projective Plane' """ return self.__method def creator(self): """ Return the creator of the covering design This field is optional, and is used in a database to give attribution for the covering design It can refer to the person who submitted it, or who originally gave a construction EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], ....: [2, 4, 5]],0, 'Projective Plane', 'Gino Fano') sage: C.creator() 'Gino Fano' """ return self.__creator def timestamp(self): """ Return the time that the covering was submitted to the database EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]],0, 'Projective Plane', ....: 'Gino Fano', '1892-01-01 00:00:00') sage: C.timestamp() # No exact date known; in Fano's 1892 article '1892-01-01 00:00:00' """ return self.__timestamp def incidence_structure(self): """ Return the incidence structure of this design, without extra parameters. EXAMPLES:: sage: from sage.combinat.designs.covering_design import CoveringDesign sage: C = CoveringDesign(7, 3, 2, 7, range(7), [[0, 1, 2], ....: [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], ....: [2, 3, 6], [2, 4, 5]], 0, 'Projective Plane') sage: D = C.incidence_structure() sage: D.ground_set() [0, 1, 2, 3, 4, 5, 6] sage: D.blocks() [[0, 1, 2], [0, 3, 4], [0, 5, 6], [1, 3, 5], [1, 4, 6], [2, 3, 6], [2, 4, 5]] """ return self.__incidence_structure