use of jkind.lustre.builders.ProgramBuilder in project AGREE by loonwerks.
the class LustreAstBuilder method getConsistencyChecks.
public static List<Pair<String, Program>> getConsistencyChecks(AgreeProgram agreeProgram) {
List<Pair<String, Program>> programs = new ArrayList<>();
List<TypeDef> types = AgreeUtils.getLustreTypes(agreeProgram);
nodes = new ArrayList<>();
uninterpretedFcns = new ArrayList<>();
Node topConsist = getConsistencyLustreNode(agreeProgram.topNode, false);
// we don't want node lemmas to show up in the consistency check
for (Node node : agreeProgram.globalLustreNodes) {
nodes.add(removeProperties(node));
}
nodes.add(topConsist);
nodes.add(getHistNode());
nodes.addAll(AgreeRealtimeCalendarBuilder.getRealTimeNodes());
uninterpretedFcns.addAll(agreeProgram.uninterpretedFunctions);
Program topConsistProg = new ProgramBuilder().addTypes(types).addFunctions(uninterpretedFcns).addNodes(nodes).setMain(topConsist.id).build();
// String topComponentName = agreeProgram.topNode.id.replace("_Instance", "");
// programs.add(Tuples.create(topComponentName + " consistent", topConsistProg));
programs.add(Tuples.create("This component consistent", topConsistProg));
for (AgreeNode subNode : agreeProgram.topNode.subNodes) {
nodes = new ArrayList<>();
subNode = flattenAgreeNode(agreeProgram, subNode, "_TOP__");
Node subConsistNode = getConsistencyLustreNode(subNode, true);
for (Node node : agreeProgram.globalLustreNodes) {
nodes.add(removeProperties(node));
}
nodes.add(subConsistNode);
nodes.add(getHistNode());
nodes.addAll(AgreeRealtimeCalendarBuilder.getRealTimeNodes());
Program subConsistProg = new ProgramBuilder().addTypes(types).addFunctions(uninterpretedFcns).addNodes(nodes).setMain(subConsistNode.id).build();
programs.add(Tuples.create(subNode.id + " consistent", subConsistProg));
}
nodes = new ArrayList<>();
// agreeProgram = translate(agreeProgram);
AgreeNode compositionNode = flattenAgreeNode(agreeProgram, agreeProgram.topNode, "_TOP__");
Node topCompositionConsist = getConsistencyLustreNode(compositionNode, true);
for (Node node : agreeProgram.globalLustreNodes) {
nodes.add(removeProperties(node));
}
// nodes.addAll(agreeProgram.globalLustreNodes);
nodes.add(topCompositionConsist);
nodes.add(getHistNode());
nodes.addAll(AgreeRealtimeCalendarBuilder.getRealTimeNodes());
Program topCompositConsistProg = new ProgramBuilder().addTypes(types).addFunctions(uninterpretedFcns).addNodes(nodes).setMain(topCompositionConsist.id).build();
programs.add(Tuples.create("Component composition consistent", topCompositConsistProg));
return programs;
}
use of jkind.lustre.builders.ProgramBuilder 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 jkind.lustre.builders.ProgramBuilder 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