public class lec09_v2 extends schemecompat {

    /* CODE RELATED TO is-prefix-list? AND is-prefix-string? TASKS */

    static boolean isDigitChar( Object c ) {
	return ("0123456789".indexOf( ((Character)c).charValue() ) != -1);
    }
    static boolean isPrefixString( Object s ) {
	return isPrefixList( stringToList(s) );
    }
    static class CannotFindAnyPrefixExp extends Exception {}
    static boolean isPrefixList( Object x ) {
	try {
	    Object afterExp = removeOnePrefixExpOrDieTrying( x );
	    return isNull( afterExp );
	} catch (CannotFindAnyPrefixExp e) {
	    return false;
	}
    }
    static Object removeOnePrefixExpOrDieTrying( Object l ) 
	throws CannotFindAnyPrefixExp {
	if (isNull( l )) {
	    throw new CannotFindAnyPrefixExp();
	} else  {
	    if (isDigitChar(car(l))) {
		return cdr(l);
	    } else if (car(l).equals(new Character('-'))) {
		Object afterMinus = cdr(l);
		Object afterExp1  = removeOnePrefixExpOrDieTrying(afterMinus);
		Object afterExp2  = removeOnePrefixExpOrDieTrying(afterExp1);
		return afterExp2;
	    } else {
		throw new CannotFindAnyPrefixExp();
	    }
	}
    }

    /* TESTS START HERE */

    static void test(String name, Object result, Object expected) {
	if ((! result.equals(expected))) {
	    display("TEST FAILURE: "); display(name);
	    display(" result: ");      display(result);
	    display(" should be: ");   display(expected);
	    newline();
	} else {
	    display("test success: "); display(name);
	    newline();
	}
    }

    static void testBool(String name, boolean result, boolean expected) {
	if (result != expected) {
	    display("TEST FAILURE: "); display(name);
	    display(" result: ");      display(result);
	    display(" should be: ");   display(expected);
	    newline();
	} else {
	    display("test success: "); display(name);
	    newline();
	}
    }

    /* DEFINITIONS FOR TEST INPUTS */
    static Object
    //  (#\1)
	list1  = cons( digits[1], empty),
    //  (#\2 #\3)
	list23 = cons( digits[2], cons( digits[3], empty )),
    //  (#\3)
	list3  = cons( digits[3], empty ),
    //  (#\- #\2 #\1 #\4)
	list_214 =
	   cons( minusChar, 
		 cons( digits[2], cons( digits[1], cons( digits[4], empty )))),
    //  (#\4)
	list4  = cons( digits[4], empty ),
    //  (#\- #\9 #\5)
	list_95 =
	   cons( minusChar, cons( digits[9], cons( digits[5], empty ))),
    //  (#\- #\- #\2 #\1 #\- #\9 #\5)
        list__21_95 =
	   cons( minusChar, cons( minusChar, 
				  cons( digits[2], cons( digits[1], list_95)))),
    //  (#\- #\1 #\- #\2 #\3)
	list_1_23 =
	   cons( minusChar, cons( digits[1], cons( minusChar, list23 ))),
    //  (#\- #\- #\- #\2 #\1 #\- #\9 #\5 #\- #\1 #\- #\2 #\3)
        list___21_95_1_23 =
	   cons( minusChar, append( list__21_95, list_1_23 )),
    //  (#\- #\- #\- #\2 #\1 #\- #\9 #\5 #\- #\1 #\- #\2 #\3 #\6)
	list___21_95_1_236 = 
	   append( list___21_95_1_23, cons( digits[6], empty )),
    //  (#\- #\n #\d)
	list_nd = cons( minusChar, 
			cons( new Character('n'), 
			      cons( new Character('d'), empty )))
	;

    public static void main(String[] args) {
	try { test("remove-1", removeOnePrefixExpOrDieTrying( list23 ),   list3 );
	} catch (CannotFindAnyPrefixExp e) { display("TEST FAILURE: remove-1 EXN"); newline(); }
	try { test("remove-2", removeOnePrefixExpOrDieTrying( list_214 ), list4 );
	} catch (CannotFindAnyPrefixExp e) { display("TEST FAILURE: remove-2 EXN"); newline(); }
	try { test("remove-3", removeOnePrefixExpOrDieTrying( list__21_95 ), empty );
	} catch (CannotFindAnyPrefixExp e) { display("TEST FAILURE: remove-3 EXN"); newline(); }
	try { removeOnePrefixExpOrDieTrying( empty ); display("TEST FAILURE: remove-4 NO EXN"); newline(); 
	} catch (CannotFindAnyPrefixExp e) { display("test success: remove-4"); newline(); }
	testBool("plst?-0", isPrefixList( empty ),       false );
	testBool("plst?-1", isPrefixList( list1 ),       true );
	testBool("plst?-2", isPrefixList( list__21_95 ), true );
	testBool("plst?-3", isPrefixList( list___21_95_1_23 ), true );
	testBool("plst?-4", isPrefixList( list___21_95_1_236 ), false );
	testBool("plst?-5", isPrefixList( list_nd ), false );
	testBool("pstr?-0", isPrefixString( ""               ), false );
	testBool("pstr?-1", isPrefixString( "1"              ), true );
	testBool("pstr?-2", isPrefixString( "--21-95"        ), true );
	testBool("pstr?-3", isPrefixString( "---21-95-1-23"  ), true );
	testBool("pstr?-4", isPrefixString( "---21-95-1-236" ), false );
	testBool("pstr?-5", isPrefixString( "-nd"            ), false );
    }
}

