use of com.ge.verdict.synthesis.dtree.DLeaf.ComponentDefense in project VERDICT by ge-high-assurance.
the class VerdictSynthesis method normalizeCosts.
/**
* Calculates (and returns) lowest common denominator of all leaf costs, and sets the
* normalizedCost field in each leaf accordingly.
*
* @param pairs
* @return
* @deprecated use the multi-requirement approach instead
*/
@Deprecated
public static int normalizeCosts(Collection<ComponentDefense> pairs) {
int costLcd = pairs.stream().flatMap((ComponentDefense pair) -> IntStream.range(0, 10).map(dal -> pair.dalToRawCost(dal).getDenominator()).mapToObj(// kind of dumb but need to go
x -> x)).reduce(1, ArithmeticUtils::lcm);
for (ComponentDefense pair : pairs) {
int[] normCosts = new int[10];
for (int dal = 0; dal < 10; dal++) {
Fraction normalizedCost = pair.dalToRawCost(dal).multiply(costLcd);
if (normalizedCost.getDenominator() != 1) {
throw new RuntimeException();
}
normCosts[dal] = normalizedCost.getNumerator();
}
pair.normalizeCosts(normCosts);
}
return costLcd;
}
use of com.ge.verdict.synthesis.dtree.DLeaf.ComponentDefense in project VERDICT by ge-high-assurance.
the class VerdictSynthesis method performSynthesisMultiple.
/**
* Performs synthesis on multiple cyber requirements. This is the only version of synthesis that
* should be used.
*
* @param tree the defense tree
* @param factory the dleaf factory used to construct the defense tree
* @param costModel the cost model
* @param partialSolution whether we are using partial solutions
* @param inputSat whether the input tree is satisfied
* @param meritAssignment whether to perform merit assignment if the input is satisfied
* @param dumpSmtLib whether to output the intermediate SMT-LIB file for debugging
* @return the result, if successful
*/
public static Optional<ResultsInstance> performSynthesisMultiple(DTree tree, DLeaf.Factory factory, CostModel costModel, boolean partialSolution, boolean inputSat, boolean meritAssignment, boolean dumpSmtLib) {
Context context = new Context();
Optimize optimizer = context.mkOptimize();
System.out.println("performSynthesisMultiple, configuration: partialSolution=" + partialSolution + ", inputSat=" + inputSat + ", meritAssignment=" + meritAssignment);
Collection<ComponentDefense> compDefPairs = factory.allComponentDefensePairs();
// Encode the logical structure of defense tree in MaxSMT
// Encode cost(impl_defense_dal) >= the target cost (based on the severity of cyber req)
// With merit assignment off and partial solution on, you will
// subtract the cost of each DAL by the impl DAL cost, and use 0 if the result is negative.
optimizer.Assert(tree.toZ3Multi(context));
if (meritAssignment) {
// set upper bounds at the current values, so that no upgrades are reported
// Encode component_defense_var <= the the implemented DAL cost
optimizer.Assert(context.mkAnd(compDefPairs.stream().map(pair -> context.mkLe(pair.toZ3Multi(context), DLeaf.fractionToZ3(pair.dalToRawCost(pair.implDal), context))).collect(Collectors.toList()).toArray(new BoolExpr[] {})));
}
// Make all component-defense var >= Cost(DAL(0));
optimizer.Assert(// to DAL, then this can be changed to the minimum of all costs.
context.mkAnd(compDefPairs.stream().map(pair -> context.mkGe(pair.toZ3Multi(context), DLeaf.fractionToZ3(pair.dalToRawCost(0), context))).collect(Collectors.toList()).toArray(new BoolExpr[] {})));
// Encode objective function: the sum of all component-defense vars
if (compDefPairs.isEmpty()) {
optimizer.MkMinimize(context.mkInt(0));
} else {
optimizer.MkMinimize(context.mkAdd(compDefPairs.stream().map(pair -> pair.toZ3Multi(context)).collect(Collectors.toList()).toArray(new ArithExpr[] {})));
}
if (dumpSmtLib) {
try {
// this dumps the file in the working directory, i.e. where the process was started
// from
PrintWriter writer = new PrintWriter("verdict-synthesis-dump.smtlib", "UTF-8");
writer.println(optimizer.toString());
writer.flush();
writer.close();
} catch (FileNotFoundException | UnsupportedEncodingException e) {
e.printStackTrace();
}
}
if (optimizer.Check().equals(Status.SATISFIABLE)) {
List<ResultsInstance.Item> items = new ArrayList<>();
Fraction totalInputCost = new Fraction(0), totalOutputCost = new Fraction(0);
Model model = optimizer.getModel();
for (ComponentDefense pair : compDefPairs) {
// get the value in the model
RatNum expr = (RatNum) model.eval(pair.toZ3Multi(context), true);
Fraction rawCost = new Fraction(expr.getNumerator().getInt(), expr.getDenominator().getInt());
// convert back to DAL (the value in the model is cost rather than DAL)
int dal = pair.rawCostToDal(rawCost);
// but we don't trust the cost obtained directly from the model.
// instead, we re-calculate using the cost model because it is less prone to failure
// The cost of implemented DAL
Fraction inputCost = costModel.cost(pair.defenseProperty, pair.component, pair.implDal);
// The cost of output DAL from SMT
Fraction outputCost = costModel.cost(pair.defenseProperty, pair.component, dal);
// keep track of total cost
totalInputCost = totalInputCost.add(inputCost);
totalOutputCost = totalOutputCost.add(outputCost);
items.add(new ResultsInstance.Item(pair.component, pair.defenseProperty, pair.implDal, dal, inputCost, outputCost));
}
return Optional.of(new ResultsInstance(partialSolution, meritAssignment, inputSat, totalInputCost, totalOutputCost, items));
} else {
System.err.println("Synthesis: SMT not satisfiable, perhaps there are unmitigatable attacks");
return Optional.empty();
}
}
use of com.ge.verdict.synthesis.dtree.DLeaf.ComponentDefense in project VERDICT by ge-high-assurance.
the class VerdictSynthesisTest method decimalCostsTest.
@Test
public void decimalCostsTest() {
CostModel costs = new CostModel(new File(getClass().getResource("decimalCosts.xml").getPath()));
DLeaf.Factory factory = new DLeaf.Factory();
int targetDal = 1;
List<ComponentDefense> leaves = new ArrayList<>();
DLeaf leafA = new DLeaf("A", "A", "A", 0, targetDal, costs, factory, false, false);
DLeaf leafB = new DLeaf("B", "B", "B", 0, targetDal, costs, factory, false, false);
DLeaf leafC = new DLeaf("C", "C", "C", 0, targetDal, costs, factory, false, false);
leaves.add(leafA.componentDefense);
leaves.add(leafB.componentDefense);
leaves.add(leafC.componentDefense);
Assertions.assertThat(leafA.componentDefense.dalToRawCost(targetDal)).isEqualByComparingTo(new Fraction(42, 10));
Assertions.assertThat(leafB.componentDefense.dalToRawCost(targetDal)).isEqualByComparingTo(new Fraction(35, 1000));
Assertions.assertThat(leafC.componentDefense.dalToRawCost(targetDal)).isEqualByComparingTo(new Fraction(1077, 100));
int costLcm = VerdictSynthesis.normalizeCosts(leaves);
Assertions.assertThat(costLcm).isEqualTo(200);
Assertions.assertThat(leafA.componentDefense.dalToNormCost(targetDal)).isEqualTo(840);
Assertions.assertThat(leafB.componentDefense.dalToNormCost(targetDal)).isEqualTo(7);
Assertions.assertThat(leafC.componentDefense.dalToNormCost(targetDal)).isEqualTo(2154);
}
Aggregations