Search in sources :

Example 1 with MeritAssignment

use of edu.uiowa.clc.verdict.merit.MeritAssignment in project VERDICT by ge-high-assurance.

the class App method runCrv.

/**
 * Run CRV.
 *
 * @param vdmPath VDM input file
 * @param modelName Name of model
 * @param instrPath temporary instrumented model file
 * @param lustrePath temporary Lustre file
 * @param threats list of threats to instrument (LB, NI, etc.)
 * @throws VerdictRunException
 */
public static void runCrv(String vdmPath, String modelName, String instrPath, String lustrePath, List<String> threats, boolean blameAssignment, boolean componentLevel, boolean globalOptimization, boolean atg, boolean meritAssignment, boolean oneIVC, boolean allMIVC, boolean oneMIVC, String outputPath, String outputBaPath, String debugDir, String kind2Bin) throws VerdictRunException {
    checkFile(vdmPath, true, false, false, false, ".xml");
    checkFile(lustrePath, false, false, true, false, ".lus");
    checkFile(outputPath, false, false, true, false, null);
    String outputFormat;
    if (outputPath.endsWith(".xml")) {
        outputFormat = "-xml";
    } else if (outputPath.endsWith(".json")) {
        outputFormat = "-json";
    } else {
        throw new VerdictRunException("Output file must be .xml or .json");
    }
    if (debugDir != null) {
        logHeader("DEBUGGING XML OUTPUT");
    }
    deleteFile(instrPath);
    deleteFile(lustrePath);
    deleteFile(outputPath);
    if (outputBaPath != null) {
        deleteFile(outputBaPath);
    }
    File vdmFile = new File(vdmPath);
    Model vdmModel = VdmTranslator.unmarshalFromXml(vdmFile);
    logHeader("VDM Instrumentor");
    Instrumentor instrumentor = null;
    if (!threats.isEmpty()) {
        log("Instrumenting model");
        // Instrument loaded model
        Timer.Sample sample = Timer.start(Metrics.globalRegistry);
        instrumentor = new Instrumentor(vdmModel);
        instrumentor.instrument(vdmModel, threats, blameAssignment, componentLevel);
        sample.stop(Metrics.timer("Timer.crv.instrumentor", "model", modelName));
    } else {
        log("No threats selected, no instrumentation necessary");
    }
    debugOutVdm(debugDir, "VERDICT_output_debug_instr.xml", vdmModel);
    {
        // For some reason we need to do this...?
        VdmTranslator.marshalToXml(vdmModel, new File(instrPath));
        vdmModel = VdmTranslator.unmarshalFromXml(new File(instrPath));
    }
    debugOutVdm(debugDir, "VERDICT_output_debug_instr_reloaded.xml", vdmModel);
    logHeader("VDM2LUS");
    log("Converting instrumented Verdict data model to Lustre");
    // Build Lustre model
    Timer.Sample vdm2lusSample = Timer.start(Metrics.globalRegistry);
    VDM2Lustre vdm2lus = new VDM2Lustre(vdmModel);
    Model lustreModel = vdm2lus.translate();
    vdm2lusSample.stop(Metrics.timer("Timer.crv.vdm2lus", "model", modelName));
    debugOutVdm(debugDir, "VERDICT_output_debug_lus", lustreModel);
    if (atg) {
        logHeader("Verdict ATG");
        log("Verdict Automatic Test-case Generation");
        log("Generating opposite guarantees");
        // Why do we do this to vdmModel and not lustreModel?
        // Good question. I don't know, but it works.
        Timer.Sample sample = Timer.start(Metrics.globalRegistry);
        VerdictTestInstrumentor atgInstrumentor = new VerdictTestInstrumentor(vdmModel);
        atgInstrumentor.instrumentTests();
        sample.stop(Metrics.timer("Timer.crv.atgInstrumentor", "model", modelName));
        debugOutVdm(debugDir, "VERDICT_output_debug_lus_atg", lustreModel);
    }
    logHeader("Output Lustre");
    log("Output Lustre file: " + lustrePath);
    // Output Lustre model
    Timer.Sample verdictlustreSample = Timer.start(Metrics.globalRegistry);
    VerdictLustreTranslator.marshalToLustre(lustreModel, new File(lustrePath));
    verdictlustreSample.stop(Metrics.timer("Timer.crv.verdictlustre", "model", modelName));
    logHeader("Kind2");
    log("Running Kind2 model checker");
    log("Output XML file: " + outputPath);
    log("Kind2 is running. Please be patient...");
    if (atg) {
        log("Test cases are embedded in XML");
        if (!threats.isEmpty()) {
            log("Counter-examples/test cases may be induced by the presence of threats");
        }
    }
    boolean mustSet = meritAssignment && (oneMIVC || allMIVC);
    Timer.Sample kind2Sample = Timer.start(Metrics.globalRegistry);
    try {
        ExecuteStreamHandler redirect = new PumpStreamHandler(new FileOutputStream(new File(outputPath)), System.err);
        if (blameAssignment && instrumentor != null && instrumentor.emptyIntrumentation() == false) {
            Binary.invokeBin(kind2Bin, null, redirect, outputFormat, lustrePath, "--check_subproperties", "false", "--enable", "MCS", "--print_mcs_legacy", "true", "--mcs_approximate", Boolean.toString(!globalOptimization));
        } else {
            Binary.invokeBin(kind2Bin, null, redirect, outputFormat, lustrePath, "--check_subproperties", "false", "--ivc", Boolean.toString(meritAssignment), "--ivc_approximate", Boolean.toString(oneIVC), "--ivc_all", Boolean.toString(allMIVC), "--ivc_category", "contracts", "--ivc_must_set", Boolean.toString(mustSet));
        }
    } catch (Binary.ExecutionException e) {
        // Kind2 does some weird things with exit codes
        if (e.getCode().isPresent()) {
            switch(e.getCode().get()) {
                case 20:
                    // Success
                    log("All properties are valid");
                    break;
                case 10:
                    if (atg) {
                        // Some properties invalid, but those might just be the ATG negative
                        // properties
                        log("Kind2 finished");
                    } else {
                        // Some properties invalid
                        log("Some properties are invalid");
                    }
                    break;
                case 2:
                    log("Kind2 terminated with an error");
                    XMLProcessor.parseLog(new File(outputPath));
                    // Terminate the process?
                    break;
                case 0:
                    log("Kind2 timed out");
                    break;
                default:
                    throw new VerdictRunException("Failed to execute kind2", e);
            }
        } else {
            throw new VerdictRunException("Failed to execute kind2", e);
        }
    } catch (IOException e) {
        throw new VerdictRunException("Failed to execute kind2", e);
    } finally {
        kind2Sample.stop(Metrics.timer("Timer.crv.kind2", "model", modelName));
    }
    if (meritAssignment) {
        logHeader("Merit Assignment");
        MeritAssignment ma = new MeritAssignment(new File(outputPath));
        ma.readAndPrintInfo();
    }
    if (blameAssignment && instrumentor != null) {
        logHeader("Blame Assignment");
        // TODO Perform blame assignment post-analysis
        // I already passed the correct parameter to Kind2 above
        // Kind2 XML/JSON is in outputPath (it's probably OK to ignore JSON for now)
        // BA output XML should go to outputBaPath
        // VDM instrumentor instance is vdmInstrumentor
        // If it is null then there were no threat models selected for instrumentations
        log("Blame assignment output: " + outputBaPath);
        try {
            Timer.Sample sample = Timer.start(Metrics.globalRegistry);
            BlameAssignment ba = new BlameAssignment();
            ba = ba.compute_blame_assignment(new File(outputPath), instrumentor.getAttackMap(), componentLevel);
            XMLProcessor.dumpXML(ba, new File(outputBaPath));
            sample.stop(Metrics.timer("Timer.crv.blameassignment", "model", modelName));
        } catch (FileNotFoundException e) {
            throw new VerdictRunException("Failed to perform blame assignment", e);
        }
    }
    logHeader("Finished");
}
Also used : MeritAssignment(edu.uiowa.clc.verdict.merit.MeritAssignment) Instrumentor(edu.uiowa.clc.verdict.crv.Instrumentor) VerdictTestInstrumentor(com.ge.verdict.test.instrumentor.VerdictTestInstrumentor) ExecuteStreamHandler(org.apache.tools.ant.taskdefs.ExecuteStreamHandler) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) VDM2Lustre(edu.uiowa.clc.verdict.lustre.VDM2Lustre) PumpStreamHandler(org.apache.tools.ant.taskdefs.PumpStreamHandler) Timer(io.micrometer.core.instrument.Timer) VerdictTestInstrumentor(com.ge.verdict.test.instrumentor.VerdictTestInstrumentor) FileOutputStream(java.io.FileOutputStream) Model(verdict.vdm.vdm_model.Model) CostModel(com.ge.verdict.synthesis.CostModel) File(java.io.File) BlameAssignment(edu.uiowa.clc.verdict.blm.BlameAssignment)

Aggregations

CostModel (com.ge.verdict.synthesis.CostModel)1 VerdictTestInstrumentor (com.ge.verdict.test.instrumentor.VerdictTestInstrumentor)1 BlameAssignment (edu.uiowa.clc.verdict.blm.BlameAssignment)1 Instrumentor (edu.uiowa.clc.verdict.crv.Instrumentor)1 VDM2Lustre (edu.uiowa.clc.verdict.lustre.VDM2Lustre)1 MeritAssignment (edu.uiowa.clc.verdict.merit.MeritAssignment)1 Timer (io.micrometer.core.instrument.Timer)1 File (java.io.File)1 FileNotFoundException (java.io.FileNotFoundException)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 ExecuteStreamHandler (org.apache.tools.ant.taskdefs.ExecuteStreamHandler)1 PumpStreamHandler (org.apache.tools.ant.taskdefs.PumpStreamHandler)1 Model (verdict.vdm.vdm_model.Model)1