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));
(*  | (Lst([]),Lst(_))*)
  | (Set([]),Set(_)) -> ()
(*  | (Lst(l1),Lst(a2::_))*)
  | (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")