33Algebraic Manipulation
44"""
55
6+
67from mathics .version import __version__ # noqa used in loading to check consistency.
78
89from mathics .builtin .base import Builtin
1516 Number ,
1617 Symbol ,
1718 SymbolFalse ,
19+ SymbolList ,
1820 SymbolNull ,
1921 SymbolTrue ,
2022)
2123from 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
2327import 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+
324385class 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