vermaseren / form

The FORM project for symbolic manipulation of very big expressions
GNU General Public License v3.0
982 stars 118 forks source link

Unintuitive order of variables when loading from save file #465

Open ahamaline opened 5 months ago

ahamaline commented 5 months ago

The ability to control the order of variables is very useful, so I want to point out a case where FORM's behavior is counterintuitive in this regard: when loading expressions from .sav files, the variables in those expressions are declared implicitly. However, their order may not be the same as it was in the original workspace. This is because some of the saved expressions may depend on different subsets of the variables, so the implicit variable declarations do not occur all at once.

After some experimentation, I found that the declarations occur the first time that each saved expression is used in defining an active expression. At that point, the variables appearing in that expression are declared - in their order taken from the original workspace, which may not be the order of appearance in the saved expression.

Example: if the original file reads

v p1,p2,p3;
G ex1=p3*p2.p2;
G ex2=p2*p1.p1;
.store
save savefile.sav ex1,ex2;
.end

and the second file reads

On names;
load savefile.sav;
L sum=ex1+ex2;
.end

then the output is

Vectors
   p2 p3 p1
 Expressions
   ex1(stored) ex2(stored) sum(local)

Note that p2 is before p3 since they both appear in ex1, even though they appear in the opposite order (since single vectors come before dotproducts). If on the other hand we change the order of the sum to read L sum=ex2+ex2; then the order of the vectors becomes p1 p2 p3.

This cost me quite a few hours of fruitless debugging, since I had been implicitly assuming that saving and loading would not affect the form of an expression. In my case the resulting issue was that Mathematica's Dot product is not commutative, so that terms from before and after the save could not be treated as equal by Mathematica.

In retrospect it was not reasonable of me to expect that the order should never be changed, since .sav files can come from several different workspaces with different variable orderings. Still, the actual behavior seems more counterintuitive than necessary. Perhaps a better option might be that all the variables appearing in a .sav file should be declared when the file is loaded, in their original order? That would seem more natural, though it would would not have helped in my case.

A 'fancier' solution, that would have helped me, would be if the variable orderings from different .sav files and expressions would be merged to a consistent ordering whenever possible. For instance, in the example above we would get the two orderings p2 p3 and p1 p2, allowing us to reconstruct the original order p1 p2 p3. When this is impossible we would give preference to the order of loading. If such a solution was implemented, then the form of a saved expression would not be changed upon loading as long as all .sav files that appear come from similar enough workspaces.

Regardless, whatever protocol is implemented should appear in the documentation.

jodavies commented 5 months ago

The "easy workaround" is to simply repeat your definitions before you load anything. Typically I have common declare file which I #include at the start of form scripts relating to a particular project.

ahamaline commented 5 months ago

Sure, maybe it's enough to just add a warning to the manual saying that if you care about variable ordering you should do that.