TranscendentalDerivativeTest.java
package com.acme.symbolic;

import church.lang.ByteStream;
import church.lang.Hash.$HashCode;
import church.lang.operators.Arithmetic.*;
import church.lang.operators.Relational.$$equal;
import church.lang.operators.Streams.$$encode;
import church.math.operators.Transcendental;
import church.math.operators.Transcendental.*;
import church.primitives.Doubles;
import church.primitives.Objects;
import church.util.HashMap;
import church.util.HashMap.$Map;
import com.acme.symbolic.Derivative.$Derivative;
import com.acme.symbolic.DerivativeTest.$Test;
import com.acme.symbolic.Expression.*;

import static church.util.Entry.entry;
import static church.util.HashMap.get;
import static com.acme.symbolic.Expression.*;

@SuppressWarnings("unchecked")
public class TranscendentalDerivativeTest {
    private static final $Cos<Expression<Double>>                                                              $S0  = TranscendentalDerivativeTest::cos;
    private static final $$equal<Double>                                                                       $S1  = Doubles::$equal;
    private static final $ExprEqual<Double>                                                                    $S2  = Expression.exprEqual($S1);
    private static final $$equal<Expression<Double>>                                                           $S3  = Expression.$equal($S2);
    private static final $Additive_identity<Double>                                                            $S4  = Doubles::additive_identity;
    private static final $Additive_identity<Expression<Double>>                                                $S5  = Expression.additive_identity($S4);
    private static final $$sum<Expression<Double>>                                                             $S6  = Expression.$sum($S3, $S5);
    private static final $Multiplicative_identity<Double>                                                      $S7  = Doubles::multiplicative_identity;
    private static final $Multiplicative_identity<Expression<Double>>                                          $S8  = Expression.multiplicative_identity($S7);
    private static final $$pow<Expression<Double>, Double>                                                     $S9  = Expression.$pow($S3, $S5, $S1, $S4, $S8, $S7);
    private static final $$encode<ByteStream, Double>                                                          $S10 = Doubles::$encode;
    private static final $$encode<ByteStream, String>                                                          $S11 = Objects::$encode;
    private static final $$encode<ByteStream, Expression<Double>>                                              $S12 = Expression.$encode($S10, $S11);
    private static final $$sum<Double>                                                                         $S13 = Doubles::$sum;
    private static final $$neg<Double>                                                                         $S14 = Doubles::$neg;
    private static final $$sub<Double>                                                                         $S15 = Doubles::$sub;
    private static final $$prd<Double, Double>                                                                 $S16 = Doubles::$prd;
    private static final $$div<Double, Double>                                                                 $S17 = Doubles::$div;
    private static final $$pow<Double, Double>                                                                 $S18 = Doubles::$pow;
    private static final $Evaluate<Double>                                                                     $S19 = Expression.evaluate($S13, $S14, $S15, $S16, $S17, $S18);
    private static final $$prd<Expression<Double>, Expression<Double>>                                         $S20 = Expression.$prd($S3, $S5, $S8);
    private static final $$neg<Expression<Double>>                                                             $S21 = Expression::$neg;
    private static final $$sub<Expression<Double>>                                                             $S22 = Expression.$sub($S3, $S5, $S21);
    private static final $$div<Expression<Double>, Expression<Double>>                                         $S23 = Expression.$div($S3, $S5, $S8);
    private static final $Derivative<Double>                                                                   $S24 = Derivative.derivative($S5, $S3, $S8, $S20, $S6, $S21, $S22, $S23, $S9, $S15, $S7);
    private static final $Test<Double>                                                                         $S25 = DerivativeTest.test($S12, $S19, $S10, $S24, $S1);
    private static final $$equal<String>                                                                       $S26 = Objects::$equal;
    private static final $HashCode<String>                                                                     $S27 = Objects::hashCode;
    private static final $Map<String, church.lang.Functions.Function1<Double, Double>>                         $S28 = HashMap.map($S26, $S27);
    private static final $Log<Double>                                                                          $S29 = Transcendental::log;
    private static final $Exp<Double>                                                                          $S30 = Transcendental::exp;
    private static final $Sqrt<Double>                                                                         $S31 = Transcendental::sqrt;
    private static final $Sin<Double>                                                                          $S32 = Transcendental::sin;
    private static final $Cos<Double>                                                                          $S33 = Transcendental::cos;
    private static final $Tan<Double>                                                                          $S34 = Transcendental::tan;
    private static final $Asin<Double>                                                                         $S35 = Transcendental::asin;
    private static final $Acos<Double>                                                                         $S36 = Transcendental::acos;
    private static final $Atan<Double>                                                                         $S37 = Transcendental::atan;
    private static final $FunNameToFunction<Double>                                                            $S38 = TranscendentalDerivativeTest.funNameToFunction($S28, $S29, $S30, $S31, $S32, $S33, $S34, $S35, $S36, $S37);
    private static final $Map<String, church.lang.Functions.Function1<Expression<Double>, Expression<Double>>> $S39 = HashMap.map($S26, $S27);
    private static final $Exp<Expression<Double>>                                                              $S40 = TranscendentalDerivativeTest::exp;
    private static final $Sqrt<Expression<Double>>                                                             $S41 = TranscendentalDerivativeTest::sqrt;
    private static final $Sin<Expression<Double>>                                                              $S42 = TranscendentalDerivativeTest::sin;
    private static final $FunNameToDerivative<Double>                                                          $S43 = TranscendentalDerivativeTest.funNameToDerivative($S7, $S13, $S39, $S23, $S40, $S20, $S41, $S0, $S21, $S42, $S9, $S22, $S6);

    public static <T> Expression<T> log(Expression<T> a) {
        return app("log", a);
    }

    public static <T> Expression<T> exp(Expression<T> a) {
        return app("exp", a);
    }

    public static <T> Expression<T> sqrt(Expression<T> a) {
        return app("sqrt", a);
    }

    public static <T> Expression<T> sin(Expression<T> a) {
        return app("sin", a);
    }

    public static <T> Expression<T> cos(Expression<T> a) {
        return app("cos", a);
    }

    public static <T> Expression<T> tan(Expression<T> a) {
        return app("tan", a);
    }

    public static <T> Expression<T> asin(Expression<T> a) {
        return app("asin", a);
    }

    public static <T> Expression<T> acos(Expression<T> a) {
        return app("acos", a);
    }

    public static <T> Expression<T> atan(Expression<T> a) {
        return app("atan", a);
    }

    public static interface $FunNameToFunction<T> {
        public church.lang.Functions.Function1<T, T> funNameToFunction(String name);
    }

    public static <T> $FunNameToFunction<T> funNameToFunction($Map<String, church.lang.Functions.Function1<T, T>> $L0, $Log<T> $L1, $Exp<T> $L2, $Sqrt<T> $L3, $Sin<T> $L4, $Cos<T> $L5, $Tan<T> $L6, $Asin<T> $L7, $Acos<T> $L8, $Atan<T> $L9) {
        return name -> get($L0.map(entry("log", $L1::log), entry("exp", $L2::exp), entry("sqrt", $L3::sqrt), entry("sin", $L4::sin), entry("cos", $L5::cos), entry("tan", $L6::tan), entry("asin", $L7::asin), entry("acos", $L8::acos), entry("atan", $L9::atan)), name);
    }

    public static interface $FunNameToDerivative<T> {
        public church.lang.Functions.Function1<Expression<T>, Expression<T>> funNameToDerivative(String name);
    }

    public static <T> $FunNameToDerivative<T> funNameToDerivative($Multiplicative_identity<T> $L0, $$sum<T> $L1, $Map<String, church.lang.Functions.Function1<Expression<T>, Expression<T>>> $L2, $$div<Expression<T>, Expression<T>> $L3, $Exp<Expression<T>> $L4, $$prd<Expression<T>, Expression<T>> $L5, $Sqrt<Expression<T>> $L6, $Cos<Expression<T>> $L7, $$neg<Expression<T>> $L8, $Sin<Expression<T>> $L9, $$pow<Expression<T>, T> $L10, $$sub<Expression<T>> $L11, $$sum<Expression<T>> $L12) {
        return name -> {
            T             t1 = $L0.multiplicative_identity();
            T             t2 = $L1.$sum(t1, t1);
            Expression<T> e1 = $const(t1);
            Expression<T> e2 = $const(t2);
            return get($L2.map(entry("log", x -> $L3.$div(e1, x)), entry("exp", x -> $L4.exp(x)), entry("sqrt", x -> $L3.$div(e1, $L5.$prd(e2, $L6.sqrt(x)))), entry("sin", x -> $L7.cos(x)), entry("cos", x -> $L8.$neg($L9.sin(x))), entry("tan", x -> $L3.$div(e1, $L10.$pow($L7.cos(x), t2))), entry("asin", x -> $L3.$div(e1, $L6.sqrt($L11.$sub(e1, $L10.$pow(x, t2))))), entry("acos", x -> $L3.$div($L8.$neg(e1), $L6.sqrt($L11.$sub(e1, $L10.$pow(x, t2))))), entry("atan", x -> $L3.$div(e1, $L12.$sum(e1, $L10.$pow(x, t2))))), name);
        };
    }

    public static Expression<Double> foo(Expression<Double> x) {
        return $S0.cos($S6.$sum($S9.$pow(x, 2.0), $const(1.0)));
    }

    public static void main(String[] args) {
        $S25.test($S38::funNameToFunction, $S43::funNameToDerivative, TranscendentalDerivativeTest::foo, 1.0, -1.8185948536513634);
    }

}