blob: 4e5e73823ed2a44dfd3ff479b9e8bdfd4dd1a50a [file] [log] [blame]
/*******************************************************************************
* 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
*
* Created on: 6 janv. 2014
*
* Contributors:
* Arnault Lapitre (CEA LIST) arnault.lapitre@cea.fr
* - Initial API and implementation
******************************************************************************/
#include "TraceNumerizer.h"
#include "TraceManager.h"
#include <computer/EvaluationEnvironment.h>
#include <solver/api/SolverFactory.h>
#include <fml/trace/TracePoint.h>
#include <fml/trace/TraceSequence.h>
#include <fml/workflow/Query.h>
#include <fml/workflow/WObject.h>
namespace sep
{
////////////////////////////////////////////////////////////////////////////////
// CONFIGURE API
////////////////////////////////////////////////////////////////////////////////
/*
prototype process::trace_generator as &avm::processor.TRACE_GENERATOR is
section PROPERTY
...
// 'OMEGA' | 'CVC4' | 'Z3' | 'YICES'
@solver = 'CVC4';
@numerizer = 'SOLVER'; // SOLVER | NONE | NEWFRESH
...
endsection PROPERTY
...
endprototype
*/
bool TraceNumerizer::configure(WObject * wfParameterObject)
{
WObject * thePROPERTY = Query::getRegexWSequence(wfParameterObject,
OR_WID2("property", "PROPERTY"), wfParameterObject);
if( thePROPERTY != WObject::_NULL_ )
{
std::string strAttribrute = Query::getWPropertyString(
thePROPERTY, "numerizer", "SOLVER");
if( strAttribrute == "SOLVER" )
{
mNumerizerOperator = AVM_OPCODE_CHECK_SAT;
}
else if( strAttribrute == "NEWFRESH" )
{
mNumerizerOperator = AVM_OPCODE_ASSIGN_NEWFRESH;
}
else //if( strAttribrute == "NONE" )
{
mNumerizerOperator = AVM_OPCODE_NOP;
}
strAttribrute = Query::getWPropertyString(thePROPERTY, "solver", "");
mSolverKind = SolverDef::toSolver(
strAttribrute, SolverDef::DEFAULT_SOLVER_KIND);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// NUMERIZE API
////////////////////////////////////////////////////////////////////////////////
void TraceNumerizer::numerize(TraceManager & aTraceManager)
{
switch( mNumerizerOperator ) {
case AVM_OPCODE_CHECK_SAT:
{
numerizeSolver( aTraceManager );
break;
}
case AVM_OPCODE_ASSIGN_NEWFRESH:
{
numerizeNewfresh( aTraceManager );
break;
}
case AVM_OPCODE_NOP:
{
numerizeNothing( aTraceManager );
break;
}
default:
{
numerizeSolver( aTraceManager );
break;
}
}
}
void TraceNumerizer::numerizeSolver(TraceManager & aTraceManager)
{
TraceManager::iterator it = aTraceManager.begin();
TraceManager::iterator endIt = aTraceManager.end();
while( it != endIt )
{
aTraceElement = (*it);
aTraceEC = aTraceElement->mEC;
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
AVM_OS_TRACE << "Avant la résolution par le solveur..." << EOL_FLUSH;
// aTraceEC->refExecutionData().toStreamData(AVM_OS_TRACE);
aTraceEC->refExecutionData().getParametersRuntimeForm().
toStreamData(aTraceEC->getExecutionData(), AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
modelED = SolverFactory::solve(mSolverKind, ENV, (* aTraceEC),
aTraceEC->refExecutionData().getAllPathCondition() );
if( modelED.invalid() )
{
AVM_IF_DEBUG_ENABLED
AVM_OS_WARN << "Error checking model: trace < "
<< aTraceElement->tid << " > for leaf context "
<< aTraceEC->str_min() << std::endl << " |= "
<< aTraceEC->refExecutionData().getAllPathCondition().wrapStr()
<< std::endl;
AVM_ENDIF_DEBUG_ENABLED
// iterator incrementation
it = aTraceManager.erase( it );
continue;
}
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
AVM_OS_TRACE << "Après la résolution par le solveur..." << EOL_FLUSH;
// modelED->toStreamData(AVM_OS_TRACE);
modelED->getParametersRuntimeForm().toStreamData(modelED, AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
SolverFactory::setModel(ENV, modelED);
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
AVM_OS_TRACE << "Après la génération du modèle par le solveur..." << EOL_FLUSH;
// modelED->toStreamData(AVM_OS_TRACE);
modelED->getParametersRuntimeForm().toStreamData(modelED, AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
numerize(aTraceElement);
SolverFactory::resetModel(modelED);
// iterator incrementation
++it;
}
}
void TraceNumerizer::numerizeNewfresh(TraceManager & aTraceManager)
{
TraceManager::const_iterator it = aTraceManager.begin();
TraceManager::const_iterator endIt = aTraceManager.end();
for( ; it != endIt ; ++it )
{
aTraceElement = (*it);
aTraceEC = aTraceElement->mEC;
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
AVM_OS_TRACE << "Avant la résolution par le solveur..." << EOL_FLUSH;
// aTraceEC->refExecutionData().toStreamData(AVM_OS_TRACE);
aTraceEC->refExecutionData().getParametersRuntimeForm().toStreamData(
aTraceEC->getExecutionData(), AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
modelED = SolverFactory::solveNewfresh(mSolverKind, ENV, (* aTraceEC),
aTraceEC->refExecutionData().getAllPathCondition() );
if( modelED.invalid() )
{
AVM_IF_DEBUG_ENABLED
AVM_OS_WARN << "Error checking model for :> "
<< aTraceEC->str_min() << std::endl << " |= "
<< aTraceEC->refExecutionData().getAllPathCondition().str()
<< std::endl;
AVM_ENDIF_DEBUG_ENABLED
continue;
}
AVM_IF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
AVM_OS_TRACE << "Après la résolution / génération par le solveur..." << EOL_FLUSH;
// modelED->toStreamData(AVM_OS_TRACE);
modelED->getParametersRuntimeForm().toStreamData(modelED, AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( HIGH , SOLVING , TRACE )
numerize(aTraceElement);
SolverFactory::resetModel(modelED);
}
}
void TraceNumerizer::numerizeNothing(TraceManager & aTraceManager)
{
//!! NOTHING
}
void TraceNumerizer::numerize(TraceSequence * aTraceElt)
{
BFList::const_iterator it = aTraceElt->points.begin();
BFList::const_iterator endIt = aTraceElt->points.end();
for( ; it != endIt ; ++it )
{
if( (*it).is< TracePoint >() )
{
numerize( (*it).to_ptr< TracePoint >() );
}
else if( (*it).is< TraceSequence >() )
{
numerize( (*it).to_ptr< TraceSequence >() );
}
}
}
void TraceNumerizer::numerize(TracePoint * aTracePoint)
{
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , SOLVING , TRACE )
AVM_OS_TRACE << "TraceNumerizer::numerize(TracePoint):> " << std::endl;
aTracePoint->toStream(AVM_OS_TRACE);
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , SOLVING , TRACE )
if( aTracePoint->value.invalid() )
{
//!! NOTING
}
else if( aTracePoint->value.is< ArrayBF >() )
{
if( ENV.eval(modelED, modelED->getSystemRID(), aTracePoint->value) )
{
aTracePoint->value = ENV.outVAL;
}
}
else if( aTracePoint->value.is< BuiltinForm >() )
{
//!! NOTING
}
else if( ENV.eval(modelED, modelED->getSystemRID(), aTracePoint->value) )
{
aTracePoint->value = ENV.outVAL;
}
AVM_IF_DEBUG_LEVEL_FLAG2( MEDIUM , SOLVING , TRACE )
aTracePoint->toStream(AVM_OS_TRACE);
AVM_OS_TRACE << std::endl;
AVM_ENDIF_DEBUG_LEVEL_FLAG2( MEDIUM , SOLVING , TRACE )
}
} /* namespace sep */