Вот некоторые предикаты Prolog, которые генерируют все двоичные функции в заданном наборе:
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).