Ejemplo n.º 1
0
void AddSynVariantsWithUnusedHomonyms(CClause& C, vector<CBuildingUnit>& BuildingUnits) 
{
	CMorphVariant synVariant(C.GetOpt()->GetGramTab());

	bool FoundUnusedHomonym;
	do
	{
		FoundUnusedHomonym = false;
		for (int UnitNo=0; UnitNo < BuildingUnits.size();UnitNo++)
		{
			int HomonymNo = 0;
			if (BuildingUnits[UnitNo].m_MaxUsedHomonymNo+1 < BuildingUnits[UnitNo].m_HomonymsCount)
			{
				BuildingUnits[UnitNo].m_MaxUsedHomonymNo++;
				HomonymNo = BuildingUnits[UnitNo].m_MaxUsedHomonymNo;
				FoundUnusedHomonym = true;
			};

			if (BuildingUnits[UnitNo].m_ChildClauseNo != -1) 
				AddUnitAsClause(BuildingUnits.begin()+UnitNo, HomonymNo, C, synVariant);
			else
				AddUnitAsWord(BuildingUnits.begin()+UnitNo, HomonymNo, C, synVariant);

		};
		if (FoundUnusedHomonym)
		{
            if (C.IsGoodVariant(synVariant)) 
			    C.m_SynVariants.push_back(synVariant);
			synVariant.Reset();

		};
	}
	while (FoundUnusedHomonym);	
};
Ejemplo n.º 2
0
static void TranslateCoordClauseForGroup(const CClause& C, CGroup& pGrp) 
{
	pGrp.m_iFirstWord = C.UnitNoByWordNo(pGrp.m_iFirstWord);
	pGrp.m_iLastWord = C.UnitNoByWordNo(pGrp.m_iLastWord);
	pGrp.m_MainGroup.m_iFirstWord = C.UnitNoByWordNo(pGrp.m_MainGroup.m_iFirstWord);
	pGrp.m_MainGroup.m_iLastWord = C.UnitNoByWordNo(pGrp.m_MainGroup.m_iLastWord);
	pGrp.m_MainWordNo = C.UnitNoByWordNo(pGrp.m_MainWordNo);
}
Ejemplo n.º 3
0
/*
 Эта функция вызывается только из RuleForEmptyClauses. Проверяет, может ли 
 клауза войти в левостоящую. Если не может, тогда возвращает истину.
*/
bool CRusSentence::HasStrictBorderLeft(int iClauseNum)
{
	CClause* pAbstClause = &GetClause(iClauseNum);

	if( HasStrictestLeftClauseBorder(iClauseNum) )
		return true;

	if( iClauseNum == 0)
		return true;

	if( pAbstClause->HasLeftStarter() )
		return true;

	return false;
}
Ejemplo n.º 4
0
int HasSubConjWithInfinitiveGovernment(const CClause& C) 
{
	for(int i = 0; i < C.m_vectorConjs.size() ; i++ )
	{
		const SConjIndex& conj = C.m_vectorConjs[i];


		if(		(conj.m_FromWhere == FROM_OBOR_DIC)
			&&	(C.GetOpt()->m_pOborDic->m_Entries[conj.m_index].m_ConjType == sub_conj) 
			&&  (C.GetOpt()->m_pOborDic->m_Entries[conj.m_index].m_bConjWithInfinitiveSubord) 
		  )
			return i;
	}

	return -1;	
}
Ejemplo n.º 5
0
int AddUnitAsWord (vector<CBuildingUnit>::const_iterator pUnit, int CurrentHomonymNo, const CClause& C, CMorphVariant& synVariant)
{
	synVariant.PushHomonymNum(CurrentHomonymNo); 
	const CSynWord& W = C.GetWords()[pUnit->m_WordNo]; 
	synVariant.m_SynUnits.back().CopyAncodePattern( W.m_Homonyms[CurrentHomonymNo] );
	synVariant.m_SynUnits.back().m_SentPeriod = CPeriod(pUnit->m_WordNo);
	return pUnit->m_WordNo+1;
};
Ejemplo n.º 6
0
void CreateGroupsForTermins(CClause& C, CFormatCaller& FormatCaller, CMorphVariant& synVariant)
{
  

	vector<int> SynVarHomonyms;
	for (int j = 0; j < synVariant.GetUnitsCount(); j++)
		SynVarHomonyms.push_back( synVariant.GetHomNum(j) );


    FormatCaller.BuildOborotGroups();

	for (size_t TerminNo=0; TerminNo< C.m_pSent->m_vectorTermins.size(); TerminNo++)
	{
		SFoundTermin T = C.m_pSent->m_vectorTermins[TerminNo];
		if (!T.is_part_of(C)) continue;
		T.m_iFirstWord = C.UnitNoByWordNo(T.m_iFirstWord);
		T.m_iLastWord = C.UnitNoByWordNo(T.m_iLastWord);

        // вставлено из-за примера "печатной информации,  фильмов, компьютерных банков данных, ничего. "
       /* bool bSubClause = false;
        for (size_t i=T.m_iFirstWord; i <= T.m_iLastWord; i++)
            if (FormatCaller.sent[i].m_UnitType == EClause)
            {
                bSubClause = true;
                break;
            }
        if (bSubClause) continue;*/


		if	(FormatCaller.create_groups_from_termin( T)) 
		{
			C.m_pSent->m_vectorTermins[TerminNo].m_bGroupsChecked = true;
			/*int WordNo = 0;
			for (int UnitNo = T.m_iFirstWord; UnitNo <= T.m_iLastWord; UnitNo++, WordNo++)
			{
				CSynWord& W = C.GetWords()[C.m_pSent->m_vectorTermins[TerminNo].m_iFirstWord+WordNo];
				//W.SetAllOtherHomsDel(SynVarHomonyms[UnitNo]); 
			};
            */
		}

	};
};
Ejemplo n.º 7
0
int AddUnitAsClause (vector<CBuildingUnit>::const_iterator pUnit, int CurrentHomonymNo, const CClause& C, CMorphVariant& synVariant)
{
	const CClause& Child = C.m_pSent->m_Clauses[pUnit->m_ChildClauseNo];
    CSynUnit SClauseHomonym(C.GetOpt()->GetGramTab());
	SClauseHomonym.m_Type = EClause;
	SClauseHomonym.m_iClauseTypeNum = (CurrentHomonymNo >= Child.m_vectorTypes.size())? -1 : CurrentHomonymNo;
	SClauseHomonym.m_SentPeriod = (CPeriod)Child;
	synVariant.m_SynUnits.push_back(SClauseHomonym);
	return Child.m_iLastWord  + 1;
};
Ejemplo n.º 8
0
tstring  CLogicThread::GetErrorText(int32 CharPos)
{
	tstring s;
    deque<CSentence*>::reverse_iterator SentenceIt = m_Text.m_SentenceList.rbegin(); 	
	while(SentenceIt!=m_Text.m_SentenceList.rend() && CharPos< (*SentenceIt)->m_BeginPos )SentenceIt++; 
	
	if(SentenceIt == m_Text.m_SentenceList.rend())return s;

    CSentence* Sentence = *SentenceIt;
		
	//再找到当前逻辑场景所包含的句子,子句,Token
	CharPos  = CharPos - Sentence->m_BeginPos;
	
    deque<CClause*>::reverse_iterator ClauseIt = m_Text.m_ClauseList.rbegin();
	while(ClauseIt!=m_Text.m_ClauseList.rend() && CharPos< (*ClauseIt)->m_BeginPos )ClauseIt++; 
	if(ClauseIt == m_Text.m_ClauseList.rend())return s;

	CClause* Clause = *ClauseIt;

	CharPos  = CharPos- Clause->m_BeginPos;
    deque<CToken*>::reverse_iterator It = m_Text.m_TokenList.rbegin();
	while(It!=m_Text.m_TokenList.rend() && CharPos< (*It)->m_BeginPos )It++; 
		
	if(It == m_Text.m_TokenList.rend())return s;
	CToken* Token  = *It;
 
	int i = 0;
	if(!Token->IsOK()){
		i = Token->m_MemoryID;
	}
	else if(!Clause->IsOK()){
	    i = Clause->m_MemoryID;
	}
	
	assert(i<LAST_ERROR);
	s = ANALYSE_ERROR[i];
	return s;
}
Ejemplo n.º 9
0
int CGerSentence::GetCountOfStrongRoots(const CClause& C, const CMorphVariant& synVar) const
{
	int iHypPredk = 0;
	int Infinitives = 0;
	bool bInfinitiveConstruction = false;
	
	for (int i = 0; i < synVar.GetUnitsCount(); i++)
	{
		if ( synVar.GetUnitType(i) == EClause ) 
			continue;

		int iWord = synVar.m_SynUnits[i].m_SentPeriod.m_iFirstWord;
			
		const CSynHomonym& Hom = C.GetWords()[iWord].GetSynHomonym(synVar.GetHomNum(i));
		if ( C.GetOpt()->GetGramTab()->IsStrongClauseRoot( Hom.m_iPoses ) )
		{
				iHypPredk++;

				if (Hom.m_bInfinitiveConstruction)
					bInfinitiveConstruction = true;
				else
				if (Hom.HasGrammem(gInfinitiv) && Hom.HasPos(gVER))
					Infinitives++;

				
					
		};
	}

	if (iHypPredk > 1)
		if (bInfinitiveConstruction)
			iHypPredk -= max(1,  iHypPredk-Infinitives);


	return iHypPredk;
};
Ejemplo n.º 10
0
void CTopClauses::AddValsToSubClauses(CClauseNode* pNode, SClauseFuncArg& arg)
{
    CClause* clause = pNode->GetMainClause();
    clause->AddValsToType(arg.m_NewValencies2, arg.m_iClause2TypeNum);

    if (clause->m_ClauseWords.size() != 0)
        return;
    yvector<CClause*> clauses;
    pNode->m_pClauseTree->GetIncludedClauses(clauses);
    for (size_t i = 0; i < clauses.size(); i++) {
        CClause& cl = *clauses[i];
        //такая заплатка: когда сочиняется клауза уже сочиненная и еще какая-то,
        //то новую валентность (обычно подлежащее) надо прописать и во все непосредственные подклаузы сочиняемой кл.
        if ((cl.GetTypesCount() == 1) &&  (arg.m_NewValencies2.size() == 1)) {
            if (!cl.GetType(0).HasSubjVal()) {
                SValency val = arg.m_NewValencies2[0];
                val.m_ValNum = cl.FindSubjVal(0);
                if (val.m_ValNum > -1)
                    cl.AddValToType(val, 0);
            }
        }
    }

}
Ejemplo n.º 11
0
bool CRusSentence::RuleForEmptyClauses(int iClauseNum)
{
	const CClause& Clause = GetClause(iClauseNum);
	int iWord = Clause.m_iFirstWord; 

	if( !IsGoodEmptyClause( &Clause ) ) return false;

	bool bStrictPrevClauseBorder = HasStrictBorderLeft(iClauseNum);	

	//берем тот фрагмент, который стоит справа от найденной цепочки	
	//  если в текущую клаузу была вложена другая клауза, которая заканчивается там же, где текущая клауза
	// тогда  не будем добавлять пустыху направо (неоднозначность границ ),
	int iNext = GetMaxClauseByFirstWord(m_Clauses[iClauseNum].m_iLastWord+1);
	CClause* pAbstClauseRight = NULL;
	if( iNext != -1 )
		pAbstClauseRight = &GetClause(iNext);
	bool bCanConnectRight =		pAbstClauseRight 
							&& 	CanBeMainClauseOfTheLeftGoodEmptyClause(pAbstClauseRight, bStrictPrevClauseBorder)
							&&  (GetMinClauseByLastWord(Clause.m_iLastWord) == iClauseNum)
							&& !HasStrictBorderLeft(iNext);

	//берем тот фрагмент, который стоит слева от найденной цепочки
	CClause* pAbstClauseLeft = NULL;
	int iPrev = GetMinClauseByLastWord(Clause.m_iFirstWord-1);
	if( iPrev != -1 ) 
		pAbstClauseLeft = &GetClause(iPrev);

	//  если предыщая клауза была вложена в другую клаузу, тогда  не будем добавлять пустыху налево,
	//  поскольку  пустыха  может войти обе клаузы (в меньшую и в большую"),
	//   например:
	//  "интервью, опубликованное в четверг, 12 апреля" // "12 апреля"  надо вкладывать в причастный  оборот
	//  "упал кран, который  нам подарили японцы, 12 апреля" // "12 апреля"  надо вкладывать в главную клаузу
	// мы имеем здесь  абсолютныю неоднозначноть
	bool bCanConnectLeft =		pAbstClauseLeft 
							&&  !pAbstClauseLeft->HasType(INP_T)
							&&  !Clause.HasLeftStarter()
							&&  !IsEnclosedClause(iPrev)
							&&  !HasStrictestLeftClauseBorder(iClauseNum);


	// соединение влево будем считать более приоритетным
	if(bCanConnectLeft)
	{
		/* если объединяется пустыха  с инфинитивом,
		   тогда  тип объединенной клаузы должен быть инфинитовом 
		   если объединяется пустыха  со сравном,
		   тогда  тип объединенной клаузы должен быть СРАВН 
		*/
		if  ( (    Clause.HasType(INFINITIVE_T) 
			       || Clause.HasType(COMPARATIVE_T) 
			      ) 
				&& pAbstClauseLeft->m_vectorTypes.empty() 
				&& 1 == pAbstClauseLeft->m_vectorTypes.size() 
			)
			UniteClauses(iPrev, iClauseNum, RightClauseParams);
		else
			UniteClauses(iPrev, iClauseNum, LeftClauseParams);			

		return true;	
	}

	if(bCanConnectRight) 
	{
		UniteClauses(iClauseNum, iNext, RightClauseParams);
		return  true;
	} 



	return false;
}
Ejemplo n.º 12
0
bool CRusSentence::RuleForParticiples(int iClauseNum)
{
	CClause* pAbstClause = &GetClause(iClauseNum);
	int iWord = pAbstClause->m_iFirstWord;

	if ( IsEnclosedClause (iClauseNum) )  return false;

	if ( pAbstClause->HasUnambiguousStrongRootWithoutWeakHomonyms()) return false;

	int iParticipleType; 
	if( (iParticipleType = pAbstClause->FindType(PARTICIPLE_T)) == -1 )
		return false;


	assert(!pAbstClause->m_vectorTypes[iParticipleType].m_Root.IsEmpty());

	CSynWord& pParticiple = m_Words[pAbstClause->m_vectorTypes[iParticipleType].m_Root.m_WordNo];

	
	int iPart = pParticiple.GetHomonymByPOS(PARTICIPLE);
	if( iPart == -1 )
		return false;

	//пытаемся найти слева
	int iPrev = FindNounFromTheLeftOfParticiple(pAbstClause, pParticiple.GetSynHomonym(iPart));

	//пытаемся найти слева подходящее сущ.(тогда причастие после определяемого слова)
	if	(			
					( m_Words[iWord].m_SubordinateConjNo == -1 )
			&&		(		(pAbstClause->m_iFirstWord != pAbstClause->m_iLastWord ) 
						||  (		(iWord+1<m_Words.size())  
								&&	(m_Words[iWord+1].m_SubordinateConjNo != -1 )
							)
					)
			&&		(iPrev != -1)
            &&      (       pAbstClause->m_iLastWord+1 == m_Words.size()  // проверка правой границы  (должен быть знак препинания)
                        ||  m_Words[pAbstClause->m_iLastWord+1].HasDes(OPun)
                     )
		)
	{

		/*
			Поскольку мы собираемся вкладывать клаузу, нам приходится удалять
			все вершины клаузы, кроме найденного причастия и все омонимы причастия
		*/
		// уничтожаем другие вершины клаузы
		int k = 0;
		for( ; k < pAbstClause->m_vectorTypes.size() ; k++)
		{
			if(iParticipleType == k) continue;


			if(k < iParticipleType)  iParticipleType--;

			int WordNo = pAbstClause->m_vectorTypes[k].m_Root.m_WordNo;

			//	не будем удалять омоним, если он единственный у слова
			if (pAbstClause->GetWords()[WordNo].GetHomonymsCount() > 1)
				pAbstClause->DeleteHomonym(pAbstClause->m_vectorTypes[k].m_Root.m_WordNo, pAbstClause->m_vectorTypes[k].m_Root.m_HomonymNo);
			else
				pAbstClause->DeleteClauseType( k );
			k--;
		}

		// заново надо найти омоними причастия, поскольку мы в предыдущем цикле удалили некоторые омонимы
		iPart = pParticiple.GetHomonymByPOS(PARTICIPLE);
		int PartWordNo = pAbstClause->m_vectorTypes[iParticipleType].m_Root.m_WordNo;
		// уничтожаем омонимы причастия (прилагательное или существительное),
		for(k = 0 ; k < pParticiple.GetHomonymsCount() ; k++)
		{
			if(iPart == k) continue;
			if(k < iPart)  iPart--;
			pAbstClause->DeleteHomonym(PartWordNo, k);
			k--;
		}


		return EncloseClauseAsWord(iClauseNum, iPrev);
	}
	else
		// пытаемся найти справа (причастие не отделено запятой)
		if( FindNounFromTheRightOfParticiple(pAbstClause, pParticiple.GetSynHomonym(iPart)  ) )
		{
			// тогда нужно удалить клаузный вариант причастия, а если вариант только один, тогда
			// нужно его отконвертировать в пустыху
			if(pAbstClause->m_vectorTypes.size() == 1)
			{
				assert (pAbstClause->m_vectorTypes[0].m_Type == PARTICIPLE_T);
				pAbstClause->ChangeAllClauseTypesToOneType( SClauseType(UnknownSyntaxElement,-1,-1) );		
			}
			else
			{
				assert( iParticipleType >= 0);
				pAbstClause->DeleteClauseType( iParticipleType );
			}
		}	

	return false;
}
Ejemplo n.º 13
0
void CClause::AssignVariantWeight(CMorphVariant& synVariant)
{
	try
	{
		int iWeight = 0;
		
		//	adding weight by each maximal group 
		int i = synVariant.m_vectorGroups.GetGroups().size() - 1;
		bool bSubjIsInsideGroup = false;
		bool bPredicateIsInsideGroup = false;
		while(  i >= 0   )
		{
			const  CGroup& group = synVariant.m_vectorGroups.GetGroups()[i];
			CPeriod PeriodInSentenceCoords = synVariant.GetSentenceCoordinates(group);

			//  if the last or the first word in the group is indeclinable, 
			bool bStartsOrEndsWithIndeclinable = false;
			{
				const CSynUnit& UnitStart = synVariant.m_SynUnits[group.m_iFirstWord];
				if	(		(UnitStart.m_Type == EWord)
						&&	(GetOpt()->m_IndeclinableMask & GetWords()[PeriodInSentenceCoords.m_iFirstWord].m_Homonyms[UnitStart.m_iHomonymNum].m_iGrammems)
					)
					bStartsOrEndsWithIndeclinable = true;

				const CSynUnit& UnitEnd = synVariant.m_SynUnits[group.m_iLastWord];
				if	(		(UnitEnd.m_Type == EWord)
						&&	(GetOpt()->m_IndeclinableMask & GetWords()[PeriodInSentenceCoords.m_iLastWord].m_Homonyms[UnitEnd.m_iHomonymNum].m_iGrammems)
					)
					bStartsOrEndsWithIndeclinable = true;
			};

			if (		GetOpt()->IsGroupWithoutWeight(group.m_GroupType, group.m_Cause )
					||	(		(group.size() == 2)
							&&	bStartsOrEndsWithIndeclinable
						)
				)
			{ 
				i--; // go to the subgroup or to the next group
				continue;
			};


			// adding weight (size of the group in words) Note, that the group can contain a clause
			iWeight += PeriodInSentenceCoords.size();		

			//  if the last or the first word in the group is indeclinable, 
			if	(bStartsOrEndsWithIndeclinable)
					iWeight--;

			if	(		!synVariant.m_Subjects.empty()
					||	CPeriod(synVariant.GetFirstSubject()).is_part_of(group)
				)
				bSubjIsInsideGroup = true;

			if (CPeriod(synVariant.m_iPredk).is_part_of(group))
				bPredicateIsInsideGroup = true;


		
			
			// go to the subclauses and add weight by each subclause
			for (long k=group.m_iFirstWord; k <= group.m_iLastWord; k++)
				if( synVariant.m_SynUnits[k].m_Type == EClause )
				{
					CPeriod p  = synVariant.m_SynUnits[k].m_SentPeriod;
					CClause* clause = m_pSent->FindClauseByPeriod(p);
					assert(clause != NULL);

					vector<CMorphVariant*> clause_vars = clause->GetSynVariantIndexesByTypeNum(synVariant.m_SynUnits[k].m_iClauseTypeNum);				

					for (long j=0; j < clause_vars.size(); j++)
						if( clause_vars[j]->m_iWeight != -1) 
							clause_vars[j]->m_iWeight += iWeight;				
				};
			
			
			// go to the next groups
			for (i--; i >=0 && synVariant.m_vectorGroups.GetGroups()[i].is_part_of(group);  i--);
		}

		
		

		if (!bSubjIsInsideGroup)
			if (synVariant.m_bGoodSubject)
				iWeight += 1;

		if (!bPredicateIsInsideGroup)
			if (synVariant.m_bGoodSubject)
				iWeight += 1;
		
		
		synVariant.m_iWeight = iWeight;
	}
	catch(...)
	{
		return;
	}
}
Ejemplo n.º 14
0
void CLogicThread::Think(CTaskDialog* Dialog,CSentence* Sentence, int32 AlterClausePos)
{
 	assert(m_Text.m_ClauseList.size() != 0);
    
	vector<int64>  TempList;

	//如果修改的子句还没有输入完毕则不做处理
	assert(AlterClausePos<m_Text.m_ClauseList.size());
    CClause* Clause = m_Text.m_ClauseList[AlterClausePos];
	int32 EndPos  = Clause->m_BeginPos+Clause->m_TokenNum -1;
	if(EndPos<0)return ; //空句子? 可能吗?
	CToken* Token = m_Text.m_TokenList[EndPos];
	if(!Token->IsClauseFlag())return;
	
	//回取逻辑场景
	SentenceLogicSense* sls = &m_SentenceSense;
		
	//如果当前句子不是之前修改的句子,或者不能继续使用之前的分析结果,则重置
    int32 pos = Sentence->m_BeginPos;
	if(sls->BelongSentence != Sentence){
		sls->BelongSentence = Sentence;
	}
	else{ //sls->BelongSentence == Sentence
		if(AlterClausePos == sls->NextClausePos){
			pos=AlterClausePos; //正常分析
		}
		else if(AlterClausePos > sls->NextClausePos){
			//因为前一个Clause已经出错,不用分析也是错,
			assert(!Sentence->IsOK());
			return;
		}
	}

   	if(pos==Sentence->m_BeginPos){
		sls->FatherList.clear();
		Sentence->m_AnalyseResult.Clear();
	}

	EndPos  = Sentence->m_BeginPos+Sentence->m_ClauseNum;
	bool HasError = false;
	
	//检查句子含有的子句之间是否有逻辑冲突
	//如果没有冲突,则试图把这些子句联系起来,推测下一句
	for(pos; pos<EndPos; pos++)
	{
		 Clause = m_Text.m_ClauseList[pos];
         assert(!Clause->IsBlank());
		 if(!Clause->IsOK()){
			 HasError = true;
			 break;
		 }

	     //并联关系词的前一子句不能是set label 和 goto label操作
		 if(Clause->m_LogicRelation == SHUNT_RELATION){
			 
			 if(pos==Sentence->m_BeginPos) //如果第一个子句是并联,警告,但继续执行
			 {
				//NotifyTokenWarning(m_Text.m_TokenList.at(0),i,SentenceIndex);
				//return false;
			 }
			 else{
				 CClause* PreClause =  m_Text.m_ClauseList.at(pos-1);
				 if(PreClause->m_MemoryID == INSTINCT_SET_LABEL ||
					 PreClause->m_MemoryID == INSTINCT_GOTO_LABEL)
				 {
					 Clause->m_MemoryID = ERROR_12;
					 NotifyClauseError(Dialog,Clause,ERROR_12);
					 HasError = true;
					 break;
				 }	
			 }
		 }
		 
		 Energy* Param = NULL;
		 if( BelongInstinct(Clause->m_MemoryID) ){
			 
			 if(BelongIndeInterAction(Clause->m_MemoryID) ){
				 Clause->m_ActionType = INDE_INTER_ACTION;
			 }	 
			 else if(BelongInterAction(Clause->m_MemoryID)){ //外部
				 Clause->m_ActionType = INTER_ACTION;
			 }
			 else Clause->m_ActionType = COMMON_ACTION;
            
			 
			 //如果本能是USE LOGIC, 需要检查临时逻辑是否和目前行为类型冲突
			 //用法: use logic srcName:NewlogicName
			 //注意:USE_LOGIC不属于IsInterOperator()的检查	
			 
			 if( INSTINCT_USE_LOGIC == Clause->m_MemoryID ){
				 eSTRING* s = (eSTRING*)Clause->m_Param;
				 assert(s!= NULL);
				
				 tstring LogicName = *(tstring*)s->Value();      				 
				 
				 //重用逻辑的格式为 原逻辑名:新逻辑名
				 
				 /*不强制要求
				 tstring::size_type n = LogicName.find(':');
				 
				 if(n == tstring::npos || n==LogicName.size()-1){
					 Clause->m_MemoryID = ERROR_23;
					 NotifyClauseError(srcMsg,Clause,ERROR_23);
					 return ;
				 }
				 */
				/* 转到执行阶段
				 LogicName.resize(n);
				 LogicName=TriToken(LogicName);

				 CLogicItem* lg = FindLogic(LogicName);
				 if(lg == NULL) {
					 Clause->m_MemoryID = ERROR_10;
					 NotifyClauseError(Clause,ERROR_10);
					 return;
				 }

				 if(!lg->IsValid()) {
					 Clause->m_MemoryID = ERROR_14;
					 NotifyClauseError(Clause,ERROR_14);
				     HasError = true;
					 break;
				 }
				 Clause->m_ActionType = lg->m_ActionState;
				 
				 ePipeline NewLogic(lg->m_LogicData);
				 *Pipe<< NewLogic;
				 Param = Pipe;
				 */
			 }
			 
			 if(Clause->m_Param){
				 Param = Clause->m_Param->Clone();
			 } 
		 }
		 else {//处理非本能,也就是逻辑行为
			 Clause->m_ActionType =  OUTER_ACTION;

			 //检查是否此子句表达的意思是否正确(思考:需要这样吗?)
			 //if(MEMORY.IsOK(ClauseID))
			 //  throw tstring("cannot understand you inputed clause,Please learn it first");
			 			 
			 //如果非本能有补语 则在本逻辑之前加入一个或多个定义字符串的行为。
			 if(Clause->m_Param != NULL){
				 assert(Clause->m_Param->EnergyType()==TYPE_PIPELINE);
				 ePipeline* Pipe = (ePipeline*)Clause->m_Param;
				 for(int i=0; i<Pipe->Size(); i++)
				 {
					 tstring* str = (tstring*)Pipe->GetData(i);
					 ePipeline*  Clause =  new ePipeline;
					 Clause->PushInt(INSTINCT_DEFINE_STRING);
					 Clause->PushString(*str);
					 Sentence->m_AnalyseResult.Push_Directly(Clause);     
				 }
			 }
			 
		 }	

		 if(Clause->m_LogicRelation == SHUNT_RELATION ){
			 Clause->m_MemoryID = -Clause->m_MemoryID;	
		 }
		 ePipeline*  ClausePipe =  new ePipeline;
		 ClausePipe->PushInt(Clause->m_MemoryID);
		 if(Param != NULL)ClausePipe->Push_Directly(Param);
		 Sentence->m_AnalyseResult.Push_Directly(ClausePipe);	 
	}
    
    sls->NextClausePos = pos; 
	Sentence->m_IsError = HasError;
	if(!HasError)SetForecast(Dialog,SENTENCE,Sentence);
	return;			
}
Ejemplo n.º 15
0
void CTopClauses::NewClause(CClauseNode* pNode1, CClauseNode* pNode2, SClauseFuncArg& arg)
{
    //try
    {
        CClause* clause1 = pNode1->GetMainClause();
        CClause* clause2 = pNode2->GetMainClause();

        bool clause1WordsCountZero = (clause1->m_ClauseWords.size() == 0);
        bool clause2WordsCountZero = (clause2->m_ClauseWords.size() == 0);

        bool bIncludeOp = clause1WordsCountZero || clause2WordsCountZero;

        CClauseNode* pClonedNode1 = NULL;
        CClauseNode* pClonedNode2 = NULL;

        if (!bIncludeOp) {
            int size1 = pNode1->m_outNodes.size();
            int size2 = pNode2->m_inNodes.size();

            if (size1 > 1)
                pClonedNode1 = pNode1->Clone();

            if (size2 > 1)
                pClonedNode2 = pNode2->Clone();

            if (arg.m_iClause2TypeNum != -1)
                clause2->AddValsToType(arg.m_NewValencies2, arg.m_iClause2TypeNum);
        }

        if (clause1WordsCountZero) {
            arg.m_bMainFirst = true;
            IncludeClause(pNode1, pNode2, arg);
            pNode1->GetMainClause()->RunSynAn();
            return;
        }

        if (clause2WordsCountZero) {
            arg.m_bMainFirst = false;
            IncludeClause(pNode1, pNode2, arg);
            pNode2->GetMainClause()->RunSynAn();
            return;
        }

        CClause* pNewClause = CClause::Create(m_Words);
        pNewClause->SetPair(clause1->FirstWord(), clause2->LastWord());

        if (arg.m_bMainFirst)
            pNewClause->m_Types = clause1->m_Types;
        else
            pNewClause->m_Types = clause2->m_Types;

        pNewClause->AddBadWeight(arg.m_BadWeight);
        pNewClause->m_Conjs = clause1->m_Conjs;

        //if( arg.m_BadWeightForCommas > 0 )
        //    pNewClause->m_BadCommas.push_back(SBadComma(clause1->LastWord(), arg.m_BadWeightForCommas) );
        //MultiplyBadCommaWeight(*pNewClause, arg.m_PairForBadCoef, arg.m_CoefficientToIncreaseBadWeightForCommas);
        pNewClause->AddBadComma(clause1->LastWord(),arg.m_BadWeightForCommas,  arg.m_PairForBadCoef, arg.m_CoefficientToIncreaseBadWeightForCommas);
        //pNewClause->m_BadWeightForCommas += arg.m_BadWeightForCommas;
        //pNewClause->m_BadWeightForCommas *= arg.m_CoefficientToIncreaseBadWeightForCommas;
        pNode1->m_pClauseTree->AddSubClauses(pNode2->m_pClauseTree, pNewClause);
        pNode1->GetMainClause()->RunSynAn();

        UpdateNodes(pNode1, pNode2, pClonedNode1, pClonedNode2, true);
    }
    /*catch(...)
    {
        ythrow yexception() << "Error in \"CTopClauses::NewClause\"";
    }*/
}