member(X, [X|_]).
member(X, [_|T]) :- member(X,T).

append([], X, X).
append([X|T], Y, [X|TY]) :- append(T,Y,TY).

:- op(700, xfx, is),
   op(700, xfx, <),
   op(700, xfx, =<),
   op(700, xfx, >),
   op(700, xfx, >=),
   op(700, xfx, =\=),
   op(700, xfx, =:=),
   op(500, yfx, +),
   op(500, yfx, -),
   op(500, yfx, /\),
   op(500, yfx, \/),
   op(500, yfx, xor),
   op(400, yfx, *),
   op(400, yfx, /),
   op(400, yfx, div),
   op(400, yfx, mod),
   op(400, yfx, <<),
   op(400, yfx, >>),
   op(200, fy, -),
   op(200, fy, +).

X is A :- number(A), !, X=A.
X is V :- var(V), !, stop('variable in arithmetics').
R is Ax + Bx :- !, A is Ax, B is Bx, int2_add(A, B, R).
R is Ax - Bx :- !, A is Ax, B is Bx, int2_sub(A, B, R).
R is Ax * Bx :- !, A is Ax, B is Bx, int2_mul(A, B, R).
R is Ax / Bx :- !, A is Ax, B is Bx, int2_div(A, B, R).
R is Ax div Bx :- !, R is Ax / Bx.
R is Ax mod Bx :- !, A is Ax, B is Bx, int2_mod(A, B, R).
R is (+Ax) :- !, A is Ax, int1_abs(A, R).
R is (-Ax) :- !, A is Ax, int1_neg(A, R).
_ is _ :- stop('arithmetics needs numbers').

Ax =:= Bx :- A is Ax, B is Bx, int2p_eq(A,B).
Ax =\= Bx :- A is Ax, B is Bx, int2p_neq(A,B).
Ax < Bx :- A is Ax, B is Bx, int2p_lt(A,B).
Ax =< Bx :- A is Ax, B is Bx, int2p_leq(A,B).
Ax > Bx :- A is Ax, B is Bx, int2p_lt(B,A).
Ax >= Bx :- A is Ax, B is Bx, int2p_leq(B,A).
zero(Ax) :- A is Ax, int1p_zero(A).

gcd(X,Y,R) :- writeln(a), fail.
gcd(X,Y,R) :- writeln(b), zero(Y), !, R=X.
gcd(X,Y,R) :- writeln(c), X1 is X mod Y, gcd(Y,X1,R).
gcd(X,Y,R) :- writeln(a), Y > X, writeln(wat), !, gcd(Y,X,R).
gcd(X,Y,R) :- writeln(b), zero(Y), !, R=X.
gcd(X,Y,R) :- writeln(c), X1 is X mod Y, gcd(Y,X1,R).

test(X) :- writeln(there), zero(X), fail.
test(X) :- writeln(here).

test :- writeln(a), a=a, !, fail.
test :- writeln(b).

xxx :- test.