Skip to content

Commit 4f7c670

Browse files
committed
Fix Times Infinity and I^q
1 parent 45e7dac commit 4f7c670

4 files changed

Lines changed: 57 additions & 10 deletions

File tree

mathics/builtin/arithmetic.py

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
SymbolFalse,
3535
SymbolNull,
3636
SymbolTrue,
37+
SymbolList,
38+
SymbolInfinity,
39+
SymbolDirectedInfinity,
40+
SymbolComplexInfinity,
3741
from_python,
3842
from_mpmath,
3943
)
@@ -642,10 +646,10 @@ def format_outputform(self, items, evaluation):
642646

643647
def apply(self, items, evaluation):
644648
"Times[items___]"
645-
646649
items = items.numerify(evaluation).get_sequence()
647650
leaves = []
648651
numbers = []
652+
infinity_factor = False
649653

650654
prec = min_prec(*items)
651655
is_machine_precision = any(item.is_machine_precision() for item in items)
@@ -681,6 +685,17 @@ def apply(self, items, evaluation):
681685
leaves[-1] = Expression(
682686
"Power", item, Expression("Plus", Integer(1), leaves[-1].leaves[1])
683687
)
688+
elif item.get_head().same(SymbolDirectedInfinity):
689+
infinity_factor = True
690+
direction = item.leaves[0]
691+
if isinstance(direction, Number):
692+
numbers.append(direction)
693+
else:
694+
leaves.append(direction)
695+
item.leaves[0]
696+
elif (item.same(SymbolInfinity) or item.same(SymbolComplexInfinity)):
697+
infinity_factor = True
698+
item.leaves[0]
684699
else:
685700
leaves.append(item)
686701

@@ -704,6 +719,8 @@ def apply(self, items, evaluation):
704719
if number.same(Integer(1)):
705720
number = None
706721
elif number.is_zero:
722+
if infinity_factor:
723+
return Symbol('Indeterminate')
707724
return number
708725
elif number.same(Integer(-1)) and leaves and leaves[0].has_form("Plus", None):
709726
leaves[0] = Expression(
@@ -716,14 +733,23 @@ def apply(self, items, evaluation):
716733
leaf.clear_cache()
717734

718735
if number is not None:
736+
if infinity_factor:
737+
number = Expression(SymbolDirectedInfinity,number/Expression("Abs",number))
719738
leaves.insert(0, number)
720739

721740
if not leaves:
741+
if infinity_factor:
742+
return SymbolInfinity
722743
return Integer(1)
744+
723745
elif len(leaves) == 1:
724-
return leaves[0]
746+
ret = leaves[0]
725747
else:
726-
return Expression("Times", *leaves)
748+
ret = Expression("Times", *leaves)
749+
if infinity_factor:
750+
return Expression(SymbolDirectedInfinity, ret)
751+
else:
752+
return ret
727753

728754

729755
class Divide(BinaryOperator):
@@ -890,6 +916,7 @@ class Power(BinaryOperator, _MPMathFunction):
890916
}
891917

892918
formats = {
919+
893920
Expression(
894921
"Power",
895922
Expression("Pattern", Symbol("x"), Expression("Blank")),
@@ -905,6 +932,9 @@ class Power(BinaryOperator, _MPMathFunction):
905932
("", "x_ ^ y_?Negative"): (
906933
"HoldForm[Divide[1, #]]&[If[y==-1, HoldForm[x], HoldForm[x]^-y]]"
907934
),
935+
("", "x_?Negative ^ y_"): (
936+
'Infix[{HoldForm[(x)], HoldForm[y]},"^", 590, Right]'
937+
),
908938
}
909939

910940
rules = {
@@ -931,6 +961,10 @@ def apply_check(self, x, y, evaluation):
931961
elif py_y < 0:
932962
evaluation.message("Power", "infy", Expression("Power", x, y_err))
933963
return Symbol("ComplexInfinity")
964+
if isinstance(x, Complex) and x.real.is_zero:
965+
yhalf = Expression("Times", y, Rational(1, 2))
966+
factor = self.apply(Expression("Sequence", x.imag, y), evaluation)
967+
return Expression("Times", factor , Expression("Power", Integer(-1), yhalf))
934968

935969
result = self.apply(Expression("Sequence", x, y), evaluation)
936970
if result is None or result != SymbolNull:
@@ -1063,8 +1097,9 @@ class DirectedInfinity(SympyFunction):
10631097
"DirectedInfinity[a_] * DirectedInfinity[b_]": "DirectedInfinity[a*b]",
10641098
"DirectedInfinity[] * DirectedInfinity[args___]": "DirectedInfinity[]",
10651099
"DirectedInfinity[0]": "DirectedInfinity[]",
1066-
"z_?NumberQ * DirectedInfinity[]": "DirectedInfinity[]",
1067-
"z_?NumberQ * DirectedInfinity[a_]": "DirectedInfinity[z * a]",
1100+
# Rules already implemented in Times.apply
1101+
# "z_?NumberQ * DirectedInfinity[]": "DirectedInfinity[]",
1102+
# "z_?NumberQ * DirectedInfinity[a_]": "DirectedInfinity[z * a]",
10681103
"DirectedInfinity[a_] + DirectedInfinity[b_] /; b == -a": (
10691104
"Message[Infinity::indet,"
10701105
" Unevaluated[DirectedInfinity[a] + DirectedInfinity[b]]];"
@@ -1269,12 +1304,19 @@ class Sign(SympyFunction):
12691304
def apply(self, x, evaluation):
12701305
"%(name)s[x_]"
12711306
# Sympy and mpmath do not give the desired form of complex number
1307+
print(x)
12721308
if isinstance(x, Complex):
12731309
return Expression("Times", x, Expression("Power", Expression("Abs", x), -1))
12741310

12751311
sympy_x = x.to_sympy()
12761312
if sympy_x is None:
1277-
return None
1313+
print(x, " does not have a sympy form")
1314+
if x.is_zero():
1315+
return Real(0)
1316+
return Expression("Times", x,
1317+
Expression("Power",
1318+
Expression("Abs", x), -1)).evaluate(evaluation)
1319+
print(sympy_x)
12781320
return super().apply(x)
12791321

12801322
def apply_error(self, x, seqs, evaluation):

mathics/builtin/base.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
PrecisionReal,
2424
String,
2525
Symbol,
26+
SymbolTrue,
27+
SymbolFalse,
2628
ensure_context,
2729
strip_context,
2830
)
@@ -526,9 +528,9 @@ def apply(self, expr, evaluation) -> Symbol:
526528
"%(name)s[expr_]"
527529

528530
if self.test(expr):
529-
return Symbol("True")
531+
return SymbolTrue
530532
else:
531-
return Symbol("False")
533+
return SymbolFalse
532534

533535

534536
class SympyFunction(SympyObject):

mathics/builtin/comparison.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,12 +275,12 @@ def apply(self, items, evaluation):
275275
if n <= 1:
276276
return SymbolTrue
277277
is_exact_vals = [Expression("ExactNumberQ", arg).evaluate(evaluation) for arg in items_sequence]
278-
if all(val == SymbolTrue for val in is_exact_vals):
278+
if all(test is SymbolTrue for test in is_exact_vals):
279279
return self.apply_other(items, evaluation)
280280
args = self.numerify_args(items, evaluation)
281281
wanted = operators[self.get_name()]
282282
pairs = zip(args[:-1],args[1:])
283-
print("apply:", args)
283+
print("Compare.apply:", args)
284284
for x, y in pairs:
285285
if isinstance(x, String) or isinstance(y, String):
286286
if not (isinstance(x, String) and isinstance(y, String)):

mathics/core/expression.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,9 @@ def __getnewargs__(self):
20142014
SymbolTrue = Symbol("True")
20152015
SymbolAborted = Symbol("$Aborted")
20162016
SymbolInfinity = Symbol("Infinity")
2017+
SymbolComplexInfinity = Symbol("ComplexInfinity")
2018+
SymbolDirectedInfinity = Symbol("DirectedInfinity")
2019+
SymbolList = Symbol("List")
20172020

20182021
@lru_cache(maxsize=1024)
20192022
def from_mpmath(value, prec=None):

0 commit comments

Comments
 (0)