Accessing Reduce through some API

Help
Friedrich
2010-07-07
2012-11-20
  • Friedrich

    Friedrich - 2010-07-07

    Hello,
    I would like to use Reduce as a "subprogram" in my Java software.
    I already asked a similar question in "Using Reduce from other software". The solution there was to basically store all commands that redlog should execute in a file, call reduce.com -w with this file and read the output

    try {
                // Execute a command 
                String command = reduceCommand + " " + filename + " " + NOGUI;
                Process child = Runtime.getRuntime().exec(command);
                // Get the input stream and read from it
                InputStream in = child.getInputStream();
                reduceResult = convertStreamToString(in);
                in.close(); 
            } catch (Exception e) { 
                System.out.println(e);
            }
    

    This works fine for now but it seems that I will have use Reduce more often than I thought (e.g. for simplifying arithmetic expressions that involve parameters) and that would generate A LOT of files and slow down the whole application.

    The new question is now:
    is there an easy way to access reduce directly from my java code and pass the commands without the "file dump" detour?

    Thanks a lot for your support.

    Btw: I found http://www.springerlink.com/content/76417q416qv21444/ which is quite an old article and describes only the idea of integrating Java in reduce - is there something more recent on the internet?

     
  • Thomas Sturm

    Thomas Sturm - 2010-07-07

    You might consider my libreduce included in the source tree. It provides a comfortable api for C. I have used it with perls as well. I do not know how complicated it is to access a C library from Java. If you want to give it a try, I will be happy to support you.

    Recently, somehow has been working on Java/Reduce again on the basis of the article that you have cited. I will forward your request to them too.

    Thomas

     
  • Heinz Kredel

    Heinz Kredel - 2010-07-08

    The authors of the mentioned paper, namely Arthur Norman, has a Java implementation of Reduce 3.7 (as I remember). I have setup a Java scripting compatible interface (see JSR 223) which I can send you. However, the Reduce in Java implementation is not public available, you can request it directly from Arthur Norman. With the scripting interface you can write your code like this:

            ScriptEngine reduce = new ScriptEngineManager().getEngineByExtension("red");
            System.out.println("Reduce service discovered: " + reduce);
        if ( reduce == null ) {
                ScriptEngineManager scriptManager = new ScriptEngineManager();
                scriptManager.registerEngineExtension("red", new ReduceScriptEngineFactory());
            reduce = scriptManager.getEngineByExtension("red");
        }
        if ( reduce == null ) {
            System.out.println("No Reduce engine found");
            return;
        }
            System.out.println("Using Reduce engine: " + reduce);
            try {
                long millis = System.currentTimeMillis();
            String ex = "int(1/(x^2-2),x);";
                System.out.println("ex: " + ex);
                Object ans = reduce.eval(ex);
                millis = System.currentTimeMillis() - millis;
                System.out.println("answer: " + ans);
                System.out.println("evaluation took " + millis);
                millis = System.currentTimeMillis();
            ex = "(x^2-2)^10;";
                System.out.println("ex: " + ex);
                ans = reduce.eval(ex);
                millis = System.currentTimeMillis() - millis;
                System.out.println("answer: " + ans);
                System.out.println("evaluation took " + millis);
            } catch (ScriptException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
     
  • Friedrich

    Friedrich - 2010-07-08

    Mr Sturm,
    thanks a lot for your hint. I might use a library written in C directly from Java using e.g. SWIG. In the source package I found generic/libreduce. Is there a tutorial available in case I want to have a closer look and play around?

    Mr Kredel,
    your suggestion sounds like the optimal solution to me. I will contact Arthur Norman and see if I can get the software. I am not familiar with JSR but from your example it looks like it is easy to use.
    Thank you very much!

     
  • Thomas Sturm

    Thomas Sturm - 2010-07-08

    For libreduce, say "make" in trunk/generic/libreduce. This should work fine on Linux and Mac. For Windows I might have to do something, viz. adding support for pipes instead of sockets. I think I could do this quite quickly if you really need it since the necessary code is literally present in redfront.

    There is trunk/generic/libreduce/src/examples/lrtest.c, which is supposed to explain everything. It is also compiled when you go "make" as described above.

    Thomas

     
  • Friedrich

    Friedrich - 2010-07-22

    Hello,
    sorry for repling so late…

    Anyway now I managed to try out the Java version of reduce throuh Heinz Kredel's script interface. E.g. the code posted above by Kredel gives this result:

    Reduce service discovered: null
    Using Reduce engine: ReduceScriptEngine(Reduce, 3.7)
    ex: int(1/(x^2-2),x);
    answer: REDUCE 3.7, 15-Jan-99 …
    restart mode in read eval print loop null null null

    1:
    sqrt(2)*(log( - sqrt(2) + x) - log(sqrt(2) + x))


                            4

    Within: begin

    evaluation took 967
    ex: (x^2-2)^10;
    answer: REDUCE 3.7, 15-Jan-99 …
    restart mode in read eval print loop null null null

    1:
    20       18        16        14         12         10          8          6
    x   - 20*x   + 180*x   - 960*x   + 3360*x   - 8064*x   + 13440*x  - 15360*x

              4         2
    + 11520*x  - 5120*x  + 1024

    Within: begin

    evaluation took 721

    I am happy that I can access reduce's functionality from my Java code, yet I have another question:

    Is it somehow possible to

    a) keep reduce alive between two

    reduce.eval(ex)
    

    calls? Currently it seems that reduce is restarted for each call, since you see

    REDUCE 3.7, 15-Jan-99 …
    restart mode in read eval print loop null null null

    at the beginning of each answer and that takes a considerable amount of time.

    b) in order to extract the actual result one has to strip away the header mentioned above as well as some other strings before and after the result. It would be nice if we can get only the result from reduce directly to our answer variable without any clutter.

    I suspect, that these issues cannot be solved when using the scripting interface but MAYBE I overlooked something and my problems can be solved easily?

    Thank you

     
  • Thomas Sturm

    Thomas Sturm - 2010-07-22

    Once you have resolved the problem of keeping Reduce alive between several calls, it might be an option to reuse parts of the libreduce approach.

    There is a Reduce package that you can load via "load_package libreduce;" at the beginning. This makes Reduce output machine-friendly rather than human-friendly. It inserts certain non-char bytes e.g. at positions where prompts start and end etc. The code for parsing this output is in the functions RedAns_readUntilPrompt and RedAns_dfa of trunk/generic/libreduce/src/RedAns.c.

    Thomas

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks