Here are some Prolog predicates that generate all binary functions in a job set:
gen_binop(A,BinOp):- cartesian(A,Cart), gen_func(Cart,A,BinOp).gen_func(Dom,Rng,Func) :- is_set(Dom), is_set(Rng), gen_func(Dom,Rng,[],Tmp), reverse(Tmp,Func). cartesian(A,B,Cart):- findall([X,Y],(member(X,A),member(Y,B)),L), list_to_set(L,Cart),!. gen_func([],_,Func,Func). gen_func([H|T],Rng,Func1,Func) :- member(Y,Rng), Func2=[[H,Y]|Func1], gen_func(T,Rng,Func2,Func). Finally, we test to see if any given binary operation is non-associative (and then negate that to find the associative ones): non_assoc_binop(BinOp):- domain(BinOp,D), flatten(D,A), cartesian3(A,A,A,Cart), member([X,Y,Z],Cart), eval(BinOp,[X,Y],X1), eval(BinOp,[Y,Z],Y2), eval(BinOp,[X1,Z],U), eval(BinOp,[X,Y2],V), U\=V. eval(F,X,Y) :- function(F), member([X,Y],F). function(PL) :- pair_list(PL), forall(image(PL,_,ImgX),func_image(PL,ImgX)). image(PL,X,ImgX) :- pair_list(PL), domain(PL,Dom), member(X,Dom), findall(Y,member([X,Y],PL),L), list_to_set(L,ImgX). func_image(PL,ImgX) :- image(PL,_,ImgX), length(ImgX,1). pair_list([]). pair_list([[_,_]|T]) :- pair_list(T).