/** * Copyright (c) 2012-2016 Marsha Chechik, Alessio Di Sandro, Michalis Famelis, * Rick Salay. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Alessio Di Sandro - Implementation. */ package edu.toronto.cs.se.modelepedia.istar_mavo.operator; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Properties; import org.eclipse.core.runtime.IStatus; import edu.toronto.cs.se.mmint.MMINTException; import edu.toronto.cs.se.mmint.mavo.constraint.MAVOMIDConstraintChecker; import edu.toronto.cs.se.mmint.mid.GenericElement; import edu.toronto.cs.se.mmint.mid.MID; import edu.toronto.cs.se.mmint.mid.Model; import edu.toronto.cs.se.mmint.mid.utils.MIDOperatorIOUtils; import edu.toronto.cs.se.modelepedia.z3.Z3IncrementalSolver; import edu.toronto.cs.se.modelepedia.z3.Z3Model; import edu.toronto.cs.se.modelepedia.z3.Z3Model.Z3Result; import edu.toronto.cs.se.modelepedia.z3.Z3Utils; import edu.toronto.cs.se.modelepedia.z3.reasoning.Z3ReasoningEngine; public class REJ15 extends FASE14 { // input-output properties private final static String PROPERTY_IN_MODELCONSTRAINT = "modelConstraint"; private final static String PROPERTY_IN_MODELCONSTRAINT_DEFAULT = null; private final static String PROPERTY_IN_GENERATETARGETSCONCRETIZATION = "generateTargetsConcretization"; private final static Boolean PROPERTY_IN_GENERATETARGETSCONCRETIZATION_DEFAULT = false; private final static String PROPERTY_OUT_TIMEALLSAT = "timeAllSAT"; private final static String PROPERTY_OUT_NUMSOLUTIONS = "numSolutions"; // input private boolean timeAnalysisEnabled; private boolean timeRNFEnabled; private String modelConstraint; private boolean generateTargetsConcretization; private boolean timeAllSATEnabled; // output private long timeAllSAT; private int numSolutions; @Override public void readInputProperties(Properties inputProperties) throws MMINTException { super.readInputProperties(inputProperties); timeAnalysisEnabled = MIDOperatorIOUtils.getBoolProperty(inputProperties, PROPERTY_OUT_TIMEANALYSIS+MIDOperatorIOUtils.PROPERTY_IN_OUTPUTENABLED_SUFFIX); timeRNFEnabled = MIDOperatorIOUtils.getBoolProperty(inputProperties, PROPERTY_OUT_TIMERNF+MIDOperatorIOUtils.PROPERTY_IN_OUTPUTENABLED_SUFFIX); modelConstraint = MIDOperatorIOUtils.getOptionalStringProperty(inputProperties, PROPERTY_IN_MODELCONSTRAINT, PROPERTY_IN_MODELCONSTRAINT_DEFAULT); generateTargetsConcretization = MIDOperatorIOUtils.getOptionalBoolProperty(inputProperties, PROPERTY_IN_GENERATETARGETSCONCRETIZATION, PROPERTY_IN_GENERATETARGETSCONCRETIZATION_DEFAULT); timeAllSATEnabled = MIDOperatorIOUtils.getBoolProperty(inputProperties, PROPERTY_OUT_TIMEALLSAT+MIDOperatorIOUtils.PROPERTY_IN_OUTPUTENABLED_SUFFIX); } @Override protected void init() { super.init(); // state if (modelConstraint != null) { smtEncoding += Z3Utils.assertion(modelConstraint); } // output timeAllSAT = -1; numSolutions = 0; } @Override protected void writeProperties(Properties properties) { super.writeProperties(properties); properties.setProperty(PROPERTY_OUT_TIMEALLSAT, String.valueOf(timeAllSAT)); properties.setProperty(PROPERTY_OUT_NUMSOLUTIONS, String.valueOf(numSolutions)); } @Override protected Z3Model doTargets(Z3IncrementalSolver z3IncSolver) { long extraTime = 0; if (!timeAnalysisEnabled) { long startTime = System.nanoTime(); z3IncSolver.firstCheckSatAndGetModel(smtEncoding); extraTime = System.nanoTime() - startTime; } Z3Model z3Model = super.doTargets(z3IncSolver); timeTargets += extraTime; return z3Model; } private void doAllSAT(Z3IncrementalSolver z3IncSolver, Z3Model z3Model) { long startTime = System.nanoTime(); Z3ReasoningEngine z3Reasoner; try { z3Reasoner = (Z3ReasoningEngine) MAVOMIDConstraintChecker.getMAVOReasoner("SMTLIB"); numSolutions = z3Reasoner.allSATWithSolver(z3IncSolver, z3ModelParser, z3Model, new HashSet<>(mavoModelObjs.values()), istar).size(); } catch (MMINTException e) { MMINTException.print(IStatus.WARNING, "Skipping allSAT", e); return; } timeAllSAT = System.nanoTime() - startTime; } // private String[] getConcretization(IStar istar, Z3Model z3Model) { // // String concretization = "", smtConcretizationConstraint = ""; // Map<String, List<String>> z3ModelElems = new HashMap<>(); // for (Entry<String, String> z3ModelElem : z3ModelParser.getZ3MAVOModelElements(z3Model).entrySet()) { // // S: x universe ids to same formula var // // V: 1 universe id to x formula vars // String universeId = z3ModelElem.getKey(); // String formulaVar = z3ModelElem.getValue(); // List<String> formulaVars = z3ModelElems.get(universeId); // if (formulaVars == null) { // formulaVars = new ArrayList<>(); // z3ModelElems.put(universeId, formulaVars); // } // formulaVars.add(formulaVar); // } // for (Entry<String, MAVOElement> mavoModelObjEntry : mavoModelObjs.entrySet()) { // MAVOElement mavoModelObj = mavoModelObjEntry.getValue(); // String formulaVar = mavoModelObjEntry.getKey(); // String sort = mavoModelObj.eClass().getName(); // String function = encodeMAVConstraintFunction(mavoModelObj); // int counterMS = 0; // List<String> mergedV = null; // for (List<String> z3ModelElemFormulaVars : z3ModelElems.values()) { // if (z3ModelElemFormulaVars.contains(formulaVar)) { // counterMS++; // mergedV = z3ModelElemFormulaVars; // } // } // boolean isNegation; // String smtConstraint = ""; // if (mavoModelObj.isMay()) { // isNegation = (counterMS == 0); // if (isNegation) { // concretization += formulaVar + " deleted (M)" + System.lineSeparator(); // } // smtConstraint = encodeMConstraint(sort, function, formulaVar, isNegation); // } // if (mavoModelObj.isSet() && counterMS > 0) { // isNegation = (counterMS > 1); // if (isNegation) { // concretization += formulaVar + " split into " + counterMS + " (S)" + System.lineSeparator(); // } // smtConstraint = encodeSConstraint(sort, function, formulaVar, isNegation); // } // if (mavoModelObj.isVar() && counterMS > 0) { // isNegation = (mergedV.size() > 1); // if (isNegation) { // concretization += formulaVar + " merged with " + mergedV + " (V)" + System.lineSeparator(); // } // else { // mergedV = MAVOUtils.getMergeableFormulaVars(istar, mavoModelObj); // if (mergedV.size() == 0) { // continue; // } // } // smtConstraint = encodeVConstraint(sort, function, formulaVar, mergedV, isNegation); // } // smtConcretizationConstraint += smtConstraint; // } // concretization += System.lineSeparator(); // Map<String, Intention> intentions = super.collectIntentions(istar); // getConcretizationAnalysisLabels(intentions, z3Model); // for (Map.Entry<String, Intention> entry : intentions.entrySet()) { // concretization += entry.getKey() + "(" + writeIntentionLabels(entry.getValue()) + ") "; // } // smtConcretizationConstraint = Z3Utils.assertion(Z3Utils.not(Z3Utils.and(smtConcretizationConstraint))); // // return new String[] {concretization, smtConcretizationConstraint}; // } // // private IStar copyIStarRootModelObj() { // // IStar istarCopy = EcoreUtil.copy(istar); // Map<String, Intention> intentions = super.collectIntentions(istarCopy); // for (Intention intention : intentions.values()) { // for (SMTLIBLabel label : SMTLIBLabel.values()) { // intention.eSet(label.getModelFeature(), false); // } // } // // return istarCopy; // } @Override public Map<String, Model> run( Map<String, Model> inputsByName, Map<String, GenericElement> genericsByName, Map<String, MID> outputMIDsByName) throws Exception { // input Model istarModel = inputsByName.get(IN_MODEL); this.init(); // run collectAnalysisModelObjects(istarModel); Z3IncrementalSolver z3IncSolver = new Z3IncrementalSolver(); if (timeAnalysisEnabled) { doAnalysis(z3IncSolver); } if (timeTargetsEnabled) { Z3Model z3Model = doTargets(z3IncSolver); if (targets == Z3Result.SAT) { if (timeRNFEnabled) { doRNF(z3IncSolver, z3Model); } if (timeAllSATEnabled) { doAllSAT(z3IncSolver, z3Model); } if (generateTargetsConcretization) { // while (true) { // String[] concretization = getConcretization(copyIStarRootModelObj(), z3Model); // //TODO MMINT[MAVO] Integrate with mu-mmint code to show concretization model // if (!MultiModelDiagramUtils.getBooleanInput("Concretization", concretization[0] + System.lineSeparator() + System.lineSeparator() + "Do you want another concretization?")) { // break; // } // //TODO MMINT[TOSEM] Integrate with tosem allsat to negate current concretization // z3Model = z3IncSolver.checkSatAndGetModel(concretization[1], Z3IncrementalBehavior.NORMAL); // if (z3Model.getZ3Bool() != Z3Bool.SAT) { // break; // } // } } } } // output Properties outputProperties = new Properties(); writeProperties(outputProperties); MIDOperatorIOUtils.writePropertiesFile( outputProperties, this, istarModel, null, MIDOperatorIOUtils.OUTPUT_PROPERTIES_SUFFIX ); if (timeRNF != -1) { writeRNF(istarModel); } return new HashMap<>(); } }