type_kodkod2(relref(Id), Env, rel(Types), relref(Id)) :- !,
lookup_reltypes(Id,Env,Types).
type_kodkod2(varref(Id), Env, VType, K) :- !,
lookup_vartypes(Id,Env,Types),
( Types = [p2i] ->
VType = int_expression, K=expr2int(varref(Id))
;
VType = rel(Types), K=varref(Id)).
type_kodkod2(int(I), _Env, int_expression, int(I)) :- !.
type_kodkod2(prj(Pos,Arg), Env, rel(P), prj(Pos,NArg)) :-
!,type_kodkod(Arg,Env,rel(S),NArg),
nth0s(Pos,S,P).
type_kodkod2(forall(Decls,Formula), Env, formula, forall(NDecls,NFormula)) :-
!,type_quantifier(Decls,Formula,Env,_,NDecls,NFormula).
type_kodkod2(exists(Decls,Formula), Env, formula, exists(NDecls,NFormula)) :-
!,type_quantifier(Decls,Formula,Env,_,NDecls,NFormula).
type_kodkod2(comp(Decls,Expr), Env, rel(Types), comp(NDecls,NExpr)) :-
!,type_quantifier(Decls,Expr,Env,rel(Types),NDecls,NExpr).
type_kodkod2(Expr, Env, Type, NExpr) :-
functor(Expr,F,Arity),
functor(Lookup,F,Arity),
ktype(Lookup,Type),!,
Expr =.. [_|Args], Lookup =.. [_|Types],
maplist(type_kodkod3(Env),Args,Types,NArgs),
NExpr =.. [F|NArgs].
type_kodkod2(Expr, _Env, _Type, _NExpr) :-
throw( unsupported_kodkod_expression(Expr) ).