/* * Test suite for Prf (Java). * Runnable as a main program, which should print "All N tests passed". * * Copyright (c) 2017 Project Nayuki * All rights reserved. Contact Nayuki for licensing. * https://www.nayuki.io/page/primitive-recursive-functions */ public final class PrfTest { public static void main(String[] args) { System.out.println("Running tests..."); int count = 0; boolean failed = false; for (TestSuite ts : testsuites) { for (TestCase tc : ts.cases) { long actual = ts.func.eval(tc.arguments); if (actual != tc.expected) { if (!failed) { System.out.println("One or more tests failed:"); failed = true; } System.out.printf(" %s %s = %d != %d%n", ts.func, toString(tc.arguments), actual, tc.expected); } count++; } } if (!failed) System.out.printf("All %d tests passed%n", count); } private static TestSuite[] testsuites = { // Primitive functions suite(Prf.Z, kase(0, 0), kase(0, 1), kase(0, 2), kase(0, 5)), suite(Prf.S, kase(1, 0), kase(2, 1), kase(3, 2), kase(6, 5)), suite(Prf.I(1,0), kase(0, 0), kase(3, 3)), suite(Prf.I(2,0), kase(4, 4, 5)), suite(Prf.I(2,1), kase(5, 4, 5)), suite(Prf.I(3,0), kase(7, 7, 8, 9)), suite(Prf.I(3,1), kase(8, 7, 8, 9)), suite(Prf.I(3,2), kase(9, 7, 8, 9)), // Boolean functions suite(Prf.not, kase(1, 0), kase(0, 1)), suite(Prf.and, kase(0, 0, 0), kase(0, 0, 1), kase(0, 1, 0), kase(1, 1, 1)), suite(Prf.or, kase(0, 0, 0), kase(1, 0, 1), kase(1, 1, 0), kase(1, 1, 1)), suite(Prf.xor, kase(0, 0, 0), kase(1, 0, 1), kase(1, 1, 0), kase(0, 1, 1)), suite(Prf.mux, kase(0, 0, 0, 0), kase(1, 0, 0, 1), kase(0, 0, 1, 0), kase(1, 0, 1, 1), kase(0, 1, 0, 0), kase(0, 1, 0, 1), kase(1, 1, 1, 0), kase(1, 1, 1, 1), kase(7, 0, 3, 7), kase(3, 1, 3, 7), kase(2, 0, 5, 2), kase(5, 1, 5, 2)), // Comparison functions suite(Prf.z, kase(1, 0), kase(0, 1), kase(0, 2), kase(0, 5)), suite(Prf.nz, kase(0, 0), kase(1, 1), kase(1, 2), kase(1, 5)), suite(Prf.eq, kase(1, 0, 0), kase(0, 0, 1), kase(0, 0, 2), kase(0, 1, 0), kase(1, 1, 1), kase(0, 1, 2), kase(0, 2, 0), kase(0, 2, 1), kase(1, 2, 2), kase(0, 5, 0), kase(1, 6, 6), kase(0, 3, 7)), suite(Prf.neq, kase(0, 0, 0), kase(1, 0, 1), kase(1, 0, 2), kase(1, 1, 0), kase(0, 1, 1), kase(1, 1, 2), kase(1, 2, 0), kase(1, 2, 1), kase(0, 2, 2), kase(1, 5, 0), kase(0, 6, 6), kase(1, 3, 7)), suite(Prf.lt, kase(0, 0, 0), kase(1, 0, 1), kase(1, 0, 2), kase(0, 1, 0), kase(0, 1, 1), kase(1, 1, 2), kase(0, 2, 0), kase(0, 2, 1), kase(0, 2, 2), kase(0, 5, 0), kase(0, 6, 6), kase(1, 3, 7)), suite(Prf.le, kase(1, 0, 0), kase(1, 0, 1), kase(1, 0, 2), kase(0, 1, 0), kase(1, 1, 1), kase(1, 1, 2), kase(0, 2, 0), kase(0, 2, 1), kase(1, 2, 2), kase(0, 5, 0), kase(1, 6, 6), kase(1, 3, 7)), suite(Prf.gt, kase(0, 0, 0), kase(0, 0, 1), kase(0, 0, 2), kase(1, 1, 0), kase(0, 1, 1), kase(0, 1, 2), kase(1, 2, 0), kase(1, 2, 1), kase(0, 2, 2), kase(1, 5, 0), kase(0, 6, 6), kase(0, 3, 7)), suite(Prf.ge, kase(1, 0, 0), kase(0, 0, 1), kase(0, 0, 2), kase(1, 1, 0), kase(1, 1, 1), kase(0, 1, 2), kase(1, 2, 0), kase(1, 2, 1), kase(1, 2, 2), kase(1, 5, 0), kase(1, 6, 6), kase(0, 3, 7)), suite(Prf.even, kase(1, 0), kase(0, 1), kase(1, 2), kase(0, 3), kase(1, 4), kase(0, 5)), suite(Prf.odd, kase(0, 0), kase(1, 1), kase(0, 2), kase(1, 3), kase(0, 4), kase(1, 5)), suite(Prf.divisible, kase(1, 0, 0), kase(0, 1, 0), kase(0, 2, 0), kase(1, 0, 1), kase(1, 1, 1), kase(1, 2, 1), kase(1, 0, 2), kase(0, 1, 2), kase(1, 2, 2), kase(0, 3, 2), kase(1, 0, 3), kase(0, 1, 3), kase(0, 2, 3), kase(1, 3, 3), kase(0, 4, 3), kase(0, 5, 3), kase(1, 6, 3), kase(0, 7, 5), kase(1, 25, 5)), suite(Prf.prime, kase(0, 0), kase(0, 1), kase(1, 2), kase(1, 3), kase(0, 4), kase(1, 5), kase(0, 6), kase(1, 7), kase(0, 8), kase(0, 9), kase(0, 10), kase(1, 11), kase(0, 12), kase(1, 13), kase(0, 14), kase(0, 15), kase(0, 16), kase(1, 17), kase(0, 18), kase(1, 19), kase(0, 20), kase(0, 21), kase(0, 22), kase(1, 23), kase(0, 24), kase(0, 25), kase(0, 26), kase(0, 27), kase(0, 28), kase(1, 29), kase(0, 30)), // Arithmetic functions suite(Prf.konst(0),kase(0, 0), kase(0, 9)), suite(Prf.konst(1),kase(1, 0), kase(1, 1), kase(1, 3)), suite(Prf.konst(2),kase(2, 0), kase(2, 1), kase(2, 2)), suite(Prf.konst(3),kase(3, 0), kase(3, 3), kase(3, 5)), suite(Prf.pred, kase(0, 0), kase(0, 1), kase(1, 2), kase(2, 3), kase(8, 9)), suite(Prf.add, kase(0, 0, 0), kase(1, 0, 1), kase(3, 0, 3), kase(1, 1, 0), kase(2, 2, 0), kase(2, 1, 1), kase(7, 2, 5), kase(9, 6, 3)), suite(Prf.sub, kase(0, 0, 0), kase(0, 0, 1), kase(0, 0, 2), kase(1, 1, 0), kase(0, 1, 1), kase(0, 1, 2), kase(2, 2, 0), kase(1, 2, 1), kase(0, 2, 2), kase(0, 2, 3), kase(3, 3, 0), kase(3, 5, 2), kase(1, 7, 6)), suite(Prf.subrev, kase(0, 0, 0), kase(0, 1, 0), kase(0, 2, 0), kase(1, 0, 1), kase(0, 1, 1), kase(0, 2, 1), kase(2, 0, 2), kase(1, 1, 2), kase(0, 2, 2), kase(0, 3, 2), kase(3, 0, 3), kase(3, 2, 5), kase(1, 6, 7)), suite(Prf.diff, kase(0, 0, 0), kase(1, 0, 1), kase(2, 0, 2), kase(1, 1, 0), kase(0, 1, 1), kase(1, 1, 2), kase(2, 2, 0), kase(1, 2, 1), kase(0, 2, 2), kase(5, 5, 0), kase(0, 6, 6), kase(4, 3, 7)), suite(Prf.min, kase(0, 0, 0), kase(0, 0, 1), kase(0, 0, 2), kase(0, 1, 0), kase(1, 1, 1), kase(1, 1, 2), kase(0, 2, 0), kase(1, 2, 1), kase(2, 2, 2), kase(0, 3, 0), kase(2, 5, 2), kase(6, 7, 6)), suite(Prf.max, kase(0, 0, 0), kase(1, 0, 1), kase(2, 0, 2), kase(1, 1, 0), kase(1, 1, 1), kase(2, 1, 2), kase(2, 2, 0), kase(2, 2, 1), kase(2, 2, 2), kase(3, 3, 0), kase(5, 5, 2), kase(7, 7, 6)), suite(Prf.mul, kase(0, 0, 0), kase(0, 0, 1), kase(0, 0, 2), kase(0, 1, 0), kase(0, 3, 0), kase(1, 1, 1), kase(2, 1, 2), kase(2, 2, 1), kase(4, 2, 2), kase(21, 3, 7), kase(40, 5, 8)), suite(Prf.pow, kase( 1, 0, 0), kase( 0, 0, 1), kase( 0, 0, 2), kase( 1, 1, 0), kase( 1, 1, 1), kase( 1, 1, 2), kase( 1, 2, 0), kase( 2, 2, 1), kase( 4, 2, 2), kase( 8, 2, 3), kase( 16, 2, 4), kase( 32, 2, 5), kase( 64, 2, 6), kase(128, 2, 7), kase(256, 2, 8), kase(512, 2, 9), kase( 3, 3, 1), kase( 9, 3, 2), kase( 64, 4, 3), kase(125, 5, 3), kase( 36, 6, 2)), suite(Prf.sqrt, kase(0, 0), kase(1, 1), kase(1, 2), kase(1, 3), kase(2, 4), kase(2, 5), kase(2, 6), kase(2, 7), kase(2, 8), kase(3, 9), kase(3, 10), kase(3, 15), kase(4, 16), kase(4, 17), kase(4, 23)), suite(Prf.log, kase(0, 0, 0), kase(1, 0, 1), kase(2, 0, 2), kase(4, 0, 4), kase(7, 0, 7), kase(0, 1, 0), kase(1, 1, 1), kase(2, 1, 2), kase(5, 1, 5), kase(9, 1, 9), kase(0, 2, 0), kase(0, 2, 1), kase(1, 2, 2), kase(1, 2, 3), kase(2, 2, 4), kase(2, 2, 5), kase(2, 2, 6), kase(2, 2, 7), kase(3, 2, 8), kase(3, 2, 9), kase(3, 2, 15), kase(4, 2, 16), kase(4, 2, 17), kase(0, 3, 0), kase(0, 3, 1), kase(0, 3, 2), kase(1, 3, 3), kase(1, 3, 4), kase(1, 3, 8), kase(2, 3, 9), kase(2, 3, 10), kase(2, 3, 26), kase(3, 3, 27), kase(0, 4, 0), kase(0, 4, 1), kase(0, 4, 2), kase(0, 4, 3), kase(1, 4, 4), kase(1, 4, 5), kase(1, 4, 8), kase(1, 4, 15), kase(2, 4, 16)), suite(Prf.div, kase(0, 0, 0), kase(1, 1, 0), kase(2, 2, 0), kase(3, 3, 0), kase(0, 0, 1), kase(1, 1, 1), kase(2, 2, 1), kase(3, 3, 1), kase(0, 0, 2), kase(0, 1, 2), kase(1, 2, 2), kase(1, 3, 2), kase(2, 4, 2), kase(5, 11, 2), kase(7, 14, 2), kase(0, 0, 3), kase(0, 1, 3), kase(0, 2, 3), kase(1, 3, 3), kase(1, 4, 3), kase(1, 5, 3), kase(2, 6, 3), kase(3, 11, 3), kase(6, 18, 3), kase(2, 8, 4), kase(0, 0, 4), kase(5, 23, 4), kase(4, 20, 5), kase(4, 21, 5), kase(0, 5, 6), kase(5, 30, 6), kase(0, 2, 7), kase(2, 19, 7)), suite(Prf.mod, kase(0, 0, 0), kase(1, 1, 0), kase(2, 2, 0), kase(3, 3, 0), kase(0, 0, 1), kase(0, 1, 1), kase(0, 2, 1), kase(0, 3, 1), kase(0, 0, 2), kase(1, 1, 2), kase(0, 2, 2), kase(1, 3, 2), kase(0, 0, 3), kase(1, 1, 3), kase(2, 2, 3), kase(0, 3, 3), kase(1, 4, 3), kase(2, 5, 3), kase(3, 7, 4), kase(1, 21, 5), kase(0, 30, 6), kase(5, 19, 7)), suite(Prf.factorial, kase( 1, 0), kase( 1, 1), kase( 2, 2), kase( 6, 3), kase( 24, 4), kase(120, 5), kase(720, 6)), suite(Prf.gcd, kase( 0, 0, 0), kase( 1, 0, 1), kase( 2, 0, 2), kase( 3, 0, 3), kase( 1, 1, 0), kase( 1, 1, 1), kase( 1, 1, 2), kase( 1, 1, 3), kase( 2, 2, 0), kase( 1, 2, 1), kase( 2, 2, 2), kase( 1, 2, 3), kase( 2, 2, 4), kase( 3, 3, 0), kase( 1, 3, 1), kase( 1, 3, 2), kase( 3, 3, 3), kase( 2, 6, 2), kase( 3, 6, 3), kase( 6, 6, 6), kase( 2, 12, 2), kase( 3, 12, 3), kase( 4, 12, 4), kase( 6, 12, 6)), suite(Prf.lcm, kase( 0, 0, 0), kase( 0, 0, 1), kase( 0, 0, 2), kase( 0, 1, 0), kase( 1, 1, 1), kase( 2, 1, 2), kase( 3, 1, 3), kase( 0, 2, 0), kase( 2, 2, 1), kase( 2, 2, 2), kase( 6, 2, 3), kase( 4, 2, 4), kase( 0, 3, 0), kase( 3, 3, 1), kase( 6, 3, 2), kase( 3, 3, 3), kase(15, 3, 5), kase(30, 6, 15), kase(30, 6, 30), kase(30, 10, 15)), suite(Prf.divisiblecount, kase(0, 0, 0), kase(0, 1, 0), kase(0, 2, 0), kase(0, 4, 0), kase(0, 7, 0), kase(0, 0, 1), kase(1, 1, 1), kase(2, 2, 1), kase(5, 5, 1), kase(9, 9, 1), kase(0, 0, 2), kase(0, 1, 2), kase(1, 2, 2), kase(0, 3, 2), kase(2, 4, 2), kase(0, 5, 2), kase(1, 6, 2), kase(0, 7, 2), kase(3, 8, 2), kase(0, 9, 2), kase(1, 10, 2), kase(0, 0, 3), kase(0, 1, 3), kase(0, 2, 3), kase(1, 3, 3), kase(0, 4, 3), kase(0, 5, 3), kase(1, 6, 3), kase(0, 7, 3), kase(0, 8, 3), kase(2, 9, 3), kase(0, 10, 3), kase(0, 0, 4), kase(0, 3, 4), kase(1, 4, 4), kase(0, 5, 4), kase(1, 8, 4), kase(2, 16, 4)), suite(Prf.nthprime, kase(2, 0), kase(3, 1), kase(5, 2), kase(7, 3)), suite(Prf.fibonacci, kase(0, 0), kase(1, 1), kase(1, 2), kase(2, 3), kase(3, 4), kase(5, 5)), // Bitwise functions suite(Prf.shl, kase( 0, 0, 0), kase( 1, 1, 0), kase( 2, 2, 0), kase( 3, 3, 0), kase( 0, 0, 1), kase( 2, 1, 1), kase( 4, 2, 1), kase( 6, 3, 1), kase( 0, 0, 2), kase( 4, 1, 2), kase( 8, 2, 2), kase(12, 3, 2), kase( 0, 0, 3), kase( 8, 1, 3), kase(16, 2, 3), kase(24, 3, 3)), suite(Prf.shr, kase(0, 0, 0), kase(1, 1, 0), kase(2, 2, 0), kase(3, 3, 0), kase(0, 0, 1), kase(0, 1, 1), kase(1, 2, 1), kase(1, 3, 1), kase(0, 0, 2), kase(0, 1, 2), kase(0, 2, 2), kase(0, 3, 2), kase(1, 4, 2), kase(1, 5, 2), kase(1, 6, 2), kase(1, 7, 2), kase(2, 8, 2)), suite(Prf.band, kase(0, 0, 0), kase(0, 1, 0), kase(0, 2, 0), kase(0, 3, 0), kase(0, 0, 1), kase(1, 1, 1), kase(0, 2, 1), kase(1, 3, 1), kase(0, 0, 2), kase(0, 1, 2), kase(2, 2, 2), kase(2, 3, 2), kase(0, 0, 3), kase(1, 1, 3), kase(2, 2, 3), kase(3, 3, 3)), suite(Prf.bandnot, kase(0, 0, 0), kase(1, 1, 0), kase(2, 2, 0), kase(3, 3, 0), kase(0, 0, 1), kase(0, 1, 1), kase(2, 2, 1), kase(2, 3, 1), kase(0, 0, 2), kase(1, 1, 2), kase(0, 2, 2), kase(1, 3, 2), kase(0, 0, 3), kase(0, 1, 3), kase(0, 2, 3), kase(0, 3, 3)), suite(Prf.bor, kase(0, 0, 0), kase(1, 1, 0), kase(2, 2, 0), kase(3, 3, 0), kase(1, 0, 1), kase(1, 1, 1), kase(3, 2, 1), kase(3, 3, 1), kase(2, 0, 2), kase(3, 1, 2), kase(2, 2, 2), kase(3, 3, 2), kase(3, 0, 3), kase(3, 1, 3), kase(3, 2, 3), kase(3, 3, 3)), suite(Prf.bxor, kase(0, 0, 0), kase(1, 1, 0), kase(2, 2, 0), kase(3, 3, 0), kase(1, 0, 1), kase(0, 1, 1), kase(3, 2, 1), kase(2, 3, 1), kase(2, 0, 2), kase(3, 1, 2), kase(0, 2, 2), kase(1, 3, 2), kase(3, 0, 3), kase(2, 1, 3), kase(1, 2, 3), kase(0, 3, 3)), suite(Prf.getbit, kase(0, 0, 0), kase(1, 1, 0), kase(0, 2, 0), kase(1, 3, 0), kase(0, 0, 1), kase(0, 1, 1), kase(1, 2, 1), kase(1, 3, 1), kase(0, 0, 2), kase(0, 1, 2), kase(0, 2, 2), kase(0, 3, 2), kase(1, 4, 2), kase(1, 5, 2), kase(1, 6, 2), kase(1, 7, 2), kase(0, 0, 3), kase(0, 5, 3), kase(1, 8, 3), kase(1, 9, 3), kase(0, 16, 3)), }; // Utility methods private static String toString(long[] xs) { StringBuilder sb = new StringBuilder("["); boolean head = true; for (long x : xs) { if (head) head = false; else sb.append(", "); sb.append(x); } return sb.append("]").toString(); } private static TestSuite suite(Prf f, TestCase... cases) { return new TestSuite(f, cases); } private static TestCase kase(long expect, long... args) { return new TestCase(expect, args); } // Test declaration data structures private static final class TestSuite { public Prf func; public TestCase[] cases; public TestSuite(Prf func, TestCase[] cases) { this.func = func; this.cases = cases; } } private static final class TestCase { public long expected; public long[] arguments; public TestCase(long expected, long[] arguments) { this.expected = expected; this.arguments = arguments; } } }