Exemplo n.º 1
0
  static void exec(T min, T max, HBlock &hist, DBlock const &input)
  {
    length_type num = hist.size();
    T delta = (max - min) / (num - 2);

    for (index_type i = 0; i < input.size(1, 0); ++i)
    {
      index_type n = hist_bin(min, max, delta, num, input.get(i));
      hist.put(n, hist.get(n) + 1);
    }
  }
QueryResultContext CBlockInterpreter::query_is(HBlock c_block, HBlock c_block1, HRunLocalScope localsEntry, QueryStack *stk_in)

{

	 
 

	if (c_block->isSame(c_block.get(), c_block1.get()))
	{
		return QEquals;
	}
	if (c_block == nullptr)
	{
		return QUndefined;
	}
	if (c_block1 == nullptr)
	{
		return QUndefined;
	}

	std::unique_ptr<QueryStack> stk_unique = nullptr;
	 
	if (stk_in != nullptr)
	{
		if (stk_in->isQuery("is", c_block, c_block1))
		{
			return QUndefined;
		}
		 stk_unique = make_unique<QueryStack>(*stk_in); 
	}
	else
	{
		  stk_unique = make_unique<QueryStack>();
		 
	}

	QueryStack *stk   = stk_unique.get();
	stk->addQuery("is", c_block, c_block1);


 



    //resolve It
 

	if (CBlock::isSame(c_block1.get(), Anything.get()))
	{
		if (is_primitive_value(c_block,localsEntry,stk))
		{
			return QEquals;
		}
	}


	if (HBlockNoum nnoum = asHBlockNoum(c_block1))
	{
		HBlock resolved = resolve_noum(nnoum, localsEntry);
		if (resolved != nullptr)
		{			
			return query_is(c_block, resolved, localsEntry, stk);
		}
		if (nnoum->named() == "kind")
		{
			if ( asHBlockKind(c_block) != nullptr) return QEquals;
		} 
	}

    if (HBlockNoum nnoum2 = asHBlockNoum(c_block))
    {
        HBlock resolved = resolve_noum(nnoum2, localsEntry);
        if (resolved) 
		{
			return query_is(resolved, c_block1, localsEntry, stk);
        }
		
		if (nnoum2->named() == "kind")
		{
			if (asHBlockKind(c_block1) != nullptr) return QEquals;
		}
    }

	//printf("Query :\n");
	//c_block->dump("");
	//c_block1->dump("");
	//printf("\n");


 

	if (HBlockKind ckind = asHBlockKind(c_block1))
	{
		return query_is_kindOf(c_block, ckind, localsEntry, stk);
	}
	else
	{
		if (HBlockKind ckind0 = asHBlockKind(c_block))
		{
			return query_is_kindOf(c_block1, ckind0, localsEntry, stk);
		}
	}
 


 
 





	if (auto vvar = asCBlockVariableNamed(c_block1.get()))
	{
		auto r_var = vvar->value;
		if (r_var == nullptr) r_var = Nothing;
		return query_is(c_block, r_var, localsEntry, stk);
	}
	if (auto vvar = asCBlockVariableNamed(c_block.get()))
	{
		auto r_var = vvar->value;
		if (r_var == nullptr) r_var = Nothing;
		return query_is( r_var, c_block1, localsEntry, stk);
	}


	// check constant values
	for (auto cc : constant_assignments)
	{
		if (CBlock::isSame(  cc->get_obj().get(), c_block.get()) )
			if (CBlock::isSame(cc->get_definition().get(), c_block1.get()))
			{
				return QEquals;
			}
	}

	if (HBlockActionNamed cann = asHBlockActionNamed(c_block))
	{
		if (HBlockNoum nnoum2 = asHBlockNoum(c_block1))
		{			 
			if ((cann->named== nnoum2->named()))
			{
				return QEquals;
			}
		}
	}
	if (HBlockActionNamed cann = asHBlockActionNamed(c_block1))
	{
		if (HBlockNoum nnoum2 = asHBlockNoum(c_block))
		{
			if ((cann->named == nnoum2->named())) return QEquals;
		}
	}


	if (HBlockInstance cinst1 = asHBlockInstance(c_block))
	{
		if (HBlockInstanceNamed cinstvalNamed = asHBlockInstanceNamed(c_block1))
		{
			auto req = query_is_instance_valueSet_valueInstance(cinst1 , cinstvalNamed  );
			if (req.result != QUndefined) return req;
		}

		if (HBlockInstance cinst2 = asHBlockInstance(c_block1))
		{
			//if (isSameString(cinst1  , cinst2 )) return QEquals;
			if ( CBlock::isSame(cinst1.get(), cinst2.get())) return QEquals;
			return QNotEquals;
		}



		if (HBlockKindEntity kThing = asHBlockKindEntity(c_block1))
		{
			if (is_derivadeOf(cinst1, kThing, localsEntry))
			{
				return QEquals;
			}
			return QNotEquals;
		}
		if (HBlockKindValue kVal = asHBlockKindValue(c_block1))
		{
			if (is_derivadeOf(cinst1, kVal, localsEntry)) return QEquals;
			return QNotEquals;
		}

		//if (HBlockNoum knn = asHBlockNoum(c_block1))
		//{
		//	if (isSameString(knn->named, cinst1->named)) return QEquals;
		//}

	}

	
	 
	   
    
    //Resolve List OR
    if (HBlockList_OR  orList = asHBlockList_OR(c_block1))
    {
        for (auto &item : orList->lista)
        {
			std::unique_ptr<QueryStack>  next_stack =  generateNextStack(stk, "is", orList, c_block, item);
			if (next_stack != nullptr)
			{
				QueryResultContext qcc = query_is(c_block, item, localsEntry, next_stack.get());
				if (qcc.result == QEquals) return qcc;
			}
        }
    }

    //Resolve List OR
    if (HBlockSelector_All  selector_all = asHBlockSelector_All(c_block))
    {
		std::unique_ptr<QueryStack>  next_stack = generateNextStack(stk, "is", selector_all, c_block, c_block1);
		if (next_stack != nullptr)
		{
			return Selector_all(selector_all->what, localsEntry, [&](HBlock e1)
			{
				return query_is(e1, c_block1, localsEntry, next_stack.get());

			});
		}
    }

    if (HBlockSelector_Any  selector_any = asHBlockSelector_Any(c_block))
    {
		std::unique_ptr<QueryStack>  next_stack = generateNextStack(stk, "is", selector_any, c_block, c_block1);
		if (next_stack != nullptr)
		{
			return Selector_any(selector_any->what, localsEntry, [&](HBlock e1)
			{
				return query_is(e1, c_block1, localsEntry, next_stack.get());

			});
		}
    }



	if (HBlockMatch  m1 = asHBlockMatch(c_block1))
	{
		auto res_x = Match(m1, c_block, localsEntry, stk);
		if (res_x.hasMatch)
		{
			return QueryResultContext(QEquals, res_x.maptch);
		}
		return QueryResultContext(QNotEquals);
	}

	if (HBlockMatch  m2 = asHBlockMatch(c_block))
	{
		auto res_x = Match(m2, c_block1, localsEntry, stk);
		if (res_x.hasMatch)
		{
			return QueryResultContext(QEquals, res_x.maptch);
		}
		return QueryResultContext(QNotEquals);
	}



    for (auto dct : decides_what) 
    {
		std::unique_ptr<QueryStack>  next_stack = generateNextStack(stk, "is", dct, c_block, c_block1);
		if (next_stack != nullptr)
		{
			//porque testando isso ?
			//if (asHBlockInstance(c_block1) == nullptr)
			{
				auto dctValueWrap_1 = getDecidedValueOf(c_block1, dct, nullptr, next_stack.get());
				if (dctValueWrap_1 != nullptr) {
					QueryResultContext rw = query_is(c_block, dctValueWrap_1, localsEntry, next_stack.get());  //is not opnional
					if (rw.result != QUndefined)
					{
						return rw;
					}
				}
			}
		}
    }





	for (auto dct : decides_noum1)
	{
		std::unique_ptr<QueryStack>  next_stack = generateNextStack(stk, "is", dct, c_block, c_block1);
		if (next_stack != nullptr)
		{ 
				auto dctValueWrap_1 = getDecidedValueOf(c_block1, dct, nullptr, next_stack.get());
				if (dctValueWrap_1 != nullptr) {
					QueryResultContext rw = query_is(c_block, dctValueWrap_1, localsEntry, next_stack.get());  //is not opnional
					if (rw.result != QUndefined)
					{
						return rw;
					}
				} 
		}
	}



 
    
	QueryResultContext qprop = query_is_propertyOf_value(c_block, c_block1, localsEntry, stk);
		if (qprop.result != QUndefined)
		{
			return qprop;
		}


	
		QueryResultContext rinst = (query_is_instance_valueSet(c_block, c_block1, stk));
		if (rinst.result != QUndefined) {
			return rinst;
		}

	
	




    for (auto it = assertions_functional.begin(); it != assertions_functional.end(); ++it) {
        if (HBlockToDecide tdef = asHBlockToDecide(*it)) 
		{

        }
    }


    {
		QueryResultContext qprop = query_is_Variable_value(c_block, c_block1,localsEntry, stk);  // Verifica as variaveis globais
        if (qprop.result != QUndefined) {
            return qprop;
        }
    }

  

	QueryResultContext r2 = query_is_same(c_block, c_block1,localsEntry, stk);
    if (r2.result == QEquals) {
        return r2;
    }

	{
		if (HBlockInstance ninst_1 = asHBlockInstance(c_block))
			if (HBlockInstance ninst_2 = asHBlockInstance(c_block1)) 
			{
				if (Comparison::isSame_BlockInstance(ninst_1.get(), ninst_2.get()))
				{
					return QEquals;
				}
				 

			}
	}

 

	for (auto dctIF : decides_if)
	{
		if (HBlockMatchDirectIs  DctQueryDirectIS = asHBlockMatchDirectIs(dctIF->queryToMatch))
		{

			auto r = query_is_DecideIf(DctQueryDirectIS, c_block, c_block1, dctIF->decideBody, localsEntry, stk);
			if (r.result != QUndefined)
			{
				return r;
			}

			//std::unique_ptr<QueryStack>  next_stack = generateNextStack(stk, "is", DctQueryDirectIS, c_block, c_block1);
			//if (next_stack != nullptr)
			//{
			//	auto result = Match_DirectIs(DctQueryDirectIS->obj, DctQueryDirectIS->value, c_block, c_block1, nullptr, next_stack.get());
			//	if (result.hasMatch == true)
			//	{
			//		printf("Matched\n");
			//		c_block->dump("");
			//		DctQueryDirectIS->obj->dump("");
			//		printf("\n");
			//		c_block1->dump("");
			//		DctQueryDirectIS->value->dump("");
			//		auto localsNext = std::make_shared< CRunLocalScope >(nullptr, result.maptch);					
			//		localsNext->locals.push_back({ "it", c_block });
			//		auto r = getDecidedValue(dctIF->decideBody, localsNext, next_stack.get());
			//		if (r.result ==QEquals)
			//		{
			//			return r;
			//		}
			//		else
			//		{
			//			return QNotEquals; //Default Outcome for Decide  IF
			//		}
			//		return r;
			//	}
			//}
		}
	}


	if (HBlockMatchNOT matchBlock_not = asHBlockMatchNOT(c_block1))
	{
		auto result = query_is(c_block, matchBlock_not->input, localsEntry, stk);
		if (result.result == QEquals) return QNotEquals;
		if (result.result == QNotEquals) return QEquals;
		return QEquals;
	}


	if (HBlockMatch matchBlock = asHBlockMatch(c_block1))
	{
		std::unique_ptr<QueryStack>  next_stack = generateNextStack(stk, "is", matchBlock, c_block, c_block1);
		if (next_stack != nullptr)
		{
			 
			auto matchBlock_r = Resolve_Selector(matchBlock, localsEntry);


			auto r_mtch = Match(matchBlock_r, c_block, localsEntry, next_stack.get());
			if (r_mtch.hasMatch)
			{
				return  QueryResultContext(QEquals, r_mtch.maptch);
			}
			return QUndefined;
		}
	}

    
    for (auto it = assertions.begin(); it != assertions.end(); ++it) {
		 
		if (HBlockAssertion_is qdef = asHBlockAssertion_is(*it))
		{
			std::unique_ptr<QueryStack>  next_stack = generateNextStack(stk, "is", qdef, c_block, c_block1);
			if (next_stack != nullptr)
			{
				auto qc = query_is_same(c_block, qdef->get_obj(), localsEntry, next_stack.get());
				if (qc.result == QEquals) 
				{
					{
						QueryResultContext r = query_is(qdef->get_definition(), c_block1, localsEntry, next_stack.get());
						if (r.result != QUndefined) 
						{
							return r;
						}
					}

				}
			}
		}
    }


	if (HBlockVariableNamed var_n = asHBlockVariableNamed(c_block1))
	{
		if (var_n->value == nullptr)	return query_is(c_block, Nothing, localsEntry,  stk);
		return query_is(c_block, var_n->value, localsEntry, stk);
	}

	if (HBlockVariableNamed var_n = asHBlockVariableNamed(c_block))
	{
		if (var_n->value == nullptr)	return query_is( Nothing, c_block1, localsEntry, stk);
		return query_is(var_n->value ,c_block1,   localsEntry, stk);
	}



	//logMessage("I cant query");
	//c_block->dump("");
	//c_block1->dump("");

	//se tudo falhar , tente isso ....
	auto resolved_b = exec_eval(c_block1, localsEntry, stk);
	if (resolved_b != nullptr)
	{
		if (CBlock::isSame(resolved_b.get(), c_block1.get()) == false)
		{
			return query_is(c_block, resolved_b, localsEntry, stk);
		}
	}
	auto resolved_a = exec_eval(c_block , localsEntry, stk);
	if (resolved_a != nullptr)
	{
		if (CBlock::isSame(resolved_a.get(), c_block.get()) == false)
		{
			return query_is(resolved_a, c_block1, localsEntry, stk);
		}
	}

 
    return QueryResultContext(QUndefined);

}
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
CBlockInterpreter::query_is_propertyOf_value_imp(HBlock propname, HBlock propObj, HBlock c_block1, HRunLocalScope localsEntry, QueryStack *stk) 
{

	if (HBlockNoum property_noum = asHBlockNoum(propname))
	{
		std::unique_ptr<QueryStack>  next_stack = generateNextStack(stk, "is", property_noum, propObj, c_block1);
		if (next_stack != nullptr)
		{
			//eh plural de algo ?
			if (isSameString(property_noum->named(), "plural"))
			{
				string c = asBlockNoum(propObj);
				if (c != "")
				{
					HBlockNoum plural_named = get_plural_of(c);
					if (plural_named != nullptr)
					{
						return query_is(plural_named, c_block1, localsEntry, next_stack.get());
					}
				}
				return QueryResultContext(QUndefined);
			}

			//propObj->dump("");

			if (HBlockInstance cinst = asHBlockInstance(propObj))
			{
				{
					HBlockVariableNamed pvar = cinst->get_property(property_noum->named());
					if (pvar != nullptr)
					{
						auto next_var = pvar->value;
						if (next_var == nullptr) next_var = Nothing;
						if (CBlock::isSame(next_var.get(), Nothing.get()))
						{
							auto def_var = get_default_property_value(property_noum, cinst, localsEntry, stk);
							if (def_var != nullptr) next_var = def_var;
						}

						QueryResultContext rprop = query_is(next_var, c_block1, localsEntry, next_stack.get());
						if (rprop.result == QEquals) return rprop;
						return QNotEquals;
					}
					//logMessage(cinst->named + " Dont have Property " + property_noum->named);
					{
						QueryResultContext  result_prop = query_relation_property(property_noum, propObj, c_block1, localsEntry, next_stack.get());
						if (result_prop.result != QUndefined)
						{
							return result_prop;
						}
						return QueryResultContext(QUndefined);
					}


				}
			}

			// resolve object
			auto obj_resolved = exec_eval(propObj, localsEntry, stk);
			if (CBlock::isSame(obj_resolved.get(), propObj.get()) == false)
			{
				QueryResultContext  result_prop = query_is_propertyOf_value_imp(property_noum, obj_resolved, c_block1, localsEntry, next_stack.get());
				if (result_prop.result != QUndefined) return result_prop;

			}
		}
	}
	else
	{
		//logError("some mistake where\n");
		return QueryResultContext(QUndefined);
	}
    return QueryResultContext(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);
}