let rec compare_types term term_type =
match term,term_type with
(Base(Var(n)),_)
| (Base(Const(n)),_)
| (Prime(Var(n)),_ )
| (Prime(Const(n)),_) ->
(try
let type_elet = Globals.type_table#get_type n in
if not (compatible_types (type_elet,term_type)) then
raise (Invalid_build "1")
with Not_found -> ignore (Globals.type_table#register_type n term_type));
| (Inv(a1),Inv(a2)) ->
compare_types a1 a2
| (Crypt(a1,b1),Crypt(a2,b2))
| (Scrypt(a1,b1),Scrypt(a2,b2))
| (Cons(a1,b1),Cons(a2,b2))
| (Pair(a1,b1),Pair(a2,b2)) ->
compare_types a1 a2;
compare_types b1 b2
| (Function(a1,[t1]),Hash(a2)) ->
compare_types a1 (Base(Hash_func));
compare_types t1 a2
| (Function(a1,l1),Function(a2,l2)) ->
compare_types a1 a2;
List.iter2 compare_types l1 l2
| (Function(a1,_),Base(a2)) ->
compare_types a1 (Base(a2));
| (Set([]),Set(_)) -> ()
| (Set(l1),Set([a2])) ->
List.iter (fun a1 -> compare_types a1 a2) l1;
| (Set([]),Function(_)) ->
()
| (Set(la1),Function(b2,l2)) ->
let rec check_each_arg = function
(Pair(a1,la1),p2::lp2) ->
compare_types a1 p2;
check_each_arg (la1,lp2)
| (a1,[]) ->
compare_types a1 b2
| _ -> invalid_arg "compare_types: incorrect number of arguments"
in
List.iter (fun a1 -> check_each_arg (a1,l2)) la1
| _ ->
if (not (always_compatible_types term_type)) then
raise (Invalid_build "1")