import java.util.Map ;
import java.util.HashMap ;


public class AusdruckTest 
{

    public static int fib( int n ) 
    {
	if ( n < 2 ) 
	    return 1 ;
	else 
	    return fib(n-1) + fib(n-2) ; 
    }

    public static int qsum( int n ) 
    {
	int summe = 0 ; 
	for ( int i = 1 ; i <= n ; i++ ) 
	    summe += i*i ; 
	return summe ; 
    }

    public static void main( String[] args ) 
    {

        int n = Integer.parseInt( args[0] ) ;  

	// Erster Test: 
	Ausdruck fib0 = new Variable( "x" ) ;
	Ausdruck fib1 = new Variable( "y" ) ;
	Ausdruck fib2 = new Plus( fib0 , fib1 ) ;  
	for ( int i = 2 ; i < n ; i++ ) 
	    {
		fib0 = fib1 ;
		fib1 = fib2 ; 
		fib2 = new Plus( fib0 , fib1 ) ;
	    }
	Map bind = new HashMap() ; 
	bind.put( "x" , new Integer( 1 ) ) ;
	bind.put( "y" , new Integer( 1 ) ) ;
	System.out.println("Wert: " +  fib2.wert( bind ) ) ;
	System.out.println("Fibonacci("+n+") = " + fib(n) ) ; 
	System.out.println("Variablen: " + fib2.variablen() ) ;

	//Zweiter Test: 
	bind.clear() ; 
	Ausdruck summe = new Mal( new Konstante( 1 ) , new Variable( "x1" ) ) ; 
	Ausdruck summand = null ; 
	bind.put( "x1" , new Integer( 1 ) ) ; 
 	for ( int i = 2 ; i <= n ; i++ ) 
	    {
		String xi = "x" + i ; 
		summand = new Mal( new Konstante( i ) , new Variable ( xi ) ) ; 
		summe = new Plus( summe , summand ) ; 
		bind.put( xi , new Integer( i ) ) ;  
	    }
	System.out.println("Wert: " +  summe.wert( bind ) ) ;
	System.out.println("Quadratsumme("+n+") = " + qsum(n) ) ; 
	System.out.println("Variablen: " + summe.variablen() ) ;

	//Dritter Test: 
	Ausdruck test = new Plus( new Variable( "x" ) , new Konstante( 5 ) ) ;
	try 
	    {
		test.wert( bind ) ; 
		throw new RuntimeException( "Hier sollte eine eigene Ausnahme ausgeloest werden." ) ;
	    }
	catch ( VariableUndefiniertAusnahme ausnahme ) 
	    {
		System.out.println("OK.") ;
	    }
    }
 
} 
