Skip to content

Commit 417f478

Browse files
mmaterarocky
authored andcommitted
basic implementation of ConditionalExpression, Assuming and
Integrate uses now ConditionalExpression Remove an unused import Misc Arg tweaks: * Arg[0] needs to be defined 0 (otherwise it can be indeterminate) * More complete doc for Arg * Add Method option improving the behaviour of Piecewise returns in Integrate misc
1 parent 91db1fb commit 417f478

9 files changed

Lines changed: 352 additions & 81 deletions

File tree

CHANGES.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ New builtins
1010

1111
* ``Arg``
1212
* ``Dispatch``
13+
* ``FullSimplify``
1314
* ``LetterNumber`` #1298. The ``alphabet`` parameter supports only a minimal number of languages.
1415
* ``Nand`` and ``Nor`` logical functions.
1516
* ``Series``, ``O`` and ``SeriesData``
@@ -21,19 +22,23 @@ New builtins
2122
Enhancements
2223
++++++++++++
2324

25+
* a function `evaluate_predicate` allows for a basic predicate evaluation using `$Assumptions`.
2426
* ``Attributes`` accepts a string parameter.
2527
* ``ColorNegate`` for colors is supported.
2628
* ``D`` and ``Derivative`` improvements.
2729
* ``FileNames`` returns a sorted list (#1250).
2830
* ``FindRoot`` now receives several optional parameters like ``Method`` and ``MaxIterations``.
29-
* ``FixedPoint`` now supports the ``SameTest`` option.
31+
* ``FixedPoint`` now supports the ``SameTest`` option.
3032
* ``Prime`` and ``PrimePi`` now accept a list parameter and have the ``NumericFunction`` attribute.
3133
* ``ReplaceRepeated`` and ``FixedPoint`` now supports the ``MaxIteration`` option (#1260).
34+
* ``Simplify`` performs a more sophisticated set of simplifications.
35+
* ``Simplify`` accepts a second parameter that temporarily overwrites ``$Assumptions``.
3236
* ``StringTake`` now accepts form containing a list of strings and specification (#1297).
3337
* ``Table`` [*expr*, *n*] is supported.
3438
* ``ToString`` accepts an optional *form* parameter.
3539
* ``ToExpression`` handles multi-line string input
3640
* The implementation of Streams was redone.
41+
3742

3843

3944
Bug fixes

mathics/builtin/algebra.py

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Algebraic Manipulation
44
"""
55

6+
67
from mathics.version import __version__ # noqa used in loading to check consistency.
78

89
from mathics.builtin.base import Builtin
@@ -15,10 +16,13 @@
1516
Number,
1617
Symbol,
1718
SymbolFalse,
19+
SymbolList,
1820
SymbolNull,
1921
SymbolTrue,
2022
)
2123
from mathics.core.convert import from_sympy, sympy_symbol_prefix
24+
from mathics.builtin.scoping import dynamic_scoping
25+
from mathics.builtin.inference import evaluate_predicate
2226

2327
import sympy
2428

@@ -288,6 +292,8 @@ class Simplify(Builtin):
288292
<dl>
289293
<dt>'Simplify[$expr$]'
290294
<dd>simplifies $expr$.
295+
<dt>'Simplify[$expr$, $assump$]'
296+
<dd>simplifies $expr$ assuming $assump$ instead of $Assumptions$.
291297
</dl>
292298
293299
>> Simplify[2*Sin[x]^2 + 2*Cos[x]^2]
@@ -297,6 +303,16 @@ class Simplify(Builtin):
297303
>> Simplify[f[x]]
298304
= f[x]
299305
306+
Simplify over conditional expressions uses $Assumptions, or $assump$
307+
to evaluate the condition:
308+
# TODO: enable this once the logic for conditional expression
309+
# be restaured.
310+
# >> $Assumptions={a <= 0};
311+
# >> Simplify[ConditionalExpression[1, a > 0]]
312+
# = Undefined
313+
# >> Simplify[ConditionalExpression[1, a > 0], { a > 0 }]
314+
# = 1
315+
300316
#> Simplify[a*x^2+b*x^2]
301317
= x ^ 2 (a + b)
302318
@@ -308,11 +324,31 @@ class Simplify(Builtin):
308324
rules = {
309325
"Simplify[list_List]": "Simplify /@ list",
310326
"Simplify[rule_Rule]": "Simplify /@ rule",
311-
"Simplify[eq_Equal]": "Simplify /@ eq",
327+
"Simplify[list_List, assum_]": "Simplify[#1, assum]& /@ list",
328+
"Simplify[rule_Rule, assum_]": "Simplify[#1, assum]& /@ rule",
329+
"Simplify[0^a_, assum_]": "ConditionalExpression[0,Simplify[a>0]]",
330+
"Simplify[b_^a_, assum_]": "ConditionalExpression[b,Simplify[{Or[a>0, b!=0]}]]",
312331
}
313332

333+
def apply_assuming(self, expr, assumptions, evaluation):
334+
"%(name)s[expr_, assumptions_]"
335+
assumptions = assumptions.evaluate(evaluation)
336+
return dynamic_scoping(
337+
lambda ev: self.apply(expr, ev),
338+
{"System`$Assumptions": assumptions},
339+
evaluation,
340+
)
341+
314342
def apply(self, expr, evaluation):
315-
"Simplify[expr_]"
343+
"%(name)s[expr_]"
344+
# Check first if we are dealing with a logic expression...
345+
expr = evaluate_predicate(expr, evaluation)
346+
if expr.is_atom():
347+
return expr
348+
# else, use sympy:
349+
leaves = [self.apply(leaf, evaluation) for leaf in expr._leaves]
350+
head = self.apply(expr.get_head(), evaluation)
351+
expr = Expression(head, *leaves)
316352

317353
sympy_expr = expr.to_sympy()
318354
if sympy_expr is None:
@@ -321,6 +357,31 @@ def apply(self, expr, evaluation):
321357
return from_sympy(sympy_result)
322358

323359

360+
class FullSimplify(Simplify):
361+
"""
362+
<dl>
363+
<dt>'FullSimplify[$expr$]'
364+
<dd>simplifies $expr$ using an extended set of simplification rules.
365+
<dt>'FullSimplify[$expr$, $assump$]'
366+
<dd>simplifies $expr$ assuming $assump$ instead of $Assumptions$.
367+
</dl>
368+
TODO: implement the extension. By now, this does the same than Simplify...
369+
370+
>> FullSimplify[2*Sin[x]^2 + 2*Cos[x]^2]
371+
= 2
372+
373+
"""
374+
375+
rules = {
376+
"FullSimplify[list_List]": "FullSimplify /@ list",
377+
"FullSimplify[rule_Rule]": "FullSimplify /@ rule",
378+
"FullSimplify[eq_Equal]": "FullSimplify /@ eq",
379+
"FullSimplify[list_List, assum_]": "FullSimplify[#1, assum]& /@ list",
380+
"FullSimplify[rule_Rule, assum_]": "FullSimplify[#1, assum]& /@ rule",
381+
"FullSimplify[eq_Equal, assum_]": "FullSimplify[#1, assum]& /@ eq",
382+
}
383+
384+
324385
class Together(Builtin):
325386
"""
326387
<dl>
@@ -1264,7 +1325,7 @@ def apply(self, expr, form, evaluation):
12641325
if expr == Integer0:
12651326
return Expression("List")
12661327
elif e_null and f_null:
1267-
return Expression("List", Integer0)
1328+
return Expression(SymbolList, Integer0)
12681329
elif e_null and not f_null:
12691330
return Expression("List", SymbolNull)
12701331
elif f_null:

0 commit comments

Comments
 (0)