| /******************************************************************************* |
| * Copyright (c) 2016 CEA LIST. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr |
| * - Initial API and implementation |
| ******************************************************************************/ |
| #include "BaseDataComparator.h" |
| |
| #include <fam/redundancy/RedundancyFilter.h> |
| |
| #include <fml/buffer/BaseBufferForm.h> |
| #include <fml/buffer/BaseBufferQueue.h> |
| #include <fml/buffer/RamBuffer.h> |
| |
| #include <fml/executable/ExecutableForm.h> |
| #include <fml/executable/ExecutableQuery.h> |
| #include <fml/executable/InstanceOfData.h> |
| #include <fml/executable/InstanceOfMachine.h> |
| |
| #include <fml/expression/ExpressionComparer.h> |
| #include <fml/expression/ExpressionFactory.h> |
| |
| #include <fml/runtime/ExecutionData.h> |
| #include <fml/runtime/Message.h> |
| #include <fml/runtime/RuntimeForm.h> |
| |
| #include <fml/type/BaseTypeSpecifier.h> |
| |
| #include <fml/workflow/Query.h> |
| #include <fml/workflow/WObject.h> |
| |
| #include <sew/Configuration.h> |
| |
| |
| namespace sep |
| { |
| |
| |
| /** |
| * destroyMachineData |
| */ |
| |
| void BaseDataComparator::destroyMachineData() |
| { |
| mListOfSelectedIOMachine.clear(); |
| |
| mListOfAllVariable.clear(); |
| |
| mListOfSelectedPresburgerVariable.clear(); |
| |
| mListOfSelectedNonPresburgerVariable.clear(); |
| } |
| |
| |
| /** |
| *************************************************************************** |
| prototype filter::redundancy as avm::core.filter.REDUNDANCY is |
| section PROPERTY |
| @predicate = 'INCLUSION'; // ( <= | INC | INCLUSION ) |
| ( == | EQ | EQUALITY ) |
| ( =a= | AEQ | ALPHA_EQUIV) |
| ( =s= | SEQ | SYNTAXIC_EQUALITY) |
| ( =t= | TEQ | TRIVIALLY_EQUALITY) |
| NONE |
| |
| @solver = 'OMEGA'; // OMEGA | CVC3 |
| |
| @path_scope = 'ALL'; // ALL | CURRENT execution graph path |
| |
| @data_scope = 'ALL'; // ALL data ; or DETAILS section |
| // DETAILS | DETAILS< exclude > some data, |
| endsection PROPERTY |
| |
| section HEURISTIC |
| @communication = false; |
| |
| @variable = true; |
| @path_condition = false; |
| endsection HEURISTIC |
| |
| section DETAILS |
| @model = ufi; |
| |
| @instance = ufi; |
| |
| @variable = ufi; |
| endsection DETAILS |
| endprototype |
| *************************************************************************** |
| */ |
| |
| /** |
| * CONFIGURE |
| */ |
| bool BaseDataComparator::configure(WObject * wfParameterObject) |
| { |
| const ExecutionData & theED = mConfiguration.getMainExecutionData(); |
| |
| mMachineCount = theED.getTableOfRuntime().size(); |
| |
| WObject * thePROPERTY = |
| RedundancyFilter::AUTO_REGISTER_TOOL.isTypeID( *wfParameterObject ) |
| ? Query::getRegexWSequence(wfParameterObject, |
| OR_WID2("property", "PROPERTY"), wfParameterObject) |
| : Query::getRegexWSequence(wfParameterObject, |
| OR_WID2("redundancy" , "REDUNDANCY"), wfParameterObject); |
| |
| std::string path_scope = Query::getRegexWPropertyString( |
| thePROPERTY, CONS_WID2("path", "scope"), "ALL"); |
| mCurrentPathScopeFlag = |
| ( (path_scope == "CURRENT") || (path_scope == "PARENT") ); |
| |
| std::string data_scope = Query::getRegexWPropertyString( |
| thePROPERTY, CONS_WID2("data", "scope"), "ALL"); |
| |
| |
| WObject * theHEURISTIC = |
| RedundancyFilter::AUTO_REGISTER_TOOL.isTypeID( *wfParameterObject ) |
| ? Query::getRegexWSequence(wfParameterObject, |
| OR_WID2("heuristic", "HEURISTIC"), thePROPERTY) |
| : Query::getRegexWSequence(wfParameterObject, |
| OR_WID2("redundancy" , "REDUNDANCY"), thePROPERTY); |
| |
| if( theHEURISTIC != WObject::_NULL_ ) |
| { |
| mUseCommunication = Query::getWPropertyBoolean( |
| theHEURISTIC, "communication", true); |
| |
| mUseVariable = Query::getWPropertyBoolean( |
| theHEURISTIC, "variable", true); |
| |
| mIgnorePathCondition = not Query::getRegexWPropertyBoolean( |
| theHEURISTIC, CONS_WID2("path", "condition"), true); |
| } |
| |
| |
| if( data_scope == "ALL" ) |
| { |
| computeAllMachineData(theED); |
| } |
| // TODO configure for @data_scope = 'DETAILS'; |
| else if( StringTools::startsWith(data_scope, "DETAILS") ) |
| { |
| WObject * theDETAILS = |
| RedundancyFilter::AUTO_REGISTER_TOOL.isTypeID( *wfParameterObject ) |
| ? Query::getRegexWSequence(wfParameterObject, |
| OR_WID2("details", "DETAILS"), thePROPERTY) |
| : Query::getRegexWSequence(wfParameterObject, |
| OR_WID2("redundancy" , "REDUNDANCY"), thePROPERTY); |
| |
| if( theDETAILS != WObject::_NULL_ ) |
| { |
| ExecutableForm * anExecutable = NULL; |
| InstanceOfMachine * aMachine = NULL; |
| InstanceOfData * aVariable = NULL; |
| |
| ListOfExecutableForm listOfExecutable; |
| ListOfInstanceOfMachine listOfInstance; |
| ListOfInstanceOfData listOfVariable; |
| |
| ExecutableQuery XQuery( mConfiguration ); |
| |
| WObject::const_iterator itWfO = theDETAILS->owned_begin(); |
| WObject::const_iterator endWfO = theDETAILS->owned_end(); |
| for( ; itWfO != endWfO ; ++itWfO ) |
| { |
| if( (*itWfO)->isWProperty() ) |
| { |
| const std::string & kind = (*itWfO)->getNameID(); |
| const std::string & qnid = (*itWfO)->toStringValue(); |
| |
| |
| if( (kind == "model") || (kind == "form") ) |
| { |
| anExecutable = XQuery.getExecutable( |
| qnid ).to_ptr< ExecutableForm >(); |
| if( anExecutable != NULL ) |
| { |
| listOfExecutable.append(anExecutable); |
| } |
| else |
| { |
| AVM_OS_WARN << "Unfound the machine " |
| << kind << " << " << qnid |
| << " >> as processor parameter:> " |
| << wfParameterObject->getFullyQualifiedNameID() |
| << std::endl; |
| } |
| } |
| else if( kind == "instance" ) |
| { |
| aMachine = XQuery.getMachine( |
| Specifier::DESIGN_INSTANCE_KIND, qnid).rawMachine(); |
| if( aMachine != NULL ) |
| { |
| listOfInstance.append(aMachine); |
| } |
| else |
| { |
| AVM_OS_WARN << "Unfound the machine " |
| << kind << " << " << qnid |
| << " >> as processor parameter:> " |
| << wfParameterObject->getFullyQualifiedNameID() |
| << std::endl; |
| } |
| } |
| // TODO: Ã faire pour les variables. |
| else if( kind == "variable" ) |
| { |
| aVariable = XQuery.getData( |
| qnid ).to_ptr< InstanceOfData >(); |
| if( aVariable != NULL ) |
| { |
| listOfVariable.append(aVariable); |
| } |
| else |
| { |
| AVM_OS_WARN << "Unfound the " << kind << " << " |
| << qnid << " >> as processor parameter:> " |
| << wfParameterObject->getFullyQualifiedNameID() |
| << std::endl; |
| } |
| } |
| else |
| { |
| AVM_OS_WARN << "Unexpected attribute << " |
| << (*itWfO)->str() << " >> as processor parameter:> " |
| << wfParameterObject->getFullyQualifiedNameID() |
| << std::endl; |
| } |
| } |
| } |
| |
| |
| if( data_scope.find("exclude") != std::string::npos ) |
| { |
| computeDetailsExcludeMachineData(theED, |
| listOfExecutable, listOfInstance, listOfVariable); |
| } |
| else |
| { |
| computeDetailsIncludeMachineData(theED, |
| listOfExecutable, listOfInstance, listOfVariable); |
| } |
| |
| } |
| else |
| { |
| AVM_OS_WARN << "Unfound section << DETAILS >> as redundancy " |
| "detector parameter" << std::endl; |
| } |
| } |
| else |
| { |
| AVM_OS_ERROR_ALERT << "Unexpected REDUNDANCY filter << @data_scope = " |
| << data_scope << "; >> !!!" << std::endl |
| << "NB. << @data_scope = {[ 'ALL' | 'DETAILS' ]}; >> !!!" |
| << SEND_ALERT; |
| |
| return( false ); |
| } |
| |
| return( true ); |
| } |
| |
| |
| void BaseDataComparator::computeAllMachineData(const ExecutionData & anED) |
| { |
| destroyMachineData(); |
| |
| selectIOMachine(anED, mListOfSelectedIOMachine); |
| |
| selectAllVariable(anED, mListOfAllVariable); |
| |
| selectPresburgerVariable(anED, mListOfSelectedPresburgerVariable); |
| |
| selectNonPresburgerVariable(anED, mListOfSelectedNonPresburgerVariable); |
| } |
| |
| |
| |
| |
| void BaseDataComparator::computeDetailsIncludeMachineData( |
| const ExecutionData & anED, |
| ListOfExecutableForm & listOfExecutable, |
| ListOfInstanceOfMachine & listOfInstance, |
| ListOfInstanceOfData & listOfVariable) |
| { |
| destroyMachineData(); |
| |
| // TODO: réécrire les 4 méthodes suivantes pour prendre en compte les |
| // DETAILS contenus dans les deux paramètres additionnels par rapport au cas ALL: |
| |
| selectDetailsIOMachine(anED, mListOfSelectedIOMachine, |
| listOfExecutable, listOfInstance); |
| |
| selectDetailsVariable(anED, mListOfAllVariable, |
| listOfExecutable, listOfInstance, listOfVariable); |
| |
| selectDetailsPresburgerVariable(anED, mListOfSelectedPresburgerVariable, |
| listOfExecutable, listOfInstance, listOfVariable); |
| |
| selectDetailsNonPresburgerVariable( |
| anED, mListOfSelectedNonPresburgerVariable, |
| listOfExecutable, listOfInstance, listOfVariable); |
| |
| if( mListOfAllVariable.empty() ) |
| { |
| // AVM_OS_WARNING_ALERT |
| // << "Attention la liste des variables utilisées pour le " |
| // "calcul de la redondance est vide (cas DETAILS) !!!" |
| // << SEND_ALERT; |
| } |
| } |
| |
| |
| static void excludeVariable(ListOfPairMachineData & includeListOfVariable, |
| ListOfExecutableForm & excludeListOfExecutable, |
| ListOfInstanceOfMachine & excludeListOfInstance, |
| ListOfInstanceOfData & excludeListOfVariable) |
| { |
| ListOfExecutableForm::iterator itExec; |
| ListOfExecutableForm::iterator endExec; |
| |
| ListOfInstanceOfMachine::iterator itRF; |
| ListOfInstanceOfMachine::iterator endRF; |
| |
| ListOfInstanceOfData::iterator itVar; |
| ListOfInstanceOfData::iterator endVar; |
| |
| bool hasEraseNothing; |
| |
| ListOfPairMachineData::iterator itPairMachineData = includeListOfVariable.begin(); |
| for( ; itPairMachineData != includeListOfVariable.end() ; ) |
| { |
| hasEraseNothing = true; |
| |
| itExec = excludeListOfExecutable.begin(); |
| endExec = excludeListOfExecutable.end(); |
| for( ; itExec != endExec ; ++itExec ) |
| { |
| if( (*itPairMachineData).first().getExecutable() == (*itExec) ) |
| { |
| itPairMachineData = includeListOfVariable.erase(itPairMachineData); |
| hasEraseNothing = false; |
| continue; |
| } |
| } |
| |
| itRF = excludeListOfInstance.begin(); |
| endRF = excludeListOfInstance.end(); |
| for( ; itRF != endRF ; ++itRF ) |
| { |
| if( (*itPairMachineData).first().getInstance() == (*itRF) ) |
| { |
| itPairMachineData = includeListOfVariable.erase(itPairMachineData); |
| hasEraseNothing = false; |
| continue; |
| } |
| } |
| |
| itVar = excludeListOfVariable.begin(); |
| endVar = excludeListOfVariable.end(); |
| for( ; itVar != endVar ; ++itVar ) |
| { |
| (*itPairMachineData).second().remove( (*itVar) ); |
| if( (*itPairMachineData).second().empty() ) |
| { |
| itPairMachineData = includeListOfVariable.erase(itPairMachineData); |
| hasEraseNothing = false; |
| continue; |
| } |
| } |
| |
| if( hasEraseNothing ) |
| { |
| ++itPairMachineData; |
| } |
| } |
| } |
| |
| |
| void BaseDataComparator::computeDetailsExcludeMachineData( |
| const ExecutionData & anED, |
| ListOfExecutableForm & listOfExecutable, |
| ListOfInstanceOfMachine & listOfInstance, |
| ListOfInstanceOfData & listOfVariable) |
| { |
| computeAllMachineData(anED); |
| |
| excludeVariable(mListOfAllVariable, |
| listOfExecutable, listOfInstance, listOfVariable); |
| |
| excludeVariable(mListOfSelectedPresburgerVariable, |
| listOfExecutable, listOfInstance, listOfVariable); |
| |
| excludeVariable(mListOfSelectedNonPresburgerVariable, |
| listOfExecutable, listOfInstance, listOfVariable); |
| |
| } |
| |
| |
| |
| |
| |
| void BaseDataComparator::selectIOMachine(const ExecutionData & anED, |
| List< RuntimeID > & aListOfSelectedIOMachine) |
| { |
| TableOfRuntimeT::const_iterator itRF = anED.getTableOfRuntime().begin(); |
| TableOfRuntimeT::const_iterator itRFEnd = anED.getTableOfRuntime().end(); |
| for( RuntimeID itRID ; itRF != itRFEnd ; ++itRF ) |
| { |
| itRID = (*itRF)->getRID(); |
| |
| if( itRID.getExecutable()->hasBuffer() ) |
| { |
| aListOfSelectedIOMachine.append( itRID ); |
| } |
| } |
| } |
| |
| void BaseDataComparator::selectDetailsIOMachine( |
| const ExecutionData & anED, |
| List< RuntimeID > & aListOfSelectedIOMachine, |
| ListOfExecutableForm & listOfExecutable, |
| ListOfInstanceOfMachine & listOfInstance) |
| { |
| TableOfRuntimeT::const_iterator itRF = anED.getTableOfRuntime().begin(); |
| TableOfRuntimeT::const_iterator itRFEnd = anED.getTableOfRuntime().end(); |
| for( RuntimeID itRID ; itRF != itRFEnd ; ++itRF ) |
| { |
| itRID = (*itRF)->getRID(); |
| |
| if( itRID.getExecutable()->hasBuffer() |
| && ( listOfExecutable.contains(itRID.getExecutable()) |
| || listOfInstance.contains(itRID.getInstance()) ) ) |
| { |
| aListOfSelectedIOMachine.append( itRID ); |
| } |
| } |
| } |
| |
| void BaseDataComparator::selectAllVariable(const ExecutionData & anED, |
| ListOfPairMachineData & aListOfSelectedVariable) |
| { |
| TableOfInstanceOfData::const_raw_iterator itVar; |
| TableOfInstanceOfData::const_raw_iterator itVarEnd; |
| |
| TableOfRuntimeT::const_iterator itRF = anED.getTableOfRuntime().begin(); |
| TableOfRuntimeT::const_iterator itRFEnd = anED.getTableOfRuntime().end(); |
| for( RuntimeForm * pRF = NULL ; itRF != itRFEnd ; ++itRF ) |
| { |
| pRF = (*itRF); |
| |
| if( pRF->getExecutable()->hasData() ) |
| { |
| aListOfSelectedVariable.append( PairMachineData(pRF->getRID()) ); |
| ListOfInstanceOfData & listOfData = |
| aListOfSelectedVariable.last().second(); |
| |
| itVar = pRF->getVariables().begin(); |
| itVarEnd = pRF->getVariables().end(); |
| for( ; itVar != itVarEnd ; ++itVar ) |
| { |
| listOfData.append( (itVar) ); |
| } |
| |
| if( listOfData.empty() ) |
| { |
| aListOfSelectedVariable.pop_last(); |
| } |
| } |
| } |
| } |
| |
| |
| // todo: collecter toutes les variables dans les sous-machines ... |
| //void BaseDataComparator::collectDetailsVariables(const RuntimeID & aRID, |
| // ListOfPairMachineData & aListOfSelectedVariable, |
| // ListOfExecutableForm & listOfExecutable, |
| // ListOfInstanceOfMachine & listOfInstance) |
| //{ |
| // PairMachineData * tmpPairMachineData = new PairMachineData(aRID); |
| // TableOfInstanceOfData::const_raw_iterator itVar = aRID->getVariables().begin(); |
| // TableOfInstanceOfData::const_raw_iterator itVarEnd = aRID->getVariables().end(); |
| // for( ; itVar != itVarEnd ; ++itVar ) |
| // { |
| // if( (itData)->anyModifierOfStateData() |
| // && (itData)->hasTypeSpecifier() |
| // && ((itData)->isTypedNumeric() |
| // || (itData)->isTypedEnumeration()) ) |
| // { |
| // tmpPairMachineData->second().append( (itData) ); |
| // } |
| // } |
| // if( tmpPairMachineData->second().nonempty() ) |
| // { |
| // aListOfSelectedVariable.append(tmpPairMachineData); |
| // } |
| // else |
| // { |
| // delete( tmpPairMachineData ); |
| // } |
| // TableOfRuntimeID::iterator itRecRID = (*itmachine)->beginChildTable() ; |
| // TableOfRuntimeID::iterator itRecEnd = (*itmachine)->endChildTable() ; |
| // for( ; itRecRID != itRecEnd ; ++itRecRID ) |
| // { |
| // //itRecMachine |
| // } |
| //} |
| |
| |
| |
| avm_size_t BaseDataComparator::selectVariable( |
| ListOfInstanceOfData & listOfData, InstanceOfData * pData) |
| { |
| if( pData->getModifier().anyModifierOfStateData() ) |
| { |
| AVM_OS_ASSERT_FATAL_ERROR_EXIT( pData->hasTypeSpecifier() ) |
| << "Unexpected variable << " << pData->getFullyQualifiedNameID() |
| << " >> without type specififer !!!" |
| << SEND_EXIT; |
| |
| avm_size_t varCount = 0; |
| |
| if( pData->isTypedNumeric() || |
| pData->isTypedEnumeration() || |
| pData->isTypedMachine() ) |
| { |
| ++varCount; |
| |
| listOfData.append( pData ); |
| } |
| else if( pData->hasTypeArrayOrStructure() ) |
| { |
| TableOfSymbol::iterator attrIt = pData->getAttribute()->begin(); |
| TableOfSymbol::iterator attrEnd = pData->getAttribute()->end(); |
| for( ; attrIt != attrEnd ; ++attrIt ) |
| { |
| varCount += selectVariable(listOfData, (*attrIt). |
| data().getAliasTarget()->as< InstanceOfData >() ); |
| } |
| } |
| |
| return( varCount ); |
| } |
| |
| return( 0 ); |
| } |
| |
| |
| avm_size_t BaseDataComparator::selectPresburgerVariable( |
| ListOfInstanceOfData & listOfData, InstanceOfData * pData) |
| { |
| if( pData->getModifier().anyModifierOfStateData() ) |
| { |
| AVM_OS_ASSERT_FATAL_ERROR_EXIT( pData->hasTypeSpecifier() ) |
| << "Unexpected variable << " << pData->getFullyQualifiedNameID() |
| << " >> without type specififer !!!" |
| << SEND_EXIT; |
| |
| avm_size_t varCount = 0; |
| |
| if( pData->weaklyTypedInteger() || |
| pData->isTypedEnumeration() || |
| pData->isTypedMachine() ) |
| { |
| ++varCount; |
| |
| listOfData.append( pData ); |
| |
| AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| AVM_OS_TRACE << "\tpresburger :> " << str_header( pData ) << std::endl; |
| AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| } |
| else if( pData->hasTypeArrayOrStructure() ) |
| { |
| TableOfSymbol::iterator attrIt = pData->getAttribute()->begin(); |
| TableOfSymbol::iterator attrEnd = pData->getAttribute()->end(); |
| for( ; attrIt != attrEnd ; ++attrIt ) |
| { |
| varCount += selectPresburgerVariable(listOfData, (*attrIt). |
| data().getAliasTarget()->as< InstanceOfData >() ); |
| } |
| } |
| else |
| { |
| AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| AVM_OS_TRACE << "\tNON presburger :> " << str_header( pData ) << std::endl; |
| AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| } |
| |
| return( varCount ); |
| } |
| |
| return( 0 ); |
| } |
| |
| |
| avm_size_t BaseDataComparator::selectNonPresburgerVariable( |
| ListOfInstanceOfData & listOfData, InstanceOfData * pData) |
| { |
| if( pData->getModifier().anyModifierOfStateData() ) |
| { |
| AVM_OS_ASSERT_FATAL_ERROR_EXIT( pData->hasTypeSpecifier() ) |
| << "Unexpected variable << " << pData->getFullyQualifiedNameID() |
| << " >> without type specififer !!!" |
| << SEND_EXIT; |
| |
| avm_size_t varCount = 0; |
| |
| if( (not pData->weaklyTypedInteger()) && |
| (not pData->isTypedEnumeration()) && |
| (not pData->isTypedMachine()) ) |
| { |
| ++varCount; |
| |
| listOfData.append( pData ); |
| } |
| else if( pData->hasTypeArrayOrStructure() ) |
| { |
| TableOfSymbol::iterator attrIt = pData->getAttribute()->begin(); |
| TableOfSymbol::iterator attrEnd = pData->getAttribute()->end(); |
| for( ; attrIt != attrEnd ; ++attrIt ) |
| { |
| selectNonPresburgerVariable(listOfData, (*attrIt). |
| data().getAliasTarget()->as< InstanceOfData >() ); |
| } |
| } |
| |
| return( varCount ); |
| } |
| |
| return( 0 ); |
| } |
| |
| |
| // TODO: attention on ne prend pas en compte les SOUS-machines !!! |
| void BaseDataComparator::selectDetailsVariable(const ExecutionData & anED, |
| ListOfPairMachineData & aListOfSelectedVariable, |
| ListOfExecutableForm & listOfExecutable, |
| ListOfInstanceOfMachine & listOfInstance, |
| ListOfInstanceOfData & listOfVariable) |
| { |
| TableOfInstanceOfData::const_raw_iterator itVar; |
| TableOfInstanceOfData::const_raw_iterator itVarEnd; |
| |
| ListOfInstanceOfData::iterator varIt; |
| ListOfInstanceOfData::iterator varEnd; |
| |
| TableOfRuntimeT::const_iterator itRF = anED.getTableOfRuntime().begin(); |
| TableOfRuntimeT::const_iterator itRFEnd = anED.getTableOfRuntime().end(); |
| for( RuntimeForm * pRF = NULL ; itRF != itRFEnd ; ++itRF ) |
| { |
| pRF = (*itRF); |
| |
| if( pRF->getExecutable()->hasData() ) |
| { |
| if( listOfInstance.contains(pRF->getInstance()) || |
| listOfExecutable.contains(pRF->getExecutable()) ) |
| { |
| aListOfSelectedVariable.append( |
| PairMachineData(pRF->getRID()) ); |
| ListOfInstanceOfData & listOfData = |
| aListOfSelectedVariable.last().second(); |
| |
| itVar = pRF->getVariables().begin(); |
| itVarEnd = pRF->getVariables().end(); |
| for( ; itVar != itVarEnd ; ++itVar ) |
| { |
| selectVariable(listOfData, (itVar)); |
| } |
| |
| // TODO: parcourir les children |
| // TableOfRuntimeID::iterator itRecMachine = (*itmachine)->beginChildTable() ; |
| // TableOfRuntimeID::iterator itRecEnd = (*itmachine)->endChildTable() ; |
| // for( ; itRecMachine != itRecEnd ; ++itRecMachine ) |
| // { |
| // } |
| } |
| else |
| { |
| aListOfSelectedVariable.append( |
| PairMachineData(pRF->getRID()) ); |
| ListOfInstanceOfData & listOfData = |
| aListOfSelectedVariable.last().second(); |
| |
| varIt = listOfVariable.begin(); |
| varEnd = listOfVariable.end(); |
| for( ; varIt != varEnd ; ++varIt ) |
| { |
| if( pRF->getExecutable()->containsAllData(*varIt) ) |
| { |
| selectVariable(listOfData, (*varIt)); |
| } |
| } |
| |
| if( listOfData.empty() ) |
| { |
| aListOfSelectedVariable.pop_last(); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| void BaseDataComparator::selectPresburgerVariable(const ExecutionData & anED, |
| ListOfPairMachineData & aListOfSelectedVariable) |
| { |
| avm_size_t varCount = 0; |
| |
| TableOfInstanceOfData::const_raw_iterator itVar; |
| TableOfInstanceOfData::const_raw_iterator itVarEnd; |
| |
| TableOfRuntimeT::const_iterator itRF = anED.getTableOfRuntime().begin(); |
| TableOfRuntimeT::const_iterator itRFEnd = anED.getTableOfRuntime().end(); |
| for( RuntimeID itRID ; itRF != itRFEnd ; ++itRF ) |
| { |
| itRID = (*itRF)->getRID(); |
| |
| if( itRID.getExecutable()->hasData() ) |
| { |
| aListOfSelectedVariable.append( PairMachineData(itRID) ); |
| ListOfInstanceOfData & listOfData = aListOfSelectedVariable.last().second(); |
| |
| AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| AVM_OS_TRACE << "presburger machine :> " << itRID.str() << std::endl; |
| AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| |
| itVar = itRID.getExecutable()->getBasicData().begin(); |
| itVarEnd = itRID.getExecutable()->getBasicData().end(); |
| for( ; itVar != itVarEnd ; ++itVar ) |
| { |
| varCount += selectPresburgerVariable(listOfData, (itVar)); |
| } |
| |
| if( listOfData.empty() ) |
| { |
| aListOfSelectedVariable.pop_last(); |
| } |
| } |
| } |
| |
| AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| AVM_OS_TRACE << "Total:> " << varCount << std::endl << std::endl; |
| AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| } |
| |
| |
| void BaseDataComparator::selectDetailsPresburgerVariable( |
| const ExecutionData & anED, |
| ListOfPairMachineData & aListOfSelectedVariable, |
| ListOfExecutableForm & listOfExecutable, |
| ListOfInstanceOfMachine & listOfInstance, |
| ListOfInstanceOfData & listOfVariable) |
| { |
| avm_size_t varCount = 0; |
| |
| TableOfInstanceOfData::const_raw_iterator itVar; |
| TableOfInstanceOfData::const_raw_iterator itVarEnd; |
| |
| ListOfInstanceOfData::iterator varIt; |
| ListOfInstanceOfData::iterator varEnd; |
| |
| TableOfRuntimeT::const_iterator itRF = anED.getTableOfRuntime().begin(); |
| TableOfRuntimeT::const_iterator itRFEnd = anED.getTableOfRuntime().end(); |
| for( RuntimeID itRID ; itRF != itRFEnd ; ++itRF ) |
| { |
| itRID = (*itRF)->getRID(); |
| |
| if( itRID.getExecutable()->hasData() ) |
| { |
| if( listOfExecutable.contains(itRID.getExecutable()) || |
| listOfInstance.contains(itRID.getInstance())) |
| { |
| aListOfSelectedVariable.append( PairMachineData(itRID) ); |
| ListOfInstanceOfData & listOfData = aListOfSelectedVariable.last().second(); |
| |
| AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| AVM_OS_TRACE << "presburger machine :> " << itRID.str() << std::endl; |
| AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| |
| itVar = itRID.getExecutable()->getBasicData().begin(); |
| itVarEnd = itRID.getExecutable()->getBasicData().end(); |
| for( ; itVar != itVarEnd ; ++itVar ) |
| { |
| varCount += selectPresburgerVariable(listOfData, (itVar)); |
| } |
| |
| if( listOfData.empty() ) |
| { |
| aListOfSelectedVariable.pop_last(); |
| } |
| } |
| else |
| { |
| aListOfSelectedVariable.append( |
| PairMachineData(itRID) ); |
| ListOfInstanceOfData & listOfData = |
| aListOfSelectedVariable.last().second(); |
| |
| varIt = listOfVariable.begin(); |
| varEnd = listOfVariable.end(); |
| for( ; varIt != varEnd ; ++varIt ) |
| { |
| if( itRID.getExecutable()->containsAllData(*varIt) ) |
| { |
| varCount += selectPresburgerVariable(listOfData, (*varIt)); |
| } |
| } |
| |
| if( listOfData.empty() ) |
| { |
| aListOfSelectedVariable.pop_last(); |
| } |
| } |
| } |
| } |
| |
| AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| AVM_OS_TRACE << "Total:> " << varCount << std::endl << std::endl; |
| AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| |
| } |
| |
| void BaseDataComparator::selectNonPresburgerVariable( |
| const ExecutionData & anED, |
| ListOfPairMachineData & aListOfSelectedVariable) |
| { |
| TableOfInstanceOfData::const_raw_iterator itVar; |
| TableOfInstanceOfData::const_raw_iterator itVarEnd; |
| |
| TableOfRuntimeT::const_iterator itRF = anED.getTableOfRuntime().begin(); |
| TableOfRuntimeT::const_iterator endRF = anED.getTableOfRuntime().end(); |
| for( RuntimeForm * pRF = NULL ; itRF != endRF ; ++itRF ) |
| { |
| pRF = (*itRF); |
| |
| if( pRF->getExecutable()->hasData() ) |
| { |
| aListOfSelectedVariable.append( |
| PairMachineData(pRF->getRID()) ); |
| ListOfInstanceOfData & listOfData = |
| aListOfSelectedVariable.last().second(); |
| |
| // AVM_OS_TRACE << "presburger machine :> " |
| // << itRID.str() << std::endl; |
| |
| itVar = pRF->getVariables().begin(); |
| itVarEnd = pRF->getVariables().end(); |
| for( ; itVar != itVarEnd ; ++itVar ) |
| { |
| selectNonPresburgerVariable(listOfData, (itVar)); |
| } |
| |
| if( listOfData.empty() ) |
| { |
| aListOfSelectedVariable.pop_last(); |
| } |
| } |
| } |
| } |
| |
| |
| void BaseDataComparator::selectDetailsNonPresburgerVariable( |
| const ExecutionData & anED, |
| ListOfPairMachineData & aListOfSelectedVariable, |
| ListOfExecutableForm & listOfExecutable, |
| ListOfInstanceOfMachine & listOfInstance, |
| ListOfInstanceOfData & listOfVariable) |
| { |
| TableOfInstanceOfData::const_raw_iterator itVar; |
| TableOfInstanceOfData::const_raw_iterator itVarEnd; |
| |
| ListOfInstanceOfData::iterator varIt; |
| ListOfInstanceOfData::iterator varEnd; |
| |
| TableOfRuntimeT::const_iterator itRF = anED.getTableOfRuntime().begin(); |
| TableOfRuntimeT::const_iterator endRF = anED.getTableOfRuntime().end(); |
| for( RuntimeForm * pRF = NULL ; itRF != endRF ; ++itRF ) |
| { |
| pRF = (*itRF); |
| |
| if( pRF->getExecutable()->hasData() ) |
| { |
| if( listOfExecutable.contains(pRF->getExecutable()) || |
| listOfInstance.contains(pRF->getInstance()) ) |
| { |
| aListOfSelectedVariable.append( |
| PairMachineData(pRF->getRID()) ); |
| ListOfInstanceOfData & listOfData = |
| aListOfSelectedVariable.last().second(); |
| |
| // AVM_OS_TRACE << "Non presburger machine :> " |
| // << itRID.str() << std::endl; |
| |
| itVar = pRF->getVariables().begin(); |
| itVarEnd = pRF->getVariables().end(); |
| for( ; itVar != itVarEnd ; ++itVar ) |
| { |
| selectNonPresburgerVariable(listOfData, (itVar)); |
| } |
| |
| if( listOfData.empty() ) |
| { |
| aListOfSelectedVariable.pop_last(); |
| } |
| } |
| else |
| { |
| aListOfSelectedVariable.append( |
| PairMachineData(pRF->getRID()) ); |
| ListOfInstanceOfData & listOfData = |
| aListOfSelectedVariable.last().second(); |
| |
| varIt = listOfVariable.begin(); |
| varEnd = listOfVariable.end(); |
| for( ; varIt != varEnd ; ++varIt ) |
| { |
| selectNonPresburgerVariable(listOfData, (*varIt)); |
| } |
| |
| if( listOfData.empty() ) |
| { |
| aListOfSelectedVariable.pop_last(); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| /* |
| * REFRESH CURRENT PRESBURGER VARIABLE |
| */ |
| |
| void BaseDataComparator::refreshCurrentVariables( |
| ListOfPairMachineData & currentVariables, |
| ListOfPairMachineData & referenceVariables, |
| const ExecutionData & newED, const ExecutionData & oldED) |
| { |
| currentVariables.clear(); |
| |
| ListOfInstanceOfData::iterator itVar; |
| ListOfInstanceOfData::iterator endVar; |
| |
| ListOfPairMachineData::iterator itPairMachineData = referenceVariables.begin(); |
| ListOfPairMachineData::iterator endPairMachineData = referenceVariables.end(); |
| for( ; itPairMachineData != endPairMachineData ; ++itPairMachineData ) |
| { |
| if( (*itPairMachineData).second().nonempty() ) |
| { |
| const RuntimeForm & newRF = |
| newED.getRuntime( (*itPairMachineData).first() ); |
| const RuntimeForm & oldRF = |
| oldED.getRuntime( (*itPairMachineData).first() ); |
| |
| currentVariables.append( PairMachineData(newRF.getRID()) ); |
| ListOfInstanceOfData & listOfData = currentVariables.last().second(); |
| |
| itVar = (*itPairMachineData).second().begin(); |
| endVar = (*itPairMachineData).second().end(); |
| for( ; itVar != endVar ; ++itVar ) |
| { |
| if( not ExpressionComparer::isTEQ( |
| newRF.getData( (*itVar)->getOffset() ), |
| oldRF.getData( (*itVar)->getOffset() )) ) |
| { |
| AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| AVM_OS_TRACE << "current var :> " << newRF.getRID().str() |
| << ":" << (*itVar)->getNameID() << std::endl; |
| AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , CONFIGURING , REDUNDANCE ) |
| |
| listOfData.append( (*itVar) ); |
| } |
| } |
| |
| if( listOfData.empty() ) |
| { |
| currentVariables.pop_last(); |
| } |
| } |
| } |
| } |
| |
| |
| /* |
| * COMPARE |
| */ |
| bool BaseDataComparator::compareIO( |
| const ExecutionContext & newEC, const ExecutionContext & oldEC) |
| { |
| newED = newEC.getExecutionData(); |
| oldED = oldEC.getExecutionData(); |
| |
| TableOfBufferT::const_iterator itNewBuf; |
| TableOfBufferT::const_iterator itNewBufEnd; |
| |
| TableOfBufferT::const_iterator itOldBuf; |
| |
| // compare BUFFER |
| List< RuntimeID >::const_iterator itRID = getSelectedIOMachine().begin(); |
| List< RuntimeID >::const_iterator endRID = getSelectedIOMachine().end(); |
| for( ; itRID != endRID ; ++itRID ) |
| { |
| newRF = newED->ptrRuntime( *itRID ); |
| oldRF = oldED->ptrRuntime( *itRID ); |
| |
| if( newRF->hasBuffer() |
| && (newRF->getBufferTable() != oldRF->getBufferTable()) ) |
| { |
| itNewBuf = newRF->getBufferTable().begin(); |
| itNewBufEnd = newRF->getBufferTable().end(); |
| itOldBuf = oldRF->getBufferTable().begin(); |
| for( ; itNewBuf != itNewBufEnd ; ++itNewBuf, ++itOldBuf ) |
| { |
| if( ((*itNewBuf) != (*itOldBuf)) |
| && (not compareBUFFER(*itNewBuf, *itOldBuf)) ) |
| { |
| AVM_IF_DEBUG_LEVEL_FLAG( MEDIUM , REDUNDANCE ) |
| AVM_OS_COUT << "oldRF :> " << oldRF->getRID().str() << std::endl; |
| oldRF->getBufferTable().toStream(AVM_OS_COUT); |
| |
| AVM_OS_COUT << "newRF :> " << newRF->getRID().str() << std::endl; |
| newRF->getBufferTable().toStream(AVM_OS_COUT); |
| |
| AVM_OS_COUT << ">>>>>>> false <<<<<<<" << std::endl; |
| AVM_ENDIF_DEBUG_LEVEL_FLAG( MEDIUM , REDUNDANCE ) |
| |
| return( false ); |
| } |
| } |
| } |
| } |
| |
| return( true ); |
| } |
| |
| |
| bool BaseDataComparator::compareBUFFER( |
| const BaseBufferForm * newBuf, const BaseBufferForm * oldBuf) |
| { |
| switch( newBuf->classKind() ) |
| { |
| case FORM_BUFFER_FIFO_KIND: |
| case FORM_BUFFER_LIFO_KIND: |
| { |
| const BaseBufferQueue * newMsgList = newBuf->to< BaseBufferQueue >(); |
| const BaseBufferQueue * oldMsgList = oldBuf->to< BaseBufferQueue >(); |
| |
| if( newMsgList->nonempty() |
| && (newMsgList->size() == oldMsgList->size()) ) |
| { |
| ListOfMessage:: |
| const_iterator itNewMsg = newMsgList->beginMessages(); |
| ListOfMessage:: |
| const_iterator itNewMsgEnd = newMsgList->endMessages(); |
| ListOfMessage:: |
| const_iterator itOldMsg = oldMsgList->beginMessages(); |
| for( ; itNewMsg != itNewMsgEnd ; ++itNewMsg, ++itOldMsg ) |
| { |
| if( ((*itNewMsg) != (*itOldMsg)) |
| && (not compareMESSAGE((*itNewMsg), (*itOldMsg))) ) |
| { |
| return( false ); |
| } |
| } |
| return( true ); |
| } |
| return( newMsgList->empty() ); |
| } |
| |
| case FORM_BUFFER_MULTISET_KIND: |
| case FORM_BUFFER_SET_KIND: |
| { // TODO correct comparaison |
| const BaseBufferQueue * newMsgList = newBuf->to< BaseBufferQueue >(); |
| const BaseBufferQueue * oldMsgList = oldBuf->to< BaseBufferQueue >(); |
| |
| if( newMsgList->size() == oldMsgList->size() ) |
| { |
| ListOfMessage:: |
| const_iterator itNewMsg = newMsgList->beginMessages(); |
| ListOfMessage:: |
| const_iterator itNewMsgEnd = newMsgList->endMessages(); |
| ListOfMessage:: |
| const_iterator itOldMsg = oldMsgList->beginMessages(); |
| for( ; itNewMsg != itNewMsgEnd ; ++itNewMsg, ++itOldMsg ) |
| { |
| if( ((*itNewMsg) != (*itOldMsg)) |
| && (not compareMESSAGE((*itNewMsg), (*itOldMsg))) ) |
| { |
| return( false ); |
| } |
| } |
| return( true ); |
| } |
| return( newMsgList->empty() ); |
| } |
| |
| case FORM_BUFFER_BROADCAST_KIND: |
| case FORM_BUFFER_RAM_KIND: |
| { |
| return( compareMESSAGE( |
| newBuf->to< RamBuffer >()->top(), |
| oldBuf->to< RamBuffer >()->top() ) ); |
| } |
| |
| default : |
| { |
| return( true ); |
| } |
| } |
| |
| return( true ); |
| } |
| |
| |
| bool BaseDataComparator::compareMESSAGE( |
| const Message & newMsg, const Message & oldMsg) |
| { |
| if( newMsg.getMID() == oldMsg.getMID() ) |
| { |
| // BFVector::const_iterator itNew = newMsg->begin(); |
| // BFVector::const_iterator itNewEnd = newMsg->end(); |
| // BFVector::const_iterator itOld = oldMsg->begin(); |
| // for( ; itNew != itNewEnd ; ++itNew, ++itOld ) |
| // { |
| // if( not ExpressionComparer::isEQ(*itNew, *itOld) ) |
| // { |
| // return( false ); |
| // } |
| // } |
| |
| return( true ); |
| } |
| |
| return( false ); |
| } |
| |
| |
| |
| bool BaseDataComparator::compare( |
| const ExecutionContext & newEC, const ExecutionContext & oldEC) |
| { |
| if( mMachineCount != newEC.refExecutionData().getTableOfRuntime().size() ) |
| { |
| mMachineCount = newEC.refExecutionData().getTableOfRuntime().size(); |
| |
| computeAllMachineData( newEC.refExecutionData() ); |
| } |
| |
| ++mComparisonCount; |
| |
| if( compareTEQ(newEC, oldEC) ) |
| { |
| return( true ); |
| } |
| else if( mUseCommunication || mUseVariable ) |
| { |
| return( (mUseCommunication ? compareIO(newEC, oldEC) : true) |
| && (mUseVariable ? compareDATA(newEC, oldEC) : true) ); |
| } |
| |
| return( true ); |
| } |
| |
| |
| |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| // TRIVIALLY DATA COMPARATOR |
| //////////////////////////////////////////////////////////////////////////////// |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| bool TriviallyDataComparison::compareDATA( |
| const ExecutionContext & newEC, const ExecutionContext & oldEC) |
| { |
| newED = newEC.getExecutionData(); |
| oldED = oldEC.getExecutionData(); |
| |
| // compare PC |
| if( mIgnorePathCondition || ExpressionComparer::isTEQ( |
| newED->getPathCondition(), oldED->getPathCondition() ) ) |
| { |
| // compare DATAs |
| itPairMachineData = getAllVariable().begin(); |
| endPairMachineData = getAllVariable().end(); |
| for( ; itPairMachineData != endPairMachineData ; ++itPairMachineData ) |
| { |
| if( (*itPairMachineData).second().nonempty() ) |
| { |
| newRF = newED->ptrRuntime( (*itPairMachineData).first() ); |
| oldRF = oldED->ptrRuntime( (*itPairMachineData).first() ); |
| |
| if( newRF->getDataTable() != oldRF->getDataTable() ) |
| { |
| itVar = (*itPairMachineData).second().begin(); |
| endVar = (*itPairMachineData).second().end(); |
| for( ; itVar != endVar ; ++itVar ) |
| { |
| if( not ExpressionComparer::isTEQ( |
| newRF->getData((*itVar)->getOffset()), |
| oldRF->getData((*itVar)->getOffset())) ) |
| { |
| return( false ); |
| } |
| } |
| } |
| } |
| } |
| |
| return( true ); |
| } |
| |
| return( false ); |
| } |
| |
| |
| } |