Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 19204
1
r"""
2
Interface to a classification database using psycopg2
3
=====================================================
4
5
The ``classification_database_psycopg2`` module defines interfaces
6
to manipulate a PostgreSQL database of Cayley graph classifications.
7
8
AUTHORS:
9
10
- Paul Leopardi (2017-10-28)
11
12
"""
13
#*****************************************************************************
14
# Copyright (C) 2017-2018 Paul Leopardi [email protected]
15
#
16
# Distributed under the terms of the GNU General Public License (GPL)
17
# as published by the Free Software Foundation; either version 2 of
18
# the License, or (at your option) any later version.
19
# http://www.gnu.org/licenses/
20
#*****************************************************************************
21
22
from builtins import object
23
import binascii
24
import hashlib
25
import psycopg2
26
import psycopg2.extras
27
28
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, quote_ident
29
30
from sage.matrix.constructor import matrix
31
32
from boolean_cayley_graphs.bent_function import BentFunction
33
from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification, default_algorithm
34
from boolean_cayley_graphs.weight_class import weight_class
35
36
37
encoding = "UTF-8"
38
39
40
class Psycopg2Default(object):
41
"""
42
A default psycopg2 value.
43
44
NOTE:
45
46
::
47
48
From: Daniele Varrazzo
49
Date: `24 August 2014, 15:50:38`
50
Source: `https://postgrespro.com/list/thread-id/1544890`
51
See: `http://initd.org/psycopg/docs/advanced.html#adapting-new-python-types-to-sql-syntax`
52
53
TESTS:
54
55
::
56
57
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
58
sage: PSYCOPG2_DEFAULT = Psycopg2Default()
59
"""
60
def __conform__(self, proto):
61
"""
62
See: http://initd.org/psycopg/docs/advanced.html
63
64
TESTS:
65
66
::
67
68
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
69
sage: PSYCOPG2_DEFAULT = Psycopg2Default()
70
sage: type(PSYCOPG2_DEFAULT.__conform__(psycopg2.extensions.ISQLQuote))
71
<class 'boolean_cayley_graphs.classification_database_psycopg2.Psycopg2Default'>
72
"""
73
if proto is psycopg2.extensions.ISQLQuote:
74
return self
75
76
77
def getquoted(self):
78
"""
79
See: http://initd.org/psycopg/docs/advanced.html
80
81
TESTS:
82
83
::
84
85
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
86
sage: PSYCOPG2_DEFAULT = Psycopg2Default()
87
sage: PSYCOPG2_DEFAULT.getquoted()
88
'DEFAULT'
89
"""
90
return 'DEFAULT'
91
92
93
PSYCOPG2_DEFAULT = Psycopg2Default()
94
95
96
def create_database(
97
dbname,
98
user=None,
99
password=None,
100
host=None):
101
"""
102
Create a database.
103
104
INPUT:
105
106
- ``dbname`` -- string. The name of the database to be created.
107
- ``user`` -- string, optional. A Postgres user with appropriate
108
permissions on the host.
109
- ``password`` -- string, optional. The Postgres password of ``user``.
110
- ``host`` -- string, optional. The machine running the Postgres database
111
management system that hosts the database.
112
113
OUTPUT: a database connection object.
114
115
EXAMPLE:
116
117
Create a database using a standardized name, then drop the database.
118
119
::
120
121
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
122
sage: from psycopg2 import ProgrammingError
123
sage: dbname = 'doctest_create_database_dbname'
124
sage: drop_database(dbname)
125
sage: conn = create_database(dbname)
126
sage: type(conn)
127
<class 'psycopg2.extensions.connection'>
128
sage: conn.close()
129
sage: drop_database(dbname)
130
"""
131
conn = psycopg2.connect(
132
dbname="postgres",
133
user=user,
134
password=password,
135
host=host)
136
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
137
curs = conn.cursor()
138
curs.execute(
139
"CREATE DATABASE %s" %
140
quote_ident(dbname, curs))
141
conn.commit()
142
return conn
143
144
145
def connect_to_database(
146
dbname,
147
user=None,
148
password=None,
149
host=None):
150
"""
151
Connect to an existing database.
152
153
INPUT:
154
155
- ``dbname`` -- string. The name of the existing database.
156
- ``user`` -- string, optional. A Postgres user with appropriate
157
permissions on the host.
158
- ``password`` -- string, optional. The Postgres password of ``user``.
159
- ``host`` -- string, optional. The machine running the Postgres database
160
management system that hosts the database.
161
162
OUTPUT: a database connection object.
163
164
EXAMPLE:
165
166
Create a database using a standardized name, connect to it,
167
then drop the database.
168
169
::
170
171
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
172
sage: from psycopg2 import ProgrammingError
173
sage: dbname = 'doctest_connect_to_database_dbname'
174
sage: drop_database(dbname)
175
sage: conn = create_database(dbname)
176
sage: conn.close()
177
sage: con2 = connect_to_database(dbname)
178
sage: type(con2)
179
<class 'psycopg2.extensions.connection'>
180
sage: con2.close()
181
sage: drop_database(dbname)
182
"""
183
conn = psycopg2.connect(
184
dbname=dbname,
185
user=user,
186
password=password,
187
host=host)
188
return conn
189
190
191
def drop_database(
192
dbname,
193
user=None,
194
password=None,
195
host=None):
196
"""
197
Drop a database, if it exists.
198
199
INPUT:
200
201
- ``dbname`` -- string. The name of the existing database.
202
- ``user`` -- string, optional. A Postgres user with appropriate
203
permissions on the host.
204
- ``password`` -- string, optional. The Postgres password of ``user``.
205
- ``host`` -- string, optional. The machine running the Postgres database
206
management system that hosts the database.
207
208
OUTPUT: None.
209
210
EXAMPLE:
211
212
Create a database using a standardized name, then drop the database.
213
214
::
215
216
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
217
sage: dbname = 'doctest_drop_database_dbname'
218
sage: drop_database(dbname)
219
sage: conn = create_database(dbname)
220
sage: type(conn)
221
<class 'psycopg2.extensions.connection'>
222
sage: conn.close()
223
sage: drop_database(dbname)
224
sage: drop_database(dbname)
225
"""
226
conn = psycopg2.connect(
227
dbname="postgres",
228
user=user,
229
password=password,
230
host=host)
231
conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
232
with conn.cursor() as curs:
233
try:
234
curs.execute(
235
"DROP DATABASE %s" %
236
quote_ident(dbname, curs))
237
except psycopg2.ProgrammingError:
238
pass
239
conn.close()
240
241
242
def create_classification_tables(
243
dbname,
244
user=None,
245
password=None,
246
host=None):
247
"""
248
Create the tables used for a database of Cayley graph classifications.
249
250
INPUT:
251
252
- ``dbname`` -- string. The name of an existing database.
253
- ``user`` -- string, optional. A Postgres user with appropriate
254
permissions on the host.
255
- ``password`` -- string, optional. The Postgres password of ``user``.
256
- ``host`` -- string, optional. The machine running the Postgres database
257
management system that hosts the database.
258
259
OUTPUT: a database connection object.
260
261
EXAMPLE:
262
263
Create a database, with tables, using a standardized name,
264
list the table names, then drop the database.
265
266
::
267
268
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
269
sage: dbname = 'doctest_create_classification_tables_dbname'
270
sage: drop_database(dbname)
271
sage: conn = create_database(dbname)
272
sage: conn.close()
273
sage: conn = create_classification_tables(dbname)
274
sage: curs = conn.cursor()
275
sage: curs.execute(
276
....: "SELECT table_name " +
277
....: "FROM information_schema.tables " +
278
....: "WHERE table_schema='public' AND table_type='BASE TABLE' " +
279
....: "ORDER BY table_name")
280
sage: for row in curs:
281
....: for x in row:
282
....: print(x)
283
....:
284
bent_function
285
cayley_graph
286
graph
287
matrices
288
sage: conn.close()
289
sage: drop_database(dbname)
290
"""
291
conn = connect_to_database(
292
dbname,
293
user=user,
294
password=password,
295
host=host)
296
curs = conn.cursor()
297
298
curs.execute("""
299
CREATE TABLE bent_function(
300
nvariables INTEGER,
301
bent_function BYTEA,
302
name TEXT UNIQUE,
303
PRIMARY KEY(nvariables, bent_function))""")
304
curs.execute("""
305
CREATE TABLE graph(
306
graph_id SERIAL PRIMARY KEY,
307
canonical_label_hash BYTEA UNIQUE,
308
canonical_label TEXT)""")
309
curs.execute("""
310
CREATE TABLE cayley_graph(
311
nvariables INTEGER,
312
bent_function BYTEA,
313
cayley_graph_index INTEGER,
314
graph_id INTEGER,
315
FOREIGN KEY(nvariables, bent_function)
316
REFERENCES bent_function(nvariables, bent_function),
317
FOREIGN KEY(graph_id)
318
REFERENCES graph(graph_id),
319
PRIMARY KEY(bent_function, cayley_graph_index))""")
320
curs.execute("""
321
CREATE TABLE matrices(
322
nvariables INTEGER,
323
bent_function BYTEA,
324
b INTEGER,
325
c INTEGER,
326
bent_cayley_graph_index INTEGER,
327
dual_cayley_graph_index INTEGER,
328
weight_class INTEGER,
329
FOREIGN KEY(nvariables, bent_function)
330
REFERENCES bent_function(nvariables, bent_function),
331
FOREIGN KEY(bent_function, bent_cayley_graph_index)
332
REFERENCES cayley_graph(bent_function, cayley_graph_index),
333
FOREIGN KEY(bent_function, dual_cayley_graph_index)
334
REFERENCES cayley_graph(bent_function, cayley_graph_index),
335
PRIMARY KEY(bent_function, b, c))""")
336
conn.commit()
337
return conn
338
339
340
def canonical_label_hash(canonical_label):
341
r"""
342
Hash function for Graph canonical labels.
343
344
INPUT:
345
346
- ``canonical_label`` -- string. A graph6_string encoding a Graph canonical label.
347
348
OUTPUT: The sha256 hash of ``canonical_label`` as a ``psycopg2.Binary`` buffer.
349
350
TESTS:
351
352
::
353
354
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
355
sage: clh = canonical_label_hash("Arbitrary string")
356
sage: type(clh)
357
<class 'psycopg2.extensions.Binary'>
358
"""
359
# return psycopg2.Binary(buffer(hashlib.sha256(canonical_label).digest()))
360
encoded_canonical_label = canonical_label.encode(encoding)
361
return psycopg2.Binary(hashlib.sha256(encoded_canonical_label).digest())
362
363
364
def insert_classification(
365
conn,
366
bfcgc,
367
name=None):
368
"""
369
Insert a Cayley graph classification into a database.
370
371
INPUT:
372
373
- ``conn`` -- a connection object for the database.
374
- ``bfcgc`` -- a Cayley graph classification.
375
- ``name`` -- string (default: `None`). The name of the bent function.
376
377
OUTPUT: None.
378
379
A cursor object corresponding to state of the database after the
380
classification is inserted.
381
382
EXAMPLE:
383
384
Create a database, with tables, using a standardized name, insert
385
a classification, retrieve it by bent function, then drop the database.
386
387
::
388
389
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
390
sage: from boolean_cayley_graphs.bent_function import BentFunction
391
sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification
392
sage: bentf = BentFunction([0,0,0,1])
393
sage: bfcgc = BentFunctionCayleyGraphClassification.from_function(bentf)
394
sage: bfcgc.algebraic_normal_form
395
x0*x1
396
sage: dbname = 'doctest_insert_classification_dbname'
397
sage: drop_database(dbname)
398
sage: conn = create_database(dbname)
399
sage: conn.close()
400
sage: conn = create_classification_tables(dbname)
401
sage: insert_classification(conn, bfcgc, 'bentf')
402
sage: result = select_classification_where_bent_function(conn, bentf)
403
sage: result.algebraic_normal_form
404
x0*x1
405
sage: conn.close()
406
sage: drop_database(dbname)
407
"""
408
bentf = BentFunction(bfcgc.algebraic_normal_form)
409
dim = bentf.nvariables()
410
nvar = int(dim)
411
bftt = psycopg2.Binary(bentf.tt_buffer())
412
cgcl = bfcgc.cayley_graph_class_list
413
bcim = bfcgc.bent_cayley_graph_index_matrix
414
dcim = bfcgc.dual_cayley_graph_index_matrix
415
wcm = bfcgc.weight_class_matrix
416
417
curs = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
418
curs.execute("""
419
INSERT INTO bent_function
420
VALUES (%s,%s,%s)""",
421
(nvar, bftt, name))
422
for n in range(len(cgcl)):
423
cgc = cgcl[n]
424
cgc_hash = canonical_label_hash(cgc)
425
curs.execute("""
426
INSERT INTO graph
427
VALUES (%s,%s,%s)
428
ON CONFLICT DO NOTHING""",
429
(PSYCOPG2_DEFAULT, cgc_hash, cgc))
430
431
curs.execute("""
432
SELECT graph_id
433
FROM graph
434
WHERE canonical_label_hash = (%s)""",
435
(cgc_hash,))
436
437
row = curs.fetchone()
438
graph_id = row["graph_id"]
439
440
curs.execute("""
441
INSERT INTO cayley_graph
442
VALUES (%s,%s,%s,%s)""",
443
(nvar, bftt, n, graph_id))
444
445
v = 2 ** dim
446
for b in range(v):
447
matrices_b_rows = (
448
(
449
nvar,
450
bftt,
451
b,
452
c,
453
int(bcim[c,b]),
454
int(dcim[c,b]),
455
int(wcm[c,b]))
456
for c in range(v))
457
curs.executemany("""
458
INSERT INTO matrices
459
VALUES (%s,%s,%s,%s,%s,%s,%s)""",
460
matrices_b_rows)
461
462
conn.commit()
463
464
465
def select_classification_where_bent_function(
466
conn,
467
bentf):
468
"""
469
Retrieve a Cayley graph classification for a given bent function from a database.
470
471
INPUT:
472
473
- ``conn`` -- a connection object for the database.
474
- ``bentf`` -- class BentFunction. A bent function.
475
476
OUTPUT:
477
478
class BentFunctionCayleyGraphClassification.
479
The corresponding a Cayley graph classification.
480
481
EXAMPLE:
482
483
Create a database, with tables, using a standardized name, insert
484
a classification, retrieve it by bent function, then drop the database.
485
486
::
487
488
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
489
sage: from boolean_cayley_graphs.bent_function import BentFunction
490
sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification
491
sage: bentf = BentFunction([0,0,0,1])
492
sage: bfcgc = BentFunctionCayleyGraphClassification.from_function(bentf)
493
sage: bfcgc.algebraic_normal_form
494
x0*x1
495
sage: dbname = 'doctest_select_classification_where_bent_function_dbname'
496
sage: drop_database(dbname)
497
sage: conn = create_database(dbname)
498
sage: conn.close()
499
sage: conn = create_classification_tables(dbname)
500
sage: insert_classification(conn, bfcgc, 'bentf')
501
sage: result = select_classification_where_bent_function(conn, bentf)
502
sage: result.algebraic_normal_form
503
x0*x1
504
sage: type(result)
505
<class 'boolean_cayley_graphs.bent_function_cayley_graph_classification.BentFunctionCayleyGraphClassification'>
506
sage: result.report(report_on_matrix_details=True)
507
Algebraic normal form of Boolean function: x0*x1
508
Function is bent.
509
<BLANKLINE>
510
Weight class matrix:
511
[0 0 0 1]
512
[0 1 0 0]
513
[0 0 1 0]
514
[1 0 0 0]
515
<BLANKLINE>
516
SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
517
<BLANKLINE>
518
Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
519
<BLANKLINE>
520
There are 2 extended Cayley classes in the extended translation class.
521
<BLANKLINE>
522
Matrix of indices of Cayley graphs:
523
[0 0 0 1]
524
[0 1 0 0]
525
[0 0 1 0]
526
[1 0 0 0]
527
sage: conn.close()
528
sage: drop_database(dbname)
529
"""
530
dim = bentf.nvariables()
531
nvar = int(dim)
532
bftt = psycopg2.Binary(bentf.tt_buffer())
533
534
curs = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
535
curs.execute("""
536
SELECT COUNT(*)
537
FROM cayley_graph
538
WHERE nvariables = (%s)
539
AND bent_function = (%s)""",
540
(nvar, bftt))
541
row = curs.fetchone()
542
if row == None:
543
return None
544
545
cgcl_len = row[0]
546
cgcl = [None] * cgcl_len
547
curs.execute("""
548
SELECT cayley_graph_index, canonical_label
549
FROM cayley_graph, graph
550
WHERE nvariables = (%s)
551
AND bent_function = (%s)
552
AND cayley_graph.graph_id = graph.graph_id""",
553
(nvar, bftt))
554
for row in curs:
555
cayley_graph_index = row["cayley_graph_index"]
556
canonical_label = row["canonical_label"]
557
cgcl[cayley_graph_index] = str(canonical_label)
558
559
v = 2 ** dim
560
bcim = matrix(v, v)
561
dcim = matrix(v, v)
562
wcm = matrix(v, v)
563
curs.execute("""
564
SELECT *
565
FROM matrices
566
WHERE nvariables = (%s)
567
AND bent_function = (%s)""",
568
(nvar, bftt))
569
for row in curs:
570
b = row["b"]
571
c = row["c"]
572
573
bent_cayley_graph_index = row["bent_cayley_graph_index"]
574
bcim[c, b] = bent_cayley_graph_index
575
576
dual_cayley_graph_index = row["dual_cayley_graph_index"]
577
dcim[c, b] = dual_cayley_graph_index
578
579
weight_class = row["weight_class"]
580
wcm[c, b] = weight_class
581
582
return BentFunctionCayleyGraphClassification(
583
algebraic_normal_form=bentf.algebraic_normal_form(),
584
cayley_graph_class_list=cgcl,
585
bent_cayley_graph_index_matrix=bcim,
586
dual_cayley_graph_index_matrix=dcim,
587
weight_class_matrix=wcm)
588
589
590
def select_classification_where_bent_function_cayley_graph(
591
conn,
592
bentf,
593
algorithm=default_algorithm):
594
"""
595
Given a bent function ``bentf``, retrieve all classifications that
596
contain a Cayley graph isomorphic to the Cayley graph of ``bentf``.
597
598
INPUT:
599
600
- ``conn`` -- a connection object for the database.
601
- ``bentf`` -- class BentFunction. A bent function.
602
- ``algorithm`` -- string (default: BentFunctionCayleyGraphClassification.default_algorithm).
603
Algorithm used for canonical labelling.
604
605
OUTPUT:
606
607
A list where each entry has class BentFunctionCayleyGraphClassification.
608
The corresponding list of Cayley graph classifications.
609
610
NOTE:
611
612
::
613
614
The list is not sorted in any way.
615
616
EXAMPLE:
617
618
Create a database, with tables, using a standardized name,
619
insert a classification, retrieve all related classifications
620
by bent function Cayley graph, then drop the database.
621
622
::
623
624
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
625
sage: from boolean_cayley_graphs.bent_function import BentFunction
626
sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification
627
sage: dbname = 'doctest_select_classification_where_bent_function_dbname'
628
sage: drop_database(dbname)
629
sage: conn = create_database(dbname)
630
sage: conn.close()
631
sage: conn = create_classification_tables(dbname)
632
sage: bentf0 = BentFunction([0,0,0,1])
633
sage: bfcgc0 = BentFunctionCayleyGraphClassification.from_function(bentf0)
634
sage: bfcgc0.algebraic_normal_form
635
x0*x1
636
sage: insert_classification(conn, bfcgc0, 'bentf0')
637
sage: bentf1 = BentFunction([1,0,0,0])
638
sage: bfcgc1 = BentFunctionCayleyGraphClassification.from_function(bentf1)
639
sage: bfcgc1.algebraic_normal_form
640
x0*x1 + x0 + x1 + 1
641
sage: insert_classification(conn, bfcgc1, 'bentf1')
642
sage: result = select_classification_where_bent_function_cayley_graph(conn, bentf1)
643
sage: type(result)
644
<class 'list'>
645
sage: len(result)
646
2
647
sage: sorted_result = sorted(result, key=lambda c: str(c.algebraic_normal_form))
648
sage: for c in sorted_result:
649
....: type(c)
650
....: c.algebraic_normal_form
651
....: c.report()
652
<class 'boolean_cayley_graphs.bent_function_cayley_graph_classification.BentFunctionCayleyGraphClassification'>
653
x0*x1
654
Algebraic normal form of Boolean function: x0*x1
655
Function is bent.
656
<BLANKLINE>
657
<BLANKLINE>
658
SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
659
<BLANKLINE>
660
Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
661
<BLANKLINE>
662
There are 2 extended Cayley classes in the extended translation class.
663
<class 'boolean_cayley_graphs.bent_function_cayley_graph_classification.BentFunctionCayleyGraphClassification'>
664
x0*x1 + x0 + x1 + 1
665
Algebraic normal form of Boolean function: x0*x1 + x0 + x1 + 1
666
Function is bent.
667
<BLANKLINE>
668
<BLANKLINE>
669
SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
670
<BLANKLINE>
671
Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
672
<BLANKLINE>
673
There are 2 extended Cayley classes in the extended translation class.
674
sage: conn.close()
675
sage: drop_database(dbname)
676
"""
677
cayley_graph = bentf.extended_cayley_graph()
678
cgcl = cayley_graph.canonical_label(algorithm=algorithm).graph6_string()
679
cgcl_hash = canonical_label_hash(cgcl)
680
681
curs = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
682
curs.execute("""
683
SELECT graph_id, canonical_label
684
FROM graph
685
WHERE canonical_label_hash = (%s)""",
686
(cgcl_hash,))
687
688
row = curs.fetchone()
689
graph_id = row["graph_id"]
690
canonical_label = row["canonical_label"]
691
692
# The result is a list of classifications.
693
result = []
694
# Check for a hash collision -- very unlikely.
695
if canonical_label != cgcl:
696
return result
697
698
curs.execute("""
699
SELECT DISTINCT nvariables, bent_function
700
FROM cayley_graph
701
WHERE graph_id = (%s)""",
702
(graph_id,))
703
704
for row in curs:
705
nvar = row["nvariables"]
706
bftt = row["bent_function"]
707
row_bentf = BentFunction.from_tt_buffer(nvar, bftt)
708
result.append(
709
select_classification_where_bent_function(
710
conn,
711
row_bentf))
712
return result
713
714
715
def select_classification_where_name(
716
conn,
717
name):
718
"""
719
Retrieve a Cayley graph classification for a bent function with a given name from a database.
720
721
INPUT:
722
723
- ``conn`` -- a connection object for the database.
724
- ``name`` -- string. The name of the bent function.
725
726
OUTPUT: class BentFunctionCayleyGraphClassification.
727
The corresponding a Cayley graph classification.
728
729
EXAMPLE:
730
731
Create a database, with tables, using a standardized name, insert
732
a classification, retrieve it by bent function, then drop the database.
733
734
::
735
736
sage: from boolean_cayley_graphs.classification_database_psycopg2 import *
737
sage: from boolean_cayley_graphs.bent_function import BentFunction
738
sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification
739
sage: bentf = BentFunction([0,0,0,1])
740
sage: bfcgc = BentFunctionCayleyGraphClassification.from_function(bentf)
741
sage: bfcgc.algebraic_normal_form
742
x0*x1
743
sage: dbname = 'doctest_select_classification_where_bent_function_dbname'
744
sage: drop_database(dbname)
745
sage: conn = create_database(dbname)
746
sage: conn.close()
747
sage: conn = create_classification_tables(dbname)
748
sage: insert_classification(conn, bfcgc, 'bentf')
749
sage: result = select_classification_where_name(conn, 'bentf')
750
sage: result.algebraic_normal_form
751
x0*x1
752
sage: type(result)
753
<class 'boolean_cayley_graphs.bent_function_cayley_graph_classification.BentFunctionCayleyGraphClassification'>
754
sage: result.report(report_on_matrix_details=True)
755
Algebraic normal form of Boolean function: x0*x1
756
Function is bent.
757
<BLANKLINE>
758
Weight class matrix:
759
[0 0 0 1]
760
[0 1 0 0]
761
[0 0 1 0]
762
[1 0 0 0]
763
<BLANKLINE>
764
SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
765
<BLANKLINE>
766
Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
767
<BLANKLINE>
768
There are 2 extended Cayley classes in the extended translation class.
769
<BLANKLINE>
770
Matrix of indices of Cayley graphs:
771
[0 0 0 1]
772
[0 1 0 0]
773
[0 0 1 0]
774
[1 0 0 0]
775
sage: conn.close()
776
sage: drop_database(dbname)
777
"""
778
curs = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
779
curs.execute("""
780
SELECT nvariables, bent_function
781
FROM bent_function
782
WHERE name = (%s)""",
783
(name,))
784
row = curs.fetchone()
785
if row == None:
786
return None
787
788
nvar = row["nvariables"]
789
bftt = row["bent_function"]
790
bentf = BentFunction.from_tt_buffer(nvar, bftt)
791
792
return select_classification_where_bent_function(
793
conn,
794
bentf)
795
796