-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Report invariants enforced by vacuous requirements #675
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,8 +95,11 @@ | |
import de.uni_freiburg.informatik.ultimate.pea2boogie.results.ReqCheckFailResult; | ||
import de.uni_freiburg.informatik.ultimate.pea2boogie.results.ReqCheckRtInconsistentResult; | ||
import de.uni_freiburg.informatik.ultimate.pea2boogie.results.ReqCheckSuccessResult; | ||
import de.uni_freiburg.informatik.ultimate.pea2boogie.results.ReqCheckVacuousResult; | ||
import de.uni_freiburg.informatik.ultimate.pea2boogie.translator.Req2BoogieTranslator; | ||
import de.uni_freiburg.informatik.ultimate.pea2boogie.translator.ReqSymboltableBuilder; | ||
import de.uni_freiburg.informatik.ultimate.pea2boogie.translator.VacuityAnnotation; | ||
import de.uni_freiburg.informatik.ultimate.plugins.generator.rcfgbuilder.cfg.BoogieIcfgLocation; | ||
import de.uni_freiburg.informatik.ultimate.plugins.generator.rcfgbuilder.cfg.CodeBlock; | ||
import de.uni_freiburg.informatik.ultimate.plugins.generator.rcfgbuilder.cfg.CodeBlockFactory; | ||
import de.uni_freiburg.informatik.ultimate.plugins.generator.rcfgbuilder.cfg.ParallelComposition; | ||
|
@@ -187,6 +190,15 @@ public IResult convertTraceAbstractionResult(final IResult result) { | |
final String failurePath = formatTimeSequenceMap(delta2var2value); | ||
return new ReqCheckRtInconsistentResult<>(element, plugin, failurePath); | ||
} | ||
if (spec == Spec.VACUOUS) { | ||
// Return a ReqCheckVacuousResult, i.e., a ReqCheckFailResult with additional | ||
// VacuityAnnotation containing an invariant that might be enforced by the | ||
// vacuous requirement. | ||
VacuityAnnotation enforcedInv = VacuityAnnotation | ||
.getAnnotation(((BoogieIcfgLocation) element).getBoogieASTNode()); | ||
return new ReqCheckVacuousResult<>(element, plugin, | ||
enforcedInv.getInvariant().toString()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be slightly cheaper to already check here if the invariant is different from |
||
} | ||
return new ReqCheckFailResult<>(element, plugin); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,8 +29,10 @@ | |
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Map.Entry; | ||
import java.util.Set; | ||
import java.util.concurrent.TimeUnit; | ||
|
@@ -57,6 +59,7 @@ | |
import de.uni_freiburg.informatik.ultimate.core.model.services.ILogger; | ||
import de.uni_freiburg.informatik.ultimate.core.model.services.IUltimateServiceProvider; | ||
import de.uni_freiburg.informatik.ultimate.lib.modelcheckerutils.boogie.BoogieDeclarations; | ||
import de.uni_freiburg.informatik.ultimate.lib.pea.CDD; | ||
import de.uni_freiburg.informatik.ultimate.lib.pea.CounterTrace; | ||
import de.uni_freiburg.informatik.ultimate.lib.pea.PEAComplement; | ||
import de.uni_freiburg.informatik.ultimate.lib.pea.Phase; | ||
|
@@ -75,6 +78,7 @@ | |
import de.uni_freiburg.informatik.ultimate.pea2boogie.preferences.Pea2BoogiePreferences.PEATransformerMode; | ||
import de.uni_freiburg.informatik.ultimate.pea2boogie.results.ReqCheck; | ||
import de.uni_freiburg.informatik.ultimate.pea2boogie.translator.CheckedReqLocation; | ||
import de.uni_freiburg.informatik.ultimate.pea2boogie.translator.VacuityAnnotation; | ||
import de.uni_freiburg.informatik.ultimate.util.CoreUtil; | ||
import de.uni_freiburg.informatik.ultimate.util.datastructures.CrossProducts; | ||
import de.uni_freiburg.informatik.ultimate.util.datastructures.relation.Pair; | ||
|
@@ -108,6 +112,7 @@ public class ReqCheckAnnotator implements IReq2PeaAnnotator { | |
private final List<ReqPeas> mReqPeas; | ||
|
||
private final Durations mDurations; | ||
private CDD mEnforcedInv; | ||
|
||
public ReqCheckAnnotator(final IUltimateServiceProvider services, final ILogger logger, final List<ReqPeas> reqPeas, | ||
final IReqSymbolTable symbolTable, final Durations durations) { | ||
|
@@ -442,7 +447,10 @@ private List<Statement> genChecksNonVacuity(final BoogieLocation bl) { | |
final PatternType<?> pattern = reqpea.getPattern(); | ||
for (final Entry<CounterTrace, PhaseEventAutomata> pea : reqpea.getCounterTrace2Pea()) { | ||
final Statement assertStmt = genAssertNonVacuous(pattern, pea.getValue(), bl); | ||
|
||
if (assertStmt != null) { | ||
VacuityAnnotation vacAnnotation = new VacuityAnnotation(mEnforcedInv); | ||
vacAnnotation.annotate(assertStmt); | ||
stmtList.add(assertStmt); | ||
} | ||
} | ||
|
@@ -467,6 +475,7 @@ private List<Statement> genChecksNonVacuity(final BoogieLocation bl) { | |
private Statement genAssertNonVacuous(final PatternType<?> req, final PhaseEventAutomata aut, | ||
final BoogieLocation bl) { | ||
final List<Phase> phases = aut.getPhases(); | ||
mEnforcedInv = CDD.TRUE; | ||
|
||
// compute the maximal phase number occurring in the automaton. | ||
int maxBits = 0; | ||
|
@@ -487,20 +496,32 @@ private Statement genAssertNonVacuous(final PatternType<?> req, final PhaseEvent | |
|
||
// check that one of those phases is eventually reached. | ||
final List<Expression> checkReached = new ArrayList<>(); | ||
final Map<Phase, CDD> enforcedInv = new HashMap<>(); | ||
|
||
if (pnr > 0) { | ||
for (int i = 0; i < phases.size(); i++) { | ||
final PhaseBits bits = phases.get(i).getPhaseBits(); | ||
if (bits == null || (bits.getActive() & 1 << pnr - 1) == 0) { | ||
checkReached.add(genComparePhaseCounter(i, mSymbolTable.getPcName(aut), bl)); | ||
} | ||
// Store state invariants of PEA locations where max DC phase is not active. | ||
if (bits.getActive() < (1 << pnr - 1)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the mask |
||
enforcedInv.put(phases.get(i), phases.get(i).getStateInv()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As |
||
} | ||
} | ||
} | ||
// Store invariant enforced by the requirement in case of vacuity | ||
if (enforcedInv.size() == 1) { | ||
mEnforcedInv = (CDD) enforcedInv.values().toArray()[0]; | ||
} | ||
if (checkReached.isEmpty()) { | ||
return null; | ||
} | ||
|
||
final Expression disjunction = genDisjunction(checkReached, bl); | ||
final ReqCheck check = createReqCheck(Spec.VACUOUS, req, aut); | ||
final String label = "VACUOUS_" + aut.getName(); | ||
|
||
return createAssert(disjunction, check, label); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright (C) 2024 University of Freiburg | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please also add your name and email address if you create a new file. |
||
* | ||
* This file is part of the ULTIMATE PEAtoBoogie plug-in. | ||
* | ||
* The ULTIMATE PEAtoBoogie plug-in is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as published | ||
* by the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* The ULTIMATE PEAtoBoogie plug-in is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with the ULTIMATE PEAtoBoogie plug-in. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
* Additional permission under GNU GPL version 3 section 7: | ||
* If you modify the ULTIMATE PEAtoBoogie plug-in, or any covered work, by linking | ||
* or combining it with Eclipse RCP (or a modified version of Eclipse RCP), | ||
* containing parts covered by the terms of the Eclipse Public License, the | ||
* licensors of the ULTIMATE PEAtoBoogie plug-in grant you additional permission | ||
* to convey the resulting work. | ||
*/ | ||
package de.uni_freiburg.informatik.ultimate.pea2boogie.results; | ||
|
||
import de.uni_freiburg.informatik.ultimate.core.model.models.IElement; | ||
import de.uni_freiburg.informatik.ultimate.lib.modelcheckerutils.cfg.structure.IAction; | ||
import de.uni_freiburg.informatik.ultimate.lib.pea.CDD; | ||
import de.uni_freiburg.informatik.ultimate.util.CoreUtil; | ||
|
||
|
||
public final class ReqCheckVacuousResult<LOC extends IElement, TE extends IAction, E> | ||
extends ReqCheckFailResult<LOC> { | ||
|
||
private final String mEnforcedInvariant; | ||
|
||
public ReqCheckVacuousResult(final LOC element, final String plugin, final String enforcedInvariant) { | ||
super(element, plugin); | ||
mEnforcedInvariant = enforcedInvariant; | ||
} | ||
|
||
public ReqCheckVacuousResult(final LOC element, final String plugin) { | ||
this(element, plugin, null); | ||
} | ||
|
||
@Override | ||
public String getLongDescription() { | ||
final StringBuilder sb = new StringBuilder(); | ||
sb.append(getShortDescription()); | ||
if (mEnforcedInvariant != CDD.TRUE.toString()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check for null instead of CDD.TRUE.toString(), and move stringbuilder into the if, e.g.:
|
||
sb.append(CoreUtil.getPlatformLineSeparator()); | ||
sb.append("Vacous requirement silently enforces invariant: " + mEnforcedInvariant); | ||
} | ||
return sb.toString(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright (C) 2024 University of Freiburg | ||
* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add your name+email |
||
* This file is part of the ULTIMATE Core. | ||
* | ||
* The ULTIMATE Core is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as published | ||
* by the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* The ULTIMATE Core is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with the ULTIMATE Core. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
* Additional permission under GNU GPL version 3 section 7: | ||
* If you modify the ULTIMATE Core, or any covered work, by linking | ||
* or combining it with Eclipse RCP (or a modified version of Eclipse RCP), | ||
* containing parts covered by the terms of the Eclipse Public License, the | ||
* licensors of the ULTIMATE Core grant you additional permission | ||
* to convey the resulting work. | ||
*/ | ||
package de.uni_freiburg.informatik.ultimate.pea2boogie.translator; | ||
|
||
import de.uni_freiburg.informatik.ultimate.core.lib.models.annotation.ModernAnnotations; | ||
import de.uni_freiburg.informatik.ultimate.core.model.models.IElement; | ||
import de.uni_freiburg.informatik.ultimate.core.model.models.ModelUtils; | ||
import de.uni_freiburg.informatik.ultimate.core.model.models.annotation.IAnnotations; | ||
import de.uni_freiburg.informatik.ultimate.lib.pea.CDD; | ||
|
||
/** | ||
* | ||
* Annotation for vacuity checks. This marks whether a vacuous requirement | ||
* enforces a trivial invariant. | ||
* | ||
*/ | ||
|
||
public class VacuityAnnotation extends ModernAnnotations { | ||
|
||
private static final long serialVersionUID = 1L; | ||
private final CDD mEnforcedInvariant; | ||
|
||
public VacuityAnnotation(final CDD enforcedInv) { | ||
mEnforcedInvariant = enforcedInv; | ||
} | ||
|
||
public CDD getInvariant() { | ||
return mEnforcedInvariant; | ||
} | ||
|
||
public IAnnotations annotate(final IElement elem) { | ||
return elem.getPayload().getAnnotations().put(VacuityAnnotation.class.getName(), this); | ||
} | ||
|
||
public static VacuityAnnotation getAnnotation(final IElement node) { | ||
return ModelUtils.getAnnotation(node, VacuityAnnotation.class); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be
final
-- do you have your save actions configured correctly?