Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
22144 views
a

B1�b6S�@s�dZddlZddlZddlZddlmZddlmZddlm	Z	m
Z
ddlmZdd�Z
d	d
�Zdd�Zd
d�Zdd�Zdd�Zddd�Zdd�Ze
fdd�Zdd�ZdS)a
Interface to a classification database using sqlite3
====================================================

The ``classification_databasepsqlite3`` module defines interfaces
to manipulate an SQLite3 database of Cayley graph classifications.

AUTHORS:

- Paul Leopardi (2017-10-28)

�N)�matrix)�BentFunction)�%BentFunctionCayleyGraphClassification�default_algorithm)�weight_classcCst�|�}tj|_|S)aN
    Create a database.

    INPUT:

    - ``db_name`` -- string. The name of the database to be created.

    OUTPUT: a database connection object.

    EXAMPLE:

    Create a database using a temporary filename, then drop the database.

    ::

        sage: from sage.misc.temporary_file import tmp_filename
        sage: db_name = tmp_filename(ext='.db')
        sage: from boolean_cayley_graphs.classification_database_sqlite3 import *
        sage: conn = create_database(db_name)
        sage: type(conn)
        <class 'sqlite3.Connection'>
        sage: drop_database(db_name)
    )�sqlite3�connect�Row�row_factory��db_name�conn�r�Y/home/user/Boolean-Cayley-graphs/boolean_cayley_graphs/classification_database_sqlite3.py�create_database#s
rcCs4tj�|�r"t�|�}tj|_|Std�|���dS)a�
    Connect to an existing database.

    INPUT:

    - ``db_name`` -- string. The name of the existing database.

    OUTPUT: a database connection object.

    EXAMPLE:

    Create a database using a temporary filename, connect to it,
    then drop the database.

    ::

        sage: from sage.misc.temporary_file import tmp_filename
        sage: db_name = tmp_filename(ext='.db')
        sage: from boolean_cayley_graphs.classification_database_sqlite3 import *
        sage: conn = create_database(db_name)
        sage: con2 = connect_to_database(db_name)
        sage: type(con2)
        <class 'sqlite3.Connection'>
        sage: drop_database(db_name)
    zFile not found: {}N)	�os�path�isfilerrr	r
�IOError�formatrrrr�connect_to_database@s

rcCs2tj�|�r.zt�|�Wnty,Yn0dS)a�
    Drop a database, if it exists.

    INPUT:

    - ``db_name`` -- string. The name of the existing database.

    OUTPUT: None.

    EXAMPLE:

    Create a database using a temporary filename, then drop the database.

    ::

        sage: from boolean_cayley_graphs.classification_database_sqlite3 import *
        sage: import os
        sage: db_name = tmp_filename(ext='.db')
        sage: conn = create_database(db_name)
        sage: os.path.exists(db_name)
        True
        sage: drop_database(db_name)
        sage: os.path.exists(db_name)
        False
        sage: drop_database(db_name)
        sage: os.path.exists(db_name)
        False
    N)rr�exists�remove�OSError)rrrr�
drop_databaseas
rcCsDt|�}|��}|�d�|�d�|�d�|�d�|��|S)a
    Create the tables used for a database of Cayley graph classifications.

    INPUT:

    - ``db_name`` -- string. The name of an existing database.

    OUTPUT: a database connection object.

    EXAMPLE:

    Create a database, with tables, using a temporary filename,
    list the table names, then drop the database.

    ::

        sage: from boolean_cayley_graphs.classification_database_sqlite3 import *
        sage: import os
        sage: db_name = tmp_filename(ext='.db')
        sage: conn = create_database(db_name)
        sage: conn.close()
        sage: conn = create_classification_tables(db_name)
        sage: os.path.exists(db_name)
        True
        sage: curs = conn.cursor()
        sage: result = curs.execute("SELECT name FROM sqlite_master WHERE type='table'")
        sage: for row in curs:
        ....:     for x in row:
        ....:         print(x)
        ....:
        bent_function
        graph
        cayley_graph
        matrices
        sage: conn.close()
        sage: drop_database(db_name)
    z�
        CREATE TABLE bent_function(
        nvariables INTEGER,
        bent_function BLOB,
        name TEXT UNIQUE,
        PRIMARY KEY(nvariables, bent_function))z�
        CREATE TABLE graph(
        canonical_label_hash BLOB,
        canonical_label TEXT,
        PRIMARY KEY(canonical_label_hash))a�
        CREATE TABLE cayley_graph(
        nvariables INTEGER,
        bent_function BLOB,
        cayley_graph_index INTEGER,
        canonical_label_hash BLOB,
        FOREIGN KEY(nvariables, bent_function)
            REFERENCES bent_function(nvariables, bent_function),
        FOREIGN KEY(canonical_label_hash)
            REFERENCES graph(canonical_label_hash),
        PRIMARY KEY(nvariables, bent_function, cayley_graph_index))a�
        CREATE TABLE matrices(
        nvariables INTEGER,
        bent_function BLOB,
        b INTEGER,
        c INTEGER,
        bent_cayley_graph_index INTEGER,
        dual_cayley_graph_index INTEGER,
        weight_class INTEGER,
        FOREIGN KEY(nvariables, bent_function)
            REFERENCES bent_function(nvariables, bent_function),
        FOREIGN KEY(nvariables, bent_function, bent_cayley_graph_index)
            REFERENCES cayley_graph(nvariables, bent_function, cayley_graph_index),
        FOREIGN KEY(nvariables, bent_function, dual_cayley_graph_index)
            REFERENCES cayley_graph(nvariables, bent_function, cayley_graph_index),
        PRIMARY KEY(nvariables, bent_function, b, c)))r�cursor�execute�commit)rr
�cursrrr�create_classification_tables�s&



rcCsd}t||�}t�|���S)a�
    Hash a graph canonical label.
    
    INPUT:
    
    - ``g`` -- a graph canonical label.
    
    OUTPUT: A hash digest as a bytes object.
    
    EXAMPLE:
    
    ::
        
        sage: from boolean_cayley_graphs.classification_database_sqlite3 import *
        sage: from boolean_cayley_graphs.bent_function import BentFunction
        sage: bentf = BentFunction([0,0,0,1])
        sage: cayley_graph = bentf.extended_cayley_graph()
        sage: cgcl = cayley_graph.canonical_label().graph6_string()
        sage: cgcl_hash = canonical_label_hash(cgcl)
        sage: print(type(cgcl_hash))
        <class 'bytes'>
        sage: print(len(cgcl_hash))
        32
    zUTF-8)�bytes�hashlib�sha256�digest)�g�encodingZbytes_grrr�canonical_label_hash�s
r&cCsdd�|D�S)NcSsg|]}|D]}|�qqSrr)�.0�sublist�itemrrr�
<listcomp>��z<lambda>.<locals>.<listcomp>r)�trrr�<lambda>�r+r-c
s�t|j�}|��}t|��|���|j�|j�|j�|j�|�	�}|�
d��|f�t��}dd��D����fdd�t|�D�}|�
d|����fdd�t|�D�}|�
d|�d|�t������fd	d�t��D��}	|�
d
|	�|��dS)aJ
    Insert a Cayley graph classification into a database.

    INPUT:

    - ``conn`` -- a connection object for the database.
    - ``bfcgc`` -- a Cayley graph classification.
    - ``name`` -- string (default: `None`). The name of the bent function.

    OUTPUT: None.

    A cursor object corresponding to state of the database after the
    classification is inserted.

    EXAMPLE:

    Create a database, with tables, using a temporary filename, insert
    a classification, retrieve it by bent function, then drop the database.

    ::

        sage: from boolean_cayley_graphs.classification_database_sqlite3 import *
        sage: from boolean_cayley_graphs.bent_function import BentFunction
        sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification
        sage: bentf = BentFunction([0,0,0,1])
        sage: bfcgc = BentFunctionCayleyGraphClassification.from_function(bentf)
        sage: bfcgc.algebraic_normal_form
        x0*x1
        sage: db_name = tmp_filename(ext='.db')
        sage: conn = create_classification_tables(db_name)
        sage: insert_classification(conn, bfcgc, 'bentf')
        sage: result = select_classification_where_bent_function(conn, bentf)
        sage: result.algebraic_normal_form
        x0*x1
        sage: drop_database(db_name)
    z9
        INSERT INTO bent_function
        VALUES (?,?,?)cSsg|]}t|��qSr)r&)r'Zcgcrrrr*1s�z)insert_classification.<locals>.<listcomp>csg|]}�|�|f�qSrr�r'�n)�
cgc_hash_list�cgclrrr*4s�z9
        INSERT OR IGNORE INTO graph
        VALUES (?,?)csg|]}��|�|f�qSrrr.)�bfttr0�nvarrrr*<s�z:
        INSERT INTO cayley_graph
        VALUES (?,?,?,?)�cs,g|]$�������fdd�t��D��qS)csBg|]:}���|t�|�f�t�|�f�t�|�f�f�qSr)�int)r'�c)�b�bcimr2�dcimr3�wcmrrr*Es��z4insert_classification.<locals>.<listcomp>.<listcomp>)�range)r')r8r2r9r3�vr:)r7rr*Es	��z<
        INSERT INTO matrices
        VALUES (?,?,?,?,?,?,?)N)r�algebraic_normal_form�
nvariablesr5�	tt_buffer�cayley_graph_class_list�bent_cayley_graph_index_matrix�dual_cayley_graph_index_matrix�weight_class_matrixrr�lenr;�executemany�flattenr)
r
Zbfcgc�name�bentf�dimr�cgcl_lenZgraph_param_listZcayley_graph_param_listZmatrices_param_listr)r8r2r0r1r9r3r<r:r�insert_classification�sH(
������	�
�rKcCs.|��}t|�}|��}|��}|�d||f�|��}|dkrDdS|d}dg|}|�d||f�|D] }|d}	|d}
t|
�||	<qjd|}t||�}t||�}
t||�}|�d||f�|D]P}|d	}|d
}|d}||||f<|d}||
||f<|d
}||||f<q�t|�	�|||
|d�S)a{
    Retrieve a Cayley graph classification for a given bent function from a database.

    INPUT:

    - ``conn`` -- a connection object for the database.
    - ``bentf`` -- class BentFunction. A bent function.

    OUTPUT:

    class BentFunctionCayleyGraphClassification.
    The corresponding Cayley graph classification.

    EXAMPLE:

    Create a database, with tables, using a temporary filename, insert
    a classification, retrieve it by bent function, then drop the database.

    ::

        sage: from boolean_cayley_graphs.classification_database_sqlite3 import *
        sage: from boolean_cayley_graphs.bent_function import BentFunction
        sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification
        sage: bentf = BentFunction([0,0,0,1])
        sage: bfcgc = BentFunctionCayleyGraphClassification.from_function(bentf)
        sage: bfcgc.algebraic_normal_form
        x0*x1
        sage: db_name = tmp_filename(ext='.db')
        sage: conn = create_classification_tables(db_name)
        sage: insert_classification(conn, bfcgc, 'bentf')
        sage: result = select_classification_where_bent_function(conn, bentf)
        sage: result.algebraic_normal_form
        x0*x1
        sage: type(result)
        <class 'boolean_cayley_graphs.bent_function_cayley_graph_classification.BentFunctionCayleyGraphClassification'>
        sage: result.report(report_on_matrix_details=True)
        Algebraic normal form of Boolean function: x0*x1
        Function is bent.
        <BLANKLINE>
        Weight class matrix:
        [0 0 0 1]
        [0 1 0 0]
        [0 0 1 0]
        [1 0 0 0]
        <BLANKLINE>
        SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
        <BLANKLINE>
        Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
        <BLANKLINE>
        There are 2 extended Cayley classes in the extended translation class.
        <BLANKLINE>
        Matrix of indices of Cayley graphs:
        [0 0 0 1]
        [0 1 0 0]
        [0 0 1 0]
        [1 0 0 0]
        sage: drop_database(db_name)
    zq
        SELECT COUNT(*)
        FROM cayley_graph
        WHERE nvariables = (?)
        AND bent_function = (?)Nrz�
        SELECT cayley_graph_index, canonical_label
        FROM cayley_graph, graph
        WHERE nvariables = (?)
        AND bent_function = (?)
        AND cayley_graph.canonical_label_hash = graph.canonical_label_hash�cayley_graph_index�canonical_labelr4zf
        SELECT *
        FROM matrices
        WHERE nvariables = (?)
        AND bent_function = (?)r7r6�bent_cayley_graph_index�dual_cayley_graph_indexr)r=r@rArBrC)
r>r5r?rr�fetchone�strrrr=)r
rHrIr3r2r�rowrJr1rLrMr<r8r9r:r7r6rNrOrrrr�)select_classification_where_bent_functionVsT=�
�


��rSc
Cs�g}|��}|j|d���}t|�}|��}|�d|f�|��}|d}	|	|krV|S|�d|f�|D]0}|d}
|d}t�|
|�}|�	t
||��qh|S)a�

    Given a bent function ``bentf``, retrieve all classifications that
    contain a Cayley graph isomorphic to the Cayley graph of ``bentf``.

    INPUT:

    - ``conn`` -- a connection object for the database.
    - ``bentf`` -- class BentFunction. A bent function.
    - ``algorithm`` -- string (default: BentFunctionCayleyGraphClassification.default_algorithm). 
      Algorithm used for canonical labelling.

    OUTPUT:

    A list where each entry has class BentFunctionCayleyGraphClassification.
    The corresponding list of Cayley graph classifications.

    NOTE:

    ::

        The list is not sorted in any way.

    EXAMPLE:

    Create a database, with tables, using a temporary filename, insert
    a classification, retrieve it by bent function Cayley graph, then drop the database.

    ::

        sage: from boolean_cayley_graphs.classification_database_sqlite3 import *
        sage: from boolean_cayley_graphs.bent_function import BentFunction
        sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification
        sage: db_name = 'doctest_select_classification_where_bent_function_db_name'
        sage: drop_database(db_name)
        sage: conn = create_database(db_name)
        sage: conn.close()
        sage: conn = create_classification_tables(db_name)
        sage: bentf0 = BentFunction([0,0,0,1])
        sage: bfcgc0 = BentFunctionCayleyGraphClassification.from_function(bentf0)
        sage: bfcgc0.algebraic_normal_form
        x0*x1
        sage: insert_classification(conn, bfcgc0, 'bentf0')
        sage: bentf1 = BentFunction([1,0,0,0])
        sage: bfcgc1 = BentFunctionCayleyGraphClassification.from_function(bentf1)
        sage: bfcgc1.algebraic_normal_form
        x0*x1 + x0 + x1 + 1
        sage: insert_classification(conn, bfcgc1, 'bentf1')
        sage: result = select_classification_where_bent_function_cayley_graph(conn, bentf1)
        sage: type(result)
        <class 'list'>
        sage: len(result)
        2
        sage: sorted_result = sorted(result, key=lambda c: str(c.algebraic_normal_form))
        sage: for c in sorted_result:
        ....:     type(c)
        ....:     c.algebraic_normal_form
        ....:     c.report()
        <class 'boolean_cayley_graphs.bent_function_cayley_graph_classification.BentFunctionCayleyGraphClassification'>
        x0*x1
        Algebraic normal form of Boolean function: x0*x1
        Function is bent.
        <BLANKLINE>
        <BLANKLINE>
        SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
        <BLANKLINE>
        Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
        <BLANKLINE>
        There are 2 extended Cayley classes in the extended translation class.
        <class 'boolean_cayley_graphs.bent_function_cayley_graph_classification.BentFunctionCayleyGraphClassification'>
        x0*x1 + x0 + x1 + 1
        Algebraic normal form of Boolean function: x0*x1 + x0 + x1 + 1
        Function is bent.
        <BLANKLINE>
        <BLANKLINE>
        SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
        <BLANKLINE>
        Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
        <BLANKLINE>
        There are 2 extended Cayley classes in the extended translation class.
        sage: conn.close()
        sage: drop_database(db_name)
    )�	algorithmz[
        SELECT canonical_label
        FROM graph
        WHERE canonical_label_hash = (?)rMzu
        SELECT DISTINCT nvariables, bent_function
        FROM cayley_graph
        WHERE canonical_label_hash = (?)r>�
bent_function)Zextended_cayley_graphrM�
graph6_stringr&rrrPr�from_tt_buffer�appendrS)
r
rHrT�result�cayley_graphr1Z	cgcl_hashrrRrMr3r2Z	row_bentfrrr�6select_classification_where_bent_function_cayley_graph�s4W����r[cCsP|��}|�d|f�|��}|dkr*dS|d}|d}t�||�}t||�S)at
    Retrieve a Cayley graph classification for a bent function with a given name from a database.

    INPUT:

    - ``conn`` -- a connection object for the database.
    - ``name`` -- string. The name of the bent function.

    OUTPUT: class BentFunctionCayleyGraphClassification.
    The corresponding a Cayley graph classification.

    EXAMPLE:

    Create a database, with tables, using a temporary filename, insert
    a classification, retrieve it by name, then drop the database.

    ::

        sage: from boolean_cayley_graphs.classification_database_sqlite3 import *
        sage: from boolean_cayley_graphs.bent_function import BentFunction
        sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification
        sage: db_name = tmp_filename(ext='.db')
        sage: conn = create_classification_tables(db_name)
        sage: bentf = BentFunction([0,0,0,1])
        sage: bfcgc = BentFunctionCayleyGraphClassification.from_function(bentf)
        sage: bfcgc.algebraic_normal_form
        x0*x1
        sage: insert_classification(conn, bfcgc,'bentf')
        sage: result = select_classification_where_name(conn, 'bentf')
        sage: result.algebraic_normal_form
        x0*x1
        sage: type(result)
        <class 'boolean_cayley_graphs.bent_function_cayley_graph_classification.BentFunctionCayleyGraphClassification'>
        sage: result.report(report_on_matrix_details=True)
        Algebraic normal form of Boolean function: x0*x1
        Function is bent.
        <BLANKLINE>
        Weight class matrix:
        [0 0 0 1]
        [0 1 0 0]
        [0 0 1 0]
        [1 0 0 0]
        <BLANKLINE>
        SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
        <BLANKLINE>
        Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
        <BLANKLINE>
        There are 2 extended Cayley classes in the extended translation class.
        <BLANKLINE>
        Matrix of indices of Cayley graphs:
        [0 0 0 1]
        [0 1 0 0]
        [0 0 1 0]
        [1 0 0 0]
        sage: drop_database(db_name)
    z]
        SELECT nvariables, bent_function
        FROM bent_function
        WHERE name = (?)Nr>rU)rrrPrrWrS)r
rGrrRr3r2rHrrr� select_classification_where_nameHs;��r\)N)�__doc__r!rr�sage.matrix.constructorrZ#boolean_cayley_graphs.bent_functionrZ?boolean_cayley_graphs.bent_function_cayley_graph_classificationrrZ"boolean_cayley_graphs.weight_classrrrrrr&rFrKrSr[r\rrrr�<module>s&!$S�
]{�
z