GaussianIntegerTest.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.math.Complex;
import church.primitives.Integers;
import church.primitives.Objects;
import com.acme.math.GaussianInteger.$ComplexQuotient;
import com.acme.math.GaussianInteger.$Round2;

import static church.lang.operators.Streams.output;
import static church.math.Complex.complex;

@SuppressWarnings("unchecked")
public class GaussianIntegerTest {
    private static final $$encode<ByteStream, String>              $S0  = Objects::$encode;
    private static final $$encode<ByteStream, Integer>             $S1  = Integers::$encode;
    private static final $$encode<ByteStream, Complex<Integer>>    $S2  = Complex.$encode($S0, $S1);
    private static final $$equal<Integer>                          $S3  = Integers::$equal;
    private static final $$equal<Complex<Integer>>                 $S4  = Complex.$equal($S3);
    private static final $Additive_identity<Integer>               $S5  = Integers::additive_identity;
    private static final $Additive_identity<Complex<Integer>>      $S6  = Complex.additive_identity($S5);
    private static final $$sum<Integer>                            $S7  = Integers::$sum;
    private static final $$sum<Complex<Integer>>                   $S8  = Complex.$sum($S7);
    private static final $$neg<Integer>                            $S9  = Integers::$neg;
    private static final $$neg<Complex<Integer>>                   $S10 = Complex.$neg($S9);
    private static final $$sub<Complex<Integer>>                   $S11 = Arithmetic.$sub($S8, $S10);
    private static final $$sub<Integer>                            $S12 = Integers::$sub;
    private static final $$prd<Integer, Integer>                   $S13 = Integers::$prd;
    private static final $$prd<Complex<Integer>, Complex<Integer>> $S14 = Complex.$prd($S12, $S13, $S7);
    private static final $Quotient<Integer>                        $S15 = Integers::quotient;
    private static final $Sign<Integer>                            $S16 = Integers::sign;
    private static final $Multiplicative_identity<Integer>         $S17 = Integers::multiplicative_identity;
    private static final $Round2<Integer>                          $S18 = GaussianInteger.round2($S15, $S7, $S13, $S16, $S17);
    private static final $ComplexQuotient<Integer, Integer>        $S19 = GaussianInteger.complexQuotient($S7, $S13, $S12, $S13, $S18);
    private static final $$rem<Complex<Integer>>                   $S20 = GaussianInteger.$rem($S11, $S14, $S19);
    private static final $Gcd<Complex<Integer>>                    $S21 = Arithmetic.gcd($S2, $S4, $S6, $S20);
    private static final $Test<Complex<Integer>>                   $S22 = GaussianIntegerTest.test($S21, $S2);

    public static interface $Test<T> {
        public T test(T c1, T c2);
    }

    public static <T> $Test<T> test($Gcd<T> $L0, $$encode<ByteStream, T> $L1) {
        return (c1, c2) -> {
            T c3 = $L0.gcd(c1, c2);
            $S0.$encode($L1.$encode($S0.$encode($L1.$encode($S0.$encode($L1.$encode($S0.$encode(output, "gcd("), c1), ", "), c2), ") = "), c3), "\n");
            return c3;
        };
    }

    public static void main(String[] args) {
        Complex<Integer> c0 = $S22.test(complex(3, 2), complex(-1, 3));
        assert $S4.$equal(c0, complex(0, 1));
        $S22.test(complex(312, 2234), complex(-134, 3232));
        Complex<Integer> c1 = complex(2, 3);
        Complex<Integer> c2 = complex(1, 5);
        Complex<Integer> c3 = complex(3, 7);
        Complex<Integer> c4 = $S22.test($S14.$prd(c1, c3), $S14.$prd(c2, c3));
        assert $S4.$equal(c3, c4);
    }

}