-module(ask@equivalence). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([trivial/0, 'and'/2, 'or'/2, 'not'/1, list/1, pair/2, map_input/2]). -spec trivial() -> fun((FLQ, FLQ) -> boolean()). trivial() -> fun(_, _) -> true end. -spec 'and'(fun((FLS, FLS) -> boolean()), fun((FLS, FLS) -> boolean())) -> fun((FLS, FLS) -> boolean()). 'and'(First, Second) -> fun(Value, Other) -> First(Value, Other) andalso Second(Value, Other) end. -spec 'or'(fun((FLW, FLW) -> boolean()), fun((FLW, FLW) -> boolean())) -> fun((FLW, FLW) -> boolean()). 'or'(First, Second) -> fun(Value, Other) -> First(Value, Other) orelse Second(Value, Other) end. -spec 'not'(fun((FMA, FMA) -> boolean())) -> fun((FMA, FMA) -> boolean()). 'not'(Eq) -> fun(Value, Other) -> not Eq(Value, Other) end. -spec list(fun((FMD, FMD) -> boolean())) -> fun((list(FMD), list(FMD)) -> boolean()). list(Eq) -> fun(Values, Others) -> case {Values, Others} of {[], []} -> true; {[Value | Values@1], [Other | Others@1]} -> Eq(Value, Other) andalso (list(Eq))(Values@1, Others@1); {_, _} -> false end end. -spec pair(fun((FMH, FMH) -> boolean()), fun((FMJ, FMJ) -> boolean())) -> fun(({FMH, FMJ}, {FMH, FMJ}) -> boolean()). pair(First, Second) -> fun(Value, Other) -> case {Value, Other} of {{Value1, Value2}, {Other1, Other2}} -> First(Value1, Other1) andalso Second(Value2, Other2) end end. -spec map_input(fun((FMM, FMM) -> boolean()), fun((FMO) -> FMM)) -> fun((FMO, FMO) -> boolean()). map_input(Eq, Fun) -> fun(Value, Other) -> Eq(Fun(Value), Fun(Other)) end.