use of jkind.lustre.builders.NodeBuilder in project AGREE by loonwerks.
the class AgreeRealtimeCalendarBuilder method getMinPosNode.
private static Node getMinPosNode() {
NodeBuilder builder = new NodeBuilder(MIN_POS_NODE_NAME);
IdExpr a = new IdExpr("a");
IdExpr b = new IdExpr("b");
IdExpr ret = new IdExpr("ret");
builder.addInput(new VarDecl(a.id, NamedType.REAL));
builder.addInput(new VarDecl(b.id, NamedType.REAL));
builder.addOutput(new VarDecl(ret.id, NamedType.REAL));
Expr aLessB = new BinaryExpr(a, BinaryOp.LESSEQUAL, b);
Expr bNeg = new BinaryExpr(b, BinaryOp.LESSEQUAL, new RealExpr(BigDecimal.ZERO));
Expr aNeg = new BinaryExpr(a, BinaryOp.LESSEQUAL, new RealExpr(BigDecimal.ZERO));
Expr ifALessB = new IfThenElseExpr(aLessB, a, b);
Expr ifBNeg = new IfThenElseExpr(bNeg, a, ifALessB);
Expr ifANeg = new IfThenElseExpr(aNeg, b, ifBNeg);
builder.addEquation(new Equation(ret, ifANeg));
return builder.build();
}
use of jkind.lustre.builders.NodeBuilder in project AGREE by loonwerks.
the class AgreeRealtimeCalendarBuilder method getRiseNode.
private static Node getRiseNode() {
NodeBuilder builder = new NodeBuilder(RISE_NODE_NAME);
builder.addInput(new VarDecl("input", NamedType.BOOL));
builder.addOutput(new VarDecl("output", NamedType.BOOL));
IdExpr inputId = new IdExpr("input");
IdExpr outputId = new IdExpr("output");
Expr outputExpr = new UnaryExpr(UnaryOp.NOT, inputId);
outputExpr = new UnaryExpr(UnaryOp.PRE, outputExpr);
outputExpr = new BinaryExpr(outputExpr, BinaryOp.AND, inputId);
outputExpr = new BinaryExpr(inputId, BinaryOp.ARROW, outputExpr);
builder.addEquation(new Equation(outputId, outputExpr));
return builder.build();
}
use of jkind.lustre.builders.NodeBuilder 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.NodeBuilder 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();
}
use of jkind.lustre.builders.NodeBuilder in project AGREE by loonwerks.
the class AgreeCalendarUtils method queueNode.
public static Node queueNode(String nodeName, Type type, int queueSize) {
List<VarDecl> inputs = new ArrayList<>();
List<VarDecl> outputs = new ArrayList<>();
List<VarDecl> locals = new ArrayList<>();
List<IdExpr> els = new ArrayList<>();
List<Equation> eqs = new ArrayList<>();
String elBase = "el";
IdExpr elemIn = new IdExpr("el_in");
IdExpr elemOut = new IdExpr("el_out");
IdExpr insert = new IdExpr("insert");
IdExpr output = new IdExpr("output");
IdExpr input = new IdExpr("input");
IdExpr numEls = new IdExpr("num_els");
inputs.add(new VarDecl(input.id, type));
inputs.add(new VarDecl(elemIn.id, NamedType.BOOL));
inputs.add(new VarDecl(elemOut.id, NamedType.BOOL));
outputs.add(new VarDecl(numEls.id, NamedType.INT));
outputs.add(new VarDecl(output.id, type));
locals.add(new VarDecl(insert.id, NamedType.INT));
// add an extra "dummy element" for handling too many inserts
for (int i = 0; i < queueSize + 1; i++) {
IdExpr el = new IdExpr(elBase + i);
els.add(el);
locals.add(new VarDecl(el.id, type));
}
// equation for insert
Expr preElemIn = new UnaryExpr(UnaryOp.PRE, elemIn);
Expr preElemOut = new UnaryExpr(UnaryOp.PRE, elemOut);
Expr preInsert = new UnaryExpr(UnaryOp.PRE, insert);
Expr preInsertMore = new BinaryExpr(preInsert, BinaryOp.PLUS, new IntExpr(BigInteger.ONE));
Expr preInsertLess = new BinaryExpr(preInsert, BinaryOp.MINUS, new IntExpr(BigInteger.ONE));
Expr insertIf0 = new IfThenElseExpr(preElemIn, preInsertMore, preInsert);
Expr insertIf1 = new IfThenElseExpr(preElemOut, preInsertLess, insertIf0);
Expr insertExpr = new BinaryExpr(new IntExpr(BigInteger.ZERO), BinaryOp.ARROW, insertIf1);
Equation insertEq = new Equation(insert, insertExpr);
eqs.add(insertEq);
// equation for numEls
Expr preNumEls = new UnaryExpr(UnaryOp.PRE, numEls);
Expr preNumElsMore = new BinaryExpr(preNumEls, BinaryOp.PLUS, new IntExpr(BigInteger.ONE));
Expr preNumElsLessExpr = new BinaryExpr(preNumEls, BinaryOp.MINUS, new IntExpr(BigInteger.ONE));
Expr numElsIf0 = new IfThenElseExpr(preElemIn, preNumElsMore, preNumEls);
Expr numElsExpr = new IfThenElseExpr(preElemOut, preNumElsLessExpr, numElsIf0);
numElsExpr = new BinaryExpr(new IntExpr(BigInteger.ZERO), BinaryOp.ARROW, numElsExpr);
Equation numElsEq = new Equation(numEls, numElsExpr);
eqs.add(numElsEq);
// equation for the output
Equation outputEq = new Equation(output, new IdExpr(elBase + 0));
eqs.add(outputEq);
// equations for each queue element
Expr preInput = new UnaryExpr(UnaryOp.PRE, input);
for (int i = 0; i < queueSize; i++) {
Expr preEl = new UnaryExpr(UnaryOp.PRE, els.get(i));
Expr cond = new UnaryExpr(UnaryOp.PRE, insert);
cond = new BinaryExpr(cond, BinaryOp.EQUAL, new IntExpr(BigInteger.valueOf(i)));
cond = new BinaryExpr(preElemIn, BinaryOp.AND, cond);
Expr elemIf0 = new IfThenElseExpr(cond, preInput, preEl);
Expr elemIf1 = new IfThenElseExpr(preElemOut, els.get(i + 1), elemIf0);
Expr elExpr = new BinaryExpr(input, BinaryOp.ARROW, elemIf1);
Equation elEq = new Equation(els.get(i), elExpr);
eqs.add(elEq);
}
// special case for the dummy element
Equation elEq = new Equation(els.get(queueSize), input);
eqs.add(elEq);
// queue properties:
List<String> props = new ArrayList<>();
// don't remove more than are present:
// Expr propExpr0 = new BinaryExpr(preRemove, BinaryOp.EQUAL,
// preInsert);
// Expr propExpr1 = new BinaryExpr(remove, BinaryOp.EQUAL, preRemove);
// Expr propImpl = new BinaryExpr(propExpr0, BinaryOp.IMPLIES,
// propExpr1);
// Expr propArrow = new BinaryExpr(remove, BinaryOp.LESSEQUAL, insert);
// propArrow = new BinaryExpr(propArrow, BinaryOp.ARROW, propImpl);
Expr propExpr = new BinaryExpr(numEls, BinaryOp.GREATEREQUAL, new IntExpr(BigInteger.ZERO));
IdExpr propId0 = new IdExpr("__REMOVE_LTE_INSERT_" + nodeName);
locals.add(new VarDecl(propId0.id, NamedType.BOOL));
Equation propEq0 = new Equation(propId0, propExpr);
eqs.add(propEq0);
props.add(propId0.id);
NodeBuilder builder = new NodeBuilder(nodeName);
builder.addInputs(inputs);
builder.addOutputs(outputs);
builder.addLocals(locals);
builder.addEquations(eqs);
builder.addProperties(props);
return builder.build();
}
Aggregations