gap-packages / SingularInterface

A GAP package for accessing Singular from within GAP
https://gap-packages.github.io/SingularInterface/
Other
6 stars 3 forks source link

Proc returning a variable causes weird error #48

Open fingolfin opened 10 years ago

fingolfin commented 10 years ago

The following is unexpected:

gap> LoadPackage( "SingularInterface", false );;
gap> Singular("int x=42;");
true
gap> SingularValueOfVar("x");
42
gap> Singular("proc HACK(){return(x);}");
true
gap> SI_CallProc("HACK", []);
Error, IsCopyableObjSingular: unsupported singtype 1
not in any function at line 5 of *stdin*

A singtype of 1 should never occur. Huh?

This might also be related to the crash in #47

fingolfin commented 10 years ago

Uhh, note this:

gap> Singular("HACK();");
...parse error
error occurred in or before STDIN line 1: `return(foo);`
leaving STDIN
false

Something is fishy?!

fingolfin commented 10 years ago

Even more concise:

gap> LoadPackage( "SingularInterface", false );;
gap> Singular("int foo=42;proc HACK(){return(foo);};HACK();");
...parse error
error occurred in or before STDIN line 1: `return(foo);`
leaving STDIN
false

The exact same command line works in the Singular interpreter:

                     SINGULAR                                 /  Development
 A Computer Algebra System for Polynomial Computations       /   version 4.0.1
                                                           0<
 by: W. Decker, G.-M. Greuel, G. Pfister, H. Schoenemann     \   Sep 2014
FB Mathematik der Universitaet, D-67653 Kaiserslautern        \
> int foo=42;proc HACK(){return(foo);};HACK();
42
>

So clearly we are doing something very wrong here.

This particular issue goes away if I remove the line myynest = 1; from Func_SI_EVALUATE in src/calls.cc. However, then other things fail. Anyway, I never understood that line anyway... we need to revise it, and this time, make sure whatever replace it, gets documented at the same time :).

hannes14 commented 10 years ago

myynest is the nesting level of the Singular interpreter and is mainly important for the definition of variables. Variables which are defined at myynest==0 are global (i.e. visible at any level), other are only visible in the same level. If the level was entered like a procedure (via iiMakeproc/iipStart/iiAllStart) all variable of the current level will be removed when leaving that level.

fingolfin commented 10 years ago

Some more notes on consequences of removing the myynest = 1; (causing myynest to be 0):

fingolfin commented 10 years ago

@hannes14 Thanks for your explanation, much appreciated! That fits with what I "discovered" via trial and error. Any idea why then, in the current code in the repo (where myynest ist set to 1), this code fails:

Singular("int foo=42;proc HACK(){return(foo);};HACK();");

Naively, it sets the variable foo on level 1, then defines a function on the same level, and calls it. Why doesn't that work?

hannes14 commented 10 years ago

because foo is defined at level 1, and the statement "return(foo)" searches for the variable foo at level 2 (each procedure call increases myynest at its start and decreases it at the end)

fingolfin commented 10 years ago

Ah, and at level 1, the variable is not global, I see. Thus this works:

Singular("int foo=42;export foo;proc HACK(){return(foo);};HACK();");

Thanks, Hans!