1 | initial version |

It looks like the singular workspace gets clobbered. Peeling apart what happens (where the error occurs) indicates this:

```
sage: R1 = singular.ring('(0,a)','(x,y)','dp')
sage: f1 = singular('x^2')
sage: g1 = singular('x')
sage: fsage = f1.sage()
sage: gsage = g1.sage()
sage: f1.parent().eval("type(%s)"%f1.name())
'// sage8 poly x2'
sage: f1.parent().eval("type(%s)"%g1.name())
'// sage9 poly x'
sage: g2 = fsage.reduce(gsage)
sage: f1.parent().eval("type(%s)"%g1.name())
'// sage9 $INVALID$ `sage9`'
sage: f1.parent().eval("type(%s)"%f1.name())
'// sage8 $INVALID$ `sage8`'
```

My guess is that singular has global state: it has the concept of a current ring. A routine like "reduce" which calls singular has to set the current ring. It probably doesn't restore the previous current ring when it's done. Probably "reduce" should use libsingular.

A reasonable workaround is to define your own singular interface instance, which can keep its global state without getting clobbered by sage's interactions with its "own" singular interface instance:

```
sage: sng = Singular()
sage: R1 = sng.ring('(0,a)','(x,y)','dp')
sage: f1 = sng('x^2')
sage: g1 = sng('x')
sage: f1,g1
(x^2, x)
sage: g2 = fsage.reduce(gsage)
sage: f1,g1,g2
(x^2, x, 0)
```

Respecting that sage needs its own singular instance where it's free to clobber global state and defining your own if you need persistent singular global state is programmatically much cleaner, easier and efficient than trying to get sage to preserve/restore global state.

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.