The problem is reproducible in Sympy :
>>> from sympy import *
>>> x=symbols("x")
>>> Ex=Piecewise((3*x+1, (x > -2) | (x < -2)), (2, Eq(x, -2)))
>>> Ex.subs({x:-2})
2
>>> limit(Ex, x, -2)
2
>>> f=Lambda((x), Ex)
>>> limit(f(x), x, -2)
2
You may yelp on the Sympy Google group...
BTW,
So does the Wolfram engine
:
sage: %%mathematica
....: f[x_]:=Piecewise[{{3*x+1, x<-2}, {3*x+1, x>-2}, {2,x==-2}}]
....: f[-2]
....: Limit[f[x], x->-2]
....:
....:
2
Out[7]= -5
Sage is worse :
sage: f(x).limit(x=-2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In [200], line 1
----> 1 f(x).limit(x=-Integer(2))
File /usr/local/sage-10/src/sage/symbolic/expression.pyx:13332, in sage.symbolic.expression.Expression.limit()
13330 """
13331 from sage.calculus.calculus import limit
> 13332 return limit(self, *args, **kwds)
13333
13334 def laplace(self, t, s):
File /usr/local/sage-10/src/sage/calculus/calculus.py:1429, in limit(ex, dir, taylor, algorithm, **argv)
1427 if algorithm == 'maxima':
1428 if dir is None:
-> 1429 l = maxima.sr_limit(ex, v, a)
1430 elif dir in dir_plus:
1431 l = maxima.sr_limit(ex, v, a, 'plus')
File /usr/local/sage-10/src/sage/interfaces/maxima_lib.py:1006, in MaximaLib.sr_limit(self, expr, v, a, dir)
1004 elif dir == "minus":
1005 L.append(max_minus)
-> 1006 return max_to_sr(maxima_eval(([max_limit], L)))
1007 except RuntimeError as error:
1008 s = str(error)
File /usr/local/sage-10/src/sage/interfaces/maxima_lib.py:1728, in max_to_sr(expr)
1724 op = max_to_pynac_table[op_max_str]
1725 else:
1726 # This could be unsafe if the conversion to SR
1727 # changes the structure of expr
-> 1728 sage_expr = SR(maxima(expr))
1729 op = sage_expr.operator()
1730 if op in sage_op_dict:
File /usr/local/sage-10/src/sage/structure/parent.pyx:901, in sage.structure.parent.Parent.__call__()
899 if mor is not None:
900 if no_extra_args:
--> 901 return mor._call_(x)
902 else:
903 return mor._call_with_args(x, args, kwds)
File /usr/local/sage-10/src/sage/structure/coerce_maps.pyx:163, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_()
161 print(type(C), C)
162 print(type(C._element_constructor), C._element_constructor)
--> 163 raise
164
165 cpdef Element _call_with_args(self, x, args=(), kwds={}):
File /usr/local/sage-10/src/sage/structure/coerce_maps.pyx:158, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_()
156 cdef Parent C = self._codomain
157 try:
--> 158 return C._element_constructor(x)
159 except Exception:
160 if print_warnings:
File /usr/local/sage-10/src/sage/symbolic/ring.pyx:376, in sage.symbolic.ring.SymbolicRing._element_constructor_()
374 TypeError: Malformed expression: λ + * !!! 1
375 """
--> 376 return new_Expression(self, x)
377
378 def _force_pyobject(self, x, bint force=False, bint recursive=True):
File /usr/local/sage-10/src/sage/symbolic/expression.pyx:13773, in sage.symbolic.expression.new_Expression()
13771 return new_Expression_from_GEx(parent, (<Expression>x)._gobj)
13772 if hasattr(x, '_symbolic_'):
> 13773 return x._symbolic_(parent)
13774 elif isinstance(x, str):
13775 try:
File /usr/local/sage-10/src/sage/interfaces/maxima_abstract.py:1280, in MaximaAbstractElement._symbolic_(self, R)
1257 def _symbolic_(self, R):
1258 """
1259 Return a symbolic expression equivalent to this Maxima object.
1260
(...)
1278 sqrt(2)
1279 """
-> 1280 return R(self._sage_())
File /usr/local/sage-10/src/sage/interfaces/maxima_abstract.py:1254, in MaximaAbstractElement._sage_(self)
1199 """
1200 Attempt to make a native Sage object out of this Maxima object.
1201 This is useful for automatic coercions in addition to other
(...)
1251 (True, False)
1252 """
1253 import sage.calculus.calculus as calculus
-> 1254 return calculus.symbolic_expression_from_maxima_string(self.name(),
1255 maxima=self.parent())
File /usr/local/sage-10/src/sage/calculus/calculus.py:2403, in symbolic_expression_from_maxima_string(x, equals_sub, maxima)
2401 SRM_parser._variable_constructor().set_names(var_syms)
2402 SRM_parser._callable_constructor().set_names(function_syms)
-> 2403 return SRM_parser.parse_sequence(s)
2404 except SyntaxError:
2405 raise TypeError("unable to make sense of Maxima expression '%s' in Sage" % s)
File /usr/local/sage-10/src/sage/misc/parser.pyx:571, in sage.misc.parser.Parser.parse_sequence()
569 return expr
570
--> 571 cpdef parse_sequence(self, s):
572 """
573 Parse a (possibly nested) set of lists and tuples.
File /usr/local/sage-10/src/sage/misc/parser.pyx:587, in sage.misc.parser.Parser.parse_sequence()
585 """
586 cdef Tokenizer tokens = Tokenizer(s)
--> 587 all = self.p_sequence(tokens)
588 if tokens.next() != EOS:
589 self.parse_error(tokens)
File /usr/local/sage-10/src/sage/misc/parser.pyx:660, in sage.misc.parser.Parser.p_sequence()
658 return all
659 else:
--> 660 obj = self.p_eqn(tokens)
661 PyList_Append(all, obj)
662 token = tokens.next()
File /usr/local/sage-10/src/sage/misc/parser.pyx:750, in sage.misc.parser.Parser.p_eqn()
748 a != b
749 """
--> 750 lhs = self.p_expr(tokens)
751 cdef int op = tokens.next()
752 if op == c'=':
File /usr/local/sage-10/src/sage/misc/parser.pyx:790, in sage.misc.parser.Parser.p_expr()
788 # Note: this is left-recursive, so we can't just recurse
789 cdef int op
--> 790 operand1 = self.p_term(tokens)
791 op = tokens.next()
792 while op == c'+' or op == c'-':
File /usr/local/sage-10/src/sage/misc/parser.pyx:824, in sage.misc.parser.Parser.p_term()
822 # Note: this is left-recursive, so we can't just recurse
823 cdef int op
--> 824 operand1 = self.p_factor(tokens)
825 op = tokens.next()
826 if op == NAME and self.implicit_multiplication:
File /usr/local/sage-10/src/sage/misc/parser.pyx:867, in sage.misc.parser.Parser.p_factor()
865 else:
866 tokens.backtrack()
--> 867 return self.p_power(tokens)
868
869 # power ::= (atom | atom!) ^ factor | atom | atom!
File /usr/local/sage-10/src/sage/misc/parser.pyx:895, in sage.misc.parser.Parser.p_power()
893
894 """
--> 895 operand1 = self.p_atom(tokens)
896 cdef int token = tokens.next()
897 if token == c'^':
File /usr/local/sage-10/src/sage/misc/parser.pyx:950, in sage.misc.parser.Parser.p_atom()
948 if token == c'(':
949 func = self.callable_constructor(name)
--> 950 args, kwds = self.p_args(tokens)
951 token = tokens.next()
952 if token != c')':
File /usr/local/sage-10/src/sage/misc/parser.pyx:987, in sage.misc.parser.Parser.p_args()
985 cdef int token = c','
986 while token == c',':
--> 987 arg = self.p_arg(tokens)
988 if isinstance(arg, tuple):
989 name, value = arg
File /usr/local/sage-10/src/sage/misc/parser.pyx:1037, in sage.misc.parser.Parser.p_arg()
1035 else:
1036 tokens.backtrack()
-> 1037 return self.p_expr(tokens)
1038
1039 cdef parse_error(self, Tokenizer tokens, msg="Malformed expression"):
File /usr/local/sage-10/src/sage/misc/parser.pyx:790, in sage.misc.parser.Parser.p_expr()
788 # Note: this is left-recursive, so we can't just recurse
789 cdef int op
--> 790 operand1 = self.p_term(tokens)
791 op = tokens.next()
792 while op == c'+' or op == c'-':
File /usr/local/sage-10/src/sage/misc/parser.pyx:824, in sage.misc.parser.Parser.p_term()
822 # Note: this is left-recursive, so we can't just recurse
823 cdef int op
--> 824 operand1 = self.p_factor(tokens)
825 op = tokens.next()
826 if op == NAME and self.implicit_multiplication:
File /usr/local/sage-10/src/sage/misc/parser.pyx:867, in sage.misc.parser.Parser.p_factor()
865 else:
866 tokens.backtrack()
--> 867 return self.p_power(tokens)
868
869 # power ::= (atom | atom!) ^ factor | atom | atom!
File /usr/local/sage-10/src/sage/misc/parser.pyx:895, in sage.misc.parser.Parser.p_power()
893
894 """
--> 895 operand1 = self.p_atom(tokens)
896 cdef int token = tokens.next()
897 if token == c'^':
File /usr/local/sage-10/src/sage/misc/parser.pyx:954, in sage.misc.parser.Parser.p_atom()
952 if token != c')':
953 self.parse_error(tokens, "Bad function call")
--> 954 return func(*args, **kwds)
955 else:
956 tokens.backtrack()
TypeError: PiecewiseFunction.__call__() takes 2 positional arguments but 3 were given
This is now #35883.
HTH,