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

���`)P�@s�dZddlZddlmmZddlZddlZddl	Z	ddl
mZddlm
Z
ddlmZmZddlmZdd�Zd	d
�Zdd�Zd
d�Zdd�Zddd�Zdd�Zefdd�Zdd�ZdS)a
Interface to a classification database using duckdb
===================================================

The ``classification_database_duckdb`` module defines interfaces
to manipulate an duckdb database of Cayley graph classifications.

AUTHORS:

- Paul Leopardi (2017-10-28)

�N)�matrix)�BentFunction)�%BentFunctionCayleyGraphClassification�default_algorithm)�weight_classcCst�|�}tj|_|S)aK
    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_duckdb import *
        sage: conn = create_database(db_name)
        sage: type(conn)
        <type 'duckdb.Connection'>
        sage: drop_database(db_name)
    )�duckdb�connect�Row�row_factory��db_name�conn�r�X/home/user/Boolean-Cayley-graphs/boolean_cayley_graphs/classification_database_duckdb.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_duckdb import *
        sage: conn = create_database(db_name)
        sage: con2 = connect_to_database(db_name)
        sage: type(con2)
        <type 'duckdb.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_duckdb 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_duckdb 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(
        graph_id INTEGER,
        canonical_label_hash BLOB UNIQUE,
        canonical_label TEXT,
        PRIMARY KEY(graph_id))a�
        CREATE TABLE cayley_graph(
        nvariables INTEGER,
        bent_function BLOB,
        cayley_graph_index INTEGER,
        graph_id INTEGER,
        FOREIGN KEY(nvariables, bent_function)
            REFERENCES bent_function(nvariables, bent_function),
        FOREIGN KEY(graph_id)
            REFERENCES graph(graph_id),
        PRIMARY KEY(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(bent_function, bent_cayley_graph_index)
            REFERENCES cayley_graph(bent_function, cayley_graph_index),
        FOREIGN KEY(bent_function, dual_cayley_graph_index)
            REFERENCES cayley_graph(bent_function, cayley_graph_index),
        PRIMARY KEY(bent_function, b, c)))r�cursor�execute�commit)rr
�cursrrr�create_classification_tables�s&



rcCsd}t||�}t�|���S)NzUTF-8)�bytes�hashlib�sha256�digest)�g�encodingZbytes_grrr�canonical_label_hash�s
r&cst|j�}|��}t|��|���|j}|j�|j�|j�|�	�}|�
d��|f�tt|��D]X}||}t
|�}	|�
dd|	|f�|�
d|	f�|��}
|
d}|�
d��||f�q`d|}t|�D]0�������fdd	�t|�D�}
|�d
|
�q�|��dS)aI
    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_duckdb 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 (?,?,?)zC
            INSERT OR IGNORE INTO graph
            VALUES (?,?,?)Nz`
            SELECT graph_id
            FROM graph
            WHERE canonical_label_hash = (?)�graph_idzB
            INSERT INTO cayley_graph
            VALUES (?,?,?,?)�c3sD|]<}���|t�|�f�t�|�f�t�|�f�fVqdS)N)�int)�.0�c��b�bcim�bftt�dcim�nvar�wcmrr�	<genexpr>-s	��z(insert_classification.<locals>.<genexpr>zD
            INSERT INTO matrices
            VALUES (?,?,?,?,?,?,?))r�algebraic_normal_form�
nvariablesr)�	tt_buffer�cayley_graph_class_list�bent_cayley_graph_index_matrix�dual_cayley_graph_index_matrix�weight_class_matrixrr�range�lenr&�fetchone�executemanyr)r
Zbfcgc�name�bentf�dim�cgclr�nZcgcZcgc_hash�rowr'�vZmatrices_b_rowsrr,r�insert_classification�sF(
���
�	�
�rFcCs.|��}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)az
    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_duckdb 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.graph_id = graph.graph_id�cayley_graph_index�canonical_labelr(zf
        SELECT *
        FROM matrices
        WHERE nvariables = (?)
        AND bent_function = (?)r-r+�bent_cayley_graph_index�dual_cayley_graph_indexr)r4r7r8r9r:)
r5r)r6rrr=�strrrr4)r
r@rAr1r/rrDZcgcl_lenrBrGrHrEr.r0r2r-r+rIrJrrrr�)select_classification_where_bent_function>sT=�
�


��rLcCs�|��}|j|d���}t|�}|��}|�d|f�|��}|d}|d}	g}
|	|kr^|
S|�d|f�|D]0}|d}|d}t�||�}
|
�	t
||
��qp|
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_duckdb 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)
        <type '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)
    )�	algorithmze
        SELECT graph_id, canonical_label
        FROM graph
        WHERE canonical_label_hash = (?)r'rHzi
        SELECT DISTINCT nvariables, bent_function
        FROM cayley_graph
        WHERE graph_id = (?)r5�
bent_function)�extended_cayley_graphrH�
graph6_stringr&rrr=r�from_tt_buffer�appendrL)r
r@rM�cayley_graphrBZ	cgcl_hashrrDr'rH�resultr1r/Z	row_bentfrrr�6select_classification_where_bent_function_cayley_graph�s6V����rUcCsP|��}|�d|f�|��}|dkr*dS|d}|d}t�||�}t||�S)as
    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_duckdb 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 = (?)Nr5rN)rrr=rrQrL)r
r?rrDr1r/r@rrr� select_classification_where_name2s;��rV)N)�__doc__�builtins�@py_builtins�_pytest.assertion.rewrite�	assertion�rewrite�
@pytest_arr!rr�sage.matrix.constructorr�#boolean_cayley_graphs.bent_functionrZ?boolean_cayley_graphs.bent_function_cayley_graph_classificationrr�"boolean_cayley_graphs.weight_classrrrrrr&rFrLrUrVrrrr�<module>s$"!$T	�
_{�
|