// maska.code




bool isEqualeTree(var A,var B){
	n=A.getRowSize();
	if(n!=B.getRowSize())return 0;
	if(n==0)return A==B;
	type=A.typeof();
	if(type!=B.typeof())return 0;
	if(n==2){if({"+","*","||","&&","|","&","==","!="}.find(type)>=0){
		ok=isEqualeTree(A.getSub({0}),B.getSub({0}));
		if(ok)ok=isEqualeTree(A.getSub({1}),B.getSub({1}));
		if(ok)return 1;
		ok=isEqualeTree(A.getSub({0}),B.getSub({1}));
		if(ok)ok=isEqualeTree(A.getSub({1}),B.getSub({0}));
		return ok;
		}}
	i=0;
	for(;i<n;++i)if(!isEqualeTree(A.getSub({i}),B.getSub({i})))return 0;
	return 1;
}



bool CommandIsMask(var cod,var mask,var map){
	if(isset(map)){if(typeof((*map))!="map")( *map)=((map)0);}
	type=mask.typeof();
	if(type=="#")return 1;
	if(type=="var"){
		if(isset(map)){
			if(map->find(((string)mask)))return isEqualeTree((*map)[((string)mask)],cod);
			(*map)[((string)mask)]=cod;
			}
		return 1;
		}
	typeCode=cod.typeof();
	if(typeCode!=type)return 0;
	if({"digit","int","string","float","double"}.find(type)>=0)return mask==cod;
	if(type=="Cast"){if(mask.typeof("type")!=cod.typeof("type"))return 0;}
	n=cod.getRowSize();
	if(type=="function"){
		n2=mask.getRowSize();
		i=0;
		for(;i<n&&i<n2;++i)if(!CommandIsMask(cod.getSub({i}),mask.getSub({i}),map))return 0;
		if(n2<n){
			for(;i<n;++i)if(cod.getSub({i}).typeof()!="#")return 0;
			return 1;
			}
		for(;i<n2;++i)if(mask.getSub({i}).typeof()!="#")return 0;
		return 1;
		}
	if(n==2){if({"+","*","||","&&","|","&","==","!="}.find(type)>=0){
		map2=((map)0);
		ok=CommandIsMask(cod.getSub({0}),mask.getSub({0}),&map2);
		if(ok)ok=CommandIsMask(cod.getSub({1}),mask.getSub({1}),&map2);
		if(ok){
			if(isset((*map)))( *map)+=map2;
			return 1;
			}
		ok=CommandIsMask(cod.getSub({0}),mask.getSub({1}),map);
		if(ok)ok=CommandIsMask(cod.getSub({1}),mask.getSub({0}),map);
		return ok;
		}}
	i=0;
	for(;i<n;++i)if(!CommandIsMask(cod.getSub({i}),mask.getSub({i}),map))return 0;
	return 1;
}



void main(){
	mask=PROGRAM("#=f(t+x,1+u)+x+u");
	cod=PROGRAM("n=ff(10+12*p,2+1)+p*12+2");
	map=0;
	ok=CommandIsMask(cod,mask,&map);
	trace(ok?"Подходит":"Неподходит");
	trace(map.export());
	getstring();
}


// maska.code	:-|