passagemath-repl 10.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_repl-10.5.1.data/scripts/sage-cachegrind +25 -0
- passagemath_repl-10.5.1.data/scripts/sage-callgrind +16 -0
- passagemath_repl-10.5.1.data/scripts/sage-cleaner +230 -0
- passagemath_repl-10.5.1.data/scripts/sage-coverage +327 -0
- passagemath_repl-10.5.1.data/scripts/sage-eval +14 -0
- passagemath_repl-10.5.1.data/scripts/sage-fixdoctests +710 -0
- passagemath_repl-10.5.1.data/scripts/sage-inline-fortran +12 -0
- passagemath_repl-10.5.1.data/scripts/sage-ipynb2rst +50 -0
- passagemath_repl-10.5.1.data/scripts/sage-ipython +16 -0
- passagemath_repl-10.5.1.data/scripts/sage-massif +25 -0
- passagemath_repl-10.5.1.data/scripts/sage-notebook +267 -0
- passagemath_repl-10.5.1.data/scripts/sage-omega +25 -0
- passagemath_repl-10.5.1.data/scripts/sage-preparse +302 -0
- passagemath_repl-10.5.1.data/scripts/sage-run +27 -0
- passagemath_repl-10.5.1.data/scripts/sage-run-cython +10 -0
- passagemath_repl-10.5.1.data/scripts/sage-runtests +9 -0
- passagemath_repl-10.5.1.data/scripts/sage-startuptime.py +163 -0
- passagemath_repl-10.5.1.data/scripts/sage-valgrind +34 -0
- passagemath_repl-10.5.1.dist-info/METADATA +77 -0
- passagemath_repl-10.5.1.dist-info/RECORD +162 -0
- passagemath_repl-10.5.1.dist-info/WHEEL +5 -0
- passagemath_repl-10.5.1.dist-info/top_level.txt +1 -0
- sage/all__sagemath_repl.py +119 -0
- sage/doctest/__init__.py +4 -0
- sage/doctest/__main__.py +236 -0
- sage/doctest/all.py +4 -0
- sage/doctest/check_tolerance.py +261 -0
- sage/doctest/control.py +1727 -0
- sage/doctest/external.py +534 -0
- sage/doctest/fixtures.py +383 -0
- sage/doctest/forker.py +2665 -0
- sage/doctest/marked_output.py +102 -0
- sage/doctest/parsing.py +1708 -0
- sage/doctest/parsing_test.py +79 -0
- sage/doctest/reporting.py +733 -0
- sage/doctest/rif_tol.py +124 -0
- sage/doctest/sources.py +1657 -0
- sage/doctest/test.py +584 -0
- sage/doctest/tests/1second.rst +4 -0
- sage/doctest/tests/99seconds.rst +4 -0
- sage/doctest/tests/abort.rst +5 -0
- sage/doctest/tests/atexit.rst +7 -0
- sage/doctest/tests/fail_and_die.rst +6 -0
- sage/doctest/tests/initial.rst +15 -0
- sage/doctest/tests/interrupt.rst +7 -0
- sage/doctest/tests/interrupt_diehard.rst +14 -0
- sage/doctest/tests/keyboardinterrupt.rst +11 -0
- sage/doctest/tests/longtime.rst +5 -0
- sage/doctest/tests/nodoctest +5 -0
- sage/doctest/tests/random_seed.rst +4 -0
- sage/doctest/tests/show_skipped.rst +18 -0
- sage/doctest/tests/sig_on.rst +9 -0
- sage/doctest/tests/simple_failure.rst +8 -0
- sage/doctest/tests/sleep_and_raise.rst +106 -0
- sage/doctest/tests/tolerance.rst +31 -0
- sage/doctest/util.py +750 -0
- sage/interfaces/cleaner.py +48 -0
- sage/interfaces/quit.py +163 -0
- sage/misc/all__sagemath_repl.py +51 -0
- sage/misc/banner.py +235 -0
- sage/misc/benchmark.py +221 -0
- sage/misc/classgraph.py +134 -0
- sage/misc/copying.py +22 -0
- sage/misc/cython.py +694 -0
- sage/misc/dev_tools.py +745 -0
- sage/misc/edit_module.py +304 -0
- sage/misc/explain_pickle.py +3079 -0
- sage/misc/gperftools.py +361 -0
- sage/misc/inline_fortran.py +212 -0
- sage/misc/messaging.py +86 -0
- sage/misc/pager.py +21 -0
- sage/misc/profiler.py +179 -0
- sage/misc/python.py +70 -0
- sage/misc/remote_file.py +53 -0
- sage/misc/sage_eval.py +249 -0
- sage/misc/sage_input.py +3621 -0
- sage/misc/sagedoc.py +1742 -0
- sage/misc/sh.py +38 -0
- sage/misc/trace.py +90 -0
- sage/repl/__init__.py +16 -0
- sage/repl/all.py +15 -0
- sage/repl/attach.py +625 -0
- sage/repl/configuration.py +186 -0
- sage/repl/display/__init__.py +1 -0
- sage/repl/display/fancy_repr.py +354 -0
- sage/repl/display/formatter.py +318 -0
- sage/repl/display/jsmol_iframe.py +290 -0
- sage/repl/display/pretty_print.py +153 -0
- sage/repl/display/util.py +163 -0
- sage/repl/image.py +302 -0
- sage/repl/inputhook.py +91 -0
- sage/repl/interface_magic.py +298 -0
- sage/repl/interpreter.py +854 -0
- sage/repl/ipython_extension.py +593 -0
- sage/repl/ipython_kernel/__init__.py +1 -0
- sage/repl/ipython_kernel/__main__.py +4 -0
- sage/repl/ipython_kernel/all_jupyter.py +10 -0
- sage/repl/ipython_kernel/install.py +301 -0
- sage/repl/ipython_kernel/interact.py +278 -0
- sage/repl/ipython_kernel/kernel.py +217 -0
- sage/repl/ipython_kernel/widgets.py +466 -0
- sage/repl/ipython_kernel/widgets_sagenb.py +587 -0
- sage/repl/ipython_tests.py +163 -0
- sage/repl/load.py +326 -0
- sage/repl/preparse.py +2218 -0
- sage/repl/prompts.py +90 -0
- sage/repl/rich_output/__init__.py +4 -0
- sage/repl/rich_output/backend_base.py +648 -0
- sage/repl/rich_output/backend_doctest.py +316 -0
- sage/repl/rich_output/backend_emacs.py +151 -0
- sage/repl/rich_output/backend_ipython.py +596 -0
- sage/repl/rich_output/buffer.py +311 -0
- sage/repl/rich_output/display_manager.py +829 -0
- sage/repl/rich_output/example.avi +0 -0
- sage/repl/rich_output/example.canvas3d +1 -0
- sage/repl/rich_output/example.dvi +0 -0
- sage/repl/rich_output/example.flv +0 -0
- sage/repl/rich_output/example.gif +0 -0
- sage/repl/rich_output/example.jpg +0 -0
- sage/repl/rich_output/example.mkv +0 -0
- sage/repl/rich_output/example.mov +0 -0
- sage/repl/rich_output/example.mp4 +0 -0
- sage/repl/rich_output/example.ogv +0 -0
- sage/repl/rich_output/example.pdf +0 -0
- sage/repl/rich_output/example.png +0 -0
- sage/repl/rich_output/example.svg +54 -0
- sage/repl/rich_output/example.webm +0 -0
- sage/repl/rich_output/example.wmv +0 -0
- sage/repl/rich_output/example_jmol.spt.zip +0 -0
- sage/repl/rich_output/example_wavefront_scene.mtl +7 -0
- sage/repl/rich_output/example_wavefront_scene.obj +17 -0
- sage/repl/rich_output/output_basic.py +391 -0
- sage/repl/rich_output/output_browser.py +103 -0
- sage/repl/rich_output/output_catalog.py +54 -0
- sage/repl/rich_output/output_graphics.py +320 -0
- sage/repl/rich_output/output_graphics3d.py +345 -0
- sage/repl/rich_output/output_video.py +231 -0
- sage/repl/rich_output/preferences.py +432 -0
- sage/repl/rich_output/pretty_print.py +339 -0
- sage/repl/rich_output/test_backend.py +201 -0
- sage/repl/user_globals.py +214 -0
- sage/tests/all.py +0 -0
- sage/tests/all__sagemath_repl.py +3 -0
- sage/tests/article_heuberger_krenn_kropf_fsm-in-sage.py +630 -0
- sage/tests/arxiv_0812_2725.py +351 -0
- sage/tests/benchmark.py +1925 -0
- sage/tests/book_schilling_zabrocki_kschur_primer.py +795 -0
- sage/tests/book_stein_ent.py +651 -0
- sage/tests/book_stein_modform.py +558 -0
- sage/tests/cmdline.py +796 -0
- sage/tests/combinatorial_hopf_algebras.py +52 -0
- sage/tests/finite_poset.py +623 -0
- sage/tests/functools_partial_src.py +27 -0
- sage/tests/gosper-sum.py +218 -0
- sage/tests/lazy_imports.py +28 -0
- sage/tests/modular_group_cohomology.py +80 -0
- sage/tests/numpy.py +21 -0
- sage/tests/parigp.py +76 -0
- sage/tests/startup.py +27 -0
- sage/tests/symbolic-series.py +76 -0
- sage/tests/sympy.py +16 -0
- sage/tests/test_deprecation.py +31 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-repl
|
2
|
+
# sage.doctest: needs sage.combinat sage.modules
|
3
|
+
r"""
|
4
|
+
Tests For Combinatorial Hopf Algebras
|
5
|
+
|
6
|
+
We check that the composition of `Sym \to FSym^* \to QSym`
|
7
|
+
agrees with `Sym \to QSym`::
|
8
|
+
|
9
|
+
sage: s = SymmetricFunctions(QQ).s()
|
10
|
+
sage: M = QuasiSymmetricFunctions(QQ).M()
|
11
|
+
sage: F = algebras.FSym(QQ).dual().F()
|
12
|
+
sage: all(F(s[p]).to_quasisymmetric_function() == M(s[p])
|
13
|
+
....: for n in range(5)
|
14
|
+
....: for p in Partitions(n))
|
15
|
+
True
|
16
|
+
|
17
|
+
There are various morphisms between the Hopf algebras below.
|
18
|
+
We test that the diagram of morphisms is commutative::
|
19
|
+
|
20
|
+
sage: NSym = NonCommutativeSymmetricFunctions(QQ)
|
21
|
+
sage: QSym = QuasiSymmetricFunctions(QQ)
|
22
|
+
sage: FQSym = algebras.FQSym(QQ)
|
23
|
+
sage: FSym = algebras.FSym(QQ)
|
24
|
+
sage: FSymDual = FSym.dual()
|
25
|
+
sage: Sym = SymmetricFunctions(QQ)
|
26
|
+
|
27
|
+
sage: def go(composition):
|
28
|
+
....: x = NSym.a_realization()[composition]
|
29
|
+
....: if QSym(FQSym(x)) != QSym(Sym(x)): return False
|
30
|
+
....: if Sym(FSym(x)) != Sym(x): return False
|
31
|
+
....: if FQSym(FSym(x)) != FQSym(x): return False
|
32
|
+
....: if FSymDual(Sym(x)) != FSymDual(FQSym(x)): return False
|
33
|
+
....: return True
|
34
|
+
|
35
|
+
sage: go([2,1,2]) # not tested (needs more morphisms)
|
36
|
+
True
|
37
|
+
sage: all(all(go(comp) for comp in Compositions(n)) for n in range(5)) # not tested (needs more morphisms)
|
38
|
+
True
|
39
|
+
|
40
|
+
sage: def go2(n):
|
41
|
+
....: for sigma in Permutations(n):
|
42
|
+
....: x = FQSym.F()[sigma]
|
43
|
+
....: if QSym(FSymDual(x)) != QSym(x): return False
|
44
|
+
....: s = Sym.s()
|
45
|
+
....: for mu in Partitions(n):
|
46
|
+
....: x = s[mu]
|
47
|
+
....: if QSym(FSymDual(x)) != QSym(x): return False
|
48
|
+
....: return True
|
49
|
+
|
50
|
+
sage: all(go2(n) for n in range(6)) # not tested (needs more morphisms)
|
51
|
+
True
|
52
|
+
"""
|
@@ -0,0 +1,623 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-repl
|
2
|
+
# sage.doctest: needs sage.graphs sage.modules
|
3
|
+
"""
|
4
|
+
This file contains test functions that can be used to search
|
5
|
+
bugs by testing random finite posets and lattices.
|
6
|
+
|
7
|
+
As an examples: if a lattice is distributive, then it must be also
|
8
|
+
modular, and if a poset is ranked, then the dual poset must also
|
9
|
+
be ranked.
|
10
|
+
"""
|
11
|
+
|
12
|
+
from sage.misc.prandom import randint
|
13
|
+
from sage.misc.call import attrcall
|
14
|
+
from functools import reduce
|
15
|
+
|
16
|
+
implications = {
|
17
|
+
'doubling_convex': ['doubling_any'],
|
18
|
+
'doubling_interval': ['doubling_lower', 'doubling_upper'],
|
19
|
+
'doubling_lower': ['doubling_convex', 'meet_semidistributive'],
|
20
|
+
'doubling_upper': ['doubling_convex', 'join_semidistributive'],
|
21
|
+
'cosectionally_complemented': ['complemented', 'coatomic', 'regular'],
|
22
|
+
'distributive': ['modular', 'semidistributive', 'join_distributive', 'meet_distributive', 'subdirectly_reducible', 'doubling_interval', 'extremal'],
|
23
|
+
'geometric': ['upper_semimodular', 'relatively_complemented'],
|
24
|
+
'isoform': ['uniform'],
|
25
|
+
'join_distributive': ['meet_semidistributive', 'upper_semimodular'],
|
26
|
+
'join_semidistributive': ['join_pseudocomplemented', 'interval_dismantlable'],
|
27
|
+
'lower_semimodular': ['graded'],
|
28
|
+
'meet_distributive': ['join_semidistributive', 'lower_semimodular'],
|
29
|
+
'meet_semidistributive': ['pseudocomplemented', 'interval_dismantlable'],
|
30
|
+
'modular': ['upper_semimodular', 'lower_semimodular', 'supersolvable'],
|
31
|
+
'orthocomplemented': ['self_dual', 'complemented'],
|
32
|
+
'planar': ['dismantlable'],
|
33
|
+
'dismantlable': ['sublattice_dismantlable'],
|
34
|
+
'interval_dismantlable': ['sublattice_dismantlable'],
|
35
|
+
'relatively_complemented': ['sectionally_complemented', 'cosectionally_complemented', 'isoform'],
|
36
|
+
'sectionally_complemented': ['complemented', 'atomic', 'regular'],
|
37
|
+
'semidistributive': ['join_semidistributive', 'meet_semidistributive'],
|
38
|
+
'simple': ['isoform'],
|
39
|
+
'supersolvable': ['graded'],
|
40
|
+
'uniform': ['regular'],
|
41
|
+
'uniq_orthocomplemented': ['orthocomplemented'],
|
42
|
+
'upper_semimodular': ['graded'],
|
43
|
+
'vertically_decomposable': ['subdirectly_reducible'],
|
44
|
+
}
|
45
|
+
|
46
|
+
dual_properties = [
|
47
|
+
['atomic', 'coatomic'],
|
48
|
+
['upper_semimodular', 'lower_semimodular'],
|
49
|
+
['sectionally_complemented', 'cosectionally_complemented'],
|
50
|
+
['join_distributive', 'meet_distributive'],
|
51
|
+
['join_semidistributive', 'meet_semidistributive'],
|
52
|
+
['pseudocomplemented', 'join_pseudocomplemented'],
|
53
|
+
['doubling_lower', 'doubling_upper'],
|
54
|
+
]
|
55
|
+
|
56
|
+
selfdual_properties = ['distributive', 'modular', 'semidistributive', 'complemented',
|
57
|
+
'relatively_complemented', 'orthocomplemented', 'uniq_orthocomplemented', 'supersolvable', 'planar',
|
58
|
+
'dismantlable', 'vertically_decomposable', 'simple', 'isoform', 'uniform', 'regular',
|
59
|
+
'subdirectly_reducible', 'doubling_any', 'doubling_convex', 'doubling_interval',
|
60
|
+
'interval_dismantlable', 'interval_dismantlable']
|
61
|
+
|
62
|
+
dual_elements = [
|
63
|
+
['atoms', 'coatoms'],
|
64
|
+
['meet_irreducibles', 'join_irreducibles'],
|
65
|
+
['meet_primes', 'join_primes']
|
66
|
+
]
|
67
|
+
|
68
|
+
two_to_one = [ ['distributive', 'dismantlable', 'planar'],
|
69
|
+
['upper_semimodular', 'lower_semimodular', 'modular'],
|
70
|
+
['meet_distributive', 'join_distributive', 'distributive'],
|
71
|
+
['meet_semidistributive', 'join_semidistributive', 'semidistributive'],
|
72
|
+
['lower_semimodular', 'meet_semidistributive', 'distributive'],
|
73
|
+
['upper_semimodular', 'join_semidistributive', 'distributive'],
|
74
|
+
['complemented', 'modular', 'relatively_complemented'],
|
75
|
+
]
|
76
|
+
|
77
|
+
mutually_exclusive = [
|
78
|
+
['doubling_any', 'simple'],
|
79
|
+
['vertically_decomposable', 'atomic'],
|
80
|
+
['vertically_decomposable', 'coatomic'],
|
81
|
+
['vertically_decomposable', 'regular'],
|
82
|
+
]
|
83
|
+
|
84
|
+
set_inclusions = [
|
85
|
+
['atoms', 'join_irreducibles'],
|
86
|
+
['coatoms', 'meet_irreducibles'],
|
87
|
+
['double_irreducibles', 'join_irreducibles'],
|
88
|
+
['double_irreducibles', 'meet_irreducibles'],
|
89
|
+
['meet_primes', 'meet_irreducibles'],
|
90
|
+
['join_primes', 'join_irreducibles'],
|
91
|
+
]
|
92
|
+
|
93
|
+
sublattice_closed = ['distributive', 'modular', 'semidistributive', 'join_semidistributive', 'meet_semidistributive']
|
94
|
+
|
95
|
+
|
96
|
+
def test_attrcall(name, L):
|
97
|
+
"""
|
98
|
+
Return a function by name.
|
99
|
+
|
100
|
+
This is a helper function for test_finite_lattice(). This
|
101
|
+
will unify all Boolean-valued functions to a function without
|
102
|
+
parameters.
|
103
|
+
|
104
|
+
EXAMPLES::
|
105
|
+
|
106
|
+
sage: from sage.tests.finite_poset import test_attrcall
|
107
|
+
sage: N5 = posets.PentagonPoset()
|
108
|
+
sage: N5.is_modular() == test_attrcall('is_modular', N5)
|
109
|
+
True
|
110
|
+
sage: N5.is_constructible_by_doublings('convex') == test_attrcall('is_doubling_convex', N5) # needs sage.combinat
|
111
|
+
True
|
112
|
+
"""
|
113
|
+
if name == 'is_doubling_any':
|
114
|
+
return L.is_constructible_by_doublings('any')
|
115
|
+
if name == 'is_doubling_lower':
|
116
|
+
return L.is_constructible_by_doublings('upper')
|
117
|
+
if name == 'is_doubling_upper':
|
118
|
+
return L.is_constructible_by_doublings('lower')
|
119
|
+
if name == 'is_doubling_convex':
|
120
|
+
return L.is_constructible_by_doublings('convex')
|
121
|
+
if name == 'is_doubling_interval':
|
122
|
+
return L.is_constructible_by_doublings('interval')
|
123
|
+
if name == 'is_uniq_orthocomplemented':
|
124
|
+
return L.is_orthocomplemented(unique=True)
|
125
|
+
return attrcall(name)(L)
|
126
|
+
|
127
|
+
|
128
|
+
def test_finite_lattice(L):
|
129
|
+
"""
|
130
|
+
Test several functions on a given finite lattice.
|
131
|
+
|
132
|
+
The function contains tests of different kinds:
|
133
|
+
|
134
|
+
- Implications of Boolean properties. Examples: a distributive lattice is modular,
|
135
|
+
a dismantlable and distributive lattice is planar, a simple lattice can not be
|
136
|
+
constructible by Day's doublings.
|
137
|
+
- Dual and self-dual properties. Examples: Dual of a modular lattice is modular,
|
138
|
+
dual of an atomic lattice is co-atomic.
|
139
|
+
- Certificate tests. Example: certificate for a non-complemented lattice must be
|
140
|
+
an element without a complement.
|
141
|
+
- Verification of some property by known property or by a random test.
|
142
|
+
Examples: A lattice is distributive iff join-primes are exactly
|
143
|
+
join-irreducibles and an interval of a relatively complemented
|
144
|
+
lattice is complemented.
|
145
|
+
- Set inclusions. Example: Every co-atom must be meet-irreducible.
|
146
|
+
- And several other tests. Example: The skeleton of a pseudocomplemented
|
147
|
+
lattice must be Boolean.
|
148
|
+
|
149
|
+
EXAMPLES::
|
150
|
+
|
151
|
+
sage: from sage.tests.finite_poset import test_finite_lattice
|
152
|
+
sage: L = posets.RandomLattice(10, 0.98)
|
153
|
+
sage: test_finite_lattice(L) is None # Long time
|
154
|
+
True
|
155
|
+
"""
|
156
|
+
from sage.combinat.posets.lattices import LatticePoset
|
157
|
+
|
158
|
+
from sage.sets.set import Set
|
159
|
+
from sage.combinat.subset import Subsets
|
160
|
+
|
161
|
+
from sage.misc.prandom import randint
|
162
|
+
from sage.misc.flatten import flatten
|
163
|
+
from sage.misc.call import attrcall
|
164
|
+
|
165
|
+
from sage.misc.sageinspect import sage_getargspec
|
166
|
+
|
167
|
+
if L.cardinality() < 4:
|
168
|
+
# Special cases should be tested in specific TESTS-sections.
|
169
|
+
return None
|
170
|
+
|
171
|
+
all_props = set(list(implications) + flatten(implications.values()))
|
172
|
+
P = {x: test_attrcall('is_' + x, L) for x in all_props}
|
173
|
+
|
174
|
+
### Relations between boolean-valued properties ###
|
175
|
+
|
176
|
+
# Direct one-property implications
|
177
|
+
for prop1 in implications:
|
178
|
+
if P[prop1]:
|
179
|
+
for prop2 in implications[prop1]:
|
180
|
+
if not P[prop2]:
|
181
|
+
raise ValueError("error: %s should implicate %s" % (prop1, prop2))
|
182
|
+
|
183
|
+
# Impossible combinations
|
184
|
+
for p1, p2 in mutually_exclusive:
|
185
|
+
if P[p1] and P[p2]:
|
186
|
+
raise ValueError("error: %s and %s should be impossible combination" % (p1, p2))
|
187
|
+
|
188
|
+
# Two-property implications
|
189
|
+
for p1, p2, p3 in two_to_one:
|
190
|
+
if P[p1] and P[p2] and not P[p3]:
|
191
|
+
raise ValueError("error: %s and %s, so should be %s" % (p1, p2, p3))
|
192
|
+
|
193
|
+
Ldual = L.dual()
|
194
|
+
# Selfdual properties
|
195
|
+
for p in selfdual_properties:
|
196
|
+
if P[p] != test_attrcall('is_'+p, Ldual):
|
197
|
+
raise ValueError("selfdual property %s error" % p)
|
198
|
+
# Dual properties and elements
|
199
|
+
for p1, p2 in dual_properties:
|
200
|
+
if P[p1] != test_attrcall('is_'+p2, Ldual):
|
201
|
+
raise ValueError("dual properties error %s" % p1)
|
202
|
+
for e1, e2 in dual_elements:
|
203
|
+
if set(attrcall(e1)(L)) != set(attrcall(e2)(Ldual)):
|
204
|
+
raise ValueError("dual elements error %s" % e1)
|
205
|
+
|
206
|
+
### Certificates ###
|
207
|
+
|
208
|
+
# Return value must be a pair with correct result as first element.
|
209
|
+
for p_ in all_props:
|
210
|
+
# Dirty fix first
|
211
|
+
if p_[:9] == 'doubling_' or p_[:5] == 'uniq_':
|
212
|
+
continue
|
213
|
+
p = "is_"+p_
|
214
|
+
if 'certificate' in sage_getargspec(getattr(L, p)).args:
|
215
|
+
res = attrcall(p, certificate=True)(L)
|
216
|
+
if not isinstance(res, tuple) or len(res) != 2:
|
217
|
+
raise ValueError("certificate-option does not return a pair in %s" % p)
|
218
|
+
if P[p_] != res[0]:
|
219
|
+
raise ValueError("certificate-option changes result in %s" % p)
|
220
|
+
|
221
|
+
# Test for "yes"-certificates
|
222
|
+
if P['supersolvable']:
|
223
|
+
a = L.is_supersolvable(certificate=True)[1]
|
224
|
+
S = Subsets(L).random_element()
|
225
|
+
if L.is_chain_of_poset(S):
|
226
|
+
if not L.sublattice(a+list(S)).is_distributive():
|
227
|
+
raise ValueError("certificate error in is_supersolvable")
|
228
|
+
if P['dismantlable']:
|
229
|
+
elms = L.is_dismantlable(certificate=True)[1]
|
230
|
+
if len(elms) != L.cardinality():
|
231
|
+
raise ValueError("certificate error 1 in is_dismantlable")
|
232
|
+
elms = elms[:randint(0, len(elms)-1)]
|
233
|
+
L_ = L.sublattice([x for x in L if x not in elms])
|
234
|
+
if L_.cardinality() != L.cardinality() - len(elms):
|
235
|
+
raise ValueError("certificate error 2 in is_dismantlable")
|
236
|
+
if P['vertically_decomposable']:
|
237
|
+
c = L.is_vertically_decomposable(certificate=True)[1]
|
238
|
+
if c == L.bottom() or c == L.top():
|
239
|
+
raise ValueError("certificate error 1 in is_vertically_decomposable")
|
240
|
+
e = L.random_element()
|
241
|
+
if L.compare_elements(c, e) is None:
|
242
|
+
raise ValueError("certificate error 2 in is_vertically_decomposable")
|
243
|
+
|
244
|
+
# Test for "no"-certificates
|
245
|
+
if not P['atomic']:
|
246
|
+
a = L.is_atomic(certificate=True)[1]
|
247
|
+
if a in L.atoms() or a not in L.join_irreducibles():
|
248
|
+
raise ValueError("certificate error in is_atomic")
|
249
|
+
if not P['coatomic']:
|
250
|
+
a = L.is_coatomic(certificate=True)[1]
|
251
|
+
if a in L.coatoms() or a not in L.meet_irreducibles():
|
252
|
+
raise ValueError("certificate error in is_coatomic")
|
253
|
+
|
254
|
+
if not P['complemented']:
|
255
|
+
a = L.is_complemented(certificate=True)[1]
|
256
|
+
if L.complements(a):
|
257
|
+
raise ValueError("compl. error 1")
|
258
|
+
if not P['sectionally_complemented']:
|
259
|
+
a, b = L.is_sectionally_complemented(certificate=True)[1]
|
260
|
+
L_ = L.sublattice(L.interval(L.bottom(), a))
|
261
|
+
if L_.is_complemented():
|
262
|
+
raise ValueError("sec. compl. error 1")
|
263
|
+
if len(L_.complements(b)) > 0:
|
264
|
+
raise ValueError("sec. compl. error 2")
|
265
|
+
if not P['cosectionally_complemented']:
|
266
|
+
a, b = L.is_cosectionally_complemented(certificate=True)[1]
|
267
|
+
L_ = L.sublattice(L.interval(a, L.top()))
|
268
|
+
if L_.is_complemented():
|
269
|
+
raise ValueError("cosec. compl. error 1")
|
270
|
+
if L_.complements(b):
|
271
|
+
raise ValueError("cosec. compl. error 2")
|
272
|
+
if not P['relatively_complemented']:
|
273
|
+
a, b, c = L.is_relatively_complemented(certificate=True)[1]
|
274
|
+
I = L.interval(a, c)
|
275
|
+
if len(I) != 3 or b not in I:
|
276
|
+
raise ValueError("rel. compl. error 1")
|
277
|
+
|
278
|
+
if not P['upper_semimodular']:
|
279
|
+
a, b = L.is_upper_semimodular(certificate=True)[1]
|
280
|
+
if not set(L.lower_covers(a)).intersection(set(L.lower_covers(b))) or set(L.upper_covers(a)).intersection(set(L.upper_covers(b))):
|
281
|
+
raise ValueError("certificate error in is_upper_semimodular")
|
282
|
+
if not P['lower_semimodular']:
|
283
|
+
a, b = L.is_lower_semimodular(certificate=True)[1]
|
284
|
+
if set(L.lower_covers(a)).intersection(set(L.lower_covers(b))) or not set(L.upper_covers(a)).intersection(set(L.upper_covers(b))):
|
285
|
+
raise ValueError("certificate error in is_lower_semimodular")
|
286
|
+
|
287
|
+
if not P['distributive']:
|
288
|
+
x, y, z = L.is_distributive(certificate=True)[1]
|
289
|
+
if L.meet(x, L.join(y, z)) == L.join(L.meet(x, y), L.meet(x, z)):
|
290
|
+
raise ValueError("certificate error in is_distributive")
|
291
|
+
if not P['modular']:
|
292
|
+
x, a, b = L.is_modular(certificate=True)[1]
|
293
|
+
if not L.is_less_than(x, b) or L.join(x, L.meet(a, b)) == L.meet(L.join(x, a), b):
|
294
|
+
raise ValueError("certificate error in is_modular")
|
295
|
+
|
296
|
+
if not P['pseudocomplemented']:
|
297
|
+
a = L.is_pseudocomplemented(certificate=True)[1]
|
298
|
+
L_ = L.subposet([e for e in L if L.meet(e, a) == L.bottom()])
|
299
|
+
if L_.has_top():
|
300
|
+
raise ValueError("certificate error in is_pseudocomplemented")
|
301
|
+
if not P['join_pseudocomplemented']:
|
302
|
+
a = L.is_join_pseudocomplemented(certificate=True)[1]
|
303
|
+
L_ = L.subposet([e for e in L if L.join(e, a) == L.top()])
|
304
|
+
if L_.has_bottom():
|
305
|
+
raise ValueError("certificate error in is_join_pseudocomplemented")
|
306
|
+
|
307
|
+
if not P['join_semidistributive']:
|
308
|
+
e, x, y = L.is_join_semidistributive(certificate=True)[1]
|
309
|
+
if L.join(e, x) != L.join(e, y) or L.join(e, x) == L.join(e, L.meet(x, y)):
|
310
|
+
raise ValueError("certificate error in is_join_semidistributive")
|
311
|
+
if not P['meet_semidistributive']:
|
312
|
+
e, x, y = L.is_meet_semidistributive(certificate=True)[1]
|
313
|
+
if L.meet(e, x) != L.meet(e, y) or L.meet(e, x) == L.meet(e, L.join(x, y)):
|
314
|
+
raise ValueError("certificate error in is_meet_semidistributive")
|
315
|
+
|
316
|
+
if not P['simple']:
|
317
|
+
c = L.is_simple(certificate=True)[1]
|
318
|
+
if len(L.congruence([c[randint(0, len(c)-1)]])) == 1:
|
319
|
+
raise ValueError("certificate error in is_simple")
|
320
|
+
if not P['isoform']:
|
321
|
+
c = L.is_isoform(certificate=True)[1]
|
322
|
+
if len(c) == 1:
|
323
|
+
raise ValueError("certificate error in is_isoform")
|
324
|
+
if all(L.subposet(c[i]).is_isomorphic(L.subposet(c[i+1])) for i in range(len(c)-1)):
|
325
|
+
raise ValueError("certificate error in is_isoform")
|
326
|
+
if not P['uniform']:
|
327
|
+
c = L.is_uniform(certificate=True)[1]
|
328
|
+
if len(c) == 1:
|
329
|
+
raise ValueError("certificate error in is_uniform")
|
330
|
+
if all(len(c[i]) == len(c[i+1]) for i in range(len(c)-1)):
|
331
|
+
raise ValueError("certificate error in is_uniform")
|
332
|
+
if not P['regular']:
|
333
|
+
c = L.is_regular(certificate=True)[1]
|
334
|
+
if len(c[0]) == 1:
|
335
|
+
raise ValueError("certificate error 1 in is_regular")
|
336
|
+
if Set(c[1]) not in c[0]:
|
337
|
+
raise ValueError("certificate error 2 in is_regular")
|
338
|
+
if L.congruence([c[1]]) == c[0]:
|
339
|
+
raise ValueError("certificate error 3 in is_regular")
|
340
|
+
|
341
|
+
if not P['subdirectly_reducible']:
|
342
|
+
x, y = L.is_subdirectly_reducible(certificate=True)[1]
|
343
|
+
a = L.random_element()
|
344
|
+
b = L.random_element()
|
345
|
+
c = L.congruence([[a, b]])
|
346
|
+
if len(c) != L.cardinality():
|
347
|
+
for c_ in c:
|
348
|
+
if x in c_:
|
349
|
+
if y not in c_:
|
350
|
+
raise ValueError("certificate error 1 in is_subdirectly_reducible")
|
351
|
+
break
|
352
|
+
else:
|
353
|
+
raise ValueError("certificate error 2 in is_subdirectly_reducible")
|
354
|
+
|
355
|
+
if not P['join_distributive']:
|
356
|
+
a = L.is_join_distributive(certificate=True)[1]
|
357
|
+
L_ = L.sublattice(L.interval(a, L.join(L.upper_covers(a))))
|
358
|
+
if L_.is_distributive():
|
359
|
+
raise ValueError("certificate error in is_join_distributive")
|
360
|
+
if not P['meet_distributive']:
|
361
|
+
a = L.is_meet_distributive(certificate=True)[1]
|
362
|
+
L_ = L.sublattice(L.interval(L.meet(L.lower_covers(a)), a))
|
363
|
+
if L_.is_distributive():
|
364
|
+
raise ValueError("certificate error in is_meet_distributive")
|
365
|
+
|
366
|
+
### Other ###
|
367
|
+
|
368
|
+
# Other ways to recognize some boolean property
|
369
|
+
if P['distributive'] != (set(L.join_primes()) == set(L.join_irreducibles())):
|
370
|
+
raise ValueError("every join-irreducible of a distributive lattice should be join-prime")
|
371
|
+
if P['distributive'] != (set(L.meet_primes()) == set(L.meet_irreducibles())):
|
372
|
+
raise ValueError("every meet-irreducible of a distributive lattice should be meet-prime")
|
373
|
+
if P['join_semidistributive'] != all(L.canonical_joinands(e) is not None for e in L):
|
374
|
+
raise ValueError("every element of join-semidistributive lattice should have canonical joinands")
|
375
|
+
if P['meet_semidistributive'] != all(L.canonical_meetands(e) is not None for e in L):
|
376
|
+
raise ValueError("every element of meet-semidistributive lattice should have canonical meetands")
|
377
|
+
|
378
|
+
# Random verification of a Boolean property
|
379
|
+
if P['relatively_complemented']:
|
380
|
+
a = L.random_element()
|
381
|
+
b = L.random_element()
|
382
|
+
if not L.sublattice(L.interval(a, b)).is_complemented():
|
383
|
+
raise ValueError("rel. compl. error 3")
|
384
|
+
if P['sectionally_complemented']:
|
385
|
+
a = L.random_element()
|
386
|
+
if not L.sublattice(L.interval(L.bottom(), a)).is_complemented():
|
387
|
+
raise ValueError("sec. compl. error 3")
|
388
|
+
if P['cosectionally_complemented']:
|
389
|
+
a = L.random_element()
|
390
|
+
if not L.sublattice(L.interval(a, L.top())).is_complemented():
|
391
|
+
raise ValueError("cosec. compl. error 2")
|
392
|
+
|
393
|
+
# Element set inclusions
|
394
|
+
for s1, s2 in set_inclusions:
|
395
|
+
if not set(attrcall(s1)(L)).issubset(set(attrcall(s2)(L))):
|
396
|
+
raise ValueError("%s should be a subset of %s" % (s1, s2))
|
397
|
+
|
398
|
+
# Sublattice-closed properties
|
399
|
+
L_ = L.sublattice(Subsets(L).random_element())
|
400
|
+
for p in sublattice_closed:
|
401
|
+
if P[p] and not test_attrcall('is_'+p, L_):
|
402
|
+
raise ValueError("property %s should apply to sublattices" % p)
|
403
|
+
|
404
|
+
# Some sublattices
|
405
|
+
L_ = L.center() # Center is a Boolean lattice
|
406
|
+
if not L_.is_atomic() or not L_.is_distributive():
|
407
|
+
raise ValueError("error in center")
|
408
|
+
if P['pseudocomplemented']:
|
409
|
+
L_ = L.skeleton() # Skeleton is a Boolean lattice
|
410
|
+
if not L_.is_atomic() or not L_.is_distributive():
|
411
|
+
raise ValueError("error in skeleton")
|
412
|
+
L_ = L.frattini_sublattice()
|
413
|
+
S = Subsets(L).random_element()
|
414
|
+
if L.sublattice(S) == L and L.sublattice([e for e in S if e not in L_]) != L:
|
415
|
+
raise ValueError("error in Frattini sublattice")
|
416
|
+
L_ = L.maximal_sublattices()
|
417
|
+
L_ = L_[randint(0, len(L_)-1)]
|
418
|
+
e = L.random_element()
|
419
|
+
if e not in L_ and L.sublattice(list(L_)+[e]) != L:
|
420
|
+
raise ValueError("error in maximal_sublattices")
|
421
|
+
|
422
|
+
# Reverse functions: vertical composition and decomposition
|
423
|
+
L_ = reduce(lambda a, b: a.vertical_composition(b), L.vertical_decomposition(), LatticePoset())
|
424
|
+
if not L.is_isomorphic(L_):
|
425
|
+
raise ValueError("error in vertical [de]composition")
|
426
|
+
|
427
|
+
# Meet and join
|
428
|
+
a = L.random_element()
|
429
|
+
b = L.random_element()
|
430
|
+
m = L.meet(a, b)
|
431
|
+
j = L.join(a, b)
|
432
|
+
m_ = L.subposet([e for e in L.principal_lower_set(a) if e in L.principal_lower_set(b)]).top()
|
433
|
+
j_ = L.subposet([e for e in L.principal_upper_set(a) if e in L.principal_upper_set(b)]).bottom()
|
434
|
+
if m != m_ or m != Ldual.join(a, b):
|
435
|
+
raise ValueError("error in meet")
|
436
|
+
if j != j_ or j != Ldual.meet(a, b):
|
437
|
+
raise ValueError("error in join")
|
438
|
+
|
439
|
+
# Misc misc
|
440
|
+
e = L.neutral_elements()
|
441
|
+
e = e[randint(0, len(e)-1)]
|
442
|
+
a = L.random_element()
|
443
|
+
b = L.random_element()
|
444
|
+
if not L.sublattice([e, a, b]).is_distributive():
|
445
|
+
raise ValueError("error in neutral_elements")
|
446
|
+
|
447
|
+
|
448
|
+
def test_finite_poset(P):
|
449
|
+
"""
|
450
|
+
Test several functions on a given finite poset.
|
451
|
+
|
452
|
+
The function contains tests of different kinds, for example
|
453
|
+
|
454
|
+
- Numerical properties jump number, dimension etc. can't be a bigger
|
455
|
+
in a subposet with one element less.
|
456
|
+
- "Dual tests", for example the dual of meet-semilattice must be a join-semilattice.
|
457
|
+
- Random tries: for example if the dimension of a poset is `k`, then it can't be the
|
458
|
+
intersection of `k-1` random linear extensions.
|
459
|
+
|
460
|
+
EXAMPLES::
|
461
|
+
|
462
|
+
sage: from sage.tests.finite_poset import test_finite_poset
|
463
|
+
sage: P = posets.RandomPoset(10, 0.15)
|
464
|
+
sage: test_finite_poset(P) is None # Long time
|
465
|
+
True
|
466
|
+
"""
|
467
|
+
from sage.combinat.posets.posets import Poset
|
468
|
+
from sage.combinat.subset import Subsets
|
469
|
+
from sage.misc.prandom import shuffle
|
470
|
+
|
471
|
+
from sage.misc.call import attrcall
|
472
|
+
|
473
|
+
e = P.random_element()
|
474
|
+
P_one_less = P.subposet([x for x in P if x != e])
|
475
|
+
|
476
|
+
# Cardinality
|
477
|
+
if len(P) != P.cardinality():
|
478
|
+
raise ValueError("error 1 in cardinality")
|
479
|
+
if P.cardinality()-1 != P_one_less.cardinality():
|
480
|
+
raise ValueError("error 5 in cardinality")
|
481
|
+
|
482
|
+
# Height
|
483
|
+
h1 = P.height()
|
484
|
+
h2, chain = P.height(certificate=True)
|
485
|
+
if h1 != h2:
|
486
|
+
raise ValueError("error 1 in height")
|
487
|
+
if h1 != len(chain):
|
488
|
+
raise ValueError("error 2 in height")
|
489
|
+
if not P.is_chain_of_poset(chain):
|
490
|
+
raise ValueError("error 3 in height")
|
491
|
+
if len(P.random_maximal_chain()) > h1:
|
492
|
+
raise ValueError("error 4 in height")
|
493
|
+
if h1-P_one_less.height() not in [0, 1]:
|
494
|
+
raise ValueError("error 5 in height")
|
495
|
+
|
496
|
+
# Width
|
497
|
+
w1 = P.width()
|
498
|
+
w2, antichain = P.width(certificate=True)
|
499
|
+
if w1 != w2:
|
500
|
+
raise ValueError("error 1 in width")
|
501
|
+
if w1 != len(antichain):
|
502
|
+
raise ValueError("error 2 in width")
|
503
|
+
if not P.is_antichain_of_poset(antichain):
|
504
|
+
raise ValueError("error 3 in width")
|
505
|
+
if len(P.random_maximal_antichain()) > w1:
|
506
|
+
raise ValueError("error 4 in width")
|
507
|
+
if w1-P_one_less.width() not in [0, 1]:
|
508
|
+
raise ValueError("error 5 in width")
|
509
|
+
|
510
|
+
# Dimension
|
511
|
+
dim1 = P.dimension()
|
512
|
+
dim2, linexts = P.dimension(certificate=True)
|
513
|
+
if dim1 != dim2:
|
514
|
+
raise ValueError("error 1 in dimension")
|
515
|
+
if dim1 != len(linexts):
|
516
|
+
raise ValueError("error 2 in dimension")
|
517
|
+
P_ = Poset( (P.list(), lambda a, b: all(linext.index(a) < linext.index(b) for linext in linexts)) )
|
518
|
+
if P_ != Poset(P.hasse_diagram()):
|
519
|
+
raise ValueError("error 3 in dimension")
|
520
|
+
x = [P.random_linear_extension() for _ in range(dim1-1)]
|
521
|
+
P_ = Poset( (P.list(), lambda a, b: all(linext.index(a) < linext.index(b) for linext in x)) )
|
522
|
+
if P_ == Poset(P.hasse_diagram()):
|
523
|
+
raise ValueError("error 4 in dimension")
|
524
|
+
if dim1-P_one_less.dimension() < 0:
|
525
|
+
raise ValueError("error 5 in dimension")
|
526
|
+
|
527
|
+
# Jump number
|
528
|
+
j1 = P.jump_number()
|
529
|
+
j2, linext = P.jump_number(certificate=True)
|
530
|
+
if j1 != j2:
|
531
|
+
raise ValueError("error 1 in jump number")
|
532
|
+
if P.linear_extension(linext).jump_count() != j1:
|
533
|
+
raise ValueError("error 2 in jump number")
|
534
|
+
if not P.is_linear_extension(linext):
|
535
|
+
raise ValueError("error 3 in jump number")
|
536
|
+
if P.linear_extension(P.random_linear_extension()).jump_count() < j1:
|
537
|
+
raise ValueError("error 4 in jump number")
|
538
|
+
if j1-P_one_less.jump_number() not in [0, 1]:
|
539
|
+
raise ValueError("error 5 in jump number")
|
540
|
+
|
541
|
+
P_dual = P.dual()
|
542
|
+
selfdual_properties = ['chain', 'bounded', 'connected', 'graded', 'ranked', 'series_parallel', 'slender', 'lattice']
|
543
|
+
for prop in selfdual_properties:
|
544
|
+
f = attrcall('is_' + prop)
|
545
|
+
if f(P) != f(P_dual):
|
546
|
+
raise ValueError(f"error in self-dual property {prop}")
|
547
|
+
if P.is_graded():
|
548
|
+
if P.is_bounded():
|
549
|
+
if P.is_eulerian() != P_dual.is_eulerian():
|
550
|
+
raise ValueError("error in self-dual property eulerian")
|
551
|
+
if P.is_eulerian():
|
552
|
+
P_ = P.star_product(P)
|
553
|
+
if not P_.is_eulerian():
|
554
|
+
raise ValueError("error in star product / eulerian")
|
555
|
+
chain1 = P.random_maximal_chain()
|
556
|
+
if len(chain1) != h1:
|
557
|
+
raise ValueError("error in is_graded")
|
558
|
+
if not P.is_ranked():
|
559
|
+
raise ValueError("error in is_ranked / is_graded")
|
560
|
+
|
561
|
+
if P.is_meet_semilattice() != P_dual.is_join_semilattice():
|
562
|
+
raise ValueError("error in meet/join semilattice")
|
563
|
+
|
564
|
+
if set(P.minimal_elements()) != set(P_dual.maximal_elements()):
|
565
|
+
raise ValueError("error in min/max elements")
|
566
|
+
if P.top() != P_dual.bottom():
|
567
|
+
raise ValueError("error in top/bottom element")
|
568
|
+
|
569
|
+
parts = P.connected_components()
|
570
|
+
P_ = Poset()
|
571
|
+
for part in parts:
|
572
|
+
P_ = P_.disjoint_union(part)
|
573
|
+
if not P.is_isomorphic(P_):
|
574
|
+
raise ValueError("error in connected components / disjoint union")
|
575
|
+
parts = P.ordinal_summands()
|
576
|
+
P_ = Poset()
|
577
|
+
for part in parts:
|
578
|
+
P_ = P_.ordinal_sum(part)
|
579
|
+
if not P.is_isomorphic(P_):
|
580
|
+
raise ValueError("error in ordinal summands / ordinal sum")
|
581
|
+
|
582
|
+
P_ = P.with_bounds().without_bounds()
|
583
|
+
if not P.is_isomorphic(P_):
|
584
|
+
raise ValueError("error in with bounds / without bounds")
|
585
|
+
|
586
|
+
P_ = P.completion_by_cuts().irreducibles_poset()
|
587
|
+
if not P.has_isomorphic_subposet(P_):
|
588
|
+
raise ValueError("error in completion by cuts / irreducibles poset")
|
589
|
+
|
590
|
+
P_ = P.subposet(Subsets(P).random_element())
|
591
|
+
if not P_.is_induced_subposet(P):
|
592
|
+
raise ValueError("error in subposet / is induced subposet")
|
593
|
+
|
594
|
+
if not P.is_linear_extension(P.random_linear_extension()):
|
595
|
+
raise ValueError("error in is linear extension")
|
596
|
+
|
597
|
+
x = list(P)
|
598
|
+
shuffle(x)
|
599
|
+
if not P.is_linear_extension(P.sorted(x)):
|
600
|
+
raise ValueError("error in sorted")
|
601
|
+
|
602
|
+
dil = P.dilworth_decomposition()
|
603
|
+
chain = dil[randint(0, len(dil)-1)]
|
604
|
+
if not P.is_chain_of_poset(chain):
|
605
|
+
raise ValueError("error in Dilworth decomposition")
|
606
|
+
lev = P.level_sets()
|
607
|
+
level = lev[randint(0, len(lev)-1)]
|
608
|
+
if not P.is_antichain_of_poset(level):
|
609
|
+
raise ValueError("error in level sets")
|
610
|
+
|
611
|
+
# certificate=True must return a pair
|
612
|
+
bool_with_cert = ['eulerian', 'greedy', 'join_semilattice',
|
613
|
+
'jump_critical', 'meet_semilattice', 'slender']
|
614
|
+
for p in bool_with_cert:
|
615
|
+
try: # some properties are not always defined for all posets
|
616
|
+
res1 = attrcall('is_' + p)(P)
|
617
|
+
except ValueError:
|
618
|
+
continue
|
619
|
+
res2 = attrcall('is_' + p, certificate=True)(P)
|
620
|
+
if not isinstance(res2, tuple) or len(res2) != 2:
|
621
|
+
raise ValueError("certificate-option does not return a pair in %s" % p)
|
622
|
+
if res1 != res2[0]:
|
623
|
+
raise ValueError("certificate-option changes result in %s" % p)
|