passagemath-symbolics 10.6.43__cp314-cp314t-musllinux_1_2_x86_64.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.

Potentially problematic release.


This version of passagemath-symbolics might be problematic. Click here for more details.

Files changed (171) hide show
  1. passagemath_symbolics/__init__.py +3 -0
  2. passagemath_symbolics-10.6.43.dist-info/METADATA +187 -0
  3. passagemath_symbolics-10.6.43.dist-info/RECORD +171 -0
  4. passagemath_symbolics-10.6.43.dist-info/WHEEL +5 -0
  5. passagemath_symbolics-10.6.43.dist-info/top_level.txt +3 -0
  6. sage/all__sagemath_symbolics.py +17 -0
  7. sage/calculus/all.py +14 -0
  8. sage/calculus/calculus.py +2826 -0
  9. sage/calculus/desolvers.py +1866 -0
  10. sage/calculus/predefined.py +51 -0
  11. sage/calculus/tests.py +225 -0
  12. sage/calculus/var.cpython-314t-x86_64-linux-musl.so +0 -0
  13. sage/calculus/var.pyx +401 -0
  14. sage/dynamics/all__sagemath_symbolics.py +6 -0
  15. sage/dynamics/complex_dynamics/all.py +5 -0
  16. sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
  17. sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-314t-x86_64-linux-musl.so +0 -0
  18. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
  19. sage/ext/all__sagemath_symbolics.py +1 -0
  20. sage/ext_data/kenzo/CP2.txt +45 -0
  21. sage/ext_data/kenzo/CP3.txt +349 -0
  22. sage/ext_data/kenzo/CP4.txt +4774 -0
  23. sage/ext_data/kenzo/README.txt +49 -0
  24. sage/ext_data/kenzo/S4.txt +20 -0
  25. sage/ext_data/magma/latex/latex.m +1021 -0
  26. sage/ext_data/magma/latex/latex.spec +1 -0
  27. sage/ext_data/magma/sage/basic.m +356 -0
  28. sage/ext_data/magma/sage/sage.spec +1 -0
  29. sage/ext_data/magma/spec +9 -0
  30. sage/geometry/all__sagemath_symbolics.py +8 -0
  31. sage/geometry/hyperbolic_space/all.py +5 -0
  32. sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
  33. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
  37. sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
  38. sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
  39. sage/geometry/riemannian_manifolds/all.py +7 -0
  40. sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
  41. sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
  42. sage/interfaces/all__sagemath_symbolics.py +1 -0
  43. sage/interfaces/magma.py +3017 -0
  44. sage/interfaces/magma_free.py +92 -0
  45. sage/interfaces/maple.py +1397 -0
  46. sage/interfaces/mathematica.py +1345 -0
  47. sage/interfaces/mathics.py +1312 -0
  48. sage/interfaces/sympy.py +1398 -0
  49. sage/interfaces/sympy_wrapper.py +197 -0
  50. sage/interfaces/tides.py +938 -0
  51. sage/libs/all__sagemath_symbolics.py +6 -0
  52. sage/manifolds/all.py +7 -0
  53. sage/manifolds/calculus_method.py +555 -0
  54. sage/manifolds/catalog.py +437 -0
  55. sage/manifolds/chart.py +4019 -0
  56. sage/manifolds/chart_func.py +3419 -0
  57. sage/manifolds/continuous_map.py +2183 -0
  58. sage/manifolds/continuous_map_image.py +155 -0
  59. sage/manifolds/differentiable/affine_connection.py +2475 -0
  60. sage/manifolds/differentiable/all.py +1 -0
  61. sage/manifolds/differentiable/automorphismfield.py +1383 -0
  62. sage/manifolds/differentiable/automorphismfield_group.py +604 -0
  63. sage/manifolds/differentiable/bundle_connection.py +1445 -0
  64. sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
  65. sage/manifolds/differentiable/chart.py +1241 -0
  66. sage/manifolds/differentiable/curve.py +1028 -0
  67. sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
  68. sage/manifolds/differentiable/degenerate.py +559 -0
  69. sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
  70. sage/manifolds/differentiable/diff_form.py +1658 -0
  71. sage/manifolds/differentiable/diff_form_module.py +1062 -0
  72. sage/manifolds/differentiable/diff_map.py +1315 -0
  73. sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
  74. sage/manifolds/differentiable/examples/all.py +1 -0
  75. sage/manifolds/differentiable/examples/euclidean.py +2517 -0
  76. sage/manifolds/differentiable/examples/real_line.py +897 -0
  77. sage/manifolds/differentiable/examples/sphere.py +1186 -0
  78. sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
  79. sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
  80. sage/manifolds/differentiable/integrated_curve.py +4035 -0
  81. sage/manifolds/differentiable/levi_civita_connection.py +841 -0
  82. sage/manifolds/differentiable/manifold.py +4254 -0
  83. sage/manifolds/differentiable/manifold_homset.py +1826 -0
  84. sage/manifolds/differentiable/metric.py +3032 -0
  85. sage/manifolds/differentiable/mixed_form.py +1507 -0
  86. sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
  87. sage/manifolds/differentiable/multivector_module.py +800 -0
  88. sage/manifolds/differentiable/multivectorfield.py +1520 -0
  89. sage/manifolds/differentiable/poisson_tensor.py +268 -0
  90. sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
  91. sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
  92. sage/manifolds/differentiable/scalarfield.py +1343 -0
  93. sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
  94. sage/manifolds/differentiable/symplectic_form.py +910 -0
  95. sage/manifolds/differentiable/symplectic_form_test.py +220 -0
  96. sage/manifolds/differentiable/tangent_space.py +412 -0
  97. sage/manifolds/differentiable/tangent_vector.py +616 -0
  98. sage/manifolds/differentiable/tensorfield.py +4665 -0
  99. sage/manifolds/differentiable/tensorfield_module.py +963 -0
  100. sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
  101. sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
  102. sage/manifolds/differentiable/vector_bundle.py +1728 -0
  103. sage/manifolds/differentiable/vectorfield.py +1717 -0
  104. sage/manifolds/differentiable/vectorfield_module.py +2445 -0
  105. sage/manifolds/differentiable/vectorframe.py +1832 -0
  106. sage/manifolds/family.py +270 -0
  107. sage/manifolds/local_frame.py +1490 -0
  108. sage/manifolds/manifold.py +3090 -0
  109. sage/manifolds/manifold_homset.py +452 -0
  110. sage/manifolds/operators.py +359 -0
  111. sage/manifolds/point.py +994 -0
  112. sage/manifolds/scalarfield.py +3718 -0
  113. sage/manifolds/scalarfield_algebra.py +629 -0
  114. sage/manifolds/section.py +3111 -0
  115. sage/manifolds/section_module.py +831 -0
  116. sage/manifolds/structure.py +229 -0
  117. sage/manifolds/subset.py +2764 -0
  118. sage/manifolds/subsets/all.py +1 -0
  119. sage/manifolds/subsets/closure.py +131 -0
  120. sage/manifolds/subsets/pullback.py +885 -0
  121. sage/manifolds/topological_submanifold.py +891 -0
  122. sage/manifolds/trivialization.py +733 -0
  123. sage/manifolds/utilities.py +1348 -0
  124. sage/manifolds/vector_bundle.py +1342 -0
  125. sage/manifolds/vector_bundle_fiber.py +332 -0
  126. sage/manifolds/vector_bundle_fiber_element.py +111 -0
  127. sage/matrix/all__sagemath_symbolics.py +1 -0
  128. sage/matrix/matrix_symbolic_dense.cpython-314t-x86_64-linux-musl.so +0 -0
  129. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  130. sage/matrix/matrix_symbolic_dense.pyx +1022 -0
  131. sage/matrix/matrix_symbolic_sparse.cpython-314t-x86_64-linux-musl.so +0 -0
  132. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  133. sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
  134. sage/modules/all__sagemath_symbolics.py +1 -0
  135. sage/modules/vector_callable_symbolic_dense.py +105 -0
  136. sage/modules/vector_symbolic_dense.py +116 -0
  137. sage/modules/vector_symbolic_sparse.py +118 -0
  138. sage/rings/all__sagemath_symbolics.py +4 -0
  139. sage/rings/asymptotic/all.py +6 -0
  140. sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
  141. sage/rings/asymptotic/asymptotic_ring.py +4858 -0
  142. sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
  143. sage/rings/asymptotic/growth_group.py +5373 -0
  144. sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
  145. sage/rings/asymptotic/term_monoid.py +5237 -0
  146. sage/rings/function_field/all__sagemath_symbolics.py +2 -0
  147. sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
  148. sage/symbolic/all.py +15 -0
  149. sage/symbolic/assumptions.py +985 -0
  150. sage/symbolic/benchmark.py +93 -0
  151. sage/symbolic/callable.py +459 -0
  152. sage/symbolic/complexity_measures.py +35 -0
  153. sage/symbolic/constants.py +1287 -0
  154. sage/symbolic/expression_conversion_algebraic.py +310 -0
  155. sage/symbolic/expression_conversion_sympy.py +317 -0
  156. sage/symbolic/expression_conversions.py +1713 -0
  157. sage/symbolic/function_factory.py +355 -0
  158. sage/symbolic/integration/all.py +1 -0
  159. sage/symbolic/integration/external.py +270 -0
  160. sage/symbolic/integration/integral.py +1115 -0
  161. sage/symbolic/maxima_wrapper.py +162 -0
  162. sage/symbolic/operators.py +267 -0
  163. sage/symbolic/random_tests.py +462 -0
  164. sage/symbolic/relation.py +1907 -0
  165. sage/symbolic/ring.cpython-314t-x86_64-linux-musl.so +0 -0
  166. sage/symbolic/ring.pxd +5 -0
  167. sage/symbolic/ring.pyx +1396 -0
  168. sage/symbolic/subring.py +1025 -0
  169. sage/symbolic/symengine.py +19 -0
  170. sage/symbolic/tests.py +40 -0
  171. sage/symbolic/units.py +1470 -0
@@ -0,0 +1,985 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ """
3
+ Assumptions
4
+
5
+ The ``GenericDeclaration`` class provides assumptions about a symbol or
6
+ function in verbal form. Such assumptions can be made using the :func:`assume`
7
+ function in this module, which also can take any relation of symbolic
8
+ expressions as argument. Use :func:`forget` to clear all assumptions.
9
+ Creating a variable with a specific domain is equivalent with making an
10
+ assumption about it.
11
+
12
+ There is only rudimentary support for consistency and satisfiability checking
13
+ in Sage. Assumptions are used both in Maxima and Pynac to support or refine
14
+ some computations. In the following we show how to make and query assumptions.
15
+ Please see the respective modules for more practical examples.
16
+
17
+ In addition to the global :func:`assumptions` database, :func:`assuming`
18
+ creates reusable, stackable context managers allowing for temporary
19
+ updates of the database for evaluation of a (block of) statements.
20
+
21
+ EXAMPLES:
22
+
23
+ The default domain of a symbolic variable is the complex plane::
24
+
25
+ sage: var('x')
26
+ x
27
+ sage: x.is_real()
28
+ False
29
+ sage: assume(x,'real')
30
+ sage: x.is_real()
31
+ True
32
+ sage: forget()
33
+ sage: x.is_real()
34
+ False
35
+
36
+ Here is the list of acceptable features::
37
+
38
+ sage: ", ".join(map(str, maxima("features")._sage_()))
39
+ 'integer, noninteger, even, odd, rational, irrational, real, imaginary,
40
+ complex, analytic, increasing, decreasing, oddfun, evenfun, posfun,
41
+ constant, commutative, lassociative, rassociative, symmetric,
42
+ antisymmetric, integervalued'
43
+
44
+ Set positive domain using a relation::
45
+
46
+ sage: assume(x>0)
47
+ sage: x.is_positive()
48
+ True
49
+ sage: x.is_real()
50
+ True
51
+ sage: assumptions()
52
+ [x > 0]
53
+
54
+ Assumptions also affect operations that do not use Maxima::
55
+
56
+ sage: forget()
57
+ sage: assume(x, 'even')
58
+ sage: assume(x, 'real')
59
+ sage: (-1)^x
60
+ 1
61
+ sage: (-gamma(pi))^x
62
+ gamma(pi)^x
63
+ sage: binomial(2*x, x).is_integer()
64
+ True
65
+
66
+ Assumptions are added and in some cases checked for consistency::
67
+
68
+ sage: assume(x>0)
69
+ sage: assume(x<0)
70
+ Traceback (most recent call last):
71
+ ...
72
+ ValueError: Assumption is inconsistent
73
+ sage: forget()
74
+ """
75
+ from sage.rings.integer_ring import ZZ
76
+ from sage.rings.rational_field import QQ
77
+ from sage.rings.real_mpfr import RR
78
+ from sage.rings.cc import CC
79
+ from sage.structure.element import Expression
80
+ from sage.structure.unique_representation import UniqueRepresentation
81
+
82
+ # #30074: We use the keys of a dict to store the assumptions.
83
+ # As of Python 3.6.x, dicts preserve the insertion order.
84
+ # In this way, we keep the same order of the assumptions
85
+ # as previous code that was using lists.
86
+ _assumptions = dict()
87
+
88
+ _valid_feature_strings = set()
89
+
90
+
91
+ class GenericDeclaration(UniqueRepresentation):
92
+ """
93
+ This class represents generic assumptions, such as a variable being
94
+ an integer or a function being increasing. It passes such
95
+ information to Maxima's declare (wrapped in a context so it is able
96
+ to forget) and to Pynac.
97
+
98
+ INPUT:
99
+
100
+ - ``var`` -- the variable about which assumptions are being made
101
+
102
+ - ``assumption`` -- string containing a Maxima feature, either user
103
+ defined or in the list given by ``maxima('features')``
104
+
105
+ EXAMPLES::
106
+
107
+ sage: from sage.symbolic.assumptions import GenericDeclaration
108
+ sage: decl = GenericDeclaration(x, 'integer')
109
+ sage: decl.assume()
110
+ sage: sin(x*pi)
111
+ 0
112
+ sage: decl.forget()
113
+ sage: sin(x*pi)
114
+ sin(pi*x)
115
+ sage: sin(x*pi).simplify()
116
+ sin(pi*x)
117
+
118
+ Here is the list of acceptable features::
119
+
120
+ sage: ", ".join(map(str, maxima("features")._sage_()))
121
+ 'integer, noninteger, even, odd, rational, irrational, real, imaginary,
122
+ complex, analytic, increasing, decreasing, oddfun, evenfun, posfun,
123
+ constant, commutative, lassociative, rassociative, symmetric,
124
+ antisymmetric, integervalued'
125
+
126
+ Test unique representation behavior::
127
+
128
+ sage: GenericDeclaration(x, 'integer') is GenericDeclaration(SR.var("x"), 'integer')
129
+ True
130
+ """
131
+
132
+ def __init__(self, var, assumption):
133
+ """
134
+ This class represents generic assumptions, such as a variable being
135
+ an integer or a function being increasing. It passes such
136
+ information to maxima's declare (wrapped in a context so it is able
137
+ to forget).
138
+
139
+ INPUT:
140
+
141
+ - ``var`` -- the variable about which assumptions are being made
142
+
143
+ - ``assumption`` -- a Maxima feature, either user
144
+ defined or in the list given by ``maxima('features')``
145
+
146
+ EXAMPLES::
147
+
148
+ sage: from sage.symbolic.assumptions import GenericDeclaration
149
+ sage: decl = GenericDeclaration(x, 'integer')
150
+ sage: decl.assume()
151
+ sage: sin(x*pi)
152
+ 0
153
+ sage: decl.forget()
154
+ sage: sin(x*pi)
155
+ sin(pi*x)
156
+
157
+ Here is the list of acceptable features::
158
+
159
+ sage: ", ".join(map(str, maxima("features")._sage_()))
160
+ 'integer, noninteger, even, odd, rational, irrational, real,
161
+ imaginary, complex, analytic, increasing, decreasing, oddfun,
162
+ evenfun, posfun, constant, commutative, lassociative, rassociative,
163
+ symmetric, antisymmetric, integervalued'
164
+ """
165
+ self._var = var
166
+ self._assumption = assumption
167
+ self._context = None
168
+
169
+ def __repr__(self):
170
+ """
171
+ EXAMPLES::
172
+
173
+ sage: from sage.symbolic.assumptions import GenericDeclaration
174
+ sage: GenericDeclaration(x, 'foo')
175
+ x is foo
176
+ """
177
+ return "%s is %s" % (self._var, self._assumption)
178
+
179
+ def has(self, arg):
180
+ """
181
+ Check if this assumption contains the argument ``arg``.
182
+
183
+ EXAMPLES::
184
+
185
+ sage: from sage.symbolic.assumptions import GenericDeclaration as GDecl
186
+ sage: var('y')
187
+ y
188
+ sage: d = GDecl(x, 'integer')
189
+ sage: d.has(x)
190
+ True
191
+ sage: d.has(y)
192
+ False
193
+ """
194
+ return (arg - self._var).is_trivial_zero()
195
+
196
+ def _validate_feature(self):
197
+ """
198
+ Check if this assumption is a known maxima feature, raise an error otherwise.
199
+
200
+ EXAMPLES::
201
+
202
+ sage: from sage.symbolic.assumptions import GenericDeclaration as GDecl
203
+ sage: var('b')
204
+ b
205
+ sage: GDecl(b, 'bougie')
206
+ b is bougie
207
+ sage: _.assume()
208
+ Traceback (most recent call last):
209
+ ...
210
+ ValueError: bougie not a valid assumption, must be one of ['analytic', ... 'symmetric']
211
+ """
212
+ from sage.calculus.calculus import maxima
213
+ global _valid_feature_strings
214
+ if self._assumption in _valid_feature_strings:
215
+ return
216
+ # We get the list here because features may be added with time.
217
+ _valid_feature_strings.update(repr(x).strip() for x in list(maxima("features")))
218
+ if self._assumption in _valid_feature_strings:
219
+ return
220
+ raise ValueError("%s not a valid assumption, must be one of %s"
221
+ % (self._assumption, sorted(_valid_feature_strings)))
222
+
223
+ def assume(self):
224
+ """
225
+ Make this assumption.
226
+
227
+ TESTS::
228
+
229
+ sage: from sage.symbolic.assumptions import GenericDeclaration
230
+ sage: decl = GenericDeclaration(x, 'even')
231
+ sage: decl.assume()
232
+ sage: cos(x*pi).simplify()
233
+ 1
234
+ sage: decl2 = GenericDeclaration(x, 'odd')
235
+ sage: decl2.assume()
236
+ Traceback (most recent call last):
237
+ ...
238
+ ValueError: Assumption is inconsistent
239
+ sage: decl.forget()
240
+ """
241
+ if self in _assumptions:
242
+ return
243
+ from sage.calculus.calculus import maxima
244
+ cur = None
245
+ context = None
246
+ if self._context is None:
247
+ self._validate_feature()
248
+ cur = maxima.get("context")
249
+ # newcontext makes a fresh context that only has $global as
250
+ # a subcontext, and makes it the current $context,
251
+ # but does not deactivate other current contexts.
252
+ context = maxima.newcontext('context' + maxima._next_var_name())
253
+ must_declare = True
254
+ elif not maxima.featurep(self._var, self._assumption):
255
+ # Reactivating a previously active context.
256
+ # Run $declare again with the assumption
257
+ # to catch possible inconsistency
258
+ # with the active contexts.
259
+ cur = maxima.get("context")
260
+ # Redeclaring on the existing context does not seem to trigger
261
+ # inconsistency checking.
262
+ # maxima.set("context", self._context._maxima_init_())
263
+ # Instead, use a temporary context for this purpose
264
+ context = maxima.newcontext('context' + maxima._next_var_name())
265
+ must_declare = True
266
+ else:
267
+ must_declare = False
268
+
269
+ if must_declare:
270
+ try:
271
+ maxima.eval("declare(%s, %s)" % (self._var._maxima_init_(), self._assumption))
272
+ except RuntimeError as mess:
273
+ if 'inconsistent' in str(mess): # note Maxima doesn't tell you if declarations are redundant
274
+ # Inconsistency with one of the active contexts.
275
+ raise ValueError("Assumption is inconsistent")
276
+ else:
277
+ raise
278
+ else:
279
+ if self._context is None:
280
+ self._context = context
281
+ context = None
282
+ finally:
283
+ assert cur is not None
284
+ maxima.set("context", cur)
285
+ if context is not None:
286
+ maxima.killcontext(context)
287
+
288
+ maxima.activate(self._context)
289
+ self._var.decl_assume(self._assumption)
290
+ _assumptions[self] = True
291
+
292
+ def forget(self):
293
+ """
294
+ Forget this assumption.
295
+
296
+ TESTS::
297
+
298
+ sage: from sage.symbolic.assumptions import GenericDeclaration
299
+ sage: decl = GenericDeclaration(x, 'odd')
300
+ sage: decl.assume()
301
+ sage: cos(pi*x)
302
+ cos(pi*x)
303
+ sage: cos(pi*x).simplify()
304
+ -1
305
+ sage: decl.forget()
306
+ sage: cos(x*pi).simplify()
307
+ cos(pi*x)
308
+ """
309
+ self._var.decl_forget(self._assumption)
310
+ from sage.calculus.calculus import maxima
311
+ if self._context is not None:
312
+ try:
313
+ del _assumptions[self]
314
+ except KeyError:
315
+ return
316
+ maxima.deactivate(self._context)
317
+ else: # trying to forget a declaration explicitly rather than implicitly
318
+ for x in _assumptions:
319
+ if repr(self) == repr(x): # so by implication x is also a GenericDeclaration
320
+ x.forget()
321
+ break
322
+ return
323
+
324
+ def contradicts(self, soln):
325
+ """
326
+ Return ``True`` if this assumption is violated by the given
327
+ variable assignment(s).
328
+
329
+ INPUT:
330
+
331
+ - ``soln`` -- either a dictionary with variables as keys or a symbolic
332
+ relation with a variable on the left hand side
333
+
334
+ EXAMPLES::
335
+
336
+ sage: from sage.symbolic.assumptions import GenericDeclaration
337
+ sage: GenericDeclaration(x, 'integer').contradicts(x==4)
338
+ False
339
+ sage: GenericDeclaration(x, 'integer').contradicts(x==4.0)
340
+ False
341
+ sage: GenericDeclaration(x, 'integer').contradicts(x==4.5)
342
+ True
343
+ sage: GenericDeclaration(x, 'integer').contradicts(x==sqrt(17))
344
+ True
345
+ sage: GenericDeclaration(x, 'noninteger').contradicts(x==sqrt(17))
346
+ False
347
+ sage: GenericDeclaration(x, 'noninteger').contradicts(x==17)
348
+ True
349
+ sage: GenericDeclaration(x, 'even').contradicts(x==3)
350
+ True
351
+ sage: GenericDeclaration(x, 'complex').contradicts(x==3)
352
+ False
353
+ sage: GenericDeclaration(x, 'imaginary').contradicts(x==3)
354
+ True
355
+ sage: GenericDeclaration(x, 'imaginary').contradicts(x==I)
356
+ False
357
+
358
+ sage: var('y,z')
359
+ (y, z)
360
+ sage: GenericDeclaration(x, 'imaginary').contradicts(x==y+z)
361
+ False
362
+
363
+ sage: GenericDeclaration(x, 'rational').contradicts(y==pi)
364
+ False
365
+ sage: GenericDeclaration(x, 'rational').contradicts(x==pi)
366
+ True
367
+ sage: GenericDeclaration(x, 'irrational').contradicts(x!=pi)
368
+ False
369
+ sage: GenericDeclaration(x, 'rational').contradicts({x: pi, y: pi})
370
+ True
371
+ sage: GenericDeclaration(x, 'rational').contradicts({z: pi, y: pi})
372
+ False
373
+ """
374
+ if isinstance(soln, dict):
375
+ value = soln.get(self._var)
376
+ if value is None:
377
+ return False
378
+ elif soln.lhs() == self._var:
379
+ value = soln.rhs()
380
+ else:
381
+ return False
382
+ try:
383
+ CC(value)
384
+ except TypeError:
385
+ return False
386
+ if self._assumption == 'integer':
387
+ return value not in ZZ
388
+ elif self._assumption == 'noninteger':
389
+ return value in ZZ
390
+ elif self._assumption == 'even':
391
+ return value not in ZZ or bool(ZZ(value) % 2)
392
+ elif self._assumption == 'odd':
393
+ return value not in ZZ or not (ZZ(value) % 2)
394
+ elif self._assumption == 'rational':
395
+ return value not in QQ
396
+ elif self._assumption == 'irrational':
397
+ return value in QQ
398
+ elif self._assumption == 'real':
399
+ return value not in RR
400
+ elif self._assumption == 'imaginary':
401
+ return value not in CC or CC(value).real() != 0
402
+ elif self._assumption == 'complex':
403
+ return value not in CC
404
+
405
+
406
+ def preprocess_assumptions(args):
407
+ """
408
+ Turn a list of the form ``(var1, var2, ..., 'property')`` into a
409
+ sequence of declarations ``(var1 is property), (var2 is property),
410
+ ...``
411
+
412
+ EXAMPLES::
413
+
414
+ sage: from sage.symbolic.assumptions import preprocess_assumptions
415
+ sage: preprocess_assumptions([x, 'integer', x > 4])
416
+ [x is integer, x > 4]
417
+ sage: var('x, y')
418
+ (x, y)
419
+ sage: preprocess_assumptions([x, y, 'integer', x > 4, y, 'even'])
420
+ [x is integer, y is integer, x > 4, y is even]
421
+ """
422
+ args = list(args)
423
+ last = None
424
+ for i, x in reversed(list(enumerate(args))):
425
+ if isinstance(x, str):
426
+ del args[i]
427
+ last = x
428
+ elif ((not hasattr(x, 'assume')
429
+ or (isinstance(x, Expression) and x.is_symbol()))
430
+ and last is not None):
431
+ args[i] = GenericDeclaration(x, last)
432
+ else:
433
+ last = None
434
+ return args
435
+
436
+
437
+ def assume(*args):
438
+ r"""
439
+ Make the given assumptions.
440
+
441
+ INPUT:
442
+
443
+ - ``*args`` -- a variable-length sequence of assumptions, each
444
+ consisting of:
445
+
446
+ - any number of symbolic inequalities, like ``0 < x, x < 1``
447
+
448
+ - a subsequence of variable names, followed by some property that
449
+ should be assumed for those variables; for example, ``x, y, z,
450
+ 'integer'`` would assume that each of ``x``, ``y``, and ``z``
451
+ are integer variables, and ``x, 'odd'`` would assume that ``x``
452
+ is odd (as opposed to even).
453
+
454
+ The two types can be combined, but a symbolic inequality cannot
455
+ appear in the middle of a list of variables.
456
+
457
+ OUTPUT: if everything goes as planned, there is no output
458
+
459
+ If you assume something that is not one of the two forms above, then
460
+ an :exc:`AttributeError` is raised as we try to call its ``assume``
461
+ method.
462
+
463
+ If you make inconsistent assumptions (for example, that ``x`` is
464
+ both even and odd), then a :exc:`ValueError` is raised.
465
+
466
+ .. WARNING::
467
+
468
+ Do not use Python's chained comparison notation in assumptions.
469
+ Python literally translates the expression ``0 < x < 1`` to
470
+ ``(0 < x) and (x < 1)``, but the value of ``bool(0 < x)`` is
471
+ ``False`` when ``x`` is a symbolic variable. Therefore, by the
472
+ definition of Python's logical "and" operator, the entire expression
473
+ is equal to ``0 < x``.
474
+
475
+ EXAMPLES:
476
+
477
+ Assumptions are typically used to ensure certain relations are
478
+ evaluated as true that are not true in general.
479
+
480
+ Here, we verify that for `x>0`, `\sqrt{x^2}=x`::
481
+
482
+ sage: assume(x > 0)
483
+ sage: bool(sqrt(x^2) == x)
484
+ True
485
+
486
+ This will be assumed in the current Sage session until forgotten::
487
+
488
+ sage: bool(sqrt(x^2) == x)
489
+ True
490
+ sage: forget()
491
+ sage: bool(sqrt(x^2) == x)
492
+ False
493
+
494
+ Another major use case is in taking certain integrals and limits
495
+ where the answers may depend on some sign condition::
496
+
497
+ sage: var('x, n')
498
+ (x, n)
499
+ sage: assume(n+1>0)
500
+ sage: integral(x^n,x)
501
+ x^(n + 1)/(n + 1)
502
+ sage: forget()
503
+
504
+ ::
505
+
506
+ sage: var('q, a, k')
507
+ (q, a, k)
508
+ sage: assume(q > 1)
509
+ sage: sum(a*q^k, k, 0, oo)
510
+ Traceback (most recent call last):
511
+ ...
512
+ ValueError: Sum is divergent.
513
+ sage: forget()
514
+ sage: assume(abs(q) < 1)
515
+ sage: sum(a*q^k, k, 0, oo)
516
+ -a/(q - 1)
517
+ sage: forget()
518
+
519
+ An integer constraint::
520
+
521
+ sage: n,P,r,r2 = SR.var('n, P, r, r2')
522
+ sage: assume(n, 'integer')
523
+ sage: c = P*e^(r*n)
524
+ sage: d = P*(1+r2)^n
525
+ sage: solve(c==d,r2)
526
+ [r2 == e^r - 1]
527
+ sage: forget()
528
+
529
+ Simplifying certain well-known identities works as well::
530
+
531
+ sage: n = SR.var('n')
532
+ sage: assume(n, 'integer')
533
+ sage: sin(n*pi)
534
+ 0
535
+ sage: forget()
536
+ sage: sin(n*pi).simplify()
537
+ sin(pi*n)
538
+
539
+ Instead of using chained comparison notation, each relationship
540
+ should be passed as a separate assumption::
541
+
542
+ sage: x = SR.var('x')
543
+ sage: assume(0 < x, x < 1) # instead of assume(0 < x < 1)
544
+ sage: assumptions()
545
+ [0 < x, x < 1]
546
+ sage: forget()
547
+
548
+ If you make inconsistent or meaningless assumptions,
549
+ Sage will let you know::
550
+
551
+ sage: assume(x<0)
552
+ sage: assume(x>0)
553
+ Traceback (most recent call last):
554
+ ...
555
+ ValueError: Assumption is inconsistent
556
+ sage: assume(x<1)
557
+ Traceback (most recent call last):
558
+ ...
559
+ ValueError: Assumption is redundant
560
+ sage: assumptions()
561
+ [x < 0]
562
+ sage: forget()
563
+ sage: assume(x,'even')
564
+ sage: assume(x,'odd')
565
+ Traceback (most recent call last):
566
+ ...
567
+ ValueError: Assumption is inconsistent
568
+ sage: forget()
569
+
570
+ You can also use assumptions to evaluate simple
571
+ truth values::
572
+
573
+ sage: x, y, z = var('x, y, z')
574
+ sage: assume(x>=y,y>=z,z>=x)
575
+ sage: bool(x==z)
576
+ True
577
+ sage: bool(z<x)
578
+ False
579
+ sage: bool(z>y)
580
+ False
581
+ sage: bool(y==z)
582
+ True
583
+ sage: forget()
584
+ sage: assume(x>=1,x<=1)
585
+ sage: bool(x==1)
586
+ True
587
+ sage: bool(x>1)
588
+ False
589
+ sage: forget()
590
+
591
+ TESTS:
592
+
593
+ Test that you can do two non-relational
594
+ declarations at once (fixing :issue:`7084`)::
595
+
596
+ sage: var('m,n')
597
+ (m, n)
598
+ sage: assume(n, 'integer'); assume(m, 'integer')
599
+ sage: sin(n*pi).simplify()
600
+ 0
601
+ sage: sin(m*pi).simplify()
602
+ 0
603
+ sage: forget()
604
+ sage: sin(n*pi).simplify()
605
+ sin(pi*n)
606
+ sage: sin(m*pi).simplify()
607
+ sin(pi*m)
608
+
609
+ Check that positive integers can be created (:issue:`20132`)
610
+
611
+ sage: x = SR.var('x', domain='positive')
612
+ sage: assume(x, 'integer')
613
+ sage: x.is_positive() and x.is_integer()
614
+ True
615
+ sage: forget()
616
+
617
+ sage: x = SR.var('x', domain='integer')
618
+ sage: assume(x > 0)
619
+ sage: x.is_positive() and x.is_integer()
620
+ True
621
+ sage: forget()
622
+
623
+ sage: assume(x, "integer")
624
+ sage: assume(x > 0)
625
+ sage: x.is_positive() and x.is_integer()
626
+ True
627
+ sage: forget()
628
+
629
+ Ensure that an :exc:`AttributeError` is raised if we are given junk::
630
+
631
+ sage: assume(3)
632
+ Traceback (most recent call last):
633
+ ...
634
+ AttributeError: 'sage.rings.integer.Integer' object has no
635
+ attribute 'assume'...
636
+
637
+ Ensure that we can combine the two types of assumptions, as documented::
638
+
639
+ sage: x,y = SR.var('x,y')
640
+ sage: assume(x > 0, x, y, 'integer')
641
+ sage: assumptions()
642
+ [x > 0, x is integer, y is integer]
643
+ sage: forget()
644
+ sage: assume(x, y, 'integer', x > 0)
645
+ sage: assumptions()
646
+ [x is integer, y is integer, x > 0]
647
+ sage: forget()
648
+
649
+ Test that our WARNING block is accurate::
650
+
651
+ sage: x = SR.var('x')
652
+ sage: bool(0 < x)
653
+ False
654
+ sage: 0 < x < 1
655
+ 0 < x
656
+ sage: assume(0 < x < 1)
657
+ sage: assumptions()
658
+ [0 < x]
659
+ sage: forget()
660
+
661
+ Check that :issue:`28538` is fixed::
662
+
663
+ sage: x, y = SR.var('x, y')
664
+ sage: assume(x > 0)
665
+ sage: assume(y > 0)
666
+ sage: bool(y*(x - y) == 0)
667
+ False
668
+ """
669
+ for x in preprocess_assumptions(args):
670
+ if isinstance(x, (tuple, list)):
671
+ assume(*x)
672
+ else:
673
+ x.assume()
674
+
675
+
676
+ def forget(*args):
677
+ """
678
+ Forget the given assumption, or call with no arguments to forget
679
+ all assumptions.
680
+
681
+ Here an assumption is some sort of symbolic constraint.
682
+
683
+ INPUT:
684
+
685
+ - ``*args`` -- assumptions (default: forget all assumptions)
686
+
687
+ EXAMPLES:
688
+
689
+ We define and forget multiple assumptions::
690
+
691
+ sage: forget()
692
+ sage: var('x,y,z')
693
+ (x, y, z)
694
+ sage: assume(x>0, y>0, z == 1, y>0)
695
+ sage: sorted(assumptions(), key=lambda x:str(x))
696
+ [x > 0, y > 0, z == 1]
697
+ sage: forget(x>0, z==1)
698
+ sage: assumptions()
699
+ [y > 0]
700
+ sage: assume(y, 'even', z, 'complex')
701
+ sage: assumptions()
702
+ [y > 0, y is even, z is complex]
703
+ sage: cos(y*pi).simplify()
704
+ 1
705
+ sage: forget(y,'even')
706
+ sage: cos(y*pi).simplify()
707
+ cos(pi*y)
708
+ sage: assumptions()
709
+ [y > 0, z is complex]
710
+ sage: forget()
711
+ sage: assumptions()
712
+ []
713
+ """
714
+ if len(args) == 0:
715
+ _forget_all()
716
+ return
717
+ for x in preprocess_assumptions(args):
718
+ if isinstance(x, (tuple, list)):
719
+ forget(*x)
720
+ else:
721
+ try:
722
+ x.forget()
723
+ except KeyError:
724
+ raise TypeError("forget not defined for objects of type '%s'" % type(x))
725
+
726
+
727
+ def assumptions(*args):
728
+ """
729
+ List all current symbolic assumptions.
730
+
731
+ INPUT:
732
+
733
+ - ``args`` -- list of variables which can be empty
734
+
735
+ OUTPUT: list of assumptions on variables; if ``args`` is empty it returns all
736
+ assumptions
737
+
738
+ EXAMPLES::
739
+
740
+ sage: var('x, y, z, w')
741
+ (x, y, z, w)
742
+ sage: forget()
743
+ sage: assume(x^2+y^2 > 0)
744
+ sage: assumptions()
745
+ [x^2 + y^2 > 0]
746
+ sage: forget(x^2+y^2 > 0)
747
+ sage: assumptions()
748
+ []
749
+ sage: assume(x > y)
750
+ sage: assume(z > w)
751
+ sage: sorted(assumptions(), key=lambda x: str(x))
752
+ [x > y, z > w]
753
+ sage: forget()
754
+ sage: assumptions()
755
+ []
756
+
757
+ It is also possible to query for assumptions on a variable independently::
758
+
759
+ sage: x, y, z = var('x y z')
760
+ sage: assume(x, 'integer')
761
+ sage: assume(y > 0)
762
+ sage: assume(y**2 + z**2 == 1)
763
+ sage: assume(x < 0)
764
+ sage: assumptions()
765
+ [x is integer, y > 0, y^2 + z^2 == 1, x < 0]
766
+ sage: assumptions(x)
767
+ [x is integer, x < 0]
768
+ sage: assumptions(x, y)
769
+ [x is integer, x < 0, y > 0, y^2 + z^2 == 1]
770
+ sage: assumptions(z)
771
+ [y^2 + z^2 == 1]
772
+ """
773
+ if len(args) == 0:
774
+ return list(_assumptions)
775
+
776
+ result = []
777
+ if len(args) == 1:
778
+ result.extend([statement for statement in _assumptions
779
+ if statement.has(args[0])])
780
+ else:
781
+ for v in args:
782
+ result += [statement for statement in list(_assumptions)
783
+ if str(v) in str(statement)]
784
+ return result
785
+
786
+
787
+ def _forget_all():
788
+ """
789
+ Forget all symbolic assumptions.
790
+
791
+ This is called by ``forget()``.
792
+
793
+ EXAMPLES::
794
+
795
+ sage: forget()
796
+ sage: var('x,y')
797
+ (x, y)
798
+ sage: assume(x > 0, y < 0)
799
+ sage: bool(x*y < 0) # means definitely true
800
+ True
801
+ sage: bool(x*y > 0) # might not be true
802
+ False
803
+ sage: forget() # implicitly calls _forget_all
804
+ sage: bool(x*y < 0) # might not be true
805
+ False
806
+ sage: bool(x*y > 0) # might not be true
807
+ False
808
+
809
+ TESTS:
810
+
811
+ Check that :issue:`7315` is fixed::
812
+
813
+ sage: var('m,n')
814
+ (m, n)
815
+ sage: assume(n, 'integer'); assume(m, 'integer')
816
+ sage: sin(n*pi).simplify()
817
+ 0
818
+ sage: sin(m*pi).simplify()
819
+ 0
820
+ sage: forget()
821
+ sage: sin(n*pi).simplify()
822
+ sin(pi*n)
823
+ sage: sin(m*pi).simplify()
824
+ sin(pi*m)
825
+ """
826
+ global _assumptions
827
+ if not _assumptions:
828
+ return
829
+ for x in list(_assumptions):
830
+ # need to do this because x.forget() removes x from _assumptions
831
+ x.forget()
832
+ _assumptions = dict()
833
+
834
+
835
+ class assuming:
836
+ """
837
+ Temporarily modify assumptions.
838
+
839
+ Create a context manager in which temporary assumptions are added
840
+ (or substituted) to the current assumptions set.
841
+
842
+ The set of possible assumptions and declarations is the same as for
843
+ :func:`assume`.
844
+
845
+ This can be useful in interactive mode to discover the assumptions
846
+ necessary to a given integration, or the exact solution to a system of
847
+ equations.
848
+
849
+ It can also be used to explore the branches of a :func:`cases()` expression.
850
+
851
+ As with :func:`assume`, it is an error to add an assumption either redundant
852
+ or inconsistent with the current assumption set (unless ``replace=True`` is
853
+ used). See examples.
854
+
855
+ INPUT:
856
+
857
+ - ``*args`` -- assumptions (same format as for :func:`assume`)
858
+
859
+ - ``replace`` -- boolean (default: ``False``); specifies whether the new
860
+ assumptions are added to (default) or replace (if ``replace=True``) the
861
+ current assumption set
862
+
863
+ OUTPUT:
864
+
865
+ A context manager useable in a ``with`` statement (see examples).
866
+
867
+ EXAMPLES:
868
+
869
+ Basic functionality : inside a :func:`with assuming:` block, Sage uses the
870
+ updated assumptions database. After exit, the original database is
871
+ restored. ::
872
+
873
+ sage: var("x")
874
+ x
875
+ sage: forget(assumptions())
876
+ sage: solve(x^2 == 4,x)
877
+ [x == -2, x == 2]
878
+ sage: with assuming(x > 0):
879
+ ....: solve(x^2 == 4,x)
880
+ [x == 2]
881
+ sage: assumptions()
882
+ []
883
+
884
+ The local assumptions can be stacked. We can use this functionality to
885
+ discover incrementally the assumptions necessary to a given calculation
886
+ (and by the way, to check that Sage's default integrator
887
+ (Maxima's, that is), sometimes nitpicks for naught). ::
888
+
889
+ sage: var("y,k,theta")
890
+ (y, k, theta)
891
+ sage: dgamma(y,k,theta)=y^(k-1)*e^(-y/theta)/(theta^k*gamma(k))
892
+ sage: integrate(dgamma(y,k,theta),y,0,oo)
893
+ Traceback (most recent call last):
894
+ ...
895
+ ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before evaluation *may* help (example of legal syntax is 'assume(theta>0)', see `assume?` for more details)
896
+ Is theta positive or negative?
897
+ sage: a1=assuming(theta>0)
898
+ sage: with a1:integrate(dgamma(y,k,theta),y,0,oo)
899
+ Traceback (most recent call last):
900
+ ...
901
+ ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before evaluation *may* help (example of legal syntax is 'assume(k>0)', see `assume?` for more details)
902
+ Is k positive, negative or zero?
903
+ sage: a2=assuming(k>0)
904
+ sage: with a1,a2:integrate(dgamma(y,k,theta),y,0,oo)
905
+ Traceback (most recent call last):
906
+ ...
907
+ ValueError: Computation failed since Maxima requested additional constraints; using the 'assume' command before evaluation *may* help (example of legal syntax is 'assume(k>0)', see `assume?` for more details)
908
+ Is k an integer?
909
+ sage: a3=assuming(k,"noninteger")
910
+ sage: with a1,a2,a3:integrate(dgamma(y,k,theta),y,0,oo)
911
+ 1
912
+ sage: a4=assuming(k,"integer")
913
+ sage: with a1,a2,a4:integrate(dgamma(y,k,theta),y,0,oo)
914
+ 1
915
+
916
+ As mentioned above, it is an error to try to introduce redundant or
917
+ inconsistent assumptions. ::
918
+
919
+ sage: assume(x > 0)
920
+ sage: with assuming(x > -1): "I won't see this"
921
+ Traceback (most recent call last):
922
+ ...
923
+ ValueError: Assumption is redundant
924
+
925
+ sage: with assuming(x < -1): "I won't see this"
926
+ Traceback (most recent call last):
927
+ ...
928
+ ValueError: Assumption is inconsistent
929
+ """
930
+ def __init__(self, *args, **kwds):
931
+ r"""
932
+ EXAMPLES::
933
+
934
+ sage: forget()
935
+ sage: foo = assuming(x>0)
936
+ sage: foo.Ass
937
+ (x > 0,)
938
+ sage: bool(x>-1)
939
+ False
940
+ """
941
+ self.replace = kwds.pop("replace", False)
942
+ self.Ass = args
943
+
944
+ def __enter__(self):
945
+ r"""
946
+ EXAMPLES::
947
+
948
+ sage: forget()
949
+ sage: foo = assuming(x>0)
950
+ sage: bool(x>-1)
951
+ False
952
+ sage: foo.__enter__()
953
+ sage: bool(x>-1)
954
+ True
955
+ sage: foo.__exit__()
956
+ sage: bool(x>-1)
957
+ False
958
+ """
959
+ if self.replace:
960
+ self.OldAss = assumptions()
961
+ forget(assumptions())
962
+ assume(self.Ass)
963
+
964
+ def __exit__(self, *args, **kwds):
965
+ r"""
966
+ EXAMPLES::
967
+
968
+ sage: forget()
969
+ sage: foo = assuming(x>0)
970
+ sage: bool(x>-1)
971
+ False
972
+ sage: foo.__enter__()
973
+ sage: bool(x>-1)
974
+ True
975
+ sage: foo.__exit__()
976
+ sage: bool(x>-1)
977
+ False
978
+ sage: forget()
979
+ """
980
+ if self.replace:
981
+ forget(assumptions())
982
+ assume(self.OldAss)
983
+ else:
984
+ if len(self.Ass) > 0:
985
+ forget(self.Ass)