%% nat [0,10]/10

:- dynamic and_prod/3, and_godel/3, and_luka/3, or_prod/3, or_godel/3, or_luka/3, pri_prod/3,pri_sub/3,pri_add/3,pri_min/3,pri_max/3.

member(0).
member(0.1).
member(0.2).
member(0.3).
member(0.4).
member(0.5).
member(0.6).
member(0.7).
member(0.8).
member(0.9).
member(1).

members([0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1]).

top(1).
bot(0).

leq(X,Y):-X =< Y.

and_prod(X,Y,Z) :- pri_prod(X,Y,Z).
and_godel(X,Y,Z) :- pri_min(X,Y,Z).
and_luka(X,Y,Z) :- pri_add(X,Y,U1), pri_sub(U1,1,U2), pri_max(U2,0,Z).

or_prod(X,Y,Z) :- pri_prod(X,Y,U1), pri_add(X,Y,U2), pri_sub(U2,U1,Z).
or_godel(X,Y,Z) :- pri_max(X,Y,Z).
or_luka(X,Y,Z) :- pri_add(X,Y,U1), pri_min(U1,1,Z).

pri_prod(X,Y,Z) :- A is X * Y, aprox(A,Z).
pri_sub(X,Y,Z) :- A is X-Y, aprox(A,Z).
pri_add(X,Y,Z) :- A is X+Y, aprox(A,Z).
pri_min(X,Y,Z) :- (X=<Y,Z=X;X>Y,Z=Y).
pri_max(X,Y,Z) :- (X=<Y,Z=Y;X>Y,Z=X). % max(x,y)

aprox(X,Y) :- members([A|B]), aprox2(A,B,Y,X).
aprox2(A,[],A,_).
aprox2(A,[B|C],R,D):- Aux is A-D, abs(Aux, Abs), Aux2 is B-D, abs(Aux2,Abs2), (Abs < Abs2, !, aprox2(A,C,R,D); aprox2(B,C,R,D)).

abs(X,X):- X > 0,!.
abs(X,Y):- Y is 0-X.