plus(0, Y, Y).
plus(s(X), Y, s(Z)) :- plus(X, Y, Z).

times(0, Y, 0).
times(s(X), Y, W) :- times(X, Y, Z), plus(Z, Y, W).

eq(X,Y) :- unify_with_occurs_check(X,Y).

tpof(Gamma, lam(X,M), arrow(A,B)) :-
    tpof([tp(X,A)|Gamma], M, B).

tpof(Gamma, app(M,N), B) :-
    tpof(Gamma, M, arrow(A1,B)),
    tpof(Gamma, N, A2),
    eq(A1,A2).

tpof([tp(X,A1)|Gamma], var(X), A2) :-
    eq(A1,A2).

tpof([tp(Y,B)|Gamma], var(X), A) :-
    X \= Y,
    tpof(Gamma, var(X), A).
