use of edu.uah.rsesc.aadlsimulator.agree.SimulationProperty in project AGREE by loonwerks.
the class CounterexampleLoaderHelper method simulateCounterexample.
private void simulateCounterexample(final Counterexample cex, final int startStepIndex, final Map<String, Object> signalNameToSimStateElementMap, final AGREESimulationEngine simulationEngine, final SimulationService simulationService, final SimulationUIService simulationUIService) {
// For each frame in the counter example, step through the simulation and constrain the arguments to match those of the counter example
for (int stepIndex = startStepIndex; stepIndex < cex.getLength(); stepIndex++) {
simulationEngine.resetInputConstraints();
// Constraint simulation variables based on the counterexample
for (final Entry<String, Value> sv : cex.getStep(stepIndex).entrySet()) {
final String signalName = sv.getKey();
final Object stateElement = signalNameToSimStateElementMap.get(signalName);
// Throw exception if the state element corresponding to the signal in the counterexample was not found unless the signal corresponds to a clock or a specification statement
if (stateElement == null) {
// TODO: Cleanup
// Ignore variables that do not have state elements. Need a way to verify that they can be safely ignored. Clocks may be ignored if they aren't
// used. Variables for SpecStatements are okay to ignore but we don't have a way of getting the reference in all cases.
// In the case of a monolithic analysis, the references for all layers are not contained in the reference map
/*
final String renamedClockIdSuffix = agreeSimulationEngine.getSimulationProgram().getAgreeRenaming().forceRename(AgreeASTBuilder.clockIDSuffix);
final boolean isClock = signalName.endsWith(renamedClockIdSuffix);
final EObject ref = refMap.get(signalName);
if(!isClock && !(ref instanceof SpecStatement)) {
//throw new RuntimeException("Unable to find state element for signal '" + signalName + "'");
}
*/
} else {
// Don't include hidden variables
if (!simulationEngine.getCurrentState().isElementHidden(stateElement)) {
// Constrain the next value of the variable to match the value contained in the counter example
final InputConstraint ic = lustreValueToInputConstraint(sv.getValue());
simulationEngine.setInputConstraint(stateElement, ic);
}
}
}
simulationEngine.stepForward();
}
simulationEngine.queueNotification(notification -> {
// Check that the number of simulated frames matches the expected number. It should match the length of the counter example
if (cex.getLength() == notification.getEngineState().getNumberOfFrames()) {
simulationEngine.resetInputConstraints();
} else {
// Determine whether there are unsatisfied properties that are halting the simulation
boolean hasUnsatisfiedProperty = false;
for (final SimulationProperty simProp : simulationEngine.getSimulationProgram().getSimulationProperties()) {
if (notification.getEngineState().getPropertyStatus(simProp) == AGREEPropertyStatus.UNSATISFIED_ERROR) {
hasUnsatisfiedProperty = true;
}
}
if (hasUnsatisfiedProperty) {
Display.getDefault().syncExec(() -> {
final IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
final IWorkbenchPage activePage = window.getActivePage();
if (activePage != null) {
try {
activePage.showView(UIConstants.PROPERTIES_VIEW_ID);
} catch (final PartInitException e) {
// Ignore
}
}
final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
final String errorMsg = "One or more properties could not be satisfied. Disable one or more properties from the Simulation Properties view and select Retry to continue.";
class RetryDialog extends MessageDialog {
public RetryDialog() {
super(shell, "Unable to Simulate Counterexample", null, errorMsg, MessageDialog.ERROR, new String[] { "Retry", "End Simulation" }, 0);
setShellStyle(SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE);
setBlockOnOpen(false);
}
@Override
protected void buttonPressed(final int buttonId) {
switch(buttonId) {
case // Retry
0:
// Try to resume the simulation
simulationEngine.stepBackward();
simulateCounterexample(cex, notification.getEngineState().getNumberOfFrames() - 1, signalNameToSimStateElementMap, simulationEngine, simulationService, simulationUIService);
break;
case // End Simulation
1:
simulationService.dispose(simulationEngine);
break;
}
super.buttonPressed(buttonId);
}
}
final MessageDialog dlg = new RetryDialog();
dlg.open();
});
} else {
final StatusAdapter statusAdapter = new StatusAdapter(new Status(IStatus.WARNING, FrameworkUtil.getBundle(getClass()).getSymbolicName(), "Simulation halted before every step in the counterexample was simulated.", new RuntimeException("The number of simulated frames does not match the length of the counterexample.")));
statusAdapter.setProperty(IStatusAdapterConstants.TITLE_PROPERTY, "Unable to Simulate Counterexample");
StatusManager.getManager().handle(statusAdapter, StatusManager.SHOW);
}
}
});
}
use of edu.uah.rsesc.aadlsimulator.agree.SimulationProperty in project AGREE by loonwerks.
the class AGREESimulationState method createEvaluator.
private Evaluator createEvaluator(final Collection<Expr> constraints, final Set<SimulationProperty> disabledProperties) {
try {
final SimulationFrameResults lastFrameResults = frameInfos.size() == 0 ? null : frameInfos.get(frameInfos.size() - 1).getFrameResults();
final List<Expr> assertions = new ArrayList<Expr>();
FrameAssertionHelper.addNextFrameAssertions(simulationProgram, lastFrameResults, assertions);
assertions.addAll(constraints);
// Add assertions for property enablement variables
for (final SimulationProperty simProp : simulationProgram.getSimulationProperties()) {
if (simProp.getEnablementVariableId() != null) {
assertions.add(new BinaryExpr(new IdExpr(simProp.getEnablementVariableId()), BinaryOp.EQUAL, new BoolExpr(disabledProperties.contains(simProp) ? false : true)));
}
}
// Create the new evaluator
return new Evaluator(baseEvaluator, assertions);
} catch (EvaluationException ex) {
return null;
}
}
use of edu.uah.rsesc.aadlsimulator.agree.SimulationProperty in project AGREE by loonwerks.
the class GoToPropertyCommand method activate.
@Override
public void activate(final CommandContext ctx) {
final SimulationProperty simProp = (SimulationProperty) ctx.getBusinessObject();
com.rockwellcollins.atc.agree.analysis.AgreeUtils.getGlobalURIEditorOpener().open(EcoreUtil.getURI(simProp.getDeclarativeModelReference()), true);
}
use of edu.uah.rsesc.aadlsimulator.agree.SimulationProperty in project AGREE by loonwerks.
the class Simulation method executeFrame.
private SimulationFrameResults executeFrame(final List<Expr> assertions, final Set<SimulationProperty> disabledProperties) throws InterruptedException {
assert assertions != null;
// Build the final constrained lustre specification for the frame.
final ProgramBuilder programBuilder = new ProgramBuilder(program.getLustreProgram());
programBuilder.clearNodes();
final NodeBuilder nodeBuilder = new NodeBuilder(program.getLustreProgram().getMainNode());
// Add assignments for the sim assertions signal
// Actual assertions are not used because they can result in an inconsistent Lustre program which will prevent
// the set of support from being generated when using yices.
Expr prevSimAssertionExpr = new BoolExpr(true);
for (int assertionIndex = 0; assertionIndex < assertions.size(); assertionIndex++) {
final String simAssertionSignalId = CreateSimulationGuarantee.SIMULATION_ASSERTIONS_ID + assertionIndex;
final IdExpr simAssertionExpr = new IdExpr(simAssertionSignalId);
nodeBuilder.addLocal(new VarDecl(simAssertionSignalId, NamedType.BOOL));
nodeBuilder.addEquation(new Equation(simAssertionExpr, new BinaryExpr(prevSimAssertionExpr, BinaryOp.AND, assertions.get(assertionIndex))));
prevSimAssertionExpr = simAssertionExpr;
}
nodeBuilder.addEquation(new Equation(new IdExpr(CreateSimulationGuarantee.SIMULATION_ASSERTIONS_ID), prevSimAssertionExpr));
// Add assignments for property enablement variables
for (final SimulationProperty simProp : program.getSimulationProperties()) {
if (simProp.getEnablementVariableId() != null) {
nodeBuilder.addEquation(new Equation(new IdExpr(simProp.getEnablementVariableId()), new BoolExpr(disabledProperties.contains(simProp) ? false : true)));
}
}
// Build the lustre program for the frame
programBuilder.addNode(nodeBuilder.build());
final Program constrainedLustreProgram = programBuilder.build();
// Prepare to execute JKind
final KindApi api = PreferencesUtil.getKindApi();
// Enable IVC Reduction capability if using JKind
if (api instanceof JKindApi) {
final JKindApi jkindApi = (JKindApi) api;
jkindApi.setIvcReduction();
}
// Execute JKind
final JKindResult result = new JKindResult("Simulation");
// Lucas: This seems to be needed. If we do not add properties to the result explicitly,
// it looks like the result will grab the main property name with the main node prepended.
// This is causing an error when retrieving the property result in the
// if/then/else block structure below.
constrainedLustreProgram.getMainNode().properties.forEach(p -> result.addProperty(p));
System.out.println(constrainedLustreProgram.toString());
try {
final IProgressMonitor currentMonitor = new NullProgressMonitor();
api.execute(constrainedLustreProgram, result, currentMonitor);
// Create a model state from the results.
String simulationGuaranteeId = CreateSimulationGuarantee.SIMULATION_GUARANTEE_ID;
final PropertyResult propertyResult = result.getPropertyResult(simulationGuaranteeId);
final Property property = propertyResult.getProperty();
if (property == null) {
throw new AGREESimulatorException("Unexpected case. Unable to read property results", constrainedLustreProgram);
} else if (property instanceof InvalidProperty) {
final InvalidProperty invalidProperty = (InvalidProperty) property;
final Counterexample counterexample = invalidProperty.getCounterexample();
if (counterexample.getLength() != 1) {
throw new AGREESimulatorException("Unexpected case. Counterexample has " + counterexample.getLength() + " steps", constrainedLustreProgram);
}
SimulationState newState = SimulationState.WAITING_FOR_COMMANDS;
// and a counterexample will not have been generated. This should only occur when a disabled property, lemma, top-level guarantee, or a non-top-level assumption is false.
for (final SimulationProperty simulationProp : program.getSimulationProperties()) {
if (!disabledProperties.contains(simulationProp)) {
for (final String propLustreId : simulationProp.getLustreIds()) {
final Signal<BooleanValue> signal = counterexample.getBooleanSignal(propLustreId);
if (signal == null) {
throw new AGREESimulatorException("Unable to get signal for guarantee property: " + propLustreId, constrainedLustreProgram);
} else {
if (!signal.getValue(0).value) {
newState = SimulationState.WARNING_PROPERTY_NOT_SATISFIED;
break;
}
}
}
}
}
return new SimulationFrameResults(constrainedLustreProgram, counterexample, disabledProperties, newState);
} else if (property instanceof UnknownProperty) {
return new SimulationFrameResults(constrainedLustreProgram, assertions, disabledProperties, SimulationState.HALTED_UNABLE_TO_SATISFY_CONSTRAINTS);
} else if (property instanceof ValidProperty) {
return new SimulationFrameResults(constrainedLustreProgram, assertions, disabledProperties, ((ValidProperty) property).getIvc(), SimulationState.HALTED_UNABLE_TO_SATISFY_CONSTRAINTS);
} else {
throw new AGREESimulatorException("Unhandled case. Property is of type: " + property.getClass(), constrainedLustreProgram);
}
} catch (JKindException ex) {
if (ex.getCause() instanceof InterruptedException) {
throw (InterruptedException) ex.getCause();
}
throw new AGREESimulatorException(constrainedLustreProgram, ex, result.getText());
}
}
use of edu.uah.rsesc.aadlsimulator.agree.SimulationProperty in project AGREE by loonwerks.
the class CreateSimulationProperties method transform.
public static SimulationProgram transform(final SimulationProgram program) {
final Program lustreProgram = program.getLustreProgram();
if (lustreProgram.nodes.size() != 1) {
throw new IllegalArgumentException("Only lustre programs with exactly one node are supported");
}
final SimulationProgramBuilder builder = new SimulationProgramBuilder(program);
final Node mainNode = lustreProgram.getMainNode();
// Build a new main node which includes support statements
final NodeBuilder lustreNodeBuilder = new NodeBuilder(mainNode);
// Create simulation properties for each local variable that references a lemma, assume, guarantee, or assert statement
lustreNodeBuilder.clearIvc();
final Map<String, SimulationProperty> idToSimulationPropertyMap = new HashMap<>();
// Create a mapping from the component instance/variable reference to a collection of Lustre Id's that will be used to create the simulation properties
final Map<ComponentInstance, Map<EObject, Collection<String>>> componentInstanceToReferenceToVarIdMap = new HashMap<>();
for (final VarDecl local : mainNode.locals) {
if (local instanceof AgreeVar) {
final AgreeVar var = (AgreeVar) local;
if (var.reference instanceof LemmaStatement || var.reference instanceof AssumeStatement || var.reference instanceof GuaranteeStatement || var.reference instanceof AssertStatement) {
final boolean createSimProp = (!(var.reference instanceof AssumeStatement) || var.compInst == var.compInst.getSystemInstance()) || var instanceof SimulationPropertyVar;
if (createSimProp) {
Map<EObject, Collection<String>> referenceToVarIdMap = componentInstanceToReferenceToVarIdMap.get(var.compInst);
if (referenceToVarIdMap == null) {
referenceToVarIdMap = new HashMap<>();
componentInstanceToReferenceToVarIdMap.put(var.compInst, referenceToVarIdMap);
}
Collection<String> varIds = referenceToVarIdMap.get(var.reference);
if (varIds == null) {
varIds = new HashSet<>();
referenceToVarIdMap.put(var.reference, varIds);
}
varIds.add(var.id);
}
}
}
}
// Create the simulation properties.
// A single simulation property will be created for each component instance, reference combination.
int propertyIndex = 0;
for (final Entry<ComponentInstance, Map<EObject, Collection<String>>> componentInstanceToReferenceToVarIdMapEntry : componentInstanceToReferenceToVarIdMap.entrySet()) {
final ComponentInstance propComponentInstance = componentInstanceToReferenceToVarIdMapEntry.getKey();
for (Entry<EObject, Collection<String>> referenceToVarIdsEntry : componentInstanceToReferenceToVarIdMapEntry.getValue().entrySet()) {
final EObject propReference = referenceToVarIdsEntry.getKey();
final Collection<String> propLustreIds = referenceToVarIdsEntry.getValue();
final String propertyDesc = getDescription(propComponentInstance, propReference);
final String enablementVariableId;
// Only properties which cause the simulation to be halted may be disabled.
// That is: only top-level assumptions and non-top-level guarantees may be disabled
final boolean disableable = (propReference instanceof GuaranteeStatement && propComponentInstance != propComponentInstance.getSystemInstance()) || (propReference instanceof AssumeStatement && propComponentInstance == propComponentInstance.getSystemInstance());
if (disableable) {
enablementVariableId = propertyEnablementPrefix + propertyIndex;
lustreNodeBuilder.addLocal(new VarDecl(enablementVariableId, NamedType.BOOL));
} else {
enablementVariableId = null;
}
final SimulationProperty simProp = new SimulationProperty(propLustreIds, propertyDesc, propReference, enablementVariableId);
builder.addSimulationProperty(simProp);
propertyIndex++;
for (final String propLustreId : propLustreIds) {
idToSimulationPropertyMap.put(propLustreId, simProp);
lustreNodeBuilder.addIvc(propLustreId);
}
}
}
// Edit main node to make simulation properties inside of assertions to be disableable
final AstMapVisitor propertyVarDisableTransformation = new AstMapVisitor() {
@Override
public Expr visit(final IdExpr e) {
final SimulationProperty simProp = idToSimulationPropertyMap.get(e.id);
if (simProp != null && simProp.getEnablementVariableId() != null) {
return new BinaryExpr(new UnaryExpr(UnaryOp.NOT, new IdExpr(simProp.getEnablementVariableId())), BinaryOp.OR, e);
}
return super.visit(e);
}
@Override
public Equation visit(final Equation e) {
// Don't transform the equations for simulation properties
if (e.lhs.size() == 1 && idToSimulationPropertyMap.containsKey(e.lhs.get(0))) {
return e;
}
return super.visit(e);
}
};
// Transform assertions and equations
lustreNodeBuilder.clearAssertions();
for (final Expr assertion : mainNode.assertions) {
lustreNodeBuilder.addAssertion(assertion.accept(propertyVarDisableTransformation));
}
lustreNodeBuilder.clearEquations();
for (final Equation eq : mainNode.equations) {
lustreNodeBuilder.addEquation((Equation) eq.accept(propertyVarDisableTransformation));
}
// Build a new program with the new main node
final ProgramBuilder lustreProgramBuilder = new ProgramBuilder(lustreProgram);
lustreProgramBuilder.clearNodes();
lustreProgramBuilder.addNode(lustreNodeBuilder.build());
builder.setLustreProgram(lustreProgramBuilder.build());
return builder.build();
}
Aggregations