/*******************************************************************************
    A Simple Lambda Calculus Interpreter
    Version 1.00
    Copyright (C) 1996-1997 Colin J. Taylor
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    Main applet class

******************************************************************************/
// Alexandr Korlyukov
//          korlyukov@grsu.grodno.by

/**  Calculation of logic functions in Lambda-calculation.
  *
  *  strStart(param[nVar])
  *  strStart - is fixed for the supercompiler
  *  param[nVar] - Logic variable, is not fixed for the supercompiler
  *
  *  It is necessary to set: strStart, nVar
  *
  *  The task for the supercompiler
  *  set A=-s %lambda%\Src  Abstraction Application Binding Closure Environment Expression Lexer Numbers Operator Parser Primitive PrintVar Suspension Symbol Token Variable
  *  call jScp -m test -ul3 -i -r3000 -v0 %* Lambda -e A >L.js
  */
public class Lambda {

// Example 1     x & (y | z)
//    public static final String strStart = "\\x. \\y. \\z. and x (or y z)";
//    public static final int nVar = 3;

// Example 2     x | (y & z)
//    public static final String strStart = "\\x. \\y. \\z. or x (and y z)";
//    public static final int nVar = 3;

// Example 3     Implication 
//    public static final String strStart = "\\x. \\y. impl x y";
//    public static final int nVar = 2;

// Example 4     Identically true function 
//    public static final String strStart = "\\x. \\y. impl x (impl y x)";
//    public static final int nVar = 2;

// Example 5     Implication (3 variable)
//    public static final String strStart = "\\x. \\y. \\z. impl x y";
//    public static final int nVar = 3;

// Example 6     Identically true function 
//    public static final String strStart = "\\x. \\y. \\z. impl x (impl y x)";
//    public static final int nVar = 3;

// Example 7     Other identically true function 
//    public static final String strStart = "\\x. \\y. \\z. impl (impl x (impl y z)) (impl (impl x y) (impl x z))";
//    public static final int nVar = 3;

// Example 8     Implication (4 variable)
//    public static final String strStart = "\\x. \\y. \\z. \\u. impl x y";
//    public static final int nVar = 4;

// Example 9     True only in two cases 
//    public static final String strStart = "\\x. \\y. \\z. or (and x (and y z)) (and (not x) (and (not y) (not z)))";
//    public static final int nVar = 3;

// Example 10    (x & y) | (z & u) 
//    public static final String strStart = "\\x. \\y. \\z. \\u. or (and x y ) (and z u)";
//    public static final int nVar = 4;

// Example 11    (x | not x) & (y | not y) & z = true & true & z = z
//    public static final String strStart = "\\x. \\y. \\z. and (and (or x (not x)) (or y (not y))) z";
//    public static final int nVar = 3;

// Example 12    Max True - (x & y) | (y & z) | (x & z)   
//    public static final String strStart = "\\x. \\y. \\z. or (and x y)  (or (and y z) (and x z))";
//    public static final int nVar = 3;

// Example 13    Mostik   
//    public static final String strStart = "\\x. \\y. \\z. \\u. \\v. or (or (and x y) (and z u)) (or (and x (and v u)) (and z (and v y)))";
//    public static final int nVar = 5;

// Example 14    Equality 
//    public static final String strStart = "\\x. \\y. and (impl x y) (impl y x)";
//    public static final int nVar = 2;

// Example 15    True only in two cases
//    public static final String strStart = "\\x. \\y. \\z. \\u. x (y (z (u true false) (false)) (false)) (y (false) (z (false) (u false true)))";
//    public static final int nVar = 4;

// Example 16    True only in ... cases
//    public static final String strStart = "\\x. \\y. \\z. \\u. x (y (z (u true false) (false)) (false)) (y (false) (z (true) (u false true)))";
//    public static final int nVar = 4;

// Example 17    x y z
//    public static final String strStart = "\\x. \\y. \\z. x y z";
//    public static final int nVar = 3;

// Example 18    x y z u v
    public static final String strStart = "\\x. \\y. \\z. \\u. \\v. x y z u v";
    public static final int nVar = 5;
    
    public static final String[] instruction = {
        "let true  = \\x. \\y. x",
        "let false = \\x. \\y. y",
        "let impl  = \\x. \\y. x y true",
        "let not   = \\x. x false true",
        "let or    = \\x. \\y. impl (not x) y",
        "let and   = \\x. \\y. not (or (not x) (not y))"
    };


    public static void main(String args[]) throws Exception{
        boolean[] param = new boolean[nVar];
        for (int i=0; i<nVar; i++) {
            param[i] = true;
        }
    
        long start1 = System.currentTimeMillis();

        boolean bbb = test(param);
        System.out.println(bbb);

        long start2 = System.currentTimeMillis();
        System.out.println("");
        System.out.println("Time1 = " + (start2-start1));
    }


    public static boolean test(boolean[] param) {
        Parser p = new Parser();
        Environment topLevel = new Environment();
        Expression expr = null;
        Expression result = null;

        for (int i=0; i<instruction.length; i++) {
            Lexer lex = new Lexer(instruction[i]);
            lex.init();
            expr = p.parse(lex);
            expr.evaluate(topLevel);
        }

        String strLexer = "";
        for (int i=0; i<nVar; i++) {
            if(param[i]) strLexer = strLexer + " true";
                else     strLexer = strLexer + " false";
        }

        Lexer lex = new Lexer("(" + strStart + ")" + strLexer + " 1 0");
        lex.init();
        expr = p.parse(lex);
        result = expr.evaluate(topLevel);

       Expression b_44 = result.evaluate((Environment)null);

       if(((Numbers)b_44).value == 1) return true;
       else return false;
    }


    // Some handy methods for outputting text 
    public static void emit(String str)
    {
        System.out.print(str);
    }

    public static void emitnewln()
    {
        System.out.println("\n" );
    }

    public static void emitln(String str)
    {
        System.out.println("> " + str + "\n");
    }
}