diff --git a/mathics/builtin/arithmetic.py b/mathics/builtin/arithmetic.py
index c4719381a7..e481b487dc 100644
--- a/mathics/builtin/arithmetic.py
+++ b/mathics/builtin/arithmetic.py
@@ -260,7 +260,7 @@ def negate(item):
if item.has_form("Times", 1, None):
if isinstance(item.leaves[0], Number):
neg = -item.leaves[0]
- if neg.same(Integer(1)):
+ if neg.sameQ(Integer(1)):
if len(item.leaves) == 1:
return neg
else:
@@ -375,7 +375,7 @@ def append_last():
else:
number = Integer(0)
- if not number.same(Integer(0)):
+ if not number.sameQ(Integer(0)):
leaves.insert(0, number)
if not leaves:
@@ -583,7 +583,7 @@ def inverse(item):
item.leaves[1], (Integer, Rational, Real)
):
neg = -item.leaves[1]
- if neg.same(Integer(1)):
+ if neg.sameQ(Integer(1)):
return item.leaves[0]
else:
return Expression("Power", item.leaves[0], neg)
@@ -603,7 +603,7 @@ def inverse(item):
negative.append(inverse(item))
elif isinstance(item, Rational):
numerator = item.numerator()
- if not numerator.same(Integer(1)):
+ if not numerator.sameQ(Integer(1)):
positive.append(numerator)
negative.append(item.denominator())
else:
@@ -667,7 +667,7 @@ def apply(self, items, evaluation):
leaves
and item.has_form("Power", 2)
and leaves[-1].has_form("Power", 2)
- and item.leaves[0].same(leaves[-1].leaves[0])
+ and item.leaves[0].sameQ(leaves[-1].leaves[0])
):
leaves[-1] = Expression(
"Power",
@@ -675,7 +675,7 @@ def apply(self, items, evaluation):
Expression("Plus", item.leaves[1], leaves[-1].leaves[1]),
)
elif (
- leaves and item.has_form("Power", 2) and item.leaves[0].same(leaves[-1])
+ leaves and item.has_form("Power", 2) and item.leaves[0].sameQ(leaves[-1])
):
leaves[-1] = Expression(
"Power", leaves[-1], Expression("Plus", item.leaves[1], Integer(1))
@@ -683,12 +683,12 @@ def apply(self, items, evaluation):
elif (
leaves
and leaves[-1].has_form("Power", 2)
- and leaves[-1].leaves[0].same(item)
+ and leaves[-1].leaves[0].sameQ(item)
):
leaves[-1] = Expression(
"Power", item, Expression("Plus", Integer(1), leaves[-1].leaves[1])
)
- elif item.get_head().same(SymbolDirectedInfinity):
+ elif item.get_head().sameQ(SymbolDirectedInfinity):
infinity_factor = True
if len(item.leaves) > 1:
direction = item.leaves[0]
@@ -696,7 +696,7 @@ def apply(self, items, evaluation):
numbers.append(direction)
else:
leaves.append(direction)
- elif item.same(SymbolInfinity) or item.same(SymbolComplexInfinity):
+ elif item.sameQ(SymbolInfinity) or item.sameQ(SymbolComplexInfinity):
infinity_factor = True
else:
leaves.append(item)
@@ -718,13 +718,13 @@ def apply(self, items, evaluation):
else:
number = Integer(1)
- if number.same(Integer(1)):
+ if number.sameQ(Integer(1)):
number = None
elif number.is_zero:
if infinity_factor:
return Symbol("Indeterminate")
return number
- elif number.same(Integer(-1)) and leaves and leaves[0].has_form("Plus", None):
+ elif number.sameQ(Integer(-1)) and leaves and leaves[0].has_form("Plus", None):
leaves[0] = Expression(
leaves[0].get_head(),
*[Expression("Times", Integer(-1), leaf) for leaf in leaves[0].leaves]
diff --git a/mathics/builtin/base.py b/mathics/builtin/base.py
index 00c64d3f0b..c74064ecdf 100644
--- a/mathics/builtin/base.py
+++ b/mathics/builtin/base.py
@@ -625,8 +625,9 @@ def get_lookup_name(self):
def get_string_value(self):
return "-@" + self.get_head_name() + "@-"
- def same(self, expr):
- return expr.same(self)
+ def sameQ(self, expr) -> bool:
+ """Mathics SameQ"""
+ return expr.sameQ(self)
def is_atom(self):
return False
diff --git a/mathics/builtin/calculus.py b/mathics/builtin/calculus.py
index a3c61c0e6a..fe2e9c90bd 100644
--- a/mathics/builtin/calculus.py
+++ b/mathics/builtin/calculus.py
@@ -163,7 +163,7 @@ def apply(self, f, x, evaluation):
elif not f.is_atom() and len(f.leaves) > 1:
def summand(leaf, index):
- if leaf.same(x):
+ if leaf.sameQ(x):
result = Expression(
Expression(
Expression(
diff --git a/mathics/builtin/comparison.py b/mathics/builtin/comparison.py
index cf018855cc..e39006c9fa 100644
--- a/mathics/builtin/comparison.py
+++ b/mathics/builtin/comparison.py
@@ -4,7 +4,7 @@
from mathics.version import __version__ # noqa used in loading to check consistency.
import itertools
-from typing import Optional, Union
+from typing import Optional, Union, Any
import sympy
@@ -63,7 +63,7 @@ class SameQ(BinaryOperator):
def apply(self, lhs, rhs, evaluation):
"lhs_ === rhs_"
- if lhs.same(rhs):
+ if lhs.sameQ(rhs):
return SymbolTrue
else:
return SymbolFalse
@@ -89,7 +89,7 @@ class UnsameQ(BinaryOperator):
def apply(self, lhs, rhs, evaluation):
"lhs_ =!= rhs_"
- if lhs.same(rhs):
+ if lhs.sameQ(rhs):
return SymbolFalse
else:
return SymbolTrue
@@ -170,7 +170,7 @@ class ValueQ(Builtin):
def apply(self, expr, evaluation):
"ValueQ[expr_]"
evaluated_expr = expr.evaluate(evaluation)
- if expr.same(evaluated_expr):
+ if expr.sameQ(evaluated_expr):
return SymbolFalse
return SymbolTrue
@@ -222,8 +222,11 @@ def numerify_args(items, evaluation):
class _EqualityOperator(_InequalityOperator):
"Compares all pairs e.g. a == b == c compares a == b, b == c, and a == c."
- def do_compare(self, l1, l2) -> Union[bool, None]:
- if l1.same(l2):
+ def equal2(self, l1: Any, l2: Any) -> Union[bool, None]:
+ """
+ Two-argument Equal[]
+ """
+ if l1.sameQ(l2):
return True
elif l1 == SymbolTrue and l2 == SymbolFalse:
return False
@@ -235,7 +238,7 @@ def do_compare(self, l1, l2) -> Union[bool, None]:
if len(l1.leaves) != len(l2.leaves):
return False
for item1, item2 in zip(l1.leaves, l2.leaves):
- result = self.do_compare(item1, item2)
+ result = self.equal2(item1, item2)
if not result:
return result
return True
@@ -305,7 +308,7 @@ def apply_other(self, args, evaluation):
"%(name)s[args___?(!ExactNumberQ[#]&)]"
args = args.get_sequence()
for x, y in itertools.combinations(args, 2):
- c = self.do_compare(x, y)
+ c = self.equal2(x, y)
if c is None:
return
if self._op(c) is False:
diff --git a/mathics/builtin/compilation.py b/mathics/builtin/compilation.py
index eb5113ba79..a797350c0b 100644
--- a/mathics/builtin/compilation.py
+++ b/mathics/builtin/compilation.py
@@ -184,7 +184,8 @@ def get_sort_key(self, pattern_sort=False):
else:
return hash(self)
- def same(self, other):
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
return self is other
def to_python(self, *args, **kwargs):
@@ -248,9 +249,9 @@ def apply(self, argnames, expr, code, args, evaluation):
for arg in argseq:
if isinstance(arg, Integer):
py_args.append(arg.get_int_value())
- elif arg.same(Symbol("True")):
+ elif arg.sameQ(Symbol("True")):
py_args.append(True)
- elif arg.same(Symbol("False")):
+ elif arg.sameQ(Symbol("False")):
py_args.append(False)
else:
py_args.append(arg.round_to_float(evaluation))
diff --git a/mathics/builtin/compile/ir.py b/mathics/builtin/compile/ir.py
index babc1e76f2..2caf8075fb 100644
--- a/mathics/builtin/compile/ir.py
+++ b/mathics/builtin/compile/ir.py
@@ -339,7 +339,7 @@ def _gen_Power(self, expr):
return exponent
# E ^ exponent
- if leaves[0].same(Symbol('E')) and exponent.type == real_type:
+ if leaves[0].sameQ(Symbol('E')) and exponent.type == real_type:
return self.call_fp_intr('llvm.exp', [exponent])
# 2 ^ exponent
diff --git a/mathics/builtin/image.py b/mathics/builtin/image.py
index 11fd49ef7c..a148c076c5 100644
--- a/mathics/builtin/image.py
+++ b/mathics/builtin/image.py
@@ -2256,7 +2256,8 @@ def get_sort_key(self, pattern_sort=False):
else:
return hash(self)
- def same(self, other):
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
if not isinstance(other, Image):
return False
if self.color_space != other.color_space or self.metadata != other.metadata:
diff --git a/mathics/builtin/inout.py b/mathics/builtin/inout.py
index aa5cbcc7d9..a863db32ff 100644
--- a/mathics/builtin/inout.py
+++ b/mathics/builtin/inout.py
@@ -764,7 +764,7 @@ def apply_makeboxes(self, items, sep, f, evaluation):
else:
result = []
for index, item in enumerate(items):
- if index > 0 and not sep.same(String("")):
+ if index > 0 and not sep.sameQ(String("")):
result.append(sep)
result.append(MakeBoxes(item, f))
return RowBox(Expression(SymbolList, *result))
@@ -2294,20 +2294,20 @@ def check_options(self, options, evaluation):
def check_DigitBlock(self, value, evaluation):
py_value = value.get_int_value()
- if value.same(Symbol("Infinity")):
+ if value.sameQ(Symbol("Infinity")):
return [0, 0]
elif py_value is not None and py_value > 0:
return [py_value, py_value]
elif value.has_form("List", 2):
nleft, nright = value.leaves
py_left, py_right = nleft.get_int_value(), nright.get_int_value()
- if nleft.same(Symbol("Infinity")):
+ if nleft.sameQ(Symbol("Infinity")):
nleft = 0
elif py_left is not None and py_left > 0:
nleft = py_left
else:
nleft = None
- if nright.same(Symbol("Infinity")):
+ if nright.sameQ(Symbol("Infinity")):
nright = 0
elif py_right is not None and py_right > 0:
nright = py_right
@@ -2319,7 +2319,7 @@ def check_DigitBlock(self, value, evaluation):
return evaluation.message(self.get_name(), "dblk", value)
def check_ExponentFunction(self, value, evaluation):
- if value.same(Symbol("Automatic")):
+ if value.sameQ(Symbol("Automatic")):
return self.default_ExponentFunction
def exp_function(x):
@@ -2328,7 +2328,7 @@ def exp_function(x):
return exp_function
def check_NumberFormat(self, value, evaluation):
- if value.same(Symbol("Automatic")):
+ if value.sameQ(Symbol("Automatic")):
return self.default_NumberFormat
def num_function(man, base, exp, options):
@@ -2355,9 +2355,9 @@ def check_ExponentStep(self, value, evaluation):
return result
def check_SignPadding(self, value, evaluation):
- if value.same(Symbol("True")):
+ if value.sameQ(Symbol("True")):
return True
- elif value.same(Symbol("False")):
+ elif value.sameQ(Symbol("False")):
return False
return evaluation.message(self.get_name(), "opttf", value)
diff --git a/mathics/builtin/linalg.py b/mathics/builtin/linalg.py
index 3644c46d1f..d4be70eedd 100644
--- a/mathics/builtin/linalg.py
+++ b/mathics/builtin/linalg.py
@@ -1083,7 +1083,7 @@ def _norm_calc(head, u, v, evaluation):
expr_eval = expr.evaluate(evaluation)
finally:
evaluation.quiet_all = old_quiet_all
- if expr_eval.same(expr):
+ if expr_eval.sameQ(expr):
evaluation.message("Norm", "nvm")
return None
else:
diff --git a/mathics/builtin/lists.py b/mathics/builtin/lists.py
index d1ae9405da..e67b270ec3 100644
--- a/mathics/builtin/lists.py
+++ b/mathics/builtin/lists.py
@@ -2452,7 +2452,7 @@ def apply_iter(self, expr, i, imin, imax, di, evaluation):
result = from_sympy(result)
result = cancel(result)
- if not result.same(whole_expr):
+ if not result.sameQ(whole_expr):
return result
return
@@ -3122,7 +3122,7 @@ def listener(e, tag):
for pattern, items in sown:
if pattern.does_match(tag, evaluation):
for item in items:
- if item[0].same(tag):
+ if item[0].sameQ(tag):
item[1].append(e)
break
else:
@@ -3306,7 +3306,8 @@ def __init__(self, test, evaluation, name):
def select(self, elem):
return self._groups
- def same(self, a, b):
+ def sameQ(self, a, b) -> bool:
+ """Mathics SameQ"""
return _test_pair(self._test, a, b, self._evaluation, self._name)
@@ -3334,8 +3335,9 @@ def __init__(self):
def select(self, elem):
return self._hashes[hash(elem)]
- def same(self, a, b):
- return a.same(b)
+ def sameQ(self, a, b) -> bool:
+ """Mathics SameQ"""
+ return a.sameQ(b)
class _GatherBin:
@@ -3413,7 +3415,7 @@ def _gather(self, keys, values, equivalence):
for key, value in zip(keys.leaves, values.leaves):
selection = equivalence.select(key)
for prototype, add_to_bin in selection: # find suitable bin
- if equivalence.same(prototype, key):
+ if equivalence.sameQ(prototype, key):
add_to_bin(value) # add to existing bin
break
else:
@@ -3590,10 +3592,10 @@ def apply(self, lists, evaluation, options={}):
same_test = self.get_option(options, "SameTest", evaluation)
operands = [l.leaves for l in seq]
if not _is_sameq(same_test):
- same = lambda a, b: _test_pair(same_test, a, b, evaluation, self.get_name())
- operands = [self._remove_duplicates(op, same) for op in operands]
+ sameQ = lambda a, b: _test_pair(same_test, a, b, evaluation, self.get_name())
+ operands = [self._remove_duplicates(op, sameQ) for op in operands]
items = functools.reduce(
- lambda a, b: [e for e in self._elementwise(a, b, same)], operands
+ lambda a, b: [e for e in self._elementwise(a, b, sameQ)], operands
)
else:
items = list(
@@ -3632,11 +3634,11 @@ class Union(_SetOperation):
_operation = "union"
- def _elementwise(self, a, b, same):
+ def _elementwise(self, a, b, sameQ):
for eb in b:
yield eb
for ea in a:
- if not any(same(eb, ea) for eb in b):
+ if not any(sameQ(eb, ea) for eb in b):
yield ea
@@ -3666,9 +3668,9 @@ class Intersection(_SetOperation):
_operation = "intersection"
- def _elementwise(self, a, b, same):
+ def _elementwise(self, a, b, sameQ):
for ea in a:
- if any(same(eb, ea) for eb in b):
+ if any(sameQ(eb, ea) for eb in b):
yield ea
@@ -3711,9 +3713,9 @@ class Complement(_SetOperation):
_operation = "difference"
- def _elementwise(self, a, b, same):
+ def _elementwise(self, a, b, sameQ):
for ea in a:
- if not any(same(eb, ea) for eb in b):
+ if not any(sameQ(eb, ea) for eb in b):
yield ea
@@ -6195,13 +6197,14 @@ def apply(self, list1, list2, evaluation, options={}):
same_test = self.get_option(options, "SameTest", evaluation)
- def same(a, b):
+ def sameQ(a, b) -> bool:
+ """Mathics SameQ"""
result = Expression(same_test, a, b).evaluate(evaluation)
return result.is_true()
self.check_options(None, evaluation, options)
for a in list1.leaves:
- if not any(same(a, b) for b in list2.leaves):
+ if not any(sameQ(a, b) for b in list2.leaves):
return Symbol("False")
return Symbol("True")
diff --git a/mathics/builtin/manipulate.py b/mathics/builtin/manipulate.py
index e864cc07cb..5cf8d80da5 100755
--- a/mathics/builtin/manipulate.py
+++ b/mathics/builtin/manipulate.py
@@ -196,7 +196,7 @@ def _add_options_widget(self, symbol, options, default, label, evaluation):
default_index = 0
for i, option in enumerate(options.leaves):
- if option.same(default):
+ if option.sameQ(default):
default_index = i
widget = _create_widget(
diff --git a/mathics/builtin/numeric.py b/mathics/builtin/numeric.py
index d9d4c0d820..2a7e8daa1b 100644
--- a/mathics/builtin/numeric.py
+++ b/mathics/builtin/numeric.py
@@ -241,7 +241,7 @@ def apply_with_prec(self, expr, prec, evaluation):
name, "System`NValues", nexpr, evaluation
)
if result is not None:
- if not result.same(nexpr):
+ if not result.sameQ(nexpr):
result = Expression(SymbolN, result, prec).evaluate(evaluation)
return result
diff --git a/mathics/builtin/patterns.py b/mathics/builtin/patterns.py
index 7918081476..033753318c 100644
--- a/mathics/builtin/patterns.py
+++ b/mathics/builtin/patterns.py
@@ -340,7 +340,7 @@ def apply_list(self, expr, rules, evaluation):
result, applied = expr.apply_rules(rules, evaluation)
if applied:
result = result.evaluate(evaluation)
- if applied and not result.same(expr):
+ if applied and not result.sameQ(expr):
expr = result
else:
break
@@ -674,7 +674,7 @@ def init(self, expr):
self.content = expr.leaves[0]
def match(self, yield_func, expression, vars, evaluation, **kwargs):
- if self.content.same(expression):
+ if self.content.sameQ(expression):
yield_func(vars, None)
@@ -804,7 +804,7 @@ def match(self, yield_func, expression, vars, evaluation, **kwargs):
else:
self.pattern.match(yield_func, expression, new_vars, evaluation)
else:
- if existing.same(expression):
+ if existing.sameQ(expression):
yield_func(vars, None)
def get_match_candidates(self, leaves, expression, attributes, evaluation, vars={}):
@@ -941,7 +941,7 @@ def get_default_value(name, evaluation, k=None, n=None):
name, "System`DefaultValues", defaultexpr, evaluation
)
if result is not None:
- if result.same(defaultexpr):
+ if result.sameQ(defaultexpr):
result = result.evaluate(evaluation)
return result
return None
@@ -997,7 +997,7 @@ class Blank(_Blank):
def match(self, yield_func, expression, vars, evaluation, **kwargs):
if not expression.has_form("Sequence", 0):
if self.head is not None:
- if expression.get_head().same(self.head):
+ if expression.get_head().sameQ(self.head):
yield_func(vars, None)
else:
yield_func(vars, None)
diff --git a/mathics/builtin/strings.py b/mathics/builtin/strings.py
index 1d35aae6e2..a9b5febf81 100644
--- a/mathics/builtin/strings.py
+++ b/mathics/builtin/strings.py
@@ -209,7 +209,7 @@ def recurse(x, quantifiers=q):
if patt is not None:
if expr.leaves[1].has_form("Blank", 0):
pass # ok, no warnings
- elif not expr.leaves[1].same(patt):
+ elif not expr.leaves[1].sameQ(patt):
evaluation.message(
"StringExpression", "cond", expr.leaves[0], expr, expr.leaves[0]
)
@@ -1168,7 +1168,7 @@ def _find(py_stri, py_rules, py_n, flags):
raise NotImplementedError()
def _apply(self, string, rule, n, evaluation, options, cases):
- if n.same(Symbol("System`Private`Null")):
+ if n.sameQ(Symbol("System`Private`Null")):
expr = Expression(self.get_name(), string, rule)
n = None
else:
@@ -2269,17 +2269,17 @@ class HammingDistance(Builtin):
}
@staticmethod
- def _compute(u, v, same, evaluation):
+ def _compute(u, v, sameQ, evaluation):
if len(u) != len(v):
evaluation.message("HammingDistance", "idim", u, v)
return None
else:
- return Integer(sum(0 if same(x, y) else 1 for x, y in zip(u, v)))
+ return Integer(sum(0 if sameQ(x, y) else 1 for x, y in zip(u, v)))
def apply_list(self, u, v, evaluation):
"HammingDistance[u_List, v_List]"
return HammingDistance._compute(
- u.leaves, v.leaves, lambda x, y: x.same(y), evaluation
+ u.leaves, v.leaves, lambda x, y: x.sameQ(y), evaluation
)
def apply_string(self, u, v, evaluation, options):
@@ -2314,7 +2314,7 @@ def normalize(c):
py_b = py_b.lower()
return Integer(self._distance(py_a, py_b, lambda u, v: u == v))
elif a.get_head_name() == "System`List" and b.get_head_name() == "System`List":
- return Integer(self._distance(a.leaves, b.leaves, lambda u, v: u.same(v)))
+ return Integer(self._distance(a.leaves, b.leaves, lambda u, v: u.sameQ(v)))
else:
return Expression("EditDistance", a, b)
@@ -2354,14 +2354,14 @@ def _levenshtein_d0(s2): # compute D(0, ...)
return list(range(len(s2) + 1)) # see (1), (3)
-def _levenshtein_di(c1, s2, i, d_prev, same, cost): # compute one new row
+def _levenshtein_di(c1, s2, i, d_prev, sameQ, cost): # compute one new row
# given c1 = s1[i], s2, i, d_prev = D(i - 1, ...), compute D(i, ...)
yield i # start with D(i, 0) = i, see (2)
d_curr_prev_j = i # d_curr_prev_j stores D(i, j - 1)
for j, c2 in _one_based(enumerate(s2)): # c2 = s2[[j]]
- cond = 0 if same(c1, c2) else cost
+ cond = 0 if sameQ(c1, c2) else cost
d_curr_j = min( # see (4)
d_prev[j - 1] + cond, # D(i - 1, j - 1) + cond; substitution
@@ -2380,7 +2380,7 @@ def _levenshtein(s1, s2, same):
return d_prev[-1]
-def _damerau_levenshtein(s1, s2, same):
+def _damerau_levenshtein(s1, s2, sameQ):
# _damerau_levenshtein works like _levenshtein, except for one additional
# rule covering transposition:
#
@@ -2390,9 +2390,9 @@ def _damerau_levenshtein(s1, s2, same):
def row(d_prev_prev, d_prev, i, prev_c1, c1, cost):
# given c1 = s1[i], d_prev_prev = D(i - 2), d_prev = D(i - 1),
# prev_c1 = s1[[i - 1]], c1 = s1[[i]], compute D(i, ...)
- for j, d_curr_j in enumerate(_levenshtein_di(c1, s2, i, d_prev, same, cost)):
+ for j, d_curr_j in enumerate(_levenshtein_di(c1, s2, i, d_prev, sameQ, cost)):
if i > 1 and j > 1:
- if same(c1, s2[j - 2]) and same(prev_c1, s2[j - 1]): # transposition?
+ if sameQ(c1, s2[j - 2]) and sameQ(prev_c1, s2[j - 1]): # transposition?
# i.e. if s1[[i]] = s2[[j-1]] and s1[[i-1]] = s2[[j]]
d_curr_j = min(d_curr_j, d_prev_prev[j - 2] + cost)
yield d_curr_j
@@ -2407,8 +2407,8 @@ def row(d_prev_prev, d_prev, i, prev_c1, c1, cost):
return d_prev[-1]
-def _levenshtein_like_or_border_cases(s1, s2, same, compute):
- if len(s1) == len(s2) and all(same(c1, c2) for c1, c2 in zip(s1, s2)):
+def _levenshtein_like_or_border_cases(s1, s2, sameQ, compute):
+ if len(s1) == len(s2) and all(sameQ(c1, c2) for c1, c2 in zip(s1, s2)):
return 0
if len(s1) < len(s2):
@@ -2417,7 +2417,7 @@ def _levenshtein_like_or_border_cases(s1, s2, same, compute):
if len(s2) == 0:
return len(s1)
- return compute(s1, s2, same)
+ return compute(s1, s2, sameQ)
class EditDistance(_StringDistance):
@@ -2453,8 +2453,8 @@ class EditDistance(_StringDistance):
= 2
"""
- def _distance(self, s1, s2, same):
- return _levenshtein_like_or_border_cases(s1, s2, same, _levenshtein)
+ def _distance(self, s1, s2, sameQ):
+ return _levenshtein_like_or_border_cases(s1, s2, sameQ, _levenshtein)
class DamerauLevenshteinDistance(_StringDistance):
@@ -2491,8 +2491,8 @@ class DamerauLevenshteinDistance(_StringDistance):
= 1
"""
- def _distance(self, s1, s2, same):
- return _levenshtein_like_or_border_cases(s1, s2, same, _damerau_levenshtein)
+ def _distance(self, s1, s2, sameQ):
+ return _levenshtein_like_or_border_cases(s1, s2, sameQ, _damerau_levenshtein)
class RemoveDiacritics(Builtin):
diff --git a/mathics/builtin/tensors.py b/mathics/builtin/tensors.py
index ec896177a3..f501795454 100644
--- a/mathics/builtin/tensors.py
+++ b/mathics/builtin/tensors.py
@@ -121,7 +121,7 @@ def get_dimensions(expr, head=None):
if expr.is_atom():
return []
else:
- if head is not None and not expr.head.same(head):
+ if head is not None and not expr.head.sameQ(head):
return []
sub_dim = None
sub = []
@@ -355,13 +355,13 @@ def apply(self, f, lists, evaluation):
return
if head is None:
head = list.head
- elif not list.head.same(head):
+ elif not list.head.sameQ(head):
evaluation.message("Outer", "heads", head, list.head)
return
def rec(item, rest_lists, current):
evaluation.check_stopped()
- if item.is_atom() or not item.head.same(head):
+ if item.is_atom() or not item.head.sameQ(head):
if rest_lists:
return rec(rest_lists[0], rest_lists[1:], current + [item])
else:
diff --git a/mathics/core/definitions.py b/mathics/core/definitions.py
index c36d04b756..6fb905924f 100644
--- a/mathics/core/definitions.py
+++ b/mathics/core/definitions.py
@@ -722,7 +722,7 @@ def get_tag_position(pattern, name) -> typing.Optional[str]:
def insert_rule(values, rule) -> None:
for index, existing in enumerate(values):
- if existing.pattern.same(rule.pattern):
+ if existing.pattern.sameQ(rule.pattern):
del values[index]
break
# use insort_left to guarantee that if equal rules exist, newer rules will
@@ -818,7 +818,7 @@ def remove_rule(self, lhs) -> bool:
if position:
values = self.get_values_list(position)
for index, existing in enumerate(values):
- if existing.pattern.expr.same(lhs):
+ if existing.pattern.expr.sameQ(lhs):
del values[index]
return True
return False
diff --git a/mathics/core/expression.py b/mathics/core/expression.py
index c140d79a26..80fbc9b1bf 100644
--- a/mathics/core/expression.py
+++ b/mathics/core/expression.py
@@ -68,7 +68,7 @@ def system_symbols_dict(d):
class BoxError(Exception):
def __init__(self, box, form) -> None:
- super(BoxError, self).__init__("Box %s cannot be formatted as %s" % (box, form))
+ super().__init__("Box %s cannot be formatted as %s" % (box, form))
self.box = box
self.form = form
@@ -126,7 +126,12 @@ def from_python(arg):
# return Symbol(arg)
elif isinstance(arg, dict):
entries = [
- Expression("Rule", from_python(key), from_python(arg[key]),) for key in arg
+ Expression(
+ "Rule",
+ from_python(key),
+ from_python(arg[key]),
+ )
+ for key in arg
]
return Expression(SymbolList, *entries)
elif isinstance(arg, BaseExpression):
@@ -345,8 +350,9 @@ def user_hash(self, update) -> None:
# __hash__ might only hash a sample of the data available.
raise NotImplementedError
- def same(self, other) -> bool:
- pass
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
+ return id(self) == id(other)
def get_sequence(self):
if self.get_head().get_name() == "System`Sequence":
@@ -684,7 +690,7 @@ class Expression(BaseExpression):
_sequences: Any
def __new__(cls, head, *leaves, **kwargs) -> "Expression":
- self = super(Expression, cls).__new__(cls)
+ self = super().__new__(cls)
if isinstance(head, str):
head = Symbol(head)
self._head = head
@@ -870,7 +876,7 @@ def do_format(self, evaluation, form):
last_evaluated, (symbolname,)
):
return expr
- expr = super(Expression, self).do_format(evaluation, form)
+ expr = super().do_format(evaluation, form)
self._format_cache[form] = (evaluation.definitions.now, expr)
return expr
@@ -1183,17 +1189,18 @@ def get_sort_key(self, pattern_sort=False):
else:
return [1 if self.is_numeric() else 2, 3, self._head, self._leaves, 1]
- def same(self, other) -> bool:
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
if id(self) == id(other):
return True
if self.get_head_name() != other.get_head_name():
return False
- if not self._head.same(other.get_head()):
+ if not self._head.sameQ(other.get_head()):
return False
if len(self._leaves) != len(other.get_leaves()):
return False
for leaf, other in zip(self._leaves, other.get_leaves()):
- if not leaf.same(other):
+ if not leaf.sameQ(other):
return False
return True
@@ -1207,7 +1214,7 @@ def flatten(
sub_level = None if level is None else level - 1
do_flatten = False
for leaf in self._leaves:
- if leaf.get_head().same(head) and (
+ if leaf.get_head().sameQ(head) and (
not pattern_only or leaf.pattern_sequence
):
do_flatten = True
@@ -1215,7 +1222,7 @@ def flatten(
if do_flatten:
new_leaves = []
for leaf in self._leaves:
- if leaf.get_head().same(head) and (
+ if leaf.get_head().sameQ(head) and (
not pattern_only or leaf.pattern_sequence
):
new_leaf = leaf.flatten(
@@ -1365,7 +1372,7 @@ def flatten_callback(new_leaves, old):
if "System`Listable" in attributes:
done, threaded = new.thread(evaluation)
if done:
- if threaded.same(new):
+ if threaded.sameQ(new):
new._timestamp_cache(evaluation)
return new, False
else:
@@ -1394,7 +1401,7 @@ def rules():
if result is not None:
if isinstance(result, BoxConstruct):
return result, False
- if result.same(new):
+ if result.sameQ(new):
new._timestamp_cache(evaluation)
return new, False
else:
@@ -1537,7 +1544,9 @@ def is_list_interior(content):
self._leaves[1].boxes_to_mathml(**options),
)
elif name == "System`SqrtBox" and len(self._leaves) == 1:
- return "%s" % (self._leaves[0].boxes_to_mathml(**options))
+ return "%s" % (
+ self._leaves[0].boxes_to_mathml(**options)
+ )
elif name == "System`GraphBox":
return "%s" % (self._leaves[0].boxes_to_mathml(**options))
else:
@@ -1640,9 +1649,7 @@ def descend(expr):
return Expression(expr._head, *[apply_leaf(leaf) for leaf in expr._leaves])
if options is None: # default ReplaceAll mode; replace breadth first
- result, applied = super(Expression, self).apply_rules(
- rules, evaluation, level, options
- )
+ result, applied = super().apply_rules(rules, evaluation, level, options)
if applied:
return result, True
head, applied = self._head.apply_rules(rules, evaluation, level, options)
@@ -1753,7 +1760,7 @@ def thread(self, evaluation, head=None) -> typing.Tuple[bool, "Expression"]:
items = []
dim = None
for leaf in self._leaves:
- if leaf.get_head().same(head):
+ if leaf.get_head().sameQ(head):
if dim is None:
dim = len(leaf._leaves)
items = [(items + [innerleaf]) for innerleaf in leaf._leaves]
@@ -1776,17 +1783,21 @@ def thread(self, evaluation, head=None) -> typing.Tuple[bool, "Expression"]:
return True, Expression(head, *leaves)
def is_numeric(self) -> bool:
- return self._head.get_name() in system_symbols(
- "Sqrt",
- "Times",
- "Plus",
- "Subtract",
- "Minus",
- "Power",
- "Abs",
- "Divide",
- "Sin",
- ) and all(leaf.is_numeric() for leaf in self._leaves)
+ return (
+ self._head.get_name()
+ in system_symbols(
+ "Sqrt",
+ "Times",
+ "Plus",
+ "Subtract",
+ "Minus",
+ "Power",
+ "Abs",
+ "Divide",
+ "Sin",
+ )
+ and all(leaf.is_numeric() for leaf in self._leaves)
+ )
# TODO: complete list of numeric functions, or access NumericFunction
# attribute
@@ -1968,7 +1979,8 @@ def get_sort_key(self, pattern_sort=False):
1,
]
- def same(self, other) -> bool:
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
return isinstance(other, Symbol) and self.name == other.name
def replace_vars(self, vars, options={}, in_scoping=True):
@@ -1986,7 +1998,7 @@ def evaluate(self, evaluation):
rules = evaluation.definitions.get_ownvalues(self.name)
for rule in rules:
result = rule.apply(self, evaluation, fully=True)
- if result is not None and not result.same(self):
+ if result is not None and not result.sameQ(self):
return result.evaluate(evaluation)
return self
@@ -2114,6 +2126,10 @@ def __new__(cls, value) -> "Integer":
self.value = n
return self
+ @lru_cache()
+ def __init__(self, value) -> "Integer":
+ super().__init__()
+
def boxes_to_text(self, **options) -> str:
return str(self.value)
@@ -2150,7 +2166,8 @@ def round(self, d=None) -> typing.Union["MachineReal", "PrecisionReal"]:
def get_int_value(self) -> int:
return self.value
- def same(self, other) -> bool:
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
return isinstance(other, Integer) and self.value == other.value
def evaluate(self, evaluation):
@@ -2159,7 +2176,7 @@ def evaluate(self, evaluation):
def get_sort_key(self, pattern_sort=False):
if pattern_sort:
- return super(Integer, self).get_sort_key(True)
+ return super().get_sort_key(True)
else:
return [0, 0, self.value, 0, 1]
@@ -2184,8 +2201,9 @@ def is_zero(self) -> bool:
class Rational(Number):
+ @lru_cache()
def __new__(cls, numerator, denominator=1) -> "Rational":
- self = super(Rational, cls).__new__(cls)
+ self = super().__new__(cls)
self.value = sympy.Rational(numerator, denominator)
return self
@@ -2207,7 +2225,8 @@ def round(self, d=None) -> typing.Union["MachineReal", "PrecisionReal"]:
else:
return PrecisionReal(self.value.n(d))
- def same(self, other) -> bool:
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
return isinstance(other, Rational) and self.value == other.value
def numerator(self) -> "Integer":
@@ -2244,7 +2263,7 @@ def evaluate(self, evaluation) -> "Rational":
def get_sort_key(self, pattern_sort=False):
if pattern_sort:
- return super(Rational, self).get_sort_key(True)
+ return super().get_sort_key(True)
else:
# HACK: otherwise "Bus error" when comparing 1==1.
return [0, 0, sympy.Float(self.value), 0, 1]
@@ -2318,7 +2337,7 @@ def evaluate(self, evaluation) -> "Real":
def get_sort_key(self, pattern_sort=False):
if pattern_sort:
- return super(Real, self).get_sort_key(True)
+ return super().get_sort_key(True)
return [0, 0, self.value, 0, 1]
def __eq__(self, other) -> bool:
@@ -2380,7 +2399,8 @@ def to_mpmath(self):
def round(self, d=None) -> "MachineReal":
return self
- def same(self, other) -> bool:
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
if isinstance(other, MachineReal):
return self.value == other.value
elif isinstance(other, PrecisionReal):
@@ -2459,7 +2479,8 @@ def round(self, d=None) -> typing.Union["MachineReal", "PrecisionReal"]:
d = min(dps(self.get_precision()), d)
return PrecisionReal(self.value.n(d))
- def same(self, other) -> bool:
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
if isinstance(other, PrecisionReal):
return self.value == other.value
elif isinstance(other, MachineReal):
@@ -2500,13 +2521,13 @@ class Complex(Number):
imag: Any
def __new__(cls, real, imag):
- self = super(Complex, cls).__new__(cls)
+ self = super().__new__(cls)
if isinstance(real, Complex) or not isinstance(real, Number):
raise ValueError("Argument 'real' must be a real number.")
if isinstance(imag, Complex) or not isinstance(imag, Number):
raise ValueError("Argument 'imag' must be a real number.")
- if imag.same(Integer(0)):
+ if imag.sameQ(Integer(0)):
return real
if isinstance(real, MachineReal) and not isinstance(imag, MachineReal):
@@ -2542,7 +2563,7 @@ def do_format(self, evaluation, form) -> "Expression":
parts: typing.List[Any] = []
if self.is_machine_precision() or not self.real.is_zero:
parts.append(self.real)
- if self.imag.same(Integer(1)):
+ if self.imag.sameQ(Integer(1)):
parts.append(Symbol("I"))
else:
parts.append(Expression("Times", self.imag, Symbol("I")))
@@ -2562,11 +2583,12 @@ def default_format(self, evaluation, form) -> str:
def get_sort_key(self, pattern_sort=False):
if pattern_sort:
- return super(Complex, self).get_sort_key(True)
+ return super().get_sort_key(True)
else:
return [0, 0, self.real.get_sort_key()[2], self.imag.get_sort_key()[2], 1]
- def same(self, other) -> bool:
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
return (
isinstance(other, Complex)
and self.real == other.real
@@ -2717,7 +2739,7 @@ class String(Atom):
value: str
def __new__(cls, value):
- self = super(String, cls).__new__(cls)
+ self = super().__new__(cls)
self.value = str(value)
return self
@@ -2857,11 +2879,12 @@ def default_format(self, evaluation, form) -> str:
def get_sort_key(self, pattern_sort=False):
if pattern_sort:
- return super(String, self).get_sort_key(True)
+ return super().get_sort_key(True)
else:
return [0, 1, self.value, 0, 1]
- def same(self, other) -> bool:
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
return isinstance(other, String) and self.value == other.value
def get_string_value(self) -> str:
@@ -2929,7 +2952,8 @@ def get_sort_key(self, pattern_sort=False):
else:
return [0, 1, self.value, 0, 1]
- def same(self, other) -> bool:
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
# FIX: check
if isinstance(other, ByteArrayAtom):
return self.value == other.value
@@ -2961,7 +2985,7 @@ def __getnewargs__(self):
class StringFromPython(String):
def __new__(cls, value):
- self = super(StringFromPython, cls).__new__(cls, value)
+ self = super().__new__(cls, value)
if isinstance(value, sympy.NumberSymbol):
self.value = "sympy." + str(value)
@@ -2987,7 +3011,7 @@ def get_default_value(name, evaluation, k=None, n=None):
name, "System`DefaultValues", defaultexpr, evaluation
)
if result is not None:
- if result.same(defaultexpr):
+ if result.sameQ(defaultexpr):
result = result.evaluate(evaluation)
return result
return None
diff --git a/mathics/core/numbers.py b/mathics/core/numbers.py
index dce1d36bb5..37583fa979 100644
--- a/mathics/core/numbers.py
+++ b/mathics/core/numbers.py
@@ -90,7 +90,8 @@ def get_type(value) -> typing.Optional[str]:
return None
-def same(v1, v2) -> bool:
+def sameQ(v1, v2) -> bool:
+ """Mathics SameQ"""
return get_type(v1) == get_type(v2) and v1 == v2
diff --git a/mathics/core/pattern.py b/mathics/core/pattern.py
index f22c7c1bf5..3c6ad7c9af 100644
--- a/mathics/core/pattern.py
+++ b/mathics/core/pattern.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python3
# cython: language_level=3
# cython: profile=False
# -*- coding: utf-8 -*-
@@ -96,8 +95,9 @@ def is_atom(self):
def get_head_name(self):
return self.expr.get_head_name()
- def same(self, other):
- return self.expr.same(other.expr)
+ def sameQ(self, other) -> bool:
+ """Mathics SameQ"""
+ return self.expr.sameQ(other.expr)
def get_head(self):
return self.expr.get_head()
@@ -154,12 +154,12 @@ def match(
fully=True,
wrap_oneid=True,
):
- if expression.same(self.atom):
+ if expression.sameQ(self.atom):
# yield vars, None
yield_func(vars, None)
def get_match_candidates(self, leaves, expression, attributes, evaluation, vars={}):
- return [leaf for leaf in leaves if leaf.same(self.atom)]
+ return [leaf for leaf in leaves if leaf.sameQ(self.atom)]
def get_match_count(self, vars={}):
return (1, 1)
diff --git a/test/test_hash.py b/test/test_hash.py
index 5344156ce8..dd40bb9561 100644
--- a/test/test_hash.py
+++ b/test/test_hash.py
@@ -45,10 +45,10 @@ def _test_group(k, *group):
sys.excepthook(*info)
return False
- is_same = a.same(b)
+ is_same = a.sameQ(b)
if is_same != _symbol_truth_value(is_same_under_sameq):
print(
- "%sTest failed: %s and %s are inconsistent under same() and SameQ\n"
+ "%sTest failed: %s and %s are inconsistent under .sameQ() and SameQ\n"
% (sep, repr(a), repr(b))
)
return False
diff --git a/test/test_parser/test_convert.py b/test/test_parser/test_convert.py
index ec9df03a80..9464281a5b 100644
--- a/test/test_parser/test_convert.py
+++ b/test/test_parser/test_convert.py
@@ -28,9 +28,9 @@ def check(self, expr1, expr2):
expr2 = self.parse(expr2)
if expr1 is None:
- self.assertIsNone(expr2)
+ assert expr2 is None
else:
- self.assertTrue(expr1.same(expr2))
+ assert expr1.sameQ(expr2)
def scan_error(self, string):
self.assertRaises(ScanError, self.parse, string)
diff --git a/test/test_parser/test_util.py b/test/test_parser/test_util.py
index c1ac5f20d6..7d8ae7b623 100644
--- a/test/test_parser/test_util.py
+++ b/test/test_parser/test_util.py
@@ -44,7 +44,7 @@ def parse(self, code):
return parse(definitions, SingleLineFeeder(code))
def compare(self, expr1, expr2):
- self.assertTrue(expr1.same(expr2))
+ assert expr1.sameQ(expr2)
def test_continuation(self):
self.incomplete_error("Sin[")
@@ -61,7 +61,7 @@ def parse(self, code):
return parse(definitions, MultiLineFeeder(code))
def compare(self, expr1, expr2):
- self.assertTrue(expr1.same(expr2))
+ assert expr1.sameQ(expr2)
def test_trailing_backslash(self):
self.incomplete_error("x \\")