package com.acme.symbolic; import church.lang.ByteStream; import church.lang.operators.Relational.$$equal; import church.lang.operators.Streams.$$encode; import church.primitives.Objects; import church.util.HashMap; import static church.lang.Collections.$Empty_set; import static church.lang.Error.error; import static church.lang.operators.Streams.output; import static church.util.HashMap.get; import static com.acme.symbolic.Derivative.$Derivative; import static com.acme.symbolic.Expression.*; @SuppressWarnings("unchecked") public class DerivativeTest { private static final $$equal<String> $S0 = Objects::$equal; private static final $$encode<ByteStream, String> $S1 = Objects::$encode; private static interface $I0<T> { public T varNameToValue(String name); } public static interface $Test<T> { public ByteStream test(church.lang.Functions.Function1<String, church.lang.Functions.Function1<T, T>> funNameToFunction, church.lang.Functions.Function1<String, church.lang.Functions.Function1<Expression<T>, Expression<T>>> funNameToDerivative, church.lang.Functions.Function1<Expression<T>, Expression<T>> fn, T x0, T expectedFp0); } public static <T> $Test<T> test($$encode<ByteStream, Expression<T>> $L0, $Evaluate<T> $L1, $$encode<ByteStream, T> $L2, $Derivative<T> $L3, $$equal<T> $L4) { return (funNameToFunction, funNameToDerivative, fn, x0, expectedFp0) -> { String varName = "x"; $I0<T> varNameToValue = new $I0<T>() { public T varNameToValue(String name) { return $S0.$equal(name, varName) ? x0 : error("Undefined variable"); } }; Expression<T> x = var(varName); Expression<T> f = fn.of(x); $S1.$encode($L0.$encode($S1.$encode(output, "f(x) = "), f), "\n"); T f0 = $L1.evaluate(funNameToFunction, f, varNameToValue::varNameToValue); $S1.$encode($L2.$encode($S1.$encode(output, "f(1) = "), f0), "\n"); Expression<T> fp = $L3.derivative(funNameToDerivative, f, x); $S1.$encode($L0.$encode($S1.$encode(output, "f'(x) = "), fp), "\n"); T fp0 = $L1.evaluate(funNameToFunction, fp, varNameToValue::varNameToValue); $S1.$encode($L2.$encode($S1.$encode(output, "f'(1) = "), fp0), "\n"); assert $L4.$equal(expectedFp0, fp0); return $S1.$encode(output, "\n"); }; } public static interface $Test0<T> { public ByteStream test0(church.lang.Functions.Function1<Expression<T>, Expression<T>> fn, T x0, T fp0); } public static <T> $Test0<T> test0($Test<T> $L0, $Empty_set<HashMap<String, church.lang.Functions.Function1<T, T>>> $L1, $Empty_set<HashMap<String, church.lang.Functions.Function1<Expression<T>, Expression<T>>>> $L2) { return (fn, x0, fp0) -> $L0.test(name -> get($L1.empty_set(), name), name -> get($L2.empty_set(), name), fn, x0, fp0); } }