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.Expression.*; import static church.lang.Error.error; import static church.lang.operators.Streams.output; import static church.util.Entry.entry; import static church.util.HashMap.get; import static com.acme.symbolic.Expression.*; @SuppressWarnings("unchecked") public class ExpressionTest { private static final $Cos<Expression<Double>> $S0 = ExpressionTest::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 $$equal<String> $S10 = Objects::$equal; private static final $$encode<ByteStream, String> $S11 = Objects::$encode; private static final $$encode<ByteStream, Double> $S12 = Doubles::$encode; private static final $$encode<ByteStream, Expression<Double>> $S13 = Expression.$encode($S12, $S11); private static final $$sum<Double> $S14 = Doubles::$sum; private static final $$neg<Double> $S15 = Doubles::$neg; private static final $$sub<Double> $S16 = Doubles::$sub; private static final $$prd<Double, Double> $S17 = Doubles::$prd; private static final $$div<Double, Double> $S18 = Doubles::$div; private static final $$pow<Double, Double> $S19 = Doubles::$pow; private static final $Evaluate<Double> $S20 = Expression.evaluate($S14, $S15, $S16, $S17, $S18, $S19); private static final $Test<Double, Double, Double> $S21 = ExpressionTest.test($S13, $S20, $S12); private static final $HashCode<String> $S22 = Objects::hashCode; private static final $Map<String, church.lang.Functions.Function1<Double, Double>> $S23 = HashMap.map($S10, $S22); private static final $Log<Double> $S24 = Transcendental::log; private static final $Exp<Double> $S25 = Transcendental::exp; private static final $Sqrt<Double> $S26 = Transcendental::sqrt; private static final $Sin<Double> $S27 = Transcendental::sin; private static final $Cos<Double> $S28 = Transcendental::cos; private static final $Tan<Double> $S29 = Transcendental::tan; private static final $Asin<Double> $S30 = Transcendental::asin; private static final $Acos<Double> $S31 = Transcendental::acos; private static final $Atan<Double> $S32 = Transcendental::atan; private static final $FunNameToFunction<Double> $S33 = ExpressionTest.funNameToFunction($S23, $S24, $S25, $S26, $S27, $S28, $S29, $S30, $S31, $S32); private static interface $I0<T> { public T varNameToValue(String name); } 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 Expression<Double> foo(Expression<Double> x) { return $S0.cos($S6.$sum($S9.$pow(x, 2.0), $const(1.0))); } public static interface $Test<T, U, V> { public ByteStream test(church.lang.Functions.Function1<String, church.lang.Functions.Function1<T, T>> funNameToFunction, church.lang.Functions.Function1<Expression<U>, Expression<T>> fn, T x0, V expectedFp0); } public static <T, U, V> $Test<T, U, V> test($$encode<ByteStream, Expression<T>> $L0, $Evaluate<T> $L1, $$encode<ByteStream, T> $L2) { return (funNameToFunction, fn, x0, expectedFp0) -> { String varName = "x"; $I0<T> varNameToValue = new $I0<T>() { public T varNameToValue(String name) { return $S10.$equal(name, varName) ? x0 : error("Undefined variable"); } }; Expression<U> x = var(varName); Expression<T> f = fn.of(x); $S11.$encode($L0.$encode($S11.$encode(output, "f(x) = "), f), "\n"); T f0 = $L1.evaluate(funNameToFunction, f, varNameToValue::varNameToValue); $S11.$encode($L2.$encode($S11.$encode(output, "f(1) = "), f0), "\n"); return $S11.$encode(output, "\n"); }; } public static void main(String[] args) { $S21.test($S33::funNameToFunction, ExpressionTest::foo, 1.0, -1.8185948536513634); } }