let rec compatible (t1 : string) (t2 : string) : bool = 
  let test t1 t2 = (( t2="message" || t1="message" || (t2="function" && t1="hash_func"||  (t1="function" && t2="hash_func"|| t1=t2) && t1<>"" && t2<>"" )
  in
  if (test t1 t2) then true
  else(let decomposet1 = (decompose t1) in
       let decomposet2 = (decompose t2) in
       if(t1="set" && decomposet1=[] && decomposet2<>[] && (car decomposet2)="set"then true else
       if(t1="list" && decomposet1=[] && decomposet2<>[] && (car decomposet2)="list"then true else
       if(decomposet1<>[] && ((List.length decomposet2)=(List.length decomposet1)) &&(car decomposet1)=(car decomposet2))
       then(
               let rec aux l1 l2 =
         if(l1=[] && l2=[]) then true
         else if(compatible (car l1)(car l2)) then (aux (cdr l1)(cdr l2))
         else false
        in
        ( ((car decomposet1)=(car decomposet2))&&(aux (cdr decomposet1) (cdr decomposet2)) );
       )
       else if (decomposet1<>[] && ((List.length decomposet2)<=(List.length decomposet1)) && (car decomposet1)<>"pair" && (car decomposet1)<>"scrypt" && (car decomposet1)<>"crypt"then true 
       else false)