External Representations of Block Designs

The “ext_rep” module is an API to the abstract tree represented by an XML document containing the External Representation of a list of block designs. The module also provides the related I/O operations for reading/writing ext-rep files or data. The parsing is based on expat.

This is a modified form of the module ext_rep.py (version 0.8) written by Peter Dobcsanyi [D2009] peter@designtheory.org.

REFERENCES:

[D2009]P. Dobcsanyi et al. DesignTheory.org http://designtheory.org/database/

TODO: The XML data from the designtheory.org database contains a wealth of information about things like automorphism groups, transitivity, cycle type representatives, etc, but none of this data is made available through the current implementation.

class sage.combinat.designs.ext_rep.XTree(node)

A lazy class to wrap a rooted tree representing an XML document. The tree’s nodes are tuples of the structure:

(name, {dictionary of attributes}, [list of children])

Methods and services of an XTree object t:

  • t.attribute – attribute named
  • t.child – first child named
  • t[i] – i-th child
  • for child in t: – iterate over t‘s children
  • len(t) – number of t‘s children

If child is not an empty subtree, return the subtree as an XTree object. If child is an empty subtree, return _name of the subtree. Otherwise return the child itself.

The lazy tree idea originated from a utility class of the pyRXP 0.9 package by Robin Becker at ReportLab.

__getattr__(attr)

Returns the data for the first attribute with name attr.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import *
sage: xt = XTree(('blocks', {'ordered': 'true'}, [('block', {}, [[0, 1, 2]]), ('block', {}, [[0, 3, 4]]), ('block', {}, [[0, 5, 6]]), ('block', {}, [[0, 7, 8]]), ('block', {}, [[0, 9, 10]]), ('block', {}, [[0, 11, 12]]), ('block', {}, [[1, 3, 5]]), ('block', {}, [[1, 4, 6]]), ('block', {}, [[1, 7, 9]]), ('block', {}, [[1, 8, 11]]), ('block', {}, [[1, 10, 12]]), ('block', {}, [[2, 3, 7]]), ('block', {}, [[2, 4, 8]]), ('block', {}, [[2, 5, 10]]), ('block', {}, [[2, 6, 12]]), ('block', {}, [[2, 9, 11]]), ('block', {}, [[3, 6, 9]]), ('block', {}, [[3, 8, 12]]), ('block', {}, [[3, 10, 11]]), ('block', {}, [[4, 5, 11]]), ('block', {}, [[4, 7, 10]]), ('block', {}, [[4, 9, 12]]), ('block', {}, [[5, 7, 12]]), ('block', {}, [[5, 8, 9]]), ('block', {}, [[6, 7, 11]]), ('block', {}, [[6, 8, 10]])]))
sage: xt.__getattr__('block')
[0, 1, 2]
__getitem__(i)

Get the i-th item in the current node.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import *
sage: xt = XTree(('blocks', {'ordered': 'true'}, [('block', {}, [[0, 1, 2]]), ('block', {}, [[0, 3, 4]]), ('block', {}, [[0, 5, 6]]), ('block', {}, [[0, 7, 8]]), ('block', {}, [[0, 9, 10]]), ('block', {}, [[0, 11, 12]]), ('block', {}, [[1, 3, 5]]), ('block', {}, [[1, 4, 6]]), ('block', {}, [[1, 7, 9]]), ('block', {}, [[1, 8, 11]]), ('block', {}, [[1, 10, 12]]), ('block', {}, [[2, 3, 7]]), ('block', {}, [[2, 4, 8]]), ('block', {}, [[2, 5, 10]]), ('block', {}, [[2, 6, 12]]), ('block', {}, [[2, 9, 11]]), ('block', {}, [[3, 6, 9]]), ('block', {}, [[3, 8, 12]]), ('block', {}, [[3, 10, 11]]), ('block', {}, [[4, 5, 11]]), ('block', {}, [[4, 7, 10]]), ('block', {}, [[4, 9, 12]]), ('block', {}, [[5, 7, 12]]), ('block', {}, [[5, 8, 9]]), ('block', {}, [[6, 7, 11]]), ('block', {}, [[6, 8, 10]])]))
sage: xt.__getitem__(0)
[0, 1, 2]
sage: xt.__getitem__(1)
[0, 3, 4]
__init__(node)

Initialisation method given a node in an XML document.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import *
sage: xt = XTree(('blocks', {'ordered': 'true'}, [('block', {}, [[0, 1, 2]]), ('block', {}, [[0, 3, 4]]), ('block', {}, [[0, 5, 6]]), ('block', {}, [[0, 7, 8]]), ('block', {}, [[0, 9, 10]]), ('block', {}, [[0, 11, 12]]), ('block', {}, [[1, 3, 5]]), ('block', {}, [[1, 4, 6]]), ('block', {}, [[1, 7, 9]]), ('block', {}, [[1, 8, 11]]), ('block', {}, [[1, 10, 12]]), ('block', {}, [[2, 3, 7]]), ('block', {}, [[2, 4, 8]]), ('block', {}, [[2, 5, 10]]), ('block', {}, [[2, 6, 12]]), ('block', {}, [[2, 9, 11]]), ('block', {}, [[3, 6, 9]]), ('block', {}, [[3, 8, 12]]), ('block', {}, [[3, 10, 11]]), ('block', {}, [[4, 5, 11]]), ('block', {}, [[4, 7, 10]]), ('block', {}, [[4, 9, 12]]), ('block', {}, [[5, 7, 12]]), ('block', {}, [[5, 8, 9]]), ('block', {}, [[6, 7, 11]]), ('block', {}, [[6, 8, 10]])]))
sage: xt.xt_children  
[('block', {}, [[0, 1, 2]]),
 ('block', {}, [[0, 3, 4]]),
 ('block', {}, [[0, 5, 6]]),
 ('block', {}, [[0, 7, 8]]),
 ('block', {}, [[0, 9, 10]]),
 ('block', {}, [[0, 11, 12]]),
 ('block', {}, [[1, 3, 5]]),
 ('block', {}, [[1, 4, 6]]),
 ('block', {}, [[1, 7, 9]]),
 ('block', {}, [[1, 8, 11]]),
 ('block', {}, [[1, 10, 12]]),
 ('block', {}, [[2, 3, 7]]),
 ('block', {}, [[2, 4, 8]]),
 ('block', {}, [[2, 5, 10]]),
 ('block', {}, [[2, 6, 12]]),
 ('block', {}, [[2, 9, 11]]),
 ('block', {}, [[3, 6, 9]]),
 ('block', {}, [[3, 8, 12]]),
 ('block', {}, [[3, 10, 11]]),
 ('block', {}, [[4, 5, 11]]),
 ('block', {}, [[4, 7, 10]]),
 ('block', {}, [[4, 9, 12]]),
 ('block', {}, [[5, 7, 12]]),
 ('block', {}, [[5, 8, 9]]),
 ('block', {}, [[6, 7, 11]]),
 ('block', {}, [[6, 8, 10]])]
__len__()

Returns the length of the current node.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import *
sage: xt = XTree(('blocks', {'ordered': 'true'}, [('block', {}, [[0, 1, 2]]), ('block', {}, [[0, 3, 4]]), ('block', {}, [[0, 5, 6]]), ('block', {}, [[0, 7, 8]]), ('block', {}, [[0, 9, 10]]), ('block', {}, [[0, 11, 12]]), ('block', {}, [[1, 3, 5]]), ('block', {}, [[1, 4, 6]]), ('block', {}, [[1, 7, 9]]), ('block', {}, [[1, 8, 11]]), ('block', {}, [[1, 10, 12]]), ('block', {}, [[2, 3, 7]]), ('block', {}, [[2, 4, 8]]), ('block', {}, [[2, 5, 10]]), ('block', {}, [[2, 6, 12]]), ('block', {}, [[2, 9, 11]]), ('block', {}, [[3, 6, 9]]), ('block', {}, [[3, 8, 12]]), ('block', {}, [[3, 10, 11]]), ('block', {}, [[4, 5, 11]]), ('block', {}, [[4, 7, 10]]), ('block', {}, [[4, 9, 12]]), ('block', {}, [[5, 7, 12]]), ('block', {}, [[5, 8, 9]]), ('block', {}, [[6, 7, 11]]), ('block', {}, [[6, 8, 10]])]))
sage: xt.__len__()
26
__repr__()

String representation of an XTree object.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import *
sage: xt = XTree(('blocks', {'ordered': 'true'}, [('block', {}, [[0, 1, 2]]), ('block', {}, [[0, 3, 4]]), ('block', {}, [[0, 5, 6]]), ('block', {}, [[0, 7, 8]]), ('block', {}, [[0, 9, 10]]), ('block', {}, [[0, 11, 12]]), ('block', {}, [[1, 3, 5]]), ('block', {}, [[1, 4, 6]]), ('block', {}, [[1, 7, 9]]), ('block', {}, [[1, 8, 11]]), ('block', {}, [[1, 10, 12]]), ('block', {}, [[2, 3, 7]]), ('block', {}, [[2, 4, 8]]), ('block', {}, [[2, 5, 10]]), ('block', {}, [[2, 6, 12]]), ('block', {}, [[2, 9, 11]]), ('block', {}, [[3, 6, 9]]), ('block', {}, [[3, 8, 12]]), ('block', {}, [[3, 10, 11]]), ('block', {}, [[4, 5, 11]]), ('block', {}, [[4, 7, 10]]), ('block', {}, [[4, 9, 12]]), ('block', {}, [[5, 7, 12]]), ('block', {}, [[5, 8, 9]]), ('block', {}, [[6, 7, 11]]), ('block', {}, [[6, 8, 10]])]))
sage: xt.__repr__()
'XTree<blocks>'
__weakref__
list of weak references to the object (if defined)
class sage.combinat.designs.ext_rep.XTreeProcessor

An incremental event-driven parser for ext-rep documents. The processing stages:

  • <list_of_designs ...> opening element. call-back: list_of_designs_proc
  • <list_definition> subtree. call-back: list_definition_proc
  • <info> subtree. call-back: info_proc
  • iterating over <designs> processing each <block_design> separately. call-back: block_design_proc
  • finishing with closing </designs> and </list_of_designs>.
__init__()

Internal initialisation for the processor of XTrees.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import *
sage: proc = XTreeProcessor()
sage: proc.current_node
('root0', {}, [])
sage: proc.node_stack
[('root0', {}, [])]
sage: proc.in_item
False
__weakref__
list of weak references to the object (if defined)
_char_data(data)

Internal function to tidy up character data.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import *
sage: name = "block_design"
sage: attrs = {'b': '26', 'id': 't2-v13-b26-r6-k3-L1-0', 'v': '13'}

sage: proc = XTreeProcessor()
sage: proc._start_element(name, attrs)

sage: proc._char_data(r"   [ DESIGN-1.1, GRAPE-4.2, GAPDoc-0.9999, GAP-4.4.3]")
sage: proc.current_node
('block_design',
 {'b': 26, 'id': 't2-v13-b26-r6-k3-L1-0', 'v': 13},
 ['[ DESIGN-1.1, GRAPE-4.2, GAPDoc-0.9999, GAP-4.4.3]'])
_end_element(name)

Finish processing the element name.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import *
sage: name = "block_design"
sage: attrs = {'b': '26', 'id': 't2-v13-b26-r6-k3-L1-0', 'v': '13'}
sage: proc = XTreeProcessor()
sage: proc._start_element(name, attrs)
sage: proc._end_element(name)
sage: proc.current_node
('root0', {}, [])
_init()

Internal initialisation for the processor of XTrees.

EXAMPLES:

sage: from sage.combinat.designs import ext_rep
sage: proc = ext_rep.XTreeProcessor()
sage: proc._init()
sage: proc.current_node
('root0', {}, [])
_start_element(name, attrs)

Process the start of an element with certain name and attributes.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import *
sage: name = "block_design"
sage: attrs = {'b': '26', 'id': 't2-v13-b26-r6-k3-L1-0', 'v': '13'}
sage: proc = XTreeProcessor()
sage: proc._start_element(name, attrs)
sage: proc.current_node 
('block_design', {'b': 26, 'id': 't2-v13-b26-r6-k3-L1-0', 'v': 13}, [])
parse(xml_source)

The main parsing function. Given an XML source (either a file handle or a string), parse the entire XML source.

EXAMPLES:

sage: from sage.combinat.designs import ext_rep
sage: file_loc = ext_rep.dump_to_tmpfile(ext_rep.v2_b2_k2_icgsa)
sage: proc = ext_rep.XTreeProcessor()
sage: proc.save_designs = True
sage: f = ext_rep.open_extrep_file(file_loc)
sage: proc.parse(f)
sage: f.close()
sage: os.remove(file_loc)
sage: proc.list_of_designs[0]
(2, [[0, 1], [0, 1]])
sage.combinat.designs.ext_rep._encode_attribute(string)

Convert numbers in attributes into binary format. Currently integer and floating point conversions are implemented.

EXAMPLES:

sage: from sage.combinat.designs.ext_rep import _encode_attribute
sage: _encode_attribute('1')
1
sage: _encode_attribute('2')
2
sage: _encode_attribute('12')
12
sage: _encode_attribute('true')
'true'
sage: _encode_attribute('A')
'A'
sage: _encode_attribute('D')
'D'
sage: _encode_attribute('E')
'E'
sage.combinat.designs.ext_rep.check_dtrs_protocols(input_name, input_pv)

Check that the XML data is in a valid format. We can currently handle version 2.0. For more information see http://designtheory.org/library/extrep/

EXAMPLES:

sage: from sage.combinat.designs import ext_rep
sage: ext_rep.check_dtrs_protocols('source', '2.0')
sage: ext_rep.check_dtrs_protocols('source', '3.0')
...
RuntimeError: Incompatible dtrs_protocols: program: 2.0 source: 3.0
sage.combinat.designs.ext_rep.designs_from_XML(fname)

Returns a list of designs contained in an XML file fname. The list contains tuples of the form (v, bs) where v is the number of points of the design and bs is the list of blocks.

EXAMPLES:

sage: from sage.combinat.designs import ext_rep
sage: file_loc = ext_rep.dump_to_tmpfile(ext_rep.v2_b2_k2_icgsa)
sage: ext_rep.designs_from_XML(file_loc)[0]
(2, [[0, 1], [0, 1]])
sage: os.remove(file_loc)

sage: from sage.combinat.designs import ext_rep
sage: from sage.combinat.designs.block_design import BlockDesign
sage: file_loc = ext_rep.dump_to_tmpfile(ext_rep.v2_b2_k2_icgsa)
sage: v, blocks = ext_rep.designs_from_XML(file_loc)[0]
sage: d = BlockDesign(v, blocks)
sage: d.blocks()
[[0, 1], [0, 1]]
sage: d.parameters()
(2, 2, 2, 2)
sage.combinat.designs.ext_rep.designs_from_XML_url(url)

Returns a list of designs contained in an XML file named by a URL. The list contains tuples of the form (v, bs) where v is the number of points of the design and bs is the list of blocks.

EXAMPLES:

sage: from sage.combinat.designs import ext_rep
sage: file_loc = ext_rep.dump_to_tmpfile(ext_rep.v2_b2_k2_icgsa)
sage: ext_rep.designs_from_XML_url("file://" + file_loc)[0]
(2, [[0, 1], [0, 1]])
sage: os.remove(file_loc)

sage: from sage.combinat.designs import ext_rep
sage: ext_rep.designs_from_XML_url("http://designtheory.org/database/v-b-k/v3-b6-k2.icgsa.txt.bz2") # optional - requires internet
[(3, [[0, 1], [0, 1], [0, 1], [0, 1], [0, 1], [0, 2]]),
 (3, [[0, 1], [0, 1], [0, 1], [0, 1], [0, 2], [0, 2]]),
 (3, [[0, 1], [0, 1], [0, 1], [0, 1], [0, 2], [1, 2]]),
 (3, [[0, 1], [0, 1], [0, 1], [0, 2], [0, 2], [0, 2]]),
 (3, [[0, 1], [0, 1], [0, 1], [0, 2], [0, 2], [1, 2]]),
 (3, [[0, 1], [0, 1], [0, 2], [0, 2], [1, 2], [1, 2]])]
sage.combinat.designs.ext_rep.dump_to_tmpfile(s)

Utility function to dump a string to a temporary file.

EXAMPLE:

sage: from sage.combinat.designs import ext_rep
sage: file_loc = ext_rep.dump_to_tmpfile("boo")
sage: os.remove(file_loc)
sage.combinat.designs.ext_rep.open_extrep_file(fname)

Try to guess the compression type from extension and open the extrep file.

EXAMPLES:

sage: from sage.combinat.designs import ext_rep
sage: file_loc = ext_rep.dump_to_tmpfile(ext_rep.v2_b2_k2_icgsa)
sage: proc = ext_rep.XTreeProcessor()
sage: f = ext_rep.open_extrep_file(file_loc)
sage: proc.parse(f)
sage: f.close()
sage: os.remove(file_loc)
sage.combinat.designs.ext_rep.open_extrep_url(url)

Try to guess the compression type from extension and open the extrep file pointed to by the url. This function (unlike open_extrep_file) returns the uncompressed text contained in the file.

EXAMPLES:

sage: from sage.combinat.designs import ext_rep
sage: file_loc = ext_rep.dump_to_tmpfile(ext_rep.v2_b2_k2_icgsa)
sage: proc = ext_rep.XTreeProcessor()
sage: s = ext_rep.open_extrep_url("file://" + file_loc)
sage: proc.parse(s)
sage: os.remove(file_loc)

sage: from sage.combinat.designs import ext_rep
sage: s = ext_rep.designs_from_XML_url("http://designtheory.org/database/v-b-k/v3-b6-k2.icgsa.txt.bz2") # optional - requires internet

Previous topic

Block designs.

Next topic

Incidence structures.

This Page