QueryResultContext CBlockInterpreter::query_is_kindOf(HBlock c_block, HBlockKind c_block1, HRunLocalScope localsEntry, QueryStack *stk)
{

    //Kind vs Kind
	 

	if (HBlockKindNamed nkind = asHBlockKindNamed(c_block))
	{
		HBlock resolved = resolve_kind(nkind);
		if (resolved != nullptr)
		{
			return query_is_kindOf( resolved, c_block1,  localsEntry, stk);
		}
	}

	if (HBlockKindNamed nkind = asHBlockKindNamed(c_block1))
	{
		HBlockKind resolved1 = resolve_kind(nkind);
		if (resolved1 != nullptr)
		{
			return query_is_kindOf(  c_block , resolved1, localsEntry, stk);
		}
	}


	 
	 
	if (auto avar = asHBlockVariableNamed(c_block))
		{
			c_block->dump("");
			c_block1->dump("");
			auto qr = query_is_kindOf(avar->kind, c_block1, localsEntry, stk);
			return qr;
		}
	  

	if (auto avar = asHBlockVariableNamed(c_block))
	{
		c_block->dump("");
		c_block1->dump("");
		auto qr = query_is_kindOf(avar->kind, c_block1, localsEntry, stk);
		return qr;
	}






	if (HBlockKindNamed bkind = asHBlockKindNamed(c_block))
	{

		if (isSameString(bkind->named->named(), language->getMetaKindRelation()))
		{
			if (auto arel = asHBlockRelationBase(c_block1)) return QEquals;
			return QNotEquals;
		}
	}

	if (HBlockKindNamed bkind = asHBlockKindNamed(c_block1))
	{

		if (isSameString(bkind->named->named(), language->getMetaKindRelation()))
		{
			if (auto arel = asHBlockRelationBase(c_block)) return QEquals;
			return QNotEquals;
		}


		if (auto avar = asHBlockVariableNamed(c_block))
		{
			c_block->dump("");
			c_block1->dump("");
			auto qr = query_is(avar->kind, bkind, localsEntry, stk);
			return qr;
		}
	}




	//Metakinds
	if (HBlockKind bkind = asHBlockKind(c_block))
	{
		if (c_block1 == MetaKind)   return QEquals;
	}
	if (HBlockKindEntity bkind = asHBlockKindEntity(c_block))
	{
		if (c_block1 == MetaKindEntity)   return QEquals;
	}
	if (HBlockCompositionPhrase bkind = asHBlockCompositionPhrase(c_block))
	{
		if (c_block1 == MetaKindPhrase)   return QEquals;
	}

	if (HBlockRelationBase bkind = asHBlockRelationBase(c_block))
	{
		if (c_block1 == MetaKindRelation)   return QEquals;

		if (HBlockKindEntity bkindE = asHBlockKindEntity(c_block1))
		{
			return QEquals;
		}
	}


	if (HBlockCompositionRelation bkind = asHBlockCompositionRelation(c_block))
	{
		if (c_block1 == MetaKindRelation)   return QEquals;
	}
	if (HBlockText btext = asHBlockText(c_block))
	{
		if (CBlock::isSame(c_block1.get(), MetaKindText.get()))   return QEquals;

	}


	//is scond a kind of anything ??
 
	 
		if (HBlockKind akind = asHBlockKind(c_block))
		{
			bool b = is_derivadeOf(akind, c_block1);
			if (b) return QEquals;
		}
		else if (HBlockInstance aInstance = asHBlockInstance(c_block)) {
			bool b = is_derivadeOf(aInstance, c_block1, localsEntry);
			if (b) return QEquals;
		}
	 



		if (HBlockAction act = asHBlockAction(c_block))
			if (HBlockKindValue kval = asHBlockKindValue(c_block1))
			{
				if (isSameString(kval->named, "action"))
				{
					return QEquals;
				}
			}
	

	return QUndefined;
}
QueryResultContext Interpreter::CBlockInterpreter::query_comp(string cs, HBlock vr1, HBlock vr2, HRunLocalScope localsEntry, QueryStack * stk)
{

	// vr1 e vr2 sao enum do mesmo tipo ?
	
	if (HBlockMatchNoum mm1 = asHBlockMatchNoum(vr1))
	{
		auto ax = resolve_argument(mm1->inner, localsEntry, stk);
		if (ax != nullptr)
		{
			if (CBlock::isSame(vr1.get(), ax.get()) == false)
			{
				return query_comp(cs,  ax, vr2, localsEntry, stk);
			}
		}
	}


	 if (HBlockMatchNoum mm2 = asHBlockMatchNoum(vr2))
	 {
		 auto ax = resolve_argument(mm2->inner, localsEntry, stk);
		 if (ax !=nullptr)
		 {
			 if (CBlock::isSame( vr2.get() , ax.get() ) ==false )
			 {
				 return query_comp(cs, vr1, ax, localsEntry, stk);
			 }
		 }
	 }

	if (cs == "greater" || cs == "less")
	{
		if (HBlockInstanceNamed in1 = asHBlockInstanceNamed(vr1))
		{
			if (HBlockInstanceNamed in2 = asHBlockInstanceNamed(vr2))
			{
				auto k1 = in1->baseKind;
				auto k2 = in2->baseKind;

				if (HBlockKindValue kv1 = asHBlockKindValue(k1))
					if (HBlockKindValue kv2 = asHBlockKindValue(k2))
					{
						bool is_equivalent = false;

						if (CBlock::isSame(kv1.get(), kv2.get()))is_equivalent = true;
						else
						{
							if (is_derivadeOf(k1, k2) || is_derivadeOf(k2, k1))is_equivalent = true;
						}
						if(is_equivalent)
						{
							if ((cs == "greater")&&(in1->id > in2->id)) return QueryResultContext(QEquals);
							if ((cs == "greater") && (in1->id <= in2->id)) return QueryResultContext(QNotEquals);
							if ((cs == "less") && (in1->id < in2->id)) return QueryResultContext(QEquals);
							if ((cs == "less") && (in1->id >= in2->id)) return QueryResultContext(QNotEquals);
						}
						else
						{
							logError("incompatible comparasion");
						}
					}
			}
		}
	}

	// tem algum decide para isso ?
	for (auto dctIF : decides_if)
	{
		if (HBlockMatchIsAdverbialComparasion  mAdvComp = asHBlockMatchIsAdverbialComparasion(dctIF->queryToMatch))
		{
			 
			if (mAdvComp->adverb == cs)
			{

				auto result1 = Match(mAdvComp->obj, vr1, localsEntry, stk);
				if (result1.hasMatch == true)
				{
					printf("Matched\n");
					auto localsNext = std::make_shared< CRunLocalScope >(nullptr, result1.maptch);
					
					auto result2 = Match(mAdvComp->value, vr2, localsNext, stk);
					if (result2.hasMatch == true)
					{

						HRunLocalScope localsNext_inner = std::make_shared< CRunLocalScope >(localsNext, result2.maptch);
				 

						auto r = getDecidedValue(dctIF->decideBody, localsNext_inner, stk);

						if (r.result == QEquals)
						{
							return r;
						}
						return r;
					}
				}
			}
		}
	}


	printf("==============================\n");
	if(localsEntry!=nullptr)localsEntry->dump("");
	vr1->dump("");
	vr2->dump("");

	return QueryResultContext(QUndefined);
}