Why SR('expression') fail on some but not others?

54 views
Skip to first unread message

Nasser M. Abbasi

unread,
Apr 26, 2023, 2:08:02 AM4/26/23
to sage-devel
I read integrals from a file. They all are stored as strings.

Then use SR('expression') inside sagemath to convert them to sagemath symbolic  expression before calling integrate.

Some give parsing error. 

Is using SR('expression') not the correct way to convert string to a symbolic expression?

I am using 9.8 on Linux. Here is an example

>sage
│ SageMath version 9.8, Release Date: 2023-02-11                     │
│ Using Python 3.11.1. Type "help()" for help.                       │

sage: hypergeometric((3/2,), (5/2, 3), -1/4*3^2)
hypergeometric((3/2,), (5/2, 3), -9/4)

You see, there is no error. But now if put the expression inside string and use SR, it gives error:


sage: SR('hypergeometric((3/2,), (5/2, 3), -1/4*3^2)')
---------------------------------------------------------------------------
SyntaxError                               Traceback (most recent call last)
File ~/TMP/sage-9.8/src/sage/symbolic/expression.pyx:13706, in sage.symbolic.expression.new_Expression()
  13705     from sage.calculus.calculus import symbolic_expression_from_string
> 13706     return parent(symbolic_expression_from_string(x))
  13707 except SyntaxError as err:

File ~/TMP/sage-9.8/src/sage/calculus/calculus.py:2578, in symbolic_expression_from_string(s, syms, accept_sequence, parser)
   2576 parser._callable_constructor().set_names({k[0]: v for k, v in syms.items()
   2577                                           if _is_function(v)})
-> 2578 return parse_func(s)

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:556, in sage.misc.parser.Parser.parse_expression()
    555
--> 556     cpdef parse_expression(self, s):
    557         """

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:568, in sage.misc.parser.Parser.parse_expression()
    567 cdef Tokenizer tokens = Tokenizer(s)
--> 568 expr = self.p_expr(tokens)
    569 if tokens.next() != EOS:

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:792, in sage.misc.parser.Parser.p_expr()
    791 cdef int op
--> 792 operand1 = self.p_term(tokens)
    793 op = tokens.next()

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:826, in sage.misc.parser.Parser.p_term()
    825 cdef int op
--> 826 operand1 = self.p_factor(tokens)
    827 op = tokens.next()

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:869, in sage.misc.parser.Parser.p_factor()
    868 tokens.backtrack()
--> 869 return self.p_power(tokens)
    870

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:897, in sage.misc.parser.Parser.p_power()
    896 """
--> 897 operand1 = self.p_atom(tokens)
    898 cdef int token = tokens.next()

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:952, in sage.misc.parser.Parser.p_atom()
    951 func = self.callable_constructor(name)
--> 952 args, kwds = self.p_args(tokens)
    953 token = tokens.next()

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:989, in sage.misc.parser.Parser.p_args()
    988 while token == c',':
--> 989     arg = self.p_arg(tokens)
    990     if isinstance(arg, tuple):

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:1039, in sage.misc.parser.Parser.p_arg()
   1038 tokens.backtrack()
-> 1039 return self.p_expr(tokens)
   1040

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:792, in sage.misc.parser.Parser.p_expr()
    791 cdef int op
--> 792 operand1 = self.p_term(tokens)
    793 op = tokens.next()

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:826, in sage.misc.parser.Parser.p_term()
    825 cdef int op
--> 826 operand1 = self.p_factor(tokens)
    827 op = tokens.next()

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:869, in sage.misc.parser.Parser.p_factor()
    868 tokens.backtrack()
--> 869 return self.p_power(tokens)
    870

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:897, in sage.misc.parser.Parser.p_power()
    896 """
--> 897 operand1 = self.p_atom(tokens)
    898 cdef int token = tokens.next()

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:964, in sage.misc.parser.Parser.p_atom()
    963 if token != c')':
--> 964     self.parse_error(tokens, "Mismatched parentheses")
    965 return expr

File ~/TMP/sage-9.8/src/sage/misc/parser.pyx:1042, in sage.misc.parser.Parser.parse_error()
   1041 cdef parse_error(self, Tokenizer tokens, msg="Malformed expression"):
-> 1042     raise SyntaxError(msg, tokens.s, tokens.pos)
   1043

SyntaxError: Mismatched parentheses

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
Cell In [19], line 1
----> 1 SR('hypergeometric((3/2,), (5/2, 3), -1/4*3^2)')

File ~/TMP/sage-9.8/src/sage/structure/parent.pyx:896, in sage.structure.parent.Parent.__call__()
    894 if mor is not None:
    895     if no_extra_args:
--> 896         return mor._call_(x)
    897     else:
    898         return mor._call_with_args(x, args, kwds)

File ~/TMP/sage-9.8/src/sage/structure/coerce_maps.pyx:161, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_()
    159             print(type(C), C)
    160             print(type(C._element_constructor), C._element_constructor)
--> 161         raise
    162
    163 cpdef Element _call_with_args(self, x, args=(), kwds={}):

File ~/TMP/sage-9.8/src/sage/structure/coerce_maps.pyx:156, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_()
    154 cdef Parent C = self._codomain
    155 try:
--> 156     return C._element_constructor(x)
    157 except Exception:
    158     if print_warnings:

File ~/TMP/sage-9.8/src/sage/symbolic/ring.pyx:384, in sage.symbolic.ring.SymbolicRing._element_constructor_()
    382         TypeError: Malformed expression: λ + * !!!  1
    383     """
--> 384     return new_Expression(self, x)
    385
    386 def _force_pyobject(self, x, bint force=False, bint recursive=True):

File ~/TMP/sage-9.8/src/sage/symbolic/expression.pyx:13709, in sage.symbolic.expression.new_Expression()
  13707     except SyntaxError as err:
  13708         msg, s, pos = err.args
> 13709         raise TypeError("%s: %s !!! %s" % (msg, s[:pos], s[pos:]))
  13710
  13711 from sage.rings.infinity import (infinity, minus_infinity,

TypeError: Mismatched parentheses: hypergeometric((3/2, !!! ), (5/2, 3), -1/4*3^2)
sage: 



Is this a bug or Am I doing something wrong? This happens on very few cases, not all the time. The above is an example where SR gives an error.

Thanks
--Nasser

Nils Bruin

unread,
Apr 26, 2023, 2:33:26 AM4/26/23
to sage-devel
I think the problem is that the SR exression parses does not know about python's "(a,b)" tuple notation. If you replace the round brackets with square brackets, it does seem to work; at least for the example you give:

sage: SR('hypergeometric([3/2,], [5/2, 3], -1/4*3^2)')
 hypergeometric((3/2,), (5/2, 3), -1/4*3^2)

You could use the python parser instead, via something like:

 SR(sage_eval(' hypergeometric((3/2,), (5/2, 3), -1/4*3^2)'))

but note that SR will happily define symbols it doesn't know, whereas sage_eval will complain:

sage: SR("my_function(var1,var2)")
my_function(var1, var2)
sage: SR(sage_eval("my_function(var1,var2)"))
NameError: name 'my_function' is not defined

Nasser M. Abbasi

unread,
Apr 26, 2023, 3:05:03 AM4/26/23
to sage-devel
I can't use  SR(sage_eval(' expression'))  Now all my integral are failing. 
Here is an example

>sage
│ SageMath version 9.8, Release Date: 2023-02-11                     │
│ Using Python 3.11.1. Type "help()" for help.                       │

sage: var('x')
x

sage: SR(sage_eval('sin(x)'))
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [3], line 1
----> 1 SR(sage_eval('sin(x)'))

File ~/TMP/sage-9.8/src/sage/misc/sage_eval.py:198, in sage_eval(source, locals, cmds, preparse)
    196     return locals['_sage_eval_returnval_']
    197 else:
--> 198     return eval(source, sage.all.__dict__, locals)

File <string>:1

NameError: name 'x' is not defined


But 

sage: SR('sin(x)')
sin(x)

Works. 

So adding  sage_eval() did not work.

--Nasser

dimpase

unread,
Apr 26, 2023, 5:27:19 AM4/26/23
to 'Nasser M. Abbasi' via sage-devel
On Tue, Apr 25, 2023 at 11:08:02PM -0700, 'Nasser M. Abbasi' via sage-devel wrote:
> I read integrals from a file. They all are stored as strings.
>
> Then use SR('expression') inside sagemath to convert them to sagemath
> symbolic expression before calling integrate.
>
> Some give parsing error.
>
> Is using SR('expression') not the correct way to convert string to a
> symbolic expression?
>
> I am using 9.8 on Linux. Here is an example
>
> >sage
> │ SageMath version 9.8, Release Date: 2023-02-11 │
> │ Using Python 3.11.1. Type "help()" for help. │
>
> sage: hypergeometric((3/2,), (5/2, 3), -1/4*3^2)
> hypergeometric((3/2,), (5/2, 3), -9/4)
>
> You see, there is no error. But now if put the expression inside string and
> use SR, it gives error:

IMHO Sage gives no promise that the way an SR expression printed is
always readable back as a string.
Note that

SR('hypergeometric([3/2,], [5/2, 3], -1/4*3^2)')

works just fine.


>
>
> sage: SR('hypergeometric((3/2,), (5/2, 3), -1/4*3^2)')
> ---------------------------------------------------------------------------
> SyntaxError Traceback (most recent call last)
> File ~/TMP/sage-9.8/src/sage/symbolic/expression.pyx:13706, in
> [...]
> SyntaxError: Mismatched parentheses
>
> During handling of the above exception, another exception occurred:
>
> [...]
>
>
>
> Is this a bug or Am I doing something wrong? This happens on very few
> cases, not all the time. The above is an example where SR gives an error.

What are other examples which give errors like this?

Perhaps hypergeomertic() should come with a special __repr__() function
to show the 1st two arguments as lists rather than in its internal
representation as tuples. (Or should it be _repr_() ? )


Dima


>
> Thanks
> --Nasser
>
> --
> You received this message because you are subscribed to the Google Groups "sage-devel" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/sage-devel/eeec7521-c567-4870-8442-e3eed439b32dn%40googlegroups.com.

signature.asc

Dima Pasechnik

unread,
Apr 26, 2023, 11:53:10 AM4/26/23
to 'Nasser M. Abbasi' via sage-devel
I have opened https://github.com/sagemath/sage/issues/35572 to deal with this

John H Palmieri

unread,
Apr 26, 2023, 12:35:11 PM4/26/23
to sage-devel
While

    sage_eval('sin(x)')

does not work,

    sage_eval('sin(x)', {'x': x})

does work. sage_eval needs to know the context (which variables have been defined, etc.) in which to evaluate. I am not an expert, but

    sage_eval('sin(x)', locals=locals())

might work pretty reliably, without having to specify each previously defined variable by hand.


-- John

William Stein

unread,
Apr 26, 2023, 12:49:01 PM4/26/23
to sage-...@googlegroups.com
I put a few remarks related to this in a notebook:

https://cocalc.com/wstein/support/SR-and-strings

Basically, converting to from strings via str hardly works anywhere in
Sage and that is by design, following the lead of Magma instead of
Pari. Instead Pickle is the thing that mostly works for that mapping,
but is ugly. Then lament no json...

William
Reply all
Reply to author
Forward
Message has been deleted
0 new messages