package com.acme.math; import church.math.Complex; import static church.lang.operators.Arithmetic.*; import static church.math.Complex.complex; @SuppressWarnings("unchecked") public class GaussianInteger { public static interface $Round2<T> { public T round2(T a, T b); } public static <T> $Round2<T> round2($Quotient<T> $L0, $$sum<T> $L1, $$prd<T, T> $L2, $Sign<T> $L3, $Multiplicative_identity<T> $L4) { return (a, b) -> $L0.quotient($L1.$sum(a, $L0.quotient($L2.$prd($L3.sign(a), b), $L1.$sum($L4.multiplicative_identity(), $L4.multiplicative_identity()))), b); } public static interface $ComplexQuotient<T, U> { public Complex<U> complexQuotient(Complex<T> $0, Complex<U> $1); } public static <T, U> $ComplexQuotient<T, U> complexQuotient($$sum<U> $L0, $$prd<T, U> $L1, $$sub<U> $L2, $$prd<U, U> $L3, $Round2<U> $L4) { return ($0, $1) -> { U na = $L0.$sum($L1.$prd($0.a, $1.a), $L1.$prd($0.b, $1.b)); U nb = $L2.$sub($L1.$prd($0.b, $1.a), $L1.$prd($0.a, $1.b)); U den = $L0.$sum($L3.$prd($1.a, $1.a), $L3.$prd($1.b, $1.b)); return complex($L4.round2(na, den), $L4.round2(nb, den)); }; } public static <T> $$rem<Complex<T>> $rem($$sub<Complex<T>> $L0, $$prd<Complex<T>, Complex<T>> $L1, $ComplexQuotient<T, T> $L2) { return (n, d) -> $L0.$sub(n, $L1.$prd(d, $L2.complexQuotient(n, d))); } }