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)