sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.45k stars 482 forks source link

fix Macaulay2 output when reading input from a file #25903

Closed eulerreich closed 4 years ago

eulerreich commented 6 years ago

This ticket solves the discrepancy between evaluating Macaulay2 input using a file vs directly as follows:

It is solved by using the Macaulay2 function input instead of load to read in files. With input, the results are echoed as desired. However, input also echoes the input lines. These echoed input lines need to be stripped from the output – this is accomplished by setting a custom input prompt while reading from a file. The input lines are then stripped in _post_process_from_file.


If I run

macaulay2.eval(';'.join([
'R = ZZ/101[x000, x001, x010, x011, x100, x101, x110, x111, DegreeRank=>8]', 
'idl77 = module ideal(x000*x010*x100*x110, x000*x010*x101*x111, x000*x011*x100*x111, x000*x011*x101*x111, x001*x010*x101*x110, x001*x010*x101*x111, x001*x011*x100*x110, x001*x011*x100*x111, x001*x011*x101*x110, x001*x011*x101*x111)', 
'res77 = res idl77']))

I get back the correct answer in sage.

 10      16      8      1
R   <-- R   <-- R  <-- R  <-- 0

0       1       2      3      4

ChainComplex

However if I try a larger ring and ideal,

macaulay2.eval(';'.join([
'R = ZZ/101[x0000, x0001, x0010, x0011, x0100, x0101, x0110, x0111, x1000, x1001, x1010, x1011, x1100, x1101, x1110, x1111, DegreeRank=>16]',
'idl111 = module ideal(x0000*x0010*x0100*x0110*x1000*x1010*x1100*x1110, x0000*x0010*x0100*x0110*x1001*x1011*x1101*x1111, x0000*x0010*x0101*x0111*x1000*x1010*x1101*x1111, x0000*x0010*x0101*x0111*x1001*x1011*x1101*x1111, x0000*x0011*x0100*x0111*x1000*x1011*x1100*x1111, x0000*x0011*x0100*x0111*x1001*x1011*x1101*x1111, x0000*x0011*x0101*x0111*x1000*x1011*x1101*x1111, x0000*x0011*x0101*x0111*x1001*x1011*x1101*x1111, x0001*x0010*x0101*x0110*x1001*x1010*x1101*x1110, x0001*x0010*x0101*x0110*x1001*x1011*x1101*x1111, x0001*x0010*x0101*x0111*x1001*x1010*x1101*x1111, x0001*x0010*x0101*x0111*x1001*x1011*x1101*x1111, x0001*x0011*x0100*x0110*x1001*x1011*x1100*x1110, x0001*x0011*x0100*x0110*x1001*x1011*x1101*x1111, x0001*x0011*x0100*x0111*x1001*x1011*x1100*x1111, x0001*x0011*x0100*x0111*x1001*x1011*x1101*x1111, x0001*x0011*x0101*x0110*x1001*x1011*x1101*x1110, x0001*x0011*x0101*x0110*x1001*x1011*x1101*x1111, x0001*x0011*x0101*x0111*x1000*x1010*x1100*x1110, x0001*x0011*x0101*x0111*x1000*x1010*x1101*x1111, x0001*x0011*x0101*x0111*x1000*x1011*x1100*x1111, x0001*x0011*x0101*x0111*x1000*x1011*x1101*x1111, x0001*x0011*x0101*x0111*x1001*x1010*x1101*x1110, x0001*x0011*x0101*x0111*x1001*x1010*x1101*x1111, x0001*x0011*x0101*x0111*x1001*x1011*x1100*x1110, x0001*x0011*x0101*x0111*x1001*x1011*x1100*x1111, x0001*x0011*x0101*x0111*x1001*x1011*x1101*x1110, x0001*x0011*x0101*x0111*x1001*x1011*x1101*x1111)',
'res111 = res idl111'
]
))

then I get back an empty string. However, if I rerun

macaulay2.eval('res111 = res idl111')

in the second case I'll get back the right answer.

I checked that both commands give the correct answers inside macaulay2, so it must be a bug in the bridge.

CC: @mwageringel @slel @dimpase @saliola @antonleykin

Component: interfaces: optional

Keywords: Macaulay2, interface, IMA Coding Sprint

Author: Markus Wageringel

Branch/Commit: 496ea55

Reviewer: Dima Pasechnik

Issue created by migration from https://trac.sagemath.org/ticket/25903

slel commented 6 years ago

Changed keywords from none to Macaulay2, interface

slel commented 6 years ago
comment:1

See also:

mwageringel commented 6 years ago
comment:2

This happens when the input string sent to eval is longer than 500 characters, as the Macaulay2-Expect interface is configured with the option eval_using_file_cutoff=500. This option determines whether the input is pasted into the Macaulay2 REPL directly for short input, or whether it is first written to a file and then loaded into Macaulay2. Loading the file is implemented using the load command, which exectues the code, but does not echo the output values in Macaulay2, so this results in an empty string returned by eval.

I tried to replace the load command by the input command which does echo the output values – however, it also echoes the input on additional input lines. This makes it rather difficult to handle using the Expect interface as parsing the output stops once it reaches the first input prompt. I could not figure out how to solve this.

The only way to fix this I can think of would be to add a function to Macaulay2 that just echoes the output of a file.

As a workaround, you can call macaulay2("res111") or call print at the end of your Macaulay2 code like print res idl111.

mwageringel commented 5 years ago

Branch: u/gh-mwageringel/25903

mwageringel commented 5 years ago

Changed keywords from Macaulay2, interface to Macaulay2, interface, IMA Coding Sprint

mwageringel commented 5 years ago

Commit: 496ea55

mwageringel commented 5 years ago

Author: Markus Wageringel

mwageringel commented 5 years ago
comment:3

Here is a branch solving this by using the Macaulay2 function input instead of load to read in files. With input, the results are echoed as desired. However, input also echoes the input lines. These echoed input lines need to be stripped from the output – this is accomplished by setting a custom input prompt while reading from a file. The input lines are then stripped in _post_process_from_file.

Note that this is only necessary because the Macaulay2 interface in Sage overwrites the prompts, in the first place. In a usual Macaulay2 session, echoed input lines start with ii rather than a single i:

i1 : input "testfile.m2"

ii2 : a = 7

oo2 = 7

ii3 :

i4 :

However, in the current interface, the prompt is overwritten to _EGAS_ in either case, so it confuses echoed input lines and actual input lines. With this branch, the echoed input lines start with _EGAS_LOAD_ and get stripped.


New commits:

496ea5525903: make macaulay2 echo output when evaluating using file
dimpase commented 4 years ago
comment:5

looks good. Sorry for sitting on it for such a long time.

dimpase commented 4 years ago

Reviewer: Dima Pasechnik

mwageringel commented 4 years ago

Description changed:

--- 
+++ 
@@ -1,3 +1,9 @@
+This ticket solves the discrepancy between evaluating Macaulay2 input using a file vs directly as follows:
+
+It is solved by using the Macaulay2 function `input` instead of `load` to read in files. With `input`, the results are echoed as desired. However, `input` also echoes the input lines. These echoed input lines need to be stripped from the output – this is accomplished by setting a custom input prompt while reading from a file. The input lines are then stripped in `_post_process_from_file`.
+
+---
+
 If I run 

 ```python
mwageringel commented 4 years ago
comment:6

No problem. Thank you.

vbraun commented 4 years ago

Changed branch from u/gh-mwageringel/25903 to 496ea55