PolynomialIntegerTest.java
package com.acme.math;

import church.lang.ByteStream;
import church.lang.operators.Arithmetic;
import church.lang.operators.Arithmetic.*;
import church.lang.operators.Relational.$$equal;
import church.lang.operators.Streams.$$encode;
import church.primitives.Integers;
import church.primitives.Objects;
import com.acme.math.Polynomial.*;

import static church.lang.operators.Streams.output;
import static com.acme.math.Polynomial.*;

@SuppressWarnings("unchecked")
public class PolynomialIntegerTest {
    private static final $$neg<Integer>                                  $S0  = Integers::$neg;
    private static final $$neg<Polynomial<Integer>>                      $S1  = Polynomial.$neg($S0);
    private static final $$sum<Integer>                                  $S2  = Integers::$sum;
    private static final $$equal<Integer>                                $S3  = Integers::$equal;
    private static final $Additive_identity<Integer>                     $S4  = Integers::additive_identity;
    private static final $Polynomial<Integer>                            $S5  = Polynomial.polynomial($S3, $S4);
    private static final $$sum<Polynomial<Integer>>                      $S6  = Polynomial.$sum($S2, $S5);
    private static final $$prd<Integer, Integer>                         $S7  = Integers::$prd;
    private static final $Scale<Integer, Integer>                        $S8  = Polynomial.scale($S7);
    private static final $Additive_identity<Polynomial<Integer>>         $S9  = Polynomial.additive_identity($S4);
    private static final $ScaleAndShift<Integer, Integer>                $S10 = Polynomial.scaleAndShift($S8, $S5, $S7, $S9);
    private static final $$prd<Polynomial<Integer>, Polynomial<Integer>> $S11 = Polynomial.$prd($S7, $S5, $S6, $S10);
    private static final $$equal<Polynomial<Integer>>                    $S12 = Polynomial.$equal($S3);
    private static final $$dof<Integer>                                  $S13 = Integers::$dof;
    private static final $$sub<Polynomial<Integer>>                      $S14 = Arithmetic.$sub($S6, $S1);
    private static final $Red<Integer>                                   $S15 = Polynomial.red($S9);
    private static final $Divide1<Integer>                               $S16 = Polynomial.divide1($S12, $S9, $S13, $S5, $S14, $S15, $S10);
    private static final $Divide2<Integer>                               $S17 = Polynomial.divide2($S16, $S9);
    private static final $$rem<Polynomial<Integer>>                      $S18 = Polynomial.$rem($S17);
    private static final $Quotient<Polynomial<Integer>>                  $S19 = Polynomial.quotient($S17);
    private static final $$encode<ByteStream, String>                    $S20 = Objects::$encode;
    private static final $$encode<ByteStream, Integer>                   $S21 = Integers::$encode;
    private static final $Multiplicative_identity<Integer>               $S22 = Integers::multiplicative_identity;
    private static final $$encode<ByteStream, Polynomial<Integer>>       $S23 = Polynomial.$encode($S21, $S20, $S3, $S22, $S21, $S12, $S9);

    public static void main(String[] args) {
        Polynomial<Integer> p0 = constant(0);
        Polynomial<Integer> p1 = constant(1);
        Polynomial<Integer> p2 = term(1, 2, p1);
        Polynomial<Integer> p3 = term(2, 1, p0);
        Polynomial<Integer> p4 = $S1.$neg(p2);
        Polynomial<Integer> p5 = $S6.$sum(p2, p3);
        Polynomial<Integer> p6 = $S11.$prd(p2, p2);
        Polynomial<Integer> f1 = term(1, 1, constant(1));
        Polynomial<Integer> f2 = term(1, 1, constant(-1));
        Polynomial<Integer> p7 = $S11.$prd(f1, f2);
        Polynomial<Integer> p8 = $S18.$rem(p7, f2);
        Polynomial<Integer> p9 = $S19.quotient(p7, f2);
        $S20.$encode($S23.$encode(output, p3), "\n");
        $S20.$encode($S23.$encode(output, p5), "\n");
        $S20.$encode($S23.$encode(output, $S1.$neg(p5)), "\n");
        $S20.$encode($S23.$encode(output, p6), "\n");
        $S20.$encode($S23.$encode(output, p7), "\n");
        assert $S12.$equal(p8, $S9.additive_identity());
        $S20.$encode($S23.$encode(output, p9), "\n");
        assert $S12.$equal(p5, term(1, 2, term(2, 1, constant(1))));
        assert $S12.$equal(p7, term(1, 2, constant(-1)));
    }

}