use of com.rockwellcollins.atc.agree.analysis.ast.AgreeVar in project AMASE by loonwerks.
the class AddFaultsToNodeVisitor method addNominalVars.
/**
* Creates fault nominal input to the lustre node. Only add this if there is at
* least one symmetric fault defined for this node. If only asymmetric, then
* fault nominal does not exist in the agree node, only in comm nodes.
*
* @param node Agree node with these faults.
* @param nb NodeBuilder will have nominal vars added to locals.
*/
public void addNominalVars(AgreeNode node, AgreeNodeBuilder nb) {
List<String> inputIdList = new ArrayList<String>();
for (Map.Entry<String, List<Pair>> faultyVarsExprEntry : faultyVarsExpr.entrySet()) {
// get the specific output
String outputId = faultyVarsExprEntry.getKey();
List<Pair> faultPairs = faultyVarsExprEntry.getValue();
boolean onlyAsym = true;
Fault f = null;
// for list of fault pairs associated with the specific output
for (Pair p : faultPairs) {
if (!isAsymmetric(p.f)) {
onlyAsym = false;
}
f = p.f;
// if the current fault is not asymmetric, add the nominal output id to the node input list
if (!onlyAsym) {
AgreeVar out = findVar(node.outputs, (outputId));
if (out == null) {
new SafetyException("A fault defined for " + node.id + " has a connection" + " that is not a valid output for this component." + " Valid connections include {" + node.outputs + "}");
} else {
// we only add to the input list once for the nominal var for each output
if (!inputIdList.contains(outputId)) {
nb.addInput(new AgreeVar(createNominalId((outputId)), out.type, out.reference));
inputIdList.add(outputId);
}
}
}
}
}
}
use of com.rockwellcollins.atc.agree.analysis.ast.AgreeVar in project AMASE by loonwerks.
the class AddFaultsToNodeVisitor method addLocalsAndInputForHWFaults.
/**
* Method adds unconstrained input and constrained local to represent fault
* event and whether or not fault is currently active.
*
* @param hwfaults List of hardware faults to loop through.
* @param nb Node builder has inputs added.
*/
private void addLocalsAndInputForHWFaults(List<HWFault> hwfaults, AgreeNodeBuilder nb) {
for (HWFault hwf : hwfaults) {
String base = addPathDelimiters(hwf.path, hwf.id);
nb.addInput(new AgreeVar(this.createFaultEventId(base), NamedType.BOOL, hwf.hwFaultStatement));
nb.addInput(new AgreeVar(this.createFaultIndependentActiveId(base), NamedType.BOOL, hwf.hwFaultStatement));
nb.addInput(new AgreeVar(this.createFaultDependentActiveId(base), NamedType.BOOL, hwf.hwFaultStatement));
// constrain fault-active depending on transient / permanent & map it to a
// fault in the node interface
// take the propagation map when constrainFaultActive
constrainFaultActive(hwf, base, nb);
mapFaultActiveToNodeInterface(hwf, hwf.path, base, nb);
}
}
use of com.rockwellcollins.atc.agree.analysis.ast.AgreeVar in project AMASE by loonwerks.
the class AddFaultsToNodeVisitor method buildNonFaultCombinationAssertions.
/**
* Method builds combinations of faults that cannot occur together based on
* probability values.
*
* Uses macros to shrink the size of the entire formula in case the number of
* fault combinations is too large for the Lustre parser to handle.
*
* @param topNode AgreeNode, top of program
* @param builder Node builder will have assertions
* added.
* @param elementProbabilities Prob of elements
* @param faultCombinationsAboveThreshold Which FaultSetProbabilities are above
* threshold given in top level annex.
*/
private void buildNonFaultCombinationAssertions(AgreeNode topNode, AgreeNodeBuilder builder, ArrayList<FaultProbability> elementProbabilities, ArrayList<FaultSetProbability> faultCombinationsAboveThreshold) {
// With the valid fault combinations including dependent faults, and
// noFaultExpr has the default (no-fault) case. Let's construct a proposition.
Set<FaultProbability> elementProbabilitySet = new HashSet<>(elementProbabilities);
// the default (no-fault) case
Expr faultHypothesis = getNoFaultProposition(elementProbabilitySet);
// Vars for macros
List<BinaryExpr> macroList = new ArrayList<BinaryExpr>();
List<String> macroNames = new ArrayList<String>();
int noGoodEls = 0;
int unique = 0;
for (FaultSetProbability fsp : faultCombinationsAboveThreshold) {
Set<FaultProbability> goodElements = new HashSet<>(elementProbabilities);
goodElements.removeAll(fsp.elements);
// add the assertion that the rest of the faults are not to happen
if (!goodElements.isEmpty()) {
noGoodEls = noGoodEls + goodElements.size();
Expr local = getNoFaultProposition(goodElements);
faultHypothesis = new BinaryExpr(local, BinaryOp.OR, faultHypothesis);
// Macros
if (noGoodEls > SAFE_NUM_ELEMENTS) {
IdExpr macro = new IdExpr("GOODELS_" + noGoodEls + unique);
macroNames.add("GOODELS_" + noGoodEls + unique);
noGoodEls = 0;
unique++;
BinaryExpr binMacro = new BinaryExpr(macro, BinaryOp.EQUAL, faultHypothesis);
macroList.add(binMacro);
faultHypothesis = macro;
}
} else // if there are all faults in the current combination
// add the assertion that all faults are allowed to happen
// which will be ORed with the default no fault case
{
Expr local = getAllFaultProposition(fsp.elements);
faultHypothesis = new BinaryExpr(local, BinaryOp.OR, faultHypothesis);
}
}
// Add this fault hypothesis as an assertion if not null.
if (faultHypothesis == null) {
new SafetyException("There is a problem with fault hypothesis for component: " + topNode.id + ". A possible problem is that single layer analysis" + " is being run with no faults defined in lower layer." + " Check hypothesis statements and fault defs in this analysis.");
}
for (String s : macroNames) {
builder.addLocal(new AgreeVar(s, NamedType.BOOL, topNode.reference));
}
for (BinaryExpr b : macroList) {
builder.addLocalEquation(new AgreeEquation((IdExpr) b.left, b.right, topNode.reference));
builder.addAssertion(new AgreeStatement("", b, topNode.reference));
// builder.addGuarantee(new AgreeStatement("", b, topNode.reference));
}
builder.addAssertion(new AgreeStatement("", faultHypothesis, topNode.reference));
}
use of com.rockwellcollins.atc.agree.analysis.ast.AgreeVar in project AMASE by loonwerks.
the class FaultASTBuilder method createInputForCommNode.
/**
* creates inputs for new communication node.
* @param node node builder
* @param fault asymm fault
* @param type type of asym output
* @param nodeName name of communication node
* @return node builder with these enhancements
*/
private NodeBuilder createInputForCommNode(NodeBuilder node, Fault fault, Type type, String nodeName) {
// This list is used to map the fault to the top node locals that
// will reference this node name with its corresponding inputs and outputs.
// Hence the AgreeVars that are created are specifically named for this purpose.
List<AgreeVar> localsForCommNode = new ArrayList<>();
node.createInput("input", type);
AgreeVar var1 = new AgreeVar(nodeName + "__input", type, fault.faultStatement);
localsForCommNode.add(var1);
node.createInput("output", type);
AgreeVar var2 = new AgreeVar(nodeName + "__output", type, fault.faultStatement);
localsForCommNode.add(var2);
node.createInput("__ASSUME__HIST", NamedType.BOOL);
AgreeVar var3 = new AgreeVar(nodeName + "____ASSUME__HIST", NamedType.BOOL, fault.faultStatement);
localsForCommNode.add(var3);
node.createInput("time", NamedType.REAL);
AgreeVar var4 = new AgreeVar(nodeName + "__time", NamedType.REAL, fault.faultStatement);
localsForCommNode.add(var4);
node.createInput("__fault__nominal__output", type);
AgreeVar var5 = new AgreeVar(nodeName + "____fault__nominal__output", type, fault.faultStatement);
localsForCommNode.add(var5);
node.createInput("fault__trigger__" + fault.id, NamedType.BOOL);
AgreeVar var7 = new AgreeVar(nodeName + "__fault__trigger__" + fault.id, NamedType.BOOL, fault.faultStatement);
localsForCommNode.add(var7);
// The fault node may have more than one argument. These all need to be
// added as locals to this node and put into the map for main.
// They will also be used in the node call expression.
// This helper method will add all locals as needed as well as associated
// safetyEqAssert statements. These correspond to "eq" stmts in the fault definition.
localsForCommNode.addAll(addInputListAndEqAsserts(node, fault));
// Add to map between node and list of locals in lustre
mapCommNodeToInputs.put(nodeName, localsForCommNode);
return node;
}
use of com.rockwellcollins.atc.agree.analysis.ast.AgreeVar in project AMASE by loonwerks.
the class FaultASTBuilder method renameEqId.
/**
* Make new fault with updated eq stmt ids
* @param f fault to update
* @param idMap map from old id to new
* @return new updated fault
*/
private Fault renameEqId(Fault f, Map<String, String> idMap) {
Fault newFault = new Fault(f);
newFault.safetyEqVars.clear();
newFault.safetyEqAsserts.clear();
newFault.faultOutputMap.clear();
newFault.faultInputMap.clear();
if (!f.triggers.isEmpty()) {
throw new SafetyException("User-defined triggers are currently unsupported.");
}
// update the variable declarations
for (AgreeVar eq : f.safetyEqVars) {
if (idMap.containsKey(eq.id)) {
eq = new AgreeVar(idMap.get(eq.id), eq.type, eq.reference);
}
newFault.safetyEqVars.add(eq);
}
ReplaceIdVisitor visitor = new ReplaceIdVisitor(idMap);
for (AgreeStatement s : f.safetyEqAsserts) {
newFault.safetyEqAsserts.add(visitor.visit(s));
}
for (Map.Entry<Expr, String> element : f.faultOutputMap.entrySet()) {
newFault.faultOutputMap.put(element.getKey().accept(visitor), element.getValue());
}
for (Map.Entry<String, Expr> element : f.faultInputMap.entrySet()) {
newFault.faultInputMap.put(element.getKey(), element.getValue().accept(visitor));
}
return newFault;
}
Aggregations