package church.lang.operators; import church.lang.operators.Streams.$$encode; import church.primitives.Objects; import static church.lang.Error.error; import static church.lang.operators.Relational.*; import static church.lang.operators.Streams.output; @SuppressWarnings("unchecked") public class Arithmetic { private static final $$encode<church.lang.ByteStream, String> $S0 = Objects::$encode; public static interface $Min_value<T> { public T min_value(); } public static interface $Max_value<T> { public T max_value(); } public static interface $Additive_identity<T> { public T additive_identity(); } public static interface $$sum<T> { public T $sum(T a, T b); } public static interface $$neg<T> { public T $neg(T a); } public static interface $$sub<T> { public T $sub(T a, T b); } public static <T> $$sub<T> $sub($$sum<T> $L0, $$neg<T> $L1) { return (a, b) -> $L0.$sum(a, $L1.$neg(b)); } public static interface $Sign<T> { public T sign(T a); } public static interface $Multiplicative_identity<T> { public T multiplicative_identity(); } public static interface $$prd<S, T> { public T $prd(S a, T b); } public static interface $$pow<T, U> { public T $pow(T a, U b); } public static interface $$rcp<T> { public T $rcp(T a); } public static interface $$div<T, U> { public U $div(T a, U b); } public static <T, U> $$div<T, U> $div($$prd<T, U> $L0, $$rcp<U> $L1) { return (a, b) -> $L0.$prd(a, $L1.$rcp(b)); } public static interface $Divide<T, U> { public U divide(T a, T b, church.lang.Functions.Function1<T, church.lang.Functions.Function1<T, U>> c); } public static interface $Quotient<T> { public T quotient(T n, T d); } public static <T> $Quotient<T> quotient($Divide<T, T> $L0) { return (n, d) -> $L0.divide(n, d, q -> r -> q); } public static interface $$rem<T> { public T $rem(T n, T d); } public static <T> $$rem<T> $rem($Divide<T, T> $L0) { return (n, d) -> $L0.divide(n, d, q -> r -> r); } public static interface $$dof<T> { public T $dof(T n, T d); } public static <T> $$dof<T> $dof($Divide<T, T> $L0, $$neq<T> $L1, $Additive_identity<T> $L2) { return (n, d) -> $L0.divide(n, d, q -> r -> $L1.$neq(r, $L2.additive_identity()) ? error("Division failed unexpectedly. ") : q); } public static interface $Gcd<T> { public T gcd(T a, T b); } public static <T> $Gcd<T> gcd($$encode<church.lang.ByteStream, T> $L0, $$equal<T> $L1, $Additive_identity<T> $L2, $$rem<T> $L3) { return new $Gcd<T>() { public T gcd(T a, T b) { $S0.$encode($L0.$encode($S0.$encode($L0.$encode($S0.$encode(output, "gcd> a: "), a), ", b: "), b), "\n"); return $L1.$equal(b, $L2.additive_identity()) ? a : gcd(b, $L3.$rem(a, b)); } }; } }