diff --git a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/AbstractFinishAuxiliaryComputationMacro.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/AbstractFinishAuxiliaryComputationMacro.java index 65061820a14..f2f03cf2d82 100644 --- a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/AbstractFinishAuxiliaryComputationMacro.java +++ b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/AbstractFinishAuxiliaryComputationMacro.java @@ -3,9 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.informationflow.macros; -import java.util.Map; -import java.util.Set; - import de.uka.ilkd.key.informationflow.ProofObligationVars; import de.uka.ilkd.key.informationflow.po.IFProofObligationVars; import de.uka.ilkd.key.java.Services; @@ -17,16 +14,15 @@ import de.uka.ilkd.key.macros.AbstractProofMacro; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.rule.NoPosTacletApp; -import de.uka.ilkd.key.rule.Taclet; import de.uka.ilkd.key.rule.inst.SVInstantiations; import de.uka.ilkd.key.util.InfFlowProgVarRenamer; - import org.key_project.logic.Named; import org.key_project.logic.Namespace; import org.key_project.prover.sequent.SequentFormula; import org.key_project.util.collection.ImmutableList; +import java.util.Map; + /** * @@ -51,9 +47,9 @@ public String getDescription() { static JTerm calculateResultingTerm(Proof proof, IFProofObligationVars ifVars, Goal initGoal) { final JTerm[] goalFormulas1 = - buildExecution(ifVars.c1, ifVars.getMapFor(ifVars.c1), proof.openGoals(), initGoal); + buildExecution(ifVars.c1, ifVars.getMapFor(ifVars.c1), proof.openGoals(), initGoal); final JTerm[] goalFormulas2 = - buildExecution(ifVars.c2, ifVars.getMapFor(ifVars.c2), proof.openGoals(), initGoal); + buildExecution(ifVars.c2, ifVars.getMapFor(ifVars.c2), proof.openGoals(), initGoal); final TermBuilder tb = proof.getServices().getTermBuilder(); JTerm composedStates = tb.ff(); for (int i = 0; i < goalFormulas1.length; i++) { @@ -69,7 +65,7 @@ static JTerm calculateResultingTerm(Proof proof, IFProofObligationVars ifVars, G * Merge namespaces. * * @param initiatingProof the initiating proof - * @param sideProof the side proof + * @param sideProof the side proof */ protected final void mergeNamespaces(Proof initiatingProof, Proof sideProof) { NamespaceSet initiatingProofNS = initiatingProof.getServices().getNamespaces(); @@ -95,11 +91,11 @@ private final void mergeNamespace(Namespace tar, Namespace< } private static JTerm[] buildExecution(ProofObligationVars c, Map vsMap, - ImmutableList symbExecGoals, Goal initGoal) { + ImmutableList symbExecGoals, Goal initGoal) { Services services = initGoal.proof().getServices(); final JTerm[] goalFormulas = buildFormulasFromGoals(symbExecGoals); final InfFlowProgVarRenamer renamer = new InfFlowProgVarRenamer(goalFormulas, vsMap, - c.postfix, initGoal, services.getOverlay(initGoal.getLocalNamespaces())); + c.postfix, initGoal, services.getOverlay(initGoal.getLocalNamespaces())); final JTerm[] renamedGoalFormulas = renamer.renameVariablesAndSkolemConstants(); JTerm[] result = new JTerm[renamedGoalFormulas.length]; final TermBuilder tb = services.getTermBuilder(); @@ -137,13 +133,11 @@ private static JTerm buildFormulaFromGoal(Goal symbExecGoal) { protected static void addContractApplicationTaclets(Goal initiatingGoal, Proof symbExecProof) { final ImmutableList openGoals = symbExecProof.openGoals(); for (final Goal openGoal : openGoals) { - final Set ruleApps = openGoal.indexOfTaclets().allNoPosTacletApps(); - for (final NoPosTacletApp ruleApp : ruleApps) { - final Taclet t = ruleApp.taclet(); - if (t.getSurviveSymbExec()) { - initiatingGoal.addTaclet(t, SVInstantiations.EMPTY_SVINSTANTIATIONS, true); - } - } + openGoal.indexOfTaclets() + .allNoPosTacletAppsStream() + .filter(it -> it.taclet().getSurviveSymbExec()) + .forEach(it -> + initiatingGoal.addTaclet(it.taclet(), SVInstantiations.EMPTY_SVINSTANTIATIONS, true)); } } } diff --git a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/profile/SymbolicExecutionJavaProfile.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/profile/SymbolicExecutionJavaProfile.java index 52faa9af592..e56d8566542 100644 --- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/profile/SymbolicExecutionJavaProfile.java +++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/profile/SymbolicExecutionJavaProfile.java @@ -325,4 +325,9 @@ public static boolean isTruthValueEvaluationEnabled(Profile profile) { return false; } } + + @Override + public String displayName() { + return NAME; + } } diff --git a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java index e5f650a2b08..a9182cc8ce1 100644 --- a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java +++ b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdProfile.java @@ -5,6 +5,7 @@ import java.net.URL; import java.util.Objects; +import java.util.stream.Collectors; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.proof.Proof; @@ -15,11 +16,15 @@ import de.uka.ilkd.key.proof.io.RuleSourceFactory; import de.uka.ilkd.key.proof.mgt.SpecificationRepository; import de.uka.ilkd.key.rule.*; +import de.uka.ilkd.key.settings.Configuration; import de.uka.ilkd.key.util.KeYResourceManager; +import org.key_project.logic.Choice; import org.key_project.logic.Name; import org.key_project.util.collection.ImmutableList; +import org.jspecify.annotations.Nullable; + /** * @author Alexander Weigl * @version 1 (7/27/25) @@ -97,9 +102,34 @@ public RuleCollection getStandardRules() { return wdStandardRules; } + /// {@inheritDoc} + /// + /// @param additionalProfileOptions a string representing the choice of `wdOperator` @Override - public void prepareInitConfig(InitConfig baseConfig) { + public void prepareInitConfig(InitConfig baseConfig, + @Nullable Configuration additionalProfileOptions) { var wdChoice = baseConfig.choiceNS().lookup(new Name("wdChecks:on")); baseConfig.activateChoice(wdChoice); + + if (additionalProfileOptions != null) { + final var selectedWdOperator = additionalProfileOptions.getString("wdOperator"); + if (selectedWdOperator == null) { + return; + } + + var wdOperator = baseConfig.choiceNS().lookup(selectedWdOperator); + if (wdOperator == null) { + var choices = baseConfig.choiceNS().allElements() + .stream() + .filter(it -> it.category().equals("wdOperator")) + .map(Choice::toString) + .collect(Collectors.joining(", ")); + + throw new IllegalStateException("Could not find choice for %s. \n Choices known %s." + .formatted(additionalProfileOptions, choices)); + } else { + baseConfig.activateChoice(wdOperator); + } + } } } diff --git a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdWhileInvariantRule.java b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdWhileInvariantRule.java index 49ba53d71a6..9c3de410120 100644 --- a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdWhileInvariantRule.java +++ b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/WdWhileInvariantRule.java @@ -38,10 +38,6 @@ public Name name() { return NAME; } - @Override - public @Nullable String getOrigin() { - return super.getOrigin(); - } protected static class WdWhileInvariantRuleApplier extends WhileInvariantRuleApplier { public WdWhileInvariantRuleApplier(Goal goal, LoopInvariantBuiltInRuleApp ruleApp) { diff --git a/key.core/src/main/antlr4/KeYParser.g4 b/key.core/src/main/antlr4/KeYParser.g4 index 5832a7238f7..cf96837f214 100644 --- a/key.core/src/main/antlr4/KeYParser.g4 +++ b/key.core/src/main/antlr4/KeYParser.g4 @@ -90,17 +90,18 @@ one_sort_decl : doc=DOC_COMMENT? ( - GENERIC sortIds=simple_ident_dots_comma_list + GENERIC sortIds=simple_ident_dots_comma_list_with_docs (ONEOF sortOneOf = oneof_sorts)? (EXTENDS sortExt = extends_sorts)? SEMI - | PROXY sortIds=simple_ident_dots_comma_list (EXTENDS sortExt=extends_sorts)? SEMI - | ABSTRACT? (sortIds=simple_ident_dots_comma_list | parametric_sort_decl) (EXTENDS sortExt=extends_sorts)? SEMI + | PROXY sortIds=simple_ident_dots_comma_list_with_docs (EXTENDS sortExt=extends_sorts)? SEMI + | ABSTRACT? (sortIds=simple_ident_dots_comma_list_with_docs | parametric_sort_decl) (EXTENDS sortExt=extends_sorts)? SEMI | ALIAS simple_ident_dots EQUALS sortId SEMI ) ; parametric_sort_decl : + DOC_COMMENT? simple_ident_dots formal_sort_param_decls ; @@ -115,6 +116,13 @@ simple_ident_dots_comma_list simple_ident_dots (COMMA simple_ident_dots)* ; +simple_ident_dots_comma_list_with_docs +: + simple_ident_dots_with_docs (COMMA simple_ident_dots_with_docs)* +; + +simple_ident_dots_with_docs: DOC_COMMENT? simple_ident_dots; + extends_sorts : @@ -139,7 +147,7 @@ prog_var_decls LBRACE ( kjt = keyjavatype - var_names = simple_ident_comma_list + var_names = simple_ident_comma_list_with_docs SEMI )* RBRACE @@ -161,6 +169,10 @@ simple_ident_comma_list id = simple_ident (COMMA id = simple_ident )* ; +simple_ident_comma_list_with_docs +: + id+=simple_ident_with_doc (COMMA id+=simple_ident_with_doc)* +; schema_var_decls : SCHEMAVARIABLES LBRACE @@ -259,6 +271,7 @@ datatype_decl: ; datatype_constructor: + doc=DOC_COMMENT? name=simple_ident ( LPAREN @@ -341,7 +354,12 @@ where_to_bind: ruleset_decls : - HEURISTICSDECL LBRACE (doc+=DOC_COMMENT? id+=simple_ident SEMI)* RBRACE + HEURISTICSDECL LBRACE (id+=simple_ident_with_doc SEMI)* RBRACE +; + +simple_ident_with_doc +: + doc=DOC_COMMENT? id=simple_ident ; sortId diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/loader/JP2KeYConverter.java b/key.core/src/main/java/de/uka/ilkd/key/java/loader/JP2KeYConverter.java index 0820a14a8d2..b54008bb75d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/loader/JP2KeYConverter.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/loader/JP2KeYConverter.java @@ -1736,13 +1736,13 @@ public Object handleSpecialFunctionInvocation(Node n, String name, "Requested to find the default value of an unknown sort '%s'.", sortName)); } - var doc = sort.getDocumentation(); - + String doc = services.getNamespaces().docs().findDocumentation(sort); + String origin = services.getNamespaces().docs().findOrigin(sort); if (doc == null) { return reportError(n, format("Requested to find the default value for the sort '%s', " + "which does not have a documentary comment. The sort is defined at %s. ", - sortName, sort.getOrigin())); + sortName, origin)); } int pos = doc.indexOf(DEFVALUE); @@ -1754,7 +1754,7 @@ public Object handleSpecialFunctionInvocation(Node n, String name, return reportError(n, format( "Forgotten closing parenthesis on @defaultValue annotation for sort '%s' in '%s'", - sortName, sort.getOrigin())); + sortName, origin)); } // set this as the function name, as the user had written \dl_XXX diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/JTerm.java b/key.core/src/main/java/de/uka/ilkd/key/logic/JTerm.java index dc84ea2b302..3513d8c1584 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/JTerm.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/JTerm.java @@ -16,7 +16,6 @@ import org.key_project.util.collection.ImmutableSet; import org.jspecify.annotations.NonNull; -import org.jspecify.annotations.Nullable; /** * In contrast to the distinction of formulas and terms as made by most of the inductive definitions @@ -118,9 +117,4 @@ public interface JTerm * non-empty {@link JavaBlock}, {@code false} no {@link JavaBlock} available. */ boolean containsJavaBlockRecursive(); - - /** - * Returns a human-readable source of this term. For example the filename with line and offset. - */ - default @Nullable String getOrigin() { return null; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java index cebf29cce99..4f1dba590ea 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java @@ -52,7 +52,7 @@ public class LabeledTermImpl extends TermImpl { public LabeledTermImpl(Operator op, ImmutableArray subs, ImmutableArray boundVars, ImmutableArray labels, String origin) { - super(op, subs, boundVars, origin); + super(op, subs, boundVars); assert labels != null : "Term labels must not be null"; assert !labels.isEmpty() : "There must be at least one term label"; this.labels = labels; @@ -69,7 +69,7 @@ public LabeledTermImpl(Operator op, ImmutableArray subs, public LabeledTermImpl(Operator op, ImmutableArray subs, ImmutableArray boundVars, ImmutableArray labels) { - super(op, subs, boundVars, ""); + super(op, subs, boundVars); assert labels != null : "Term labels must not be null"; assert !labels.isEmpty() : "There must be at least one term label"; this.labels = labels; diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/MetaSpace.java b/key.core/src/main/java/de/uka/ilkd/key/logic/MetaSpace.java new file mode 100644 index 00000000000..7f334d7ca86 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/MetaSpace.java @@ -0,0 +1,89 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.logic; + +import java.util.Map; +import java.util.TreeMap; + +import org.key_project.logic.HasMeta; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/// MetaSpace is a namespace for storing additional information +/// +/// @author weigl +@NullMarked +public class MetaSpace { + public static final String SPACE_PREFIX_DOC = "doc/"; + public static final String SPACE_PREFIX_ORIGIN = "origin/"; + + private @Nullable MetaSpace parent; + private final Map metadata = new TreeMap<>(); + + public MetaSpace() { + } + + public MetaSpace(Map documentation) { + this.metadata.putAll(documentation); + } + + public MetaSpace(MetaSpace parent) { + this.parent = parent; + } + + private @Nullable Object findMetadata(String key) { + return metadata.get(key); + } + + public @Nullable String findDocumentation(HasMeta entity) { + if (entity.getDocumentation() != null) { + return entity.getDocumentation(); + } + return (String) findMetadata(SPACE_PREFIX_DOC + entity.getMetaKey()); + } + + /** + * Returns a human-readable source of this term. For example the filename with line and offset. + */ + public @Nullable String findOrigin(HasMeta entity) { + return (String) findMetadata(SPACE_PREFIX_ORIGIN + entity.getMetaKey()); + } + + public void add(MetaSpace space) { + this.metadata.putAll(space.metadata); + } + + public @Nullable MetaSpace parent() { + return parent; + } + + public void setDocumentation(HasMeta entity, @Nullable String doc) { + if (doc != null && doc.isBlank()) { + return; + } + setMetadata(SPACE_PREFIX_DOC, entity, doc); + } + + public void setOrigin(HasMeta entity, @Nullable String origin) { + if (origin != null && origin.isBlank()) { + return; + } + setMetadata(SPACE_PREFIX_ORIGIN, entity, origin); + } + + private void setMetadata(String prefix, HasMeta entity, @Nullable Object val) { + var key = prefix + entity.getMetaKey(); + if (val == null) { + metadata.remove(key); + } else { + metadata.put(key, val); + } + } + + + public MetaSpace copy() { + return new MetaSpace(metadata); + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/NamespaceSet.java b/key.core/src/main/java/de/uka/ilkd/key/logic/NamespaceSet.java index 2da81a7abb9..f23613c8845 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/NamespaceSet.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/NamespaceSet.java @@ -4,6 +4,7 @@ package de.uka.ilkd.key.logic; + import de.uka.ilkd.key.logic.op.IProgramVariable; import de.uka.ilkd.key.logic.op.ParametricFunctionDecl; import de.uka.ilkd.key.logic.sort.ParametricSortDecl; @@ -18,33 +19,52 @@ import org.key_project.logic.sort.Sort; import org.key_project.prover.rules.RuleSet; -import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; + +@NullMarked public class NamespaceSet { - private Namespace<@NonNull QuantifiableVariable> varNS = new Namespace<>(); - private Namespace<@NonNull IProgramVariable> progVarNS = new Namespace<>(); + private Namespace varNS = new Namespace<>(); + private Namespace progVarNS = new Namespace<>(); // TODO: Operators should not be local to goals - private Namespace<@NonNull Function> funcNS = new Namespace<>(); - private Namespace<@NonNull RuleSet> ruleSetNS = new Namespace<>(); - private Namespace<@NonNull Sort> sortNS = new Namespace<>(); - private Namespace<@NonNull SortAlias> sortAliases = new Namespace<>(); - private Namespace<@NonNull ParametricSortDecl> parametricSortNS = new Namespace<>(); - private Namespace<@NonNull ParametricFunctionDecl> parametricFuncNS = new Namespace<>(); - private Namespace<@NonNull Choice> choiceNS = new Namespace<>(); + private Namespace funcNS = new Namespace<>(); + private Namespace ruleSetNS = new Namespace<>(); + private Namespace sortNS = new Namespace<>(); + private Namespace sortAliases = new Namespace<>(); + private Namespace parametricSortNS = new Namespace<>(); + private Namespace parametricFuncNS = new Namespace<>(); + private Namespace choiceNS = new Namespace<>(); + private MetaSpace documentation = new MetaSpace(); public NamespaceSet() { } - public NamespaceSet(Namespace<@NonNull QuantifiableVariable> varNS, - Namespace<@NonNull Function> funcNS, - Namespace<@NonNull Sort> sortNS, Namespace<@NonNull SortAlias> sortAliases, - Namespace<@NonNull RuleSet> ruleSetNS, - Namespace<@NonNull ParametricSortDecl> parametricSortNS, - Namespace<@NonNull ParametricFunctionDecl> parametricFuncNS, - Namespace<@NonNull Choice> choiceNS, - Namespace<@NonNull IProgramVariable> programVarNS) { + public NamespaceSet(Namespace varNS, + Namespace funcNS, + Namespace sortNS, + Namespace sortAliases, + Namespace ruleSetNS, + Namespace parametricSortNS, + Namespace parametricFuncNS, + Namespace choiceNS, + Namespace programVarNS) { + this(varNS, funcNS, sortNS, sortAliases, ruleSetNS, + parametricSortNS, parametricFuncNS, + choiceNS, programVarNS, new MetaSpace()); + } + + public NamespaceSet(Namespace varNS, + Namespace funcNS, + Namespace sortNS, + Namespace sortAliases, + Namespace ruleSetNS, + Namespace parametricSortNS, + Namespace parametricFuncNS, + Namespace choiceNS, + Namespace programVarNS, + MetaSpace documentation) { this.varNS = varNS; this.progVarNS = programVarNS; this.funcNS = funcNS; @@ -54,21 +74,23 @@ public NamespaceSet(Namespace<@NonNull QuantifiableVariable> varNS, this.choiceNS = choiceNS; this.parametricSortNS = parametricSortNS; this.parametricFuncNS = parametricFuncNS; + this.documentation = documentation; } + public NamespaceSet copy() { return new NamespaceSet(variables().copy(), functions().copy(), sorts().copy(), sortAliases().copy(), ruleSets().copy(), parametricSortNS.copy(), parametricFuncNS.copy(), choices().copy(), - programVariables().copy()); + programVariables().copy(), + documentation.copy()); } public NamespaceSet shallowCopy() { return new NamespaceSet(variables(), functions(), sorts(), sortAliases(), ruleSets(), parametricSorts(), parametricFunctions(), - choices(), - programVariables()); + choices(), programVariables(), new MetaSpace(documentation)); } // TODO MU: Rename into sth with wrap or similar @@ -77,79 +99,80 @@ public NamespaceSet copyWithParent() { new Namespace<>(functions()), new Namespace<>(sorts()), new Namespace<>(sortAliases()), new Namespace<>(ruleSets()), new Namespace<>(parametricSorts()), new Namespace<>(parametricFunctions()), new Namespace<>(choices()), - new Namespace<>(programVariables())); + new Namespace<>(programVariables()), + new MetaSpace(documentation)); } - public Namespace<@NonNull QuantifiableVariable> variables() { + public Namespace variables() { return varNS; } - public void setVariables(Namespace<@NonNull QuantifiableVariable> varNS) { + public void setVariables(Namespace varNS) { this.varNS = varNS; } - public Namespace<@NonNull IProgramVariable> programVariables() { + public Namespace programVariables() { return progVarNS; } - public void setProgramVariables(Namespace<@NonNull IProgramVariable> progVarNS) { + public void setProgramVariables(Namespace progVarNS) { this.progVarNS = progVarNS; } - public Namespace<@NonNull Function> functions() { + public Namespace functions() { return funcNS; } - public void setFunctions(Namespace<@NonNull Function> funcNS) { + public void setFunctions(Namespace funcNS) { this.funcNS = funcNS; } - public Namespace<@NonNull RuleSet> ruleSets() { + public Namespace ruleSets() { return ruleSetNS; } - public void setRuleSets(Namespace<@NonNull RuleSet> ruleSetNS) { + public void setRuleSets(Namespace ruleSetNS) { this.ruleSetNS = ruleSetNS; } - public Namespace<@NonNull Sort> sorts() { + public Namespace sorts() { return sortNS; } - public void setSorts(Namespace<@NonNull Sort> sortNS) { + public void setSorts(Namespace sortNS) { this.sortNS = sortNS; } - public Namespace<@NonNull SortAlias> sortAliases() { + public Namespace sortAliases() { return sortAliases; } - public void setSortAliases(Namespace<@NonNull SortAlias> sortAliases) { + public void setSortAliases(Namespace sortAliases) { this.sortAliases = sortAliases; } - public Namespace<@NonNull ParametricSortDecl> parametricSorts() { + public Namespace parametricSorts() { return parametricSortNS; } - public void setParametricSorts(Namespace<@NonNull ParametricSortDecl> parametricSortNS) { + public void setParametricSorts(Namespace parametricSortNS) { this.parametricSortNS = parametricSortNS; } - public Namespace<@NonNull ParametricFunctionDecl> parametricFunctions() { + public Namespace parametricFunctions() { return parametricFuncNS; } public void setParametricFunctions( - Namespace<@NonNull ParametricFunctionDecl> parametricFuncNS) { + Namespace parametricFuncNS) { this.parametricFuncNS = parametricFuncNS; } - public Namespace<@NonNull Choice> choices() { + public Namespace choices() { return choiceNS; } - public void setChoices(Namespace<@NonNull Choice> choiceNS) { + public void setChoices(Namespace choiceNS) { this.choiceNS = choiceNS; } @@ -286,7 +309,7 @@ public NamespaceSet getCompression() { return new NamespaceSet(varNS.compress(), funcNS.compress(), sortNS.compress(), sortAliases.compress(), ruleSetNS.compress(), parametricSortNS.compress(), parametricFuncNS.compress(), - choiceNS.compress(), progVarNS.compress()); + choiceNS.compress(), progVarNS.compress(), documentation); } public void flushToParent() { @@ -299,7 +322,10 @@ public NamespaceSet getParent() { return new NamespaceSet(varNS.parent(), funcNS.parent(), sortNS.parent(), sortAliases.parent(), ruleSetNS.parent(), parametricSortNS.parent(), parametricFuncNS.parent(), - choiceNS.parent(), progVarNS.parent()); + choiceNS.parent(), progVarNS.parent(), documentation.parent()); } + public MetaSpace docs() { + return documentation; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/TermFactory.java b/key.core/src/main/java/de/uka/ilkd/key/logic/TermFactory.java index ad9935f7a92..bdd83aacbe3 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/TermFactory.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/TermFactory.java @@ -121,7 +121,7 @@ private JTerm doCreateTerm(Operator op, ImmutableArray subs, final TermImpl newTerm = (labels == null || labels.isEmpty() - ? new TermImpl(op, subs, boundVars, origin) + ? new TermImpl(op, subs, boundVars) : new LabeledTermImpl(op, subs, boundVars, labels, origin)); // Check if caching is possible. It is not possible if a non-empty JavaBlock is available // in the term or in one of its children because the meta information like PositionInfos diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java index 42063167176..c35c8c9ab9c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java @@ -21,7 +21,6 @@ import org.key_project.util.collection.ImmutableSet; import org.jspecify.annotations.NonNull; -import org.jspecify.annotations.Nullable; /** @@ -81,10 +80,6 @@ private enum ThreeValuedTruth { */ private ThreeValuedTruth containsJavaBlockRecursive = ThreeValuedTruth.UNKNOWN; - // ------------------------------------------------------------------------- - // constructors - // ------------------------------------------------------------------------- - /** * Constructs a term for the given operator, with the given sub terms, bounded variables and (if * applicable) the code block on this term. @@ -95,37 +90,14 @@ private enum ThreeValuedTruth { * @param boundVars the bounded variables (if applicable), e.g., for quantifiers */ public TermImpl(Operator op, ImmutableArray subs, - ImmutableArray boundVars, - String origin) { + ImmutableArray boundVars) { assert op != null; assert subs != null; this.op = op; this.subs = subs.isEmpty() ? EMPTY_TERM_LIST : subs; this.boundVars = boundVars == null ? EMPTY_VAR_LIST : boundVars; - this.origin = origin; } - TermImpl(Operator op, ImmutableArray subs, - ImmutableArray boundVars) { - this(op, subs, boundVars, ""); - } - - /** - * For which feature is this information needed? - * What is the difference from {@link de.uka.ilkd.key.logic.label.OriginTermLabel}? - */ - private final String origin; - - @Override - public @Nullable String getOrigin() { - return origin; - } - - // ------------------------------------------------------------------------- - // internal methods - // ------------------------------------------------------------------------- - - private ImmutableSet determineFreeVars() { ImmutableSet localFreeVars = DefaultImmutableSet.nil(); diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/OriginTermLabel.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/OriginTermLabel.java index 05bea742469..fce39fbae7e 100755 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/OriginTermLabel.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/OriginTermLabel.java @@ -59,12 +59,12 @@ public class OriginTermLabel implements TermLabel { /** * Display name for {@link OriginTermLabel}s. */ - public final static Name NAME = new Name("origin"); + public static final Name NAME = new Name("origin"); /** * @see #getTLChildCount() */ - public final static int CHILD_COUNT = 2; + public static final int CHILD_COUNT = 2; public static final Sort[] EMPTY_SORTS = new Sort[0]; @@ -559,9 +559,13 @@ private static SubTermOriginData getSubTermOriginData(final ImmutableArray origins; /** @@ -775,6 +779,18 @@ public boolean equals(Object obj) { } } + @Override + public @Nullable String getDocumentation() { + return """ + This label saves a term's origin in the JML specification as well as the origins of all of its subterms and former subterms. + + For example, if the file "Example.java" contains the clause "requires R" at line 20, then every JavaDL term that is generated from R will have the origin + "requires @ Example.java @ line 20". + + Origin labels are not printed in the sequent view. To see a term's origin, you can mouse over it while holding the ALT button. If you want more detailed information, left click on the term and then on "Show Origin". + """; + } + /** * A {@code SpecType} is any type of JML specification which gets translated into JavaDL. * diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/ParameterlessTermLabel.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/ParameterlessTermLabel.java index 596410ce3e8..e57b7a35622 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/ParameterlessTermLabel.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/ParameterlessTermLabel.java @@ -7,6 +7,8 @@ import org.key_project.logic.Name; +import org.jspecify.annotations.Nullable; + /** * The Class {@link ParameterlessTermLabel} can be used to define labels without parameters. * @@ -56,12 +58,22 @@ public final class ParameterlessTermLabel implements TermLabel { */ public static final Name SHORTCUT_EVALUATION_LABEL_NAME = new Name("SC"); + public static final String SHORTCUT_EVALUATION_LABEL_DOC = + """ + The term label SC is used to indicate that a logical operator has originally been "shortcut" operator. + + For instance, both conjunction operators in JML (i.e., && and &) are translated to the same function in JavaDL. To differentiate between the two, the translation of && adds the label SC. + + This is relevant for welldefinedness checks. + """; + /** * Label attached to a term with the logical operator '{@literal ||}' or '{@literal &&}' to * distinguish from '{@literal |}' or '{@literal &}' respectively. */ public static final TermLabel SHORTCUT_EVALUATION_LABEL = - new ParameterlessTermLabel(SHORTCUT_EVALUATION_LABEL_NAME); + new ParameterlessTermLabel(SHORTCUT_EVALUATION_LABEL_NAME, + SHORTCUT_EVALUATION_LABEL_DOC); /** * Name of {@link #UNDEFINED_VALUE_LABEL}. @@ -115,6 +127,8 @@ public final class ParameterlessTermLabel implements TermLabel { */ private final Name name; + private final @Nullable String documentation; + /** * Instantiates a new simple term label. * @@ -122,8 +136,13 @@ public final class ParameterlessTermLabel implements TermLabel { * null. */ public ParameterlessTermLabel(Name name) { + this(name, null); + } + + public ParameterlessTermLabel(Name name, @Nullable String doc) { assert name != null; this.name = name; + this.documentation = doc; } @Override @@ -181,4 +200,9 @@ public boolean equals(Object obj) { public int hashCode() { return name.hashCode(); } + + @Override + public @Nullable String getDocumentation() { + return documentation; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/SingletonLabelFactory.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/SingletonLabelFactory.java index 025d5cf4208..b9b6b32542e 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/SingletonLabelFactory.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/SingletonLabelFactory.java @@ -7,6 +7,8 @@ import de.uka.ilkd.key.logic.TermServices; +import org.jspecify.annotations.Nullable; + /** * A factory for creating singleton {@link TermLabel}. * @@ -33,6 +35,11 @@ public SingletonLabelFactory(T singletonLabel) { this.singletonLabel = singletonLabel; } + @Override + public @Nullable String getDocumentation() { + return singletonLabel.getDocumentation(); + } + /** * {@inheritDoc} * diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabel.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabel.java index 389a84ab4f0..4e3d3a9feda 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabel.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabel.java @@ -16,6 +16,7 @@ import de.uka.ilkd.key.rule.label.TermLabelRefactoring.RefactoringScope; import de.uka.ilkd.key.rule.label.TermLabelUpdate; +import org.key_project.logic.HasMeta; import org.key_project.logic.Name; import org.key_project.logic.Named; import org.key_project.logic.TerminalSyntaxElement; @@ -151,7 +152,8 @@ * @see TermLabelManager */ // spotless:on -public interface TermLabel extends Named, /* TODO: Remove */ TerminalSyntaxElement { +public interface TermLabel + extends Named, HasMeta, /* TODO: Remove */ TerminalSyntaxElement { /** * Retrieves the i-th parameter object of this term label. @@ -183,4 +185,9 @@ public interface TermLabel extends Named, /* TODO: Remove */ TerminalSyntaxEleme default boolean isProofRelevant() { return true; } + + @Override + default String getMetaKey() { + return "termlabel/" + name(); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelFactory.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelFactory.java index a8fd1cecafe..2375c964987 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelFactory.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelFactory.java @@ -7,6 +7,8 @@ import de.uka.ilkd.key.logic.TermServices; +import org.jspecify.annotations.Nullable; + /** * A factory for creating TermLabel objects. * @@ -45,4 +47,8 @@ public interface TermLabelFactory { * @throws TermLabelException if the parameters were illegally formatted */ T parseInstance(List arguments, TermServices services) throws TermLabelException; + + default @Nullable String getDocumentation() { + return null; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java index f08bb194f98..a9438317abb 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java @@ -71,8 +71,7 @@ public class TermLabelManager { /** * {@link Map}s the {@link Name} of a {@link TermLabel} to its {@link TermLabelFactory}. */ - private final Map> factoryMap = - new LinkedHashMap<>(); + private final Map> factoryMap = new LinkedHashMap<>(); /** * {@link Map}s the {@link Name} of a {@link TermLabel} to its {@link TermLabelPolicy} applied @@ -1493,6 +1492,10 @@ protected RefactoringsContainer computeRefactorings(TermLabelState state, Servic return refactorings; } + public Map> getFactories() { + return Collections.unmodifiableMap(factoryMap); + } + /** * Utility class used by * {@link TermLabelManager#computeRefactorings(TermLabelState, Services, PosInOccurrence, JTerm, Rule, Goal, Object, JTerm)} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/op/ParametricFunctionDecl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/op/ParametricFunctionDecl.java index 78b7a6a1c49..e6d4a0f19c8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/op/ParametricFunctionDecl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/op/ParametricFunctionDecl.java @@ -5,6 +5,7 @@ import de.uka.ilkd.key.logic.GenericParameter; +import org.key_project.logic.HasMeta; import org.key_project.logic.Name; import org.key_project.logic.Named; import org.key_project.logic.Sorted; @@ -18,8 +19,8 @@ /// The abstract declaration of a parametric function, e.g., `append<[E]>(List<[E]>, List<[E]>)`. /// /// To get an instantiated instance, use [ParametricFunctionInstance#get(ParametricFunctionDecl, -/// ImmutableList, Services)]. -public final class ParametricFunctionDecl implements Named, Sorted { +/// ImmutableList, de.uka.ilkd.key.java.Services)]. +public final class ParametricFunctionDecl implements Named, Sorted, HasMeta { private final Name name; private final ImmutableList parameters; private final ImmutableArray argSorts; @@ -76,4 +77,9 @@ public ImmutableList getParameters() { public @NonNull Name name() { return name; } + + @Override + public String getMetaKey() { + return "pfun/" + name(); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/op/TermLabelSV.java b/key.core/src/main/java/de/uka/ilkd/key/logic/op/TermLabelSV.java index ca2f315c10d..3856d6acda8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/op/TermLabelSV.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/op/TermLabelSV.java @@ -31,4 +31,9 @@ public int getTLChildCount() { public Object getTLChild(int i) { throw new IndexOutOfBoundsException(); } + + @Override + public String getMetaKey() { + return super.getMetaKey(); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ArraySort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ArraySort.java index cbddb2bc76d..803535ed5ca 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ArraySort.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ArraySort.java @@ -42,7 +42,7 @@ public final class ArraySort extends SortImpl { private ArraySort(ImmutableSet extendsSorts, SortKey sk) { super(new Name((sk.elemType != null ? sk.elemType.getName() : sk.elemSort.name()) + "[]"), - extendsSorts, false, "", ""); + extendsSorts, false); if (extendsSorts.isEmpty()) { throw new IllegalArgumentException("An ArraySort extends typically three sorts" diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/GenericSort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/GenericSort.java index 61afd860737..5d44293d457 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/GenericSort.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/GenericSort.java @@ -46,22 +46,15 @@ public final class GenericSort extends SortImpl { * @param ext supersorts of this sort, which have to be either concrete sorts or plain generic * sorts (i.e. not collection sorts of generic sorts) */ - public GenericSort(Name name, ImmutableSet ext, ImmutableSet oneOf, - String documentation, String origin) + public GenericSort(Name name, ImmutableSet ext, ImmutableSet oneOf) throws GenericSupersortException { - super(name, ext, false, documentation, origin); + super(name, ext, false); this.oneOf = oneOf; checkSupersorts(); } - public GenericSort(Name name, ImmutableSet ext, ImmutableSet oneOf) - throws GenericSupersortException { - this(name, ext, oneOf, "", ""); - } - - public GenericSort(Name name) { - super(name, DefaultImmutableSet.nil(), false, "", ""); + super(name, DefaultImmutableSet.nil(), false); this.oneOf = DefaultImmutableSet.nil(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/NullSort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/NullSort.java index c181b22e9c7..bd53d514e65 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/NullSort.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/NullSort.java @@ -35,7 +35,7 @@ public final class NullSort extends SortImpl { public NullSort(Sort objectSort) { - super(NAME, null, false, "", ""); + super(NAME, null, false); assert objectSort != null; this.objectSort = objectSort; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ParametricSortDecl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ParametricSortDecl.java index a0484a75d9f..43b593c222c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ParametricSortDecl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ParametricSortDecl.java @@ -6,6 +6,7 @@ import de.uka.ilkd.key.ldt.JavaDLTheory; import de.uka.ilkd.key.logic.GenericParameter; +import org.key_project.logic.HasMeta; import org.key_project.logic.Name; import org.key_project.logic.Named; import org.key_project.logic.sort.Sort; @@ -19,23 +20,18 @@ /// /// Get instantiated versions using [ParametricSortInstance#get(ParametricSortDecl, ImmutableList, /// Services)]. -public class ParametricSortDecl implements Named { +public class ParametricSortDecl implements Named, HasMeta { private final Name name; private final boolean isAbstract; - private final String documentation; - private final ImmutableList parameters; private final ImmutableSet extendedSorts; - private final String origin; public ParametricSortDecl(Name name, boolean isAbstract, ImmutableSet ext, - ImmutableList sortParams, String documentation, String origin) { + ImmutableList sortParams) { this.name = name; this.isAbstract = isAbstract; this.extendedSorts = ext.isEmpty() ? ImmutableSet.singleton(JavaDLTheory.ANY) : ext; - this.documentation = documentation; this.parameters = sortParams; - this.origin = origin; assert Immutables.isDuplicateFree(parameters) : "The caller should have made sure that generic sorts are not duplicated"; } @@ -57,11 +53,8 @@ public ImmutableSet getExtendedSorts() { return extendedSorts; } - public String getDocumentation() { - return documentation; - } - - public String getOrigin() { - return origin; + @Override + public String getMetaKey() { + return "psort/" + name(); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProgramSVSort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProgramSVSort.java index 4e644442ee7..b5fd16060bb 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProgramSVSort.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProgramSVSort.java @@ -255,7 +255,7 @@ public boolean canStandFor(ProgramElement pe, Services services) { // -------------------------------------------------------------------------- protected ProgramSVSort(Name name) { - super(name, DefaultImmutableSet.nil(), false, "", ""); + super(name, DefaultImmutableSet.nil(), false); NAME2SORT.put(name, this); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProxySort.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProxySort.java index fca9856c8a9..c5196d3e5f0 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProxySort.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/ProxySort.java @@ -9,12 +9,11 @@ import org.key_project.util.collection.ImmutableSet; public class ProxySort extends SortImpl { - - public ProxySort(Name name, ImmutableSet ext, String documentation, String origin) { - super(name, ext, false, documentation, origin); + public ProxySort(Name name, ImmutableSet ext) { + super(name, ext, false); } public ProxySort(Name name) { - this(name, DefaultImmutableSet.nil(), "", ""); + this(name, DefaultImmutableSet.nil()); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/SortImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/SortImpl.java index 3ead17776fe..7e1bb555638 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/sort/SortImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/sort/SortImpl.java @@ -11,50 +11,27 @@ import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableSet; -import org.jspecify.annotations.Nullable; - /** * Abstract base class for implementations of the Sort interface. */ public class SortImpl extends AbstractSort { - /** - * Documentation for this sort given by the associated documentation comment. - * - * @see de.uka.ilkd.key.nparser.KeYParser.One_sort_declContext#doc - */ - private final String documentation; - - /** Information of the origin of this sort */ - private final String origin; private ImmutableSet ext; - public SortImpl(Name name, ImmutableSet ext, boolean isAbstract, String documentation, - String origin) { + public SortImpl(Name name, ImmutableSet ext, boolean isAbstract) { super(name, isAbstract); this.ext = ext; - this.documentation = documentation; - this.origin = origin; - } - - public SortImpl(Name name, ImmutableSet ext, String documentation, String origin) { - this(name, ext, false, documentation, origin); - } - - public SortImpl(Name name, ImmutableSet ext, boolean isAbstract) { - this(name, ext, isAbstract, "", ""); } public SortImpl(Name name, ImmutableSet ext) { - this(name, ext, false, "", ""); + this(name, ext, false); } public SortImpl(Name name, Sort ext) { - this(name, DefaultImmutableSet.nil().add(ext), false, "", ""); + this(name, DefaultImmutableSet.nil().add(ext), false); } - public SortImpl(Name name) { - this(name, DefaultImmutableSet.nil(), "", ""); + this(name, DefaultImmutableSet.nil()); } @Override @@ -88,16 +65,6 @@ public String declarationString() { return name().toString(); } - @Override - public @Nullable String getDocumentation() { - return documentation; - } - - @Override - public @Nullable String getOrigin() { - return origin; - } - @Override public boolean containsGenericSort() { return false; diff --git a/key.core/src/main/java/de/uka/ilkd/key/nparser/ConfigurationBuilder.java b/key.core/src/main/java/de/uka/ilkd/key/nparser/ConfigurationBuilder.java index 146723fcf0d..3e9cddbefbd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/nparser/ConfigurationBuilder.java +++ b/key.core/src/main/java/de/uka/ilkd/key/nparser/ConfigurationBuilder.java @@ -34,6 +34,9 @@ public String visitCkey(KeYParser.CkeyContext ctx) { @Override public String visitCsymbol(KeYParser.CsymbolContext ctx) { + if (ctx.getText().equals("null")) { + return null; + } return ctx.IDENT().getText(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/nparser/KeyAst.java b/key.core/src/main/java/de/uka/ilkd/key/nparser/KeyAst.java index 22a4e64f10d..61b92c54b87 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/nparser/KeyAst.java +++ b/key.core/src/main/java/de/uka/ilkd/key/nparser/KeyAst.java @@ -191,6 +191,16 @@ public Configuration asConfiguration() { throw new RuntimeException("Error in configuration. Source: " + ctx.start.getTokenSource().getSourceName()); } + + public List asConfigurationList() { + final var cfg = new ConfigurationBuilder(); + List res = cfg.visitCfile(ctx); + if (!res.isEmpty()) + return (List) res.getFirst(); + else + throw new RuntimeException("Error in configuration. Source: " + + ctx.start.getTokenSource().getSourceName()); + } } public static class SetStatementContext extends KeyAst { diff --git a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DeclarationBuilder.java b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DeclarationBuilder.java index b9d4c467101..edf31221501 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DeclarationBuilder.java +++ b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DeclarationBuilder.java @@ -4,6 +4,8 @@ package de.uka.ilkd.key.nparser.builder; import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.ast.abstraction.KeYJavaType; @@ -13,9 +15,9 @@ import de.uka.ilkd.key.logic.op.ProgramVariable; import de.uka.ilkd.key.logic.sort.*; import de.uka.ilkd.key.nparser.KeYParser; -import de.uka.ilkd.key.nparser.ParsingFacade; import org.key_project.logic.Choice; +import org.key_project.logic.HasMeta; import org.key_project.logic.Name; import org.key_project.logic.Named; import org.key_project.logic.sort.Sort; @@ -63,16 +65,15 @@ public Object visitDecls(KeYParser.DeclsContext ctx) { @Override public Object visitDatatype_decl(KeYParser.Datatype_declContext ctx) { - // boolean freeAdt = ctx.FREE() != null; var name = ctx.name.getText(); - var doc = ctx.DOC_COMMENT() != null - ? ctx.DOC_COMMENT().getText() - : null; + var doc = processDocumentation(ctx.doc); var origin = BuilderHelpers.getPosition(ctx); List typeParameters = accept(ctx.formal_sort_param_decls()); if (typeParameters == null) { - var s = new SortImpl(new Name(name), ImmutableSet.empty(), false, doc, origin); + var s = new SortImpl(new Name(name), ImmutableSet.empty(), false); sorts().addSafely(s); + docsSpace().setDocumentation(s, doc); + docsSpace().setOrigin(s, origin); } else { var doubled = CollectionUtil.findDuplicates(typeParameters); if (!doubled.isEmpty()) { @@ -81,22 +82,25 @@ public Object visitDatatype_decl(KeYParser.Datatype_declContext ctx) { doubled.getFirst()); } var s = new ParametricSortDecl(new Name(name), false, ImmutableSet.empty(), - ImmutableList.fromList(typeParameters), doc, origin); + ImmutableList.fromList(typeParameters)); namespaces().parametricSorts().addSafely(s); + docsSpace().setDocumentation(s, doc); + docsSpace().setOrigin(s, origin); } return null; } @Override public Object visitProg_var_decls(KeYParser.Prog_var_declsContext ctx) { - for (int i = 0; i < ctx.simple_ident_comma_list().size(); i++) { - List varNames = accept(ctx.simple_ident_comma_list(i)); + for (int i = 0; i < ctx.simple_ident_comma_list_with_docs().size(); i++) { + var c = ctx.simple_ident_comma_list_with_docs(i); + List varNames = c.simple_ident_with_doc() + .stream().map(it -> (String) accept(it.simple_ident())).toList(); KeYJavaType kjt = accept(ctx.keyjavatype(i)); assert varNames != null; for (String varName : varNames) { if (varName.equals("null")) { - semanticError(ctx.simple_ident_comma_list(i), - "Function '" + varName + "' is already defined!"); + semanticError(c, "Function '" + varName + "' is already defined!"); } ProgramElementName pvName = new ProgramElementName(varName); Named name = lookup(pvName); @@ -104,8 +108,8 @@ public Object visitProg_var_decls(KeYParser.Prog_var_declsContext ctx) { // commented out as pv do not have unique name (at the moment) // throw new AmbigiousDeclException(varName, getSourceName(), getLine(), // getColumn()) - if (!(name instanceof ProgramVariable) - || !((ProgramVariable) name).getKeYJavaType().equals(kjt)) { + if (!(name instanceof ProgramVariable pv) + || !(pv.getKeYJavaType().equals(kjt))) { programVariables().add(new LocationVariable(pvName, kjt)); } } else { @@ -120,21 +124,30 @@ public Object visitProg_var_decls(KeYParser.Prog_var_declsContext ctx) { @Override public Object visitChoice(KeYParser.ChoiceContext ctx) { String cat = ctx.category.getText(); + String catDoc = processDocumentation(ctx.maindoc); + docsSpace().setDocumentation(new HasMeta.OptionCategory(cat), catDoc); + for (KeYParser.OptionDeclContext optdecl : ctx.optionDecl()) { Token catctx = optdecl.IDENT; String name = cat + ":" + catctx.getText(); + Choice c = choices().lookup(new Name(name)); if (c == null) { c = new Choice(catctx.getText(), cat); choices().add(c); + + var doc = processDocumentation(optdecl.DOC_COMMENT); + docsSpace().setDocumentation(c, doc); } category2Default.putIfAbsent(cat, name); } + category2Default.computeIfAbsent(cat, it -> { - choices().add(new Choice("On", cat)); - choices().add(new Choice("Off", cat)); + choices().add(new Choice(cat + ":On", cat)); + choices().add(new Choice(cat + ":Off", cat)); return cat + ":On"; }); + return null; } @@ -154,7 +167,7 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) { boolean isProxySort = ctx.PROXY() != null; boolean isAbstractSort = ctx.ABSTRACT() != null; List createdSorts = new LinkedList<>(); - var documentation = ParsingFacade.getValueDocumentation(ctx.DOC_COMMENT()); + var sectionDoc = processDocumentation(ctx.DOC_COMMENT()); ImmutableSet ext = sortExt == null ? ImmutableSet.empty() : Immutables.createSetFrom(sortExt); @@ -176,8 +189,8 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) { } if (ctx.sortIds != null) { - for (var idCtx : ctx.sortIds.simple_ident_dots()) { - String sortId = accept(idCtx); + for (var idCtx : ctx.sortIds.simple_ident_dots_with_docs()) { + String sortId = accept(idCtx.simple_ident_dots()); Name sortName = new Name(sortId); @@ -190,9 +203,7 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) { Sort s = null; if (isGenericSort) { try { - var gs = new GenericSort(sortName, ext, oneOf, documentation, - BuilderHelpers.getPosition(idCtx)); - s = gs; + s = new GenericSort(sortName, ext, oneOf); } catch (GenericSupersortException e) { semanticError(ctx, "Illegal sort given"); } @@ -200,16 +211,18 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) { s = JavaDLTheory.ANY; } else { if (isProxySort) { - var ps = new ProxySort(sortName, ext, documentation, - BuilderHelpers.getPosition(idCtx)); - s = ps; + s = new ProxySort(sortName, ext); } else { - var si = new SortImpl(sortName, ext, isAbstractSort, - documentation, BuilderHelpers.getPosition(idCtx)); - s = si; + s = new SortImpl(sortName, ext, isAbstractSort); } } assert s != null; + String doc = processDocumentation(idCtx.DOC_COMMENT()); + String origin = BuilderHelpers.getPosition(idCtx); + docsSpace().setOrigin(s, origin); + docsSpace().setDocumentation(s, + Stream.of(doc, sectionDoc).filter(Objects::nonNull) + .collect(Collectors.joining("\n"))); sorts().add(s); createdSorts.add(s); } else { @@ -220,7 +233,7 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) { "Sort declaration of {} in {} is ignored due to collision (already " + "present in {}).", sortName, BuilderHelpers.getPosition(ctx), - existingSort.getOrigin()); + docsSpace().findOrigin(existingSort)); } } } else { @@ -243,9 +256,13 @@ public Object visitOne_sort_decl(KeYParser.One_sort_declContext ctx) { "Cannot declare parametric sort %s, as a sort of the same name has already been declared", sortName); } - var sortDecl = new ParametricSortDecl(sortName, isAbstractSort, ext, params, - documentation, BuilderHelpers.getPosition(declCtx)); + var sortDecl = new ParametricSortDecl(sortName, isAbstractSort, ext, params); namespaces().parametricSorts().addSafely(sortDecl); + docsSpace().setOrigin(sortDecl, BuilderHelpers.getPosition(declCtx)); + var doc = processDocumentation(declCtx.DOC_COMMENT()); + docsSpace().setDocumentation(sortDecl, + Stream.of(doc, sectionDoc).filter(Objects::nonNull) + .collect(Collectors.joining("\n"))); } return createdSorts; } @@ -268,10 +285,13 @@ public List visitOneof_sorts(KeYParser.Oneof_sortsContext ctx) { @Override public Object visitRuleset_decls(KeYParser.Ruleset_declsContext ctx) { - for (String id : this.mapOf(ctx.simple_ident())) { + for (KeYParser.Simple_ident_with_docContext iddoc : ctx.simple_ident_with_doc()) { + String id = accept(iddoc.simple_ident()); + String doc = processDocumentation(iddoc.DOC_COMMENT()); RuleSet h = new RuleSet(new Name(id)); if (ruleSets().lookup(new Name(id)) == null) { ruleSets().add(h); + docsSpace().setDocumentation(h, doc); } } return null; @@ -283,5 +303,4 @@ public Object visitOptions_choice(KeYParser.Options_choiceContext ctx) { return null; } - } diff --git a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DefaultBuilder.java b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DefaultBuilder.java index 4ecd37159ca..2c724b43c09 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DefaultBuilder.java +++ b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/DefaultBuilder.java @@ -7,6 +7,8 @@ import java.util.Collection; import java.util.List; import java.util.ResourceBundle; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; @@ -34,6 +36,8 @@ import org.key_project.util.collection.Pair; import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.TerminalNode; import org.jspecify.annotations.Nullable; /** @@ -278,6 +282,11 @@ protected Namespace choices() { return namespaces().choices(); } + protected MetaSpace docsSpace() { + return namespaces().docs(); + } + + @Override public String visitString_value(KeYParser.String_valueContext ctx) { return ctx.getText().substring(1, ctx.getText().length() - 1); @@ -487,4 +496,28 @@ public Object visitFuncpred_name(KeYParser.Funcpred_nameContext ctx) { } return new GenericParameter((GenericSort) paramSort, variance); } + + + protected String processDocumentation(TerminalNode terminalNode) { + if (terminalNode != null) + return processDocumentation(terminalNode.getSymbol()); + return null; + } + + protected String processDocumentation(List maindoc) { + return maindoc.stream().map(this::processDocumentation).collect(Collectors.joining("\n\n")); + } + + protected String processDocumentation(Token doc) { + if (doc == null) { + return null; + } + + var text = doc.getText(); + int prefix = doc.getCharPositionInLine() + 2; + Pattern REMOVE_INDENT = Pattern.compile("^[ ]{1," + prefix + "}", Pattern.MULTILINE); + text = text.strip().substring(3, text.length() - 2); + return REMOVE_INDENT.matcher(text).replaceAll("").trim(); + } + } diff --git a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/FunctionPredicateBuilder.java b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/FunctionPredicateBuilder.java index 344ab2ef9be..96a38da988f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/FunctionPredicateBuilder.java +++ b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/FunctionPredicateBuilder.java @@ -83,6 +83,7 @@ public Object visitDatatype_decl(KeYParser.Datatype_declContext ctx) { Name name = new Name(constructorContext.name.getText()); Sort[] args = new Sort[constructorContext.sortId().size()]; var argNames = constructorContext.argName; + var doc = processDocumentation(constructorContext.doc); for (int i = 0; i < args.length; i++) { Sort argSort = accept(constructorContext.sortId(i)); args[i] = argSort; @@ -106,10 +107,8 @@ public Object visitDatatype_decl(KeYParser.Datatype_declContext ctx) { || !alreadyDefinedFn.argSorts().equals(ImmutableList.of(sort)))) { // The condition checks whether there is already a function with the same name // but different signature. This is necessarily true if there is a globally - // defined function - // of the same name and may or may not be true if there is another constructor - // argument of the - // same name. + // defined function of the same name and may or may not be true if there + // is another constructor argument of the same name. semanticError(argNames.get(i), "Name already in namespace: %s" + ". Identifiers in datatype definitions must be unique (also wrt. global functions).", argName); @@ -128,10 +127,12 @@ public Object visitDatatype_decl(KeYParser.Datatype_declContext ctx) { if (genericParams == null) { var fn = new JFunction(name, sort, args, null, true, false); functions().addSafely(fn); + docsSpace().setDocumentation(fn, doc); } else { var fn = new ParametricFunctionDecl(name, genericParams, new ImmutableArray<>(args), sort, null, true, true, false); namespaces().parametricFunctions().add(fn); + docsSpace().setDocumentation(fn, doc); } } if (genericParams != null) { @@ -147,6 +148,7 @@ public Object visitPred_decl(KeYParser.Pred_declContext ctx) { String pred_name = accept(ctx.funcpred_name()); List params = ctx.formal_sort_param_decls() == null ? null : visitFormal_sort_param_decls(ctx.formal_sort_param_decls()); + String doc = processDocumentation(ctx.doc); List whereToBind = accept(ctx.where_to_bind()); List argSorts = accept(ctx.arg_sorts()); if (whereToBind != null && whereToBind.size() != argSorts.size()) { @@ -198,6 +200,7 @@ public Object visitPred_decl(KeYParser.Pred_declContext ctx) { if (lookup(p.name()) == null) { functions().add(p); + docsSpace().setDocumentation(p, doc); } else { // weigl: agreement on KaKeY meeting: this should be an error. semanticError(ctx, "Predicate '" + p.name() + "' is already defined!"); diff --git a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/IncludeFinder.java b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/IncludeFinder.java index 6bd25460ab1..55bbb8833e8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/IncludeFinder.java +++ b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/IncludeFinder.java @@ -57,9 +57,10 @@ private void addInclude(String filename) throws MalformedURLException { filename = filename.replace('/', File.separatorChar); // Not required for Windows, but // whatsoever filename = filename.replace('\\', File.separatorChar); // Special handling for Linux - var path = base.resolve(filename).normalize(); + var path = base.resolve(filename).normalize().toAbsolutePath(); var url = path.toUri().toURL(); + // url = URI.create(path.toString()).toURL(); source = RuleSourceFactory.initRuleFile(url); if (ldt) { includes.putLDT(filename, source); diff --git a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/TacletPBuilder.java b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/TacletPBuilder.java index 47f7a06730e..8c05a24b604 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/TacletPBuilder.java +++ b/key.core/src/main/java/de/uka/ilkd/key/nparser/builder/TacletPBuilder.java @@ -172,9 +172,11 @@ public Taclet visitTaclet(KeYParser.TacletContext ctx) { b.setName(new Name(name)); b.setChoices(choices); b.setAnnotations(tacletAnnotations); - b.setOrigin(BuilderHelpers.getPosition(ctx)); Taclet r = b.getTaclet(); - registerTaclet(ctx, r); + String doc = processDocumentation(ctx.doc); + String origin = BuilderHelpers.getPosition(ctx); + + registerTaclet(ctx, r, doc, origin); currentTBuilder.pop(); return r; } @@ -187,9 +189,8 @@ public Taclet visitTaclet(KeYParser.TacletContext ctx) { ifSeq = accept(ctx.ifSeq); } - @Nullable Object find = accept(ctx.find); - Sequent seq = find instanceof Sequent ? (Sequent) find : null; + Sequent seq = (find instanceof Sequent s) ? s : null; var applicationRestriction = ApplicationRestriction.NONE; if (!ctx.SAMEUPDATELEVEL().isEmpty()) { @@ -218,10 +219,11 @@ public Taclet visitTaclet(KeYParser.TacletContext ctx) { accept(ctx.modifiers()); b.setChoices(choices); b.setAnnotations(tacletAnnotations); - b.setOrigin(BuilderHelpers.getPosition(ctx)); + String origin = BuilderHelpers.getPosition(ctx); try { Taclet r = peekTBuilder().getTaclet(); - registerTaclet(ctx, r); + String doc = processDocumentation(ctx.doc); + registerTaclet(ctx, r, doc, origin); setSchemaVariables(schemaVariables().parent()); currentTBuilder.pop(); return r; @@ -238,8 +240,11 @@ private void registerTaclet(KeYParser.Datatype_declContext ctx, TacletBuilder ctx.start.getTokenSource().getSourceName(), ctx.start.getLine()); } - private void registerTaclet(ParserRuleContext ctx, Taclet taclet) { + private void registerTaclet(ParserRuleContext ctx, Taclet taclet, + @Nullable String documentation, @Nullable String origin) { taclet2Builder.put(taclet, peekTBuilder()); + docsSpace().setDocumentation(taclet, documentation); + docsSpace().setOrigin(taclet, origin); LOGGER.trace("Taclet announced: \"{}\" from {}:{}", taclet.name(), ctx.start.getTokenSource().getSourceName(), ctx.start.getLine()); } @@ -457,7 +462,7 @@ private TacletBuilder createAxiomTaclet( var cases = ctx.datatype_constructor().stream() .map(it -> createQuantifiedFormula(it, qvar, tb.var(phi), sort)) - .collect(Collectors.toList()); + .toList(); for (var c : cases) { if (c.vars == null) @@ -584,10 +589,6 @@ public Object visitModifiers(KeYParser.ModifiersContext ctx) { b.setDisplayName(Objects.requireNonNull(accept(ctx.dname))); } - if (ctx.HELPTEXT() != null) { // last entry - b.setHelpText(accept(ctx.htext)); - } - mapOf(ctx.triggers()); return null; } @@ -801,7 +802,6 @@ public Object visitGoalspec(KeYParser.GoalspecContext ctx) { ImmutableSLList addRList = ImmutableSLList.nil(); DefaultImmutableSet addpv = DefaultImmutableSet.nil(); - @Nullable Object rwObj = accept(ctx.replacewith()); if (ctx.add() != null) { addSeq = accept(ctx.add()); @@ -850,29 +850,32 @@ public ImmutableList visitTacletlist(KeYParser.TacletlistContext ctx) { private @NonNull TacletBuilder createTacletBuilderFor(Object find, ApplicationRestriction applicationRestriction, ParserRuleContext ctx) { - if (find == null) { - return new NoFindTacletBuilder(); - } else if (find instanceof JTerm) { - return new RewriteTacletBuilder<>().setFind((JTerm) find) - .setApplicationRestriction(applicationRestriction); - } else if (find instanceof Sequent findSeq) { - if (findSeq.isEmpty()) { + switch (find) { + case null -> { return new NoFindTacletBuilder(); - } else if (findSeq.antecedent().size() == 1 && findSeq.succedent().isEmpty()) { - AntecTacletBuilder b = new AntecTacletBuilder(); - b.setFind(findSeq); - b.setApplicationRestriction(applicationRestriction); - return b; - } else if (findSeq.antecedent().isEmpty() && findSeq.succedent().size() == 1) { - SuccTacletBuilder b = new SuccTacletBuilder(); - b.setFind(findSeq); - b.setApplicationRestriction(applicationRestriction); - return b; - } else { - semanticError(ctx, "Unknown find-sequent (perhaps null?):" + findSeq); } - } else { - semanticError(ctx, "Unknown find class type: %s", find.getClass().getName()); + case JTerm jTerm -> { + return new RewriteTacletBuilder<>().setFind(jTerm) + .setApplicationRestriction(applicationRestriction); + } + case Sequent findSeq -> { + if (findSeq.isEmpty()) { + return new NoFindTacletBuilder(); + } else if (findSeq.antecedent().size() == 1 && findSeq.succedent().isEmpty()) { + AntecTacletBuilder b = new AntecTacletBuilder(); + b.setFind(findSeq); + b.setApplicationRestriction(applicationRestriction); + return b; + } else if (findSeq.antecedent().isEmpty() && findSeq.succedent().size() == 1) { + SuccTacletBuilder b = new SuccTacletBuilder(); + b.setFind(findSeq); + b.setApplicationRestriction(applicationRestriction); + return b; + } else { + semanticError(ctx, "Unknown find-sequent (perhaps null?):" + findSeq); + } + } + default -> semanticError(ctx, "Unknown find class type: %s", find.getClass().getName()); } throw new IllegalArgumentException( diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java index 93c58da43ce..713d24ec5d0 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Node.java @@ -504,8 +504,8 @@ public int getChildNr(Node child) { return -1; } - public StringBuffer getUniqueTacletId() { - StringBuffer id = new StringBuffer(); + public StringBuilder getUniqueTacletId() { + StringBuilder id = new StringBuilder(32); int c = 0; Node n = this; diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/TacletIndex.java b/key.core/src/main/java/de/uka/ilkd/key/proof/TacletIndex.java index 2e2124aa46e..8c7f357b341 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/TacletIndex.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/TacletIndex.java @@ -5,6 +5,7 @@ import java.util.*; import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.Stream; import de.uka.ilkd.key.java.ast.JavaProgramElement; @@ -265,23 +266,16 @@ public Object clone() { } @Override - public @NonNull Set allNoPosTacletApps() { - Set result = new LinkedHashSet<>(); - for (ImmutableList tacletApps : rwList.values()) { - tacletApps.forEach(result::add); - } - - for (ImmutableList tacletApps : antecList.values()) { - tacletApps.forEach(result::add); - } - - for (ImmutableList tacletApps : succList.values()) { - tacletApps.forEach(result::add); - } - - noFindList.forEach(result::add); + public Set allNoPosTacletApps() { + return new HashSet<>(allNoPosTacletAppsStream().collect(Collectors.toUnmodifiableSet())); + } - return result; + public Stream allNoPosTacletAppsStream() { + Stream s1 = rwList.values().stream().flatMap(ImmutableList::stream); + Stream s2 = antecList.values().stream().flatMap(ImmutableList::stream); + Stream s3 = succList.values().stream().flatMap(ImmutableList::stream); + Stream s4 = noFindList.stream(); + return Stream.concat(Stream.concat(Stream.concat(s1, s2), s3), s4); } /** @@ -512,12 +506,10 @@ public ImmutableList getNoFindTaclet(RuleFilter filter, */ @Override public NoPosTacletApp lookup(Name name) { - for (NoPosTacletApp tacletApp : allNoPosTacletApps()) { - if (tacletApp.taclet().name().equals(name)) { - return tacletApp; - } - } - return null; + return allNoPosTacletAppsStream() + .filter(tacletApp -> tacletApp.taclet().name().equals(name)) + .findAny() + .orElse(null); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/init/AbstractPO.java b/key.core/src/main/java/de/uka/ilkd/key/proof/init/AbstractPO.java index 054ff20a142..3621c6d9542 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/init/AbstractPO.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/init/AbstractPO.java @@ -292,7 +292,6 @@ private Vertex getVertexFor(Pair vertexCore, ClassAxiom */ private void registerClassAxiomTaclets(KeYJavaType selfKJT, InitConfig proofConfig) { final ImmutableSet axioms = selectClassAxioms(selfKJT); - var choices = Collections.unmodifiableSet(proofConfig.getActivatedChoices().toSet()); for (ClassAxiom axiom : axioms) { final Vertex node = getVertexFor(axiom.getKJT().getSort(), axiom.getTarget(), axiom); if (node.index == -1) { @@ -305,9 +304,9 @@ private void registerClassAxiomTaclets(KeYJavaType selfKJT, InitConfig proofConf proofConfig.getServices())) { assert axiomTaclet != null : "class axiom returned null taclet: " + axiom.getName(); // only include if choices are appropriate - if (axiomTaclet.getChoices().eval(choices)) { - register(axiomTaclet, proofConfig); - } + // weigl: register always! choices are evaluated as late as possible. + // This would technically allow to change Taclet options after loading. + register(axiomTaclet, proofConfig); } } @@ -424,7 +423,9 @@ public final ProofAggregate getPO() { } proofs[i] = createProof(poNames != null ? poNames[i] : name, poTerms[i], ic); if (taclets != null) { - proofs[i].getOpenGoal(proofs[i].root()).indexOfTaclets().addTaclets(taclets); + var filteredTaclets = proofs[i].getInitConfig().filterTaclets(taclets); + proofs[i].getOpenGoal(proofs[i].root()).indexOfTaclets() + .addTaclets(filteredTaclets); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/init/InitConfig.java b/key.core/src/main/java/de/uka/ilkd/key/proof/init/InitConfig.java index ba9216516f1..cba9970a0e3 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/init/InitConfig.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/init/InitConfig.java @@ -17,7 +17,10 @@ import de.uka.ilkd.key.proof.mgt.RuleJustification; import de.uka.ilkd.key.proof.mgt.RuleJustificationByAddRules; import de.uka.ilkd.key.proof.mgt.RuleJustificationInfo; -import de.uka.ilkd.key.rule.*; +import de.uka.ilkd.key.rule.BuiltInRule; +import de.uka.ilkd.key.rule.NoPosTacletApp; +import de.uka.ilkd.key.rule.Rule; +import de.uka.ilkd.key.rule.Taclet; import de.uka.ilkd.key.rule.tacletbuilder.TacletBuilder; import de.uka.ilkd.key.settings.ProofSettings; @@ -75,10 +78,14 @@ public class InitConfig { */ private ImmutableSet activatedChoices = DefaultImmutableSet.nil(); - /** HashMap for quick lookups taclet name->taclet */ + /** + * HashMap for quick lookups taclet name->taclet + */ private Map activatedTacletCache = null; - /** the fileRepo which is responsible for consistency between source code and proof */ + /** + * the fileRepo which is responsible for consistency between source code and proof + */ private FileRepo fileRepo; // weigl this field is never set @@ -106,7 +113,6 @@ public InitConfig(Services services) { // ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- // public interface // ------------------------------------------------------------------------- @@ -255,7 +261,7 @@ private void fillActiveTacletCache() { if (activatedTacletCache != null) { return; } - final LinkedHashMap tacletCache = new LinkedHashMap<>(); + final Map tacletCache = new TreeMap<>(); var choices = Collections.unmodifiableSet(activatedChoices.toSet()); for (Taclet t : taclets) { TacletBuilder b = taclet2Builder.get(t); @@ -266,6 +272,9 @@ private void fillActiveTacletCache() { } if (t != null) { + if (tacletCache.containsKey(t.name())) { + throw new IllegalArgumentException(); + } tacletCache.put(t.name(), t); } } @@ -441,7 +450,6 @@ public InitConfig copyWithServices(Services services) { } - @Override public String toString() { return "Namespaces:" + namespaces() + "\n" + "Services:" + services + "\n" + "Taclets:" @@ -474,4 +482,19 @@ public void activateChoice(Choice choice) { public void setHeader(KeyAst.@Nullable Declarations header) { this.header = header; } + + public Collection filterTaclets(ImmutableSet taclets) { + var result = new HashMap(); + var choices = Collections.unmodifiableSet(activatedChoices.toSet()); + for (var app : taclets) { + var t = app.taclet(); + if (t.getChoices().eval(choices)) { + if (result.containsKey(t.name())) { + throw new IllegalArgumentException("Duplicate choice: " + t.name() + " by PO"); + } + result.put(t.name(), app); + } + } + return result.values(); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java b/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java index 5ccb57aa1a7..6659a1a7498 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/init/ProblemInitializer.java @@ -34,6 +34,7 @@ import de.uka.ilkd.key.rule.RewriteTaclet; import de.uka.ilkd.key.rule.Rule; import de.uka.ilkd.key.rule.Taclet; +import de.uka.ilkd.key.settings.Configuration; import de.uka.ilkd.key.settings.ProofIndependentSettings; import de.uka.ilkd.key.settings.ProofSettings; import de.uka.ilkd.key.speclang.PositionedString; @@ -53,6 +54,7 @@ import org.key_project.util.collection.ImmutableSet; import org.key_project.util.java.StringUtil; +import org.jspecify.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,6 +71,7 @@ public final class ProblemInitializer { */ private FileRepo fileRepo; private ImmutableSet warnings = DefaultImmutableSet.nil(); + private @Nullable Configuration additionalProfileOptions; // ------------------------------------------------------------------------- // constructors @@ -82,13 +85,22 @@ public ProblemInitializer(ProgressMonitor mon, Services services, } public ProblemInitializer(Profile profile) { - if (profile == null) { - throw new IllegalArgumentException("Given profile is null"); - } + this(null, new Services(Objects.requireNonNull(profile, "Given profile is null")), null); + } + + public ProblemInitializer(Profile profile, @Nullable Configuration additionalProfileOptions) { + this(profile); + this.additionalProfileOptions = additionalProfileOptions; + } + + /// An arbitrary object which is passed to the provided profile, during construction of the + /// `initConfig`. + public @Nullable Configuration getAdditionalProfileOptions() { + return additionalProfileOptions; + } - this.progMon = null; - this.listener = null; - this.services = new Services(Objects.requireNonNull(profile)); + public void setAdditionalProfileOptions(@Nullable Configuration additionalProfileOptions) { + this.additionalProfileOptions = additionalProfileOptions; } private void progressStarted(Object sender) { @@ -443,7 +455,7 @@ private InitConfig createInitConfigFor(EnvInput envInput) throws ProofInputExcep for (RuleSource tacletBase : tacletBases) { KeYFile tacletBaseFile = new KeYFile( "taclet base (%s)".formatted(tacletBase.file().getFileName()), - tacletBase, progMon, profile); + tacletBase, progMon, profile, null); readEnvInput(tacletBaseFile, config); } } @@ -454,7 +466,7 @@ private InitConfig createInitConfigFor(EnvInput envInput) throws ProofInputExcep // cache the last used init config BaseConfigCache.setBaseInputConfig(config, inputDigest); config = config.copy(); - profile.prepareInitConfig(config); + profile.prepareInitConfig(config, null); return config; } @@ -605,9 +617,8 @@ private InitConfig prepare(EnvInput envInput, InitConfig referenceConfig) if (type instanceof ClassDeclaration || type instanceof InterfaceDeclaration) { for (Field f : javaInfo.getAllFields((TypeDeclaration) type)) { final ProgramVariable pv = (ProgramVariable) f.getProgramVariable(); - if (pv instanceof LocationVariable) { - heapLDT.getFieldSymbolForPV((LocationVariable) pv, - services); + if (pv instanceof LocationVariable lv) { + heapLDT.getFieldSymbolForPV(lv, initConfig.getServices()); } } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java b/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java index 9316c659d0e..c3cfe2191cc 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/init/Profile.java @@ -12,8 +12,10 @@ import de.uka.ilkd.key.rule.Rule; import de.uka.ilkd.key.rule.UseDependencyContractRule; import de.uka.ilkd.key.rule.UseOperationContractRule; +import de.uka.ilkd.key.settings.Configuration; import de.uka.ilkd.key.strategy.StrategyFactory; +import org.jspecify.annotations.Nullable; import org.key_project.logic.Name; import org.key_project.prover.engine.GoalChooserFactory; import org.key_project.prover.proof.ProofGoal; @@ -181,7 +183,7 @@ default UseOperationContractRule getUseOperationContractRule() { /// established. /// /// @see ProblemInitializer - default void prepareInitConfig(InitConfig baseConfig) { + default void prepareInitConfig(InitConfig baseConfig, @Nullable Configuration configuration) { } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java b/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java index 851cfa8320b..3e60e3ea712 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/io/AbstractProblemLoader.java @@ -65,36 +65,6 @@ public abstract class AbstractProblemLoader { */ private boolean loadSingleJavaFile = false; - public static class ReplayResult { - - private final Node node; - private final List errors; - private final String status; - - public ReplayResult(String status, List errors, Node node) { - this.status = status; - this.errors = errors; - this.node = node; - } - - public Node getNode() { - return node; - } - - public String getStatus() { - return status; - } - - public List getErrorList() { - return errors; - } - - public boolean hasErrors() { - return errors != null && !errors.isEmpty(); - } - - } - /** * The file or folder to load. */ @@ -859,4 +829,34 @@ public void setLoadSingleJavaFile(boolean loadSingleJavaFile) { public void setIgnoreWarnings(boolean ignoreWarnings) { this.ignoreWarnings = ignoreWarnings; } + + public static class ReplayResult { + + private final Node node; + private final List errors; + private final String status; + + public ReplayResult(String status, List errors, Node node) { + this.status = status; + this.errors = errors; + this.node = node; + } + + public Node getNode() { + return node; + } + + public String getStatus() { + return status; + } + + public List getErrorList() { + return errors; + } + + public boolean hasErrors() { + return errors != null && !errors.isEmpty(); + } + + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/io/IntermediateProofReplayer.java b/key.core/src/main/java/de/uka/ilkd/key/proof/io/IntermediateProofReplayer.java index dc42cc8ec19..1fab2137899 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/io/IntermediateProofReplayer.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/io/IntermediateProofReplayer.java @@ -456,9 +456,25 @@ private TacletApp constructTacletApp(TacletAppIntermediate currInterm, Goal curr TacletApp ourApp; PosInOccurrence pos = null; - Taclet t = proof.getInitConfig().lookupActiveTaclet(new Name(tacletName)); + Name nTacletName = new Name(tacletName); + Taclet t = proof.getInitConfig().lookupActiveTaclet(nTacletName); if (t == null) { - ourApp = currGoal.indexOfTaclets().lookup(tacletName); + var possibleApps = currGoal.indexOfTaclets().allNoPosTacletAppsStream() + .filter(it -> it.taclet().name().equals(nTacletName)) + .toList(); + + if (possibleApps.isEmpty()) { + ourApp = null; + } else if (possibleApps.size() == 1) { + ourApp = possibleApps.getFirst(); + } else { + var taclets = possibleApps.stream().map(TacletApp::toString) + .collect(Collectors.joining("\n---\n")); + throw new TacletAppConstructionException( + "There are more than one possible taclet available with name \"" + tacletName + + "\". " + + "Most three similar names are: " + taclets); + } } else { ourApp = NoPosTacletApp.createNoPosTacletApp(t); } @@ -507,6 +523,9 @@ private TacletApp constructTacletApp(TacletAppIntermediate currInterm, Goal curr } ourApp = constructInsts(ourApp, currGoal, currInterm.getInsts(), services); + if(ourApp==null) { + System.out.println("§sdsfs"); + } ImmutableList ifFormulaList = ImmutableSLList.nil(); for (String ifFormulaStr : currInterm.getIfSeqFormulaList()) { diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractBlockContractRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractBlockContractRule.java index 028a83a33c4..856ccb44329 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractBlockContractRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractBlockContractRule.java @@ -276,4 +276,18 @@ public String toString() { + (excVar != null ? "Validity Branch: exceptionVar=" + excVar.name() : ""); } } + + @Override + public @Nullable String getDocumentation() { + return """ + Like methods, statement blocks can be annotated with contracts. The application of the Block Contract rules then gives rise to subgoals which roughly correspond to those of the Use Operation Contract rule (see there). + Three properties have to be shown: + + 1. Validity of block contract + + 2. Precondition of contract holds + + 3. Postcondition holds after block terminates + """; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/BuiltInRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/BuiltInRule.java index cac17c592b7..f59d007bbb1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/BuiltInRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/BuiltInRule.java @@ -40,9 +40,4 @@ public interface BuiltInRule extends Rule, RuleExecutor { default RuleExecutor getExecutor() { return this; } - - @Override - default @Nullable String getOrigin() { - return "defined in Java: " + getClass().getName(); - } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/OneStepSimplifier.java b/key.core/src/main/java/de/uka/ilkd/key/rule/OneStepSimplifier.java index c04e03ef185..48143627a1d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/OneStepSimplifier.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/OneStepSimplifier.java @@ -3,12 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.rule; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.JTerm; @@ -124,8 +119,7 @@ private ImmutableList tacletsForRuleSet(Proof proof, String ruleSetName, ImmutableList result = ImmutableSLList.nil(); // collect apps present in all open goals - Set allApps = - proof.openGoals().head().ruleAppIndex().tacletIndex().allNoPosTacletApps(); + Set allApps = proof.openGoals().head().ruleAppIndex().tacletIndex().allNoPosTacletApps(); for (Goal goal : proof.openGoals().tail()) { allApps.retainAll(goal.ruleAppIndex().tacletIndex().allNoPosTacletApps()); } @@ -795,4 +789,28 @@ public String toString() { public boolean isApplicableOnSubTerms() { return false; } + + + @Override + public String getDocumentation() { + return """ + The One Step Simplifier (OSS) aggregates the application of simplification rules into a single rule. This is done to make the calculus more efficient. + + You can activate/deactivate the simplifier by toggling the menu entry Options->One Step Simplifier. An active OSS makes the proof faster, a deactivated more transparent. + + In particular, the OSS performs normalisation and simplification on updated terms: + * Updates on terms without modality are resolved. + * Updates without effects are dropped. + * Sequential updates are merged into one parallel update. + + Technical Information: + The OSS aggregates the rules from the following heuristics (-> Taclet Base): + concrete, + update_elim, + update_apply_on_update, + update_apply, + update_join, + elimQuantifier + """; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/QueryExpand.java b/key.core/src/main/java/de/uka/ilkd/key/rule/QueryExpand.java index 7c9c327582e..a64659f4de7 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/QueryExpand.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/QueryExpand.java @@ -42,6 +42,7 @@ import org.key_project.util.collection.Pair; import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -683,4 +684,15 @@ public DefaultBuiltInRuleApp createApp(PosInOccurrence pos, TermServices service public boolean isApplicableOnSubTerms() { return true; } + + @Override + public @Nullable String getDocumentation() { + return """ + The QueryExpand rule allows to apply contracts or to symbolically execute a query + expression in the logic. It replaces the query expression by a new constant and + constructs a box formula in the antecedent 'defining' the constant as the result of + a method call. The method call is encoded directly as a method call in the box modality. + The query is invoked in a context equal to the container type of the query method. + """; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/Rule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/Rule.java index a2c53678b42..0b691486a8c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/Rule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/Rule.java @@ -4,11 +4,17 @@ package de.uka.ilkd.key.rule; -import org.key_project.logic.HasOrigin; +import org.key_project.logic.HasMeta; + +import org.jspecify.annotations.NonNull; /** * This interface has to be implemented by all classes that want to act as a rule in the calculus. */ -public interface Rule extends org.key_project.prover.rules.Rule, HasOrigin { +public interface Rule extends org.key_project.prover.rules.Rule, HasMeta { + @Override + default @NonNull String getMetaKey() { + return "rule/" + this.name(); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/Taclet.java b/key.core/src/main/java/de/uka/ilkd/key/rule/Taclet.java index 6c2660bd593..248736f25d7 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/Taclet.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/Taclet.java @@ -32,8 +32,6 @@ import org.checkerframework.checker.nullness.qual.EnsuresNonNull; import org.jspecify.annotations.NonNull; -import org.jspecify.annotations.Nullable; - /** @@ -519,23 +517,6 @@ public enum TacletOperation { public abstract @NonNull Taclet setName(@NonNull String s); - /** - * Information about the origin of the taclet. Should be a location where the user can find the - * declaration of the taclet. - *

- * This field is set by the parser with [url]:[lineNumber] - */ - private @Nullable String origin; - - @Override - public @Nullable String getOrigin() { - return origin; - } - - public void setOrigin(@Nullable String origin) { - this.origin = origin; - } - StringBuffer toStringAttribs(StringBuffer sb) { // if (noninteractive()) sb = sb.append(" \\noninteractive"); sb.append("\nChoices: ").append(choices); diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/UseDependencyContractRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/UseDependencyContractRule.java index ec6b10b9f4b..73bbb048127 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/UseDependencyContractRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/UseDependencyContractRule.java @@ -605,4 +605,15 @@ public UseDependencyContractApp createApp(PosInOccurrence pos, TermServices serv public boolean isApplicableOnSubTerms() { return true; } + + @Override + public @Nullable String getDocumentation() { + return """ + Methods and model fields may be annotated with an accessible clause. This defines a dependency contract describing the heap locations its value may depend on. + + If the heap changes in locations the symbol does not depend on, its value remains unchanged. This rules adds an according implication for a heap-dependent symbol to the sequent's antecedent. + + In automatic strategy, this rule is applied lazily (only once all other means of advancing the proof have been exhausted) to avoid endless loops. + """; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/UseOperationContractRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/UseOperationContractRule.java index 3780c359933..cf3426d24a2 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/UseOperationContractRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/UseOperationContractRule.java @@ -970,4 +970,20 @@ protected JTerm getFinalPreTerm() { return finalPreTerm; } } + + @Override + public @Nullable String getDocumentation() { + return """ + When symbolic execution reaches a method call, the according method can be approximated by its specified contract (more precisely, one or more of its contracts). + + This rule gives rise to three or four subgoals: + 1. Pre: It must be established that the pre-condition of the method holds prior to the method call. + + 2. Post: The method terminates normally, the post-condition of the method can be assumed and symbolic execution continues. + + 3. Exceptional Post: The method terminates abruptly with an exception, the exceptional post-condition is assumed, and symbolic execution continues with this exception thrown. + + 4. Null reference: The receiver of the call can be null. This case is considered on this branch. If KeY can figure out automatically that this cannot be the case, this branch is suppressed. + """; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/WhileInvariantRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/WhileInvariantRule.java index e727678997f..cc29101fd1f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/WhileInvariantRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/WhileInvariantRule.java @@ -699,4 +699,19 @@ protected void prepareUseCaseBranch(Goal useGoal) { ruleApp.posInOccurrence()); } } + + @Override + public @Nullable String getDocumentation() { + return """ + Loops can be handled by expanding or by using a loop invariant. + An invariant can be created manually or supplied by the JML specification. + Use of this rule creates three subgoals, two of which are new proof obligations: + + 1. It must be shown that the loop invariant is initially valid. + + 2. The loop body needs to preserve the invariant. + + In the third subgoal, the loop invariant can be used. + """; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/TacletExecutor.java b/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/TacletExecutor.java index c01f777c4db..c8ef5809bb2 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/TacletExecutor.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/TacletExecutor.java @@ -167,8 +167,8 @@ protected void applyAddrule(ImmutableList { protected ChoiceExpr choices = ChoiceExpr.TRUE; protected ImmutableSet tacletAnnotations = DefaultImmutableSet.nil(); - protected String origin; public void setAnnotations(ImmutableSet tacletAnnotations) { this.tacletAnnotations = tacletAnnotations; @@ -326,21 +324,7 @@ public T getTacletWithoutInactiveGoalTemplates(Set active) { } } - public void setOrigin(String origin) { - this.origin = origin; - } - - public void setHelpText(@Nullable Object accept) { - // throw new RuntimeException("To be implemented"); - } - public static class TacletBuilderException extends IllegalArgumentException { - - - /** - * - */ - private static final long serialVersionUID = -6710383705714015291L; private final Name tacletname; private final String errorMessage; diff --git a/key.core/src/main/java/de/uka/ilkd/key/scripts/ProofScriptEngine.java b/key.core/src/main/java/de/uka/ilkd/key/scripts/ProofScriptEngine.java index 4212e60ec03..4a58de0ad7c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/scripts/ProofScriptEngine.java +++ b/key.core/src/main/java/de/uka/ilkd/key/scripts/ProofScriptEngine.java @@ -71,7 +71,7 @@ public ProofScriptEngine(List script, Goal initiallySelectedGo this.script = script; } - private static Map loadCommands() { + public static Map loadCommands() { Map result = new HashMap<>(); var loader = ServiceLoader.load(ProofScriptCommand.class); @@ -137,12 +137,12 @@ public void execute(AbstractUserInterfaceControl uiControl, List boolean exists(String name, Class clazz) { - return data.containsKey(name) && clazz.isAssignableFrom(data.get(name).getClass()); + return data.containsKey(name) && data.get(name) != null + && clazz.isAssignableFrom(data.get(name).getClass()); } /** @@ -184,7 +185,7 @@ public long getLong(String name, long defaultValue) { * @throws NullPointerException if no such value entry exists */ public boolean getBool(String name) { - return get(name, Boolean.class); + return Boolean.TRUE.equals(get(name, Boolean.class)); } /** @@ -215,8 +216,7 @@ public double getDouble(String name) { * @param name property name * @throws ClassCastException if the entry is not a {@link String} */ - @Nullable - public String getString(String name) { + public @Nullable String getString(String name) { return get(name, String.class); } @@ -358,7 +358,7 @@ private ConfigurationMeta getOrCreateMeta(String name) { /** * @see #getTable(String) */ - public Configuration getSection(String name) { + public @Nullable Configuration getSection(String name) { return getTable(name); } @@ -373,39 +373,39 @@ public Configuration getSection(String name, boolean createIfNotExists) { return getSection(name); } - public Object set(String name, Object obj) { + public @Nullable Object set(String name, @Nullable Object obj) { return data.put(name, obj); } - public Object set(String name, Boolean obj) { + public @Nullable Object set(String name, @Nullable Boolean obj) { return set(name, (Object) obj); } - public Object set(String name, String obj) { + public @Nullable Object set(String name, @Nullable String obj) { return set(name, (Object) obj); } - public Object set(String name, Long obj) { + public @Nullable Object set(String name, @Nullable Long obj) { return set(name, (Object) obj); } - public Object set(String name, int obj) { + public @Nullable Object set(String name, int obj) { return set(name, (long) obj); } - public Object set(String name, Double obj) { + public @Nullable Object set(String name, @Nullable Double obj) { return set(name, (Object) obj); } - public Object set(String name, Configuration obj) { + public @Nullable Object set(String name, @Nullable Configuration obj) { return set(name, (Object) obj); } - public Object set(String name, List obj) { + public @Nullable Object set(String name, @Nullable List obj) { return set(name, (Object) obj); } - public Object set(String name, String[] seq) { + public @Nullable Object set(String name, @Nullable String[] seq) { return set(name, (Object) Arrays.asList(seq)); } @@ -544,7 +544,7 @@ public ConfigurationWriter printValue(Object value) { } else if (value instanceof Enum) { printValue(value.toString()); } else if (value == null) { - printValue("null"); + out.write("null"); } else { throw new IllegalArgumentException("Unexpected object: " + value); } @@ -552,7 +552,7 @@ public ConfigurationWriter printValue(Object value) { } private ConfigurationWriter printMap(Map value) { - out.format("{ "); + out.format("{"); indent += 4; newline().printIndent(); for (Iterator> iterator = @@ -579,7 +579,7 @@ private ConfigurationWriter print(String s) { } private ConfigurationWriter printSeq(Collection value) { - out.format("[ "); + out.print("["); indent += 4; newline(); printIndent(); @@ -598,13 +598,13 @@ private ConfigurationWriter printSeq(Collection value) { } indent -= 4; newline().printIndent(); - out.format("]"); + out.print("]"); return this; } private ConfigurationWriter printKey(String key) { printValue(key); - out.format(" : "); + out.print(" : "); return this; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/settings/PathConfig.java b/key.core/src/main/java/de/uka/ilkd/key/settings/PathConfig.java index 040aa15ba23..f1bdbaab0bd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/settings/PathConfig.java +++ b/key.core/src/main/java/de/uka/ilkd/key/settings/PathConfig.java @@ -14,8 +14,8 @@ * Keeps some central paths to files and directories. *

*

- * By default all KeY configurations are stored in a directory named ".key" inside the user's home - * directory. In Microsoft windows operating systems this is directly the hard disc that contains + * By default, all KeY configurations are stored in a directory named ".key" inside the user's home + * directory. In Microsoft Windows operating systems this is directly the hard disc that contains * the KeY code. But the eclipse integration requires to change the default location. This is * possible via {@link #setKeyConfigDir(String)} which should be called once before something is * done with KeY (e.g. before the {@code MainWindow} is opened). @@ -81,7 +81,6 @@ public static Path getKeyConfigDir() { */ public static void setKeyConfigDir(String keyConfigDir) { PathConfig.keyConfigDir = Paths.get(keyConfigDir); - recentFileStorage = getKeyConfigDir().resolve("recentFiles.json"); proofIndependentSettings = getKeyConfigDir().resolve("proofIndependentSettings.props"); logDirectory = getKeyConfigDir().resolve("logs"); diff --git a/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/GenericRemovingLemmaGenerator.java b/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/GenericRemovingLemmaGenerator.java index 778914c8cdc..7aebd45fcfc 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/GenericRemovingLemmaGenerator.java +++ b/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/GenericRemovingLemmaGenerator.java @@ -70,7 +70,7 @@ protected Sort replaceSort(Sort sort, TermServices services) { } ImmutableSet extSorts = replaceSorts(sort.extendsSorts(), services); - ProxySort result = new ProxySort(sort.name(), extSorts, "", ""); + ProxySort result = new ProxySort(sort.name(), extSorts); sortMap.put(sort, result); return result; diff --git a/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/TacletLoader.java b/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/TacletLoader.java index 0618c9668f2..ac7cb117a9a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/TacletLoader.java +++ b/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/TacletLoader.java @@ -6,7 +6,7 @@ import java.io.File; import java.nio.file.Path; import java.util.Collection; -import java.util.HashMap; +import java.util.Map; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.proof.Proof; @@ -83,7 +83,7 @@ public void manageAvailableTaclets(InitConfig initConfig, Taclet tacletToProve) ImmutableList sysTaclets = initConfig.getTaclets(); ImmutableList newTaclets = ImmutableSLList.nil(); - HashMap> map = initConfig.getTaclet2Builder(); + Map> map = initConfig.getTaclet2Builder(); boolean tacletfound = false; for (Taclet taclet : sysTaclets) { if (taclet.equals(tacletToProve)) { diff --git a/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/UserDefinedSymbols.java b/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/UserDefinedSymbols.java index 318f99bb81b..d0392bf44b1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/UserDefinedSymbols.java +++ b/key.core/src/main/java/de/uka/ilkd/key/taclettranslation/lemma/UserDefinedSymbols.java @@ -122,8 +122,7 @@ public void replaceGenericByProxySorts() { Set result = new HashSet<>(); for (Sort sort : usedExtraSorts) { if (sort instanceof GenericSort genSort) { - ProxySort proxySort = new ProxySort(genSort.name(), genSort.extendsSorts(), - "", ""); + ProxySort proxySort = new ProxySort(genSort.name(), genSort.extendsSorts()); result.add(proxySort); } else { result.add(sort); diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/ExceptionTools.java b/key.core/src/main/java/de/uka/ilkd/key/util/ExceptionTools.java index 88e38f0d97a..fb4937bde78 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/ExceptionTools.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/ExceptionTools.java @@ -7,6 +7,7 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; +import java.nio.file.Paths; import java.util.regex.Pattern; import de.uka.ilkd.key.parser.Location; @@ -39,17 +40,17 @@ public final class ExceptionTools { public static final Pattern TOKEN_MGR_ERR_PATTERN = Pattern.compile("^Lexical error at line (\\d+), column (\\d+)\\."); - private ExceptionTools() {} + private ExceptionTools() { + } /** * Get the throwable's message. This will return a nicer error message for * certain ANTLR exceptions. * - * @param throwable - * a throwable + * @param throwable a throwable * @return message for the exception */ - public static String getMessage(Throwable throwable) { + public static String getMessage(@Nullable Throwable throwable) { if (throwable == null) { return ""; } else if (throwable instanceof ParseCancellationException @@ -108,11 +109,9 @@ private static String getNiceMessageInternal(IntStream inputStream, * Tries to resolve the location (i.e., file name, line, and column) from a parsing exception. * Result may be null. * - * @param exc - * the Throwable to extract the Location from + * @param exc the Throwable to extract the Location from * @return the Location stored inside the Throwable or null if no such can be found - * @throws MalformedURLException - * if the no URL can be parsed from the String stored inside the + * @throws MalformedURLException if the no URL can be parsed from the String stored inside the * given Throwable can not be successfully converted to a URL and thus no Location can * be created */ @@ -141,14 +140,14 @@ private static URI parseFileName(String filename) throws MalformedURLException { } } - // TODO javaparser this was not unused - @Nullable - private static Location getLocation(RecognitionException exc) throws MalformedURLException { - // ANTLR 3 - Recognition Exception. - if (exc.input != null) { - // ANTLR has 0-based column numbers - return new Location(parseFileName(exc.input.getSourceName()), exc.position); - } - return null; + private static @Nullable Location getLocation(InputMismatchException exc) { + var token = exc.getOffendingToken(); + + return token == null ? null + : new Location( + // FIXME weigl: This does not work on Windows. Illegal characters. + Paths.get(Paths.get("").toString(), exc.getInputStream().getSourceName()) + .normalize().toUri(), + de.uka.ilkd.key.java.Position.fromToken(token)); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/SideProofUtil.java b/key.core/src/main/java/de/uka/ilkd/key/util/SideProofUtil.java index 75c1cda207b..7b2dd56c94c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/SideProofUtil.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/SideProofUtil.java @@ -16,7 +16,6 @@ import de.uka.ilkd.key.rule.BuiltInRule; import de.uka.ilkd.key.rule.OneStepSimplifier; import de.uka.ilkd.key.rule.Taclet; -import de.uka.ilkd.key.rule.tacletbuilder.TacletBuilder; import de.uka.ilkd.key.settings.ProofSettings; import org.key_project.logic.Choice; @@ -63,9 +62,7 @@ public static ProofEnvironment cloneProofEnvironmentWithOwnOneStepSimplifier( ? new ProofSettings(sourceInitConfig.getSettings()) : null; initConfig.setSettings(clonedSettings); - initConfig.setTaclet2Builder( - (HashMap>) sourceInitConfig.getTaclet2Builder() - .clone()); + initConfig.setTaclet2Builder(new HashMap<>(sourceInitConfig.getTaclet2Builder())); initConfig.setTaclets(sourceInitConfig.getTaclets()); // Create new ProofEnvironment and initialize it with values from initial one. ProofEnvironment env = new ProofEnvironment(initConfig); diff --git a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/heap.key b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/heap.key index 1cf51d30c4b..1243a772423 100644 --- a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/heap.key +++ b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/heap.key @@ -14,9 +14,37 @@ \functions { // select/store alpha alpha::select(Heap, Object, Field); + + + /*! This function modifies a heap by changing the value in one location. It takes four arguments: + + 1. The heap h which is to be modified + 2. The object o reference of the location which is to be modified + 3. The field of the location which is to be modified + 4. The value v which is to be written in the designated location. + + The result is a heap which coincides with h in all locations but in (o,f), where v is stored. + In the theory of arrays, store is somtimes called "write". + The field java.lang.Object::<created> cannot be updated using store; use "create". */ Heap store(Heap, Object, Field, any); + + /*! This function modifies a heap by changing the createdness of one object. + It takes two arguments: + 1. The heap h which is to be modified + 2. The object reference o for the object which is to be set created. + The result is a heap which coincides with h in all locations but in (o,java.lang.Object::), + which has been set to true. There is no means to modify a heap by setting the createdness of an object to false. + */ Heap create(Heap, Object); Heap anon(Heap, LocSet, Heap); + + /*! This function modifies a heap by changing the value in one location. It takes three arguments: + 1. The heap h which is to be modified + 2. The location set s whose locations are to be modified + 3. The value v which is to be written in the designated locations. + + The result is a heap which coincides with h in all locations but in the locations in s where v is stored. + The field java.lang.Object::<created> cannot be updated using memset; use "create". */ Heap memset(Heap, LocSet, any); // default value for a field @@ -26,6 +54,16 @@ alpha alpha::final(Object, Field); // fields + + /*! + This function turns an integer into a field reference. + + Integers are used to access the entries of entries within arrays stored on the heap. This + function provides the injection of the integer domain into that of the type Field. It is + ensured that this image of arr is disjoint from any defined field constant. + + The array access a[i], for instance for an int-array a, becomes int::select(heap, a, arr(i)). + */ \unique Field arr(int); \unique Field java.lang.Object::#$transient; \unique Field java.lang.Object::#$transactionConditionallyUpdated; @@ -36,16 +74,38 @@ \unique Field alpha::#$classInitializationInProgress; // static \unique Field alpha::#$classErroneous; // static - // array length + /*! array length + + The length of an array is not stored on the heap but is an inherent property of the object reference which denotes the array. + Hence, this functions takes only one argument: the object reference whose length (as an array) is to be retrieved. + This function always results in a non-negative value. + */ int length(Object); - // null + /*! A constant holding the object reference pointing to the Java null object. + Quite the same as the keyword "null" in Java. */ Null null; } \predicates { + /*! This predicate takes an argument of type Heap. It is true if the following conditions hold for its the argument: + 1. Every location contains a reference to a created (in this heap) object or null. + 2. Every location set stored on the heap contains only created objects. + 3. Every location belonging to a declared Java field holds a value compatible with its type. + 4. Only finitely many objects are created on the heap. + */ wellFormed(Heap); + + /*! + This predicate is true if the described array update is valid in Java. + + Java has the peculiarity of covariant array types. They allow an array assignment to fail at runtime (with an ArrayStoreException). This predicate deals with the issue in the logic. + + (tbd) + */ arrayStoreValid(any, any); + + nonNull(Heap, Object, int); // can be used to formulate assignable proof obligations in JML assert statements (via \dl_ escapes) @@ -53,5 +113,11 @@ } \programVariables { - Heap heap, savedHeap, permissions; + Heap + /*! This program variable holds to the current heap state. + Its type is Heap. Any assignment statement in a modality modifies the value of this program variable + and any expression reading from the heap within a Java modality refers to the heap stored + in this program variable. */ + heap, + savedHeap, permissions; } diff --git a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/javaHeader.key b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/javaHeader.key index 810c4692342..50e40d4503e 100644 --- a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/javaHeader.key +++ b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/javaHeader.key @@ -26,6 +26,12 @@ \functions { alpha alpha::cast(any); + + /*! A boolean function which is true iff the dynamic type of its argument is + precisely the type which is part of the function name. */ boolean alpha::exactInstance(any); + + /*! A boolean function which is true iff the dynamic type of its argument is a + subtype of the type which is part of the function name. */ boolean alpha::instance(any); } diff --git a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/locset/locSets.key b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/locset/locSets.key index b1a2a9a2cd4..be74f91a6dc 100644 --- a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/locset/locSets.key +++ b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/locset/locSets.key @@ -11,18 +11,48 @@ \functions { // unique function symbols + /*! The empty location set which does not contain any elements. */ \unique LocSet empty; + + /*! The unique location set containing all locations, i.e. elementOf(o, f, allLocs) + will always return true for an arbitrary Field f and Object o. */ \unique LocSet allLocs; // other constructors + /*! Converts a single location to a locations set with one element. */ LocSet singleton(Object, Field); + + /*! Union between two location sets. */ LocSet union(LocSet, LocSet); + + /*! Intersection between two location sets. */ LocSet intersect(LocSet, LocSet); + + /*! Realizes relative complement (a.k.a. set difference) between two locations sets. It takes as arguments + two location sets and returns another location set which contains all elements from the first argument + except those that are elements of the second argument. */ LocSet setMinus(LocSet, LocSet); + + /*! Takes as argument a term of type LocSet, which may contain a free variable. The term represents a family + of locations sets, which is parameterized by the unbound variable. The returned location set is the union + over all members of the parameterized family. */ LocSet infiniteUnion {true}(LocSet); + + /*! The set that contains all locations which belong to the object o given as argument. + + A location (a,b) is in the set allFields(o) iff a=o. + In JML, the function corresponds to `o.*`. */ LocSet allFields(Object); + + /*! The set of all locations that belong to a particular field f given as argument. + + A location (a,b) is in the set allObjects(f) iff b=f. */ LocSet allObjects(Field); + + /*! The set of locations which are fresh (that is not created) w.r.t. the heap h given as argument. + A location (a,b) is in the set freshLocs(h) iff o.<created>@h = FALSE. */ LocSet arrayRange(Object, int, int); + LocSet freshLocs(Heap); // work-a-round LocSet allElementsOfArray(Heap, Object, LocSet); @@ -30,8 +60,21 @@ } \predicates { + /*! This is the set theoretic membership predicate to be used for location sets. + + It takes three arguments: The first two (an Object and a Field) make up the location and the + third is the location set against which membership is tested. */ elementOf(Object, Field, LocSet); + + /*! This is the set theoretic subset predicate to be used for location sets. + + A location set A is subset of another location set B iff every element of A is also element of B.*/ subset(LocSet, LocSet); + + /*! This binary predicate models disjointness of location sets. + + disjoint(A,B) is true iff A and B have an empty intersection, + it is thus equivalent to intersect(A,B) = empty.*/ disjoint(LocSet, LocSet); createdInHeap(LocSet, Heap); } diff --git a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/map.key b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/map.key index 903b3fde087..cb279fdcba7 100644 --- a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/map.key +++ b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/map.key @@ -13,30 +13,47 @@ Abstract datatype of (untyped) partial maps. Map; } + + \functions { - /*! - Return a value from the given Map. - If value is undefined, `mapUndef` is used. - */ + /*! Return a value from the given Map. If value is undefined, `mapUndef` is used. */ any mapGet(Map, any); - /*! - - */ + /*! A unique value, which is returned by mapGet in case no mapping value is declared for the specified key. */ \unique any mapUndef; // constructors + /*! Generalized quantifier for maps. This is a generic constructor for maps. */ Map mapForeach {true, true}(boolean, any); + + /*! The empty map, which does not contain any entries. */ Map mapEmpty; + + /*! A map, which contains only one entry. */ Map mapSingleton(any, any); + + /*! Takes as arguments two maps and creates a new map from their entries. In case their domains overlap, + entries of the second map are used for keys from the intersection. */ Map mapOverride(Map, Map); + + /*! Converts a sequence to a map. The map domain consists of exactly those integers, which are inside the sequence bounds. */ Map seq2map(Seq); + + /*! Adds an entry to a map or overwrites an existing one. */ Map mapUpdate(Map, any, any); + + /*! Removes an entry from a map. */ Map mapRemove(Map, any); } \predicates { + /*! Takes two arguments: key ∈ any and map ∈ Map. Returns true iff key is in the domain of map. */ inDomain(Map, any); + + /*! Returns true iff the domain of the specified map contains only objects that are ; + in the implicit heap (additional non-object values may also be part of the domain). This can be used + in a JML specification as an invariant to ensure, that non-created objects are not (yet) part + of the domain of a map. */ inDomainImpliesCreated(Map); } diff --git a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/sequence/seq.key b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/sequence/seq.key index e9fa73b1381..432776504de 100644 --- a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/sequence/seq.key +++ b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/sequence/seq.key @@ -19,24 +19,59 @@ \functions { // getters + /*! Return the element at a position within a sequence. The type read from the sequence is part of the function name. */ alpha alpha::seqGet(Seq, int); + + /*! Return the length of a sequence. */ int seqLen(Seq); + + /*! Return the first index in a sequence that holds a value. */ int seqIndexOf(Seq, any); + /*! The underspecified error value if a sequence is accessed outside its idnex range. */ any seqGetOutside; // constructors + /*! The empty sequence. */ Seq seqEmpty; + /*! A singleton sequence that has the argument as only entry.*/ Seq seqSingleton(any); + + /*! Concatenates two sequences. */ Seq seqConcat(Seq, Seq); + + /*! Takes a subsequence from a sequence. + The first argument is the original sequence, + the second is the first index to consider (inclusive) and + the third is the last index to consider (!exclusive!). */ Seq seqSub(Seq, int, int); + + /*! Reverses a sequence. The result has the same entries as the argument but in reverse order. */ Seq seqReverse(Seq); Seq seqUpd(Seq, int, any); + + /*! This function binds an integer variable and evaluates an expression over this variable + for a range of values to obtain the entries of a sequence. + + The sequence + `seqDef{int i;}(-2, 3, i*i)` + has, for instance, the entries + `[ 4, 1, 0, 1, 4 ]`. + + The first and second argument give the range over which the variable goes. Again, the right-hand bound is exclusive. + + seqDef is related to the lambda operator in lambda calculus. */ Seq seqDef {false, false, true}(int, int, any); + /*! Takes a sequence and two indices. The elements at the specified indices are exchanged in the resulting sequence. In case one of the indices is out of bounds, the sequence is left unchanged.*/ Seq seqSwap(Seq, int, int); + + /*! Takes a sequence and removes the element at the specified index. In case the index is out of bounds, the sequence is left unchanged. */ Seq seqRemove(Seq, int); + + /*! Takes a sequence of naturals (zero included) and treats it as a permutation. The resulting sequence is the inverse permutation of the original one. */ Seq seqNPermInv(Seq); + /*! Convert a Java array to a JavaDL sequence. */ Seq array2seq(Heap, Object); // placeholder for values in enhanced for loop diff --git a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/wellfound.key b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/wellfound.key index 629a7daf6e7..8c8cefff393 100644 --- a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/wellfound.key +++ b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/wellfound.key @@ -26,8 +26,13 @@ \functions { // The constructor is unique which makes it also an injection. + /*! Return the (unique) ordered pair of two specified elements. */ \unique Pair pair(any, any); + + /*! Return the first element of an ordered pair. */ any first(Pair); + + /*! Return the second element of an ordered pair. */ any second(Pair); } diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/TestTermFactory.java b/key.core/src/test/java/de/uka/ilkd/key/logic/TestTermFactory.java index 80489f2a6ae..5203ffc935d 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/TestTermFactory.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/TestTermFactory.java @@ -66,8 +66,8 @@ public class TestTermFactory { @BeforeEach public void setUp() { - JTerm et_x = new TermImpl(x, new ImmutableArray<>(), null, null); - JTerm et_px = new TermImpl(p, new ImmutableArray<>(et_x), null, null); + JTerm et_x = new TermImpl(x, new ImmutableArray<>(), null); + JTerm et_px = new TermImpl(p, new ImmutableArray<>(et_x), null); et1 = et_px; TB = TacletForTests.services().getTermBuilder(); tf = TB.tf(); @@ -130,7 +130,7 @@ public void testWrongArity() { @Test public void testWithInvalidSubformulae() { JTerm invalidBuilt = new TermImpl(p, - new ImmutableArray<>(new TermImpl(y, new ImmutableArray<>(), null, null)), null, null); + new ImmutableArray<>(new TermImpl(y, new ImmutableArray<>(), null)), null); try { JTerm t_px_or_py = tf.createTerm(Junctor.OR, invalidBuilt, t1()); } catch (Exception e) { @@ -141,27 +141,27 @@ public void testWithInvalidSubformulae() { @Test public void testConstantTrue() { JTerm t_true = tf.createTerm(Junctor.TRUE); - assertEquals(t_true, new TermImpl(Junctor.TRUE, new ImmutableArray<>(), null, null)); + assertEquals(t_true, new TermImpl(Junctor.TRUE, new ImmutableArray<>(), null)); } @Test public void testQuantifierTerm() { JTerm t_forallx_px = TB.all(ImmutableSLList.nil().append(x), t1()); assertEquals(t_forallx_px, new TermImpl(Quantifier.ALL, new ImmutableArray<>(t1()), - new ImmutableArray<>(x), null)); + new ImmutableArray<>(x))); } @Test public void testJunctorTerm() { JTerm t_px_imp_ryw = tf.createTerm(Junctor.IMP, t1(), t2()); assertEquals(t_px_imp_ryw, - new TermImpl(Junctor.IMP, new ImmutableArray<>(t1(), t2()), null, null)); + new TermImpl(Junctor.IMP, new ImmutableArray<>(t1(), t2()), null)); } @Test public void testNegationTerm() { JTerm t_not_ryw = tf.createTerm(Junctor.NOT, t2()); - assertEquals(t_not_ryw, new TermImpl(Junctor.NOT, new ImmutableArray<>(t2()), null, null)); + assertEquals(t_not_ryw, new TermImpl(Junctor.NOT, new ImmutableArray<>(t2()), null)); } @Test @@ -188,7 +188,7 @@ public void testBoxTerm() { public void testSubstitutionTerm() { JTerm t_x_subst_fy_in_px = TB.subst(WarySubstOp.SUBST, x, t3(), t1()); assertEquals(new TermImpl(WarySubstOp.SUBST, new ImmutableArray<>(t3(), t1()), - new ImmutableArray<>(x), null), t_x_subst_fy_in_px); + new ImmutableArray<>(x)), t_x_subst_fy_in_px); } diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/sort/TestAlias.java b/key.core/src/test/java/de/uka/ilkd/key/logic/sort/TestAlias.java index 858f5dcd541..4636d680497 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/sort/TestAlias.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/sort/TestAlias.java @@ -57,8 +57,7 @@ public void testAliasOfParametric() { var pSet = new ParametricSortDecl(new Name("PSet"), false, ImmutableSet.empty(), ImmutableList.of( new GenericParameter(new GenericSort(new Name("A")), - GenericParameter.Variance.INVARIANT)), - "", ""); + GenericParameter.Variance.INVARIANT))); nss.parametricSorts().add(pSet); ParametricSortInstance intSet = ParametricSortInstance.get(pSet, ImmutableList.of(new GenericArgument(nss.lookupSortOrAlias("int"))), services); diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/sort/TestParametricSorts.java b/key.core/src/test/java/de/uka/ilkd/key/logic/sort/TestParametricSorts.java index e6f2e32576b..c8d544db6d4 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/sort/TestParametricSorts.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/sort/TestParametricSorts.java @@ -62,8 +62,8 @@ private ParametricSortDecl addParametricSort(String name, GenericSort genSort = (GenericSort) nss.sorts().lookup("G" + (i + 1)); params = params.prepend(new GenericParameter(genSort, varia)); } - ParametricSortDecl psd = new ParametricSortDecl(new Name(name), false, ImmutableSet.empty(), - params, "", ""); + ParametricSortDecl psd = + new ParametricSortDecl(new Name(name), false, ImmutableSet.empty(), params); nss.parametricSorts().add(psd); return psd; } diff --git a/key.core/tacletProofs/locSet/Taclet_disjointArrayRangeAllFields1.proof b/key.core/tacletProofs/locSet/Taclet_disjointArrayRangeAllFields1.proof index af8ab5faeef..e0e9c85d9a9 100644 --- a/key.core/tacletProofs/locSet/Taclet_disjointArrayRangeAllFields1.proof +++ b/key.core/tacletProofs/locSet/Taclet_disjointArrayRangeAllFields1.proof @@ -1,68 +1,105 @@ \profile "Java Profile"; \settings { -"#Proof-Settings-Config-File -#Wed Apr 12 13:28:59 CEST 2023 -[NewSMT]NoTypeHierarchy=false -[Labels]UseOriginLabels=true -[StrategyProperty]QUERYAXIOM_OPTIONS_KEY=QUERYAXIOM_ON -[NewSMT]Presburger=false -[SMTSettings]invariantForall=false -[Strategy]ActiveStrategy=JavaCardDLStrategy -[StrategyProperty]USER_TACLETS_OPTIONS_KEY1=USER_TACLETS_OFF -[StrategyProperty]QUANTIFIERS_OPTIONS_KEY=QUANTIFIERS_NON_SPLITTING_WITH_PROGS -[StrategyProperty]USER_TACLETS_OPTIONS_KEY2=USER_TACLETS_OFF -[Choice]DefaultChoices=JavaCard-JavaCard\\:on, Strings-Strings\\:on, assertions-assertions\\:safe, bigint-bigint\\:on, finalFields-finalFields\\:immutable, floatRules-floatRules\\:strictfpOnly, initialisation-initialisation\\:disableStaticInitialisation, intRules-intRules\\:arithmeticSemanticsIgnoringOF, integerSimplificationRules-integerSimplificationRules\\:full, javaLoopTreatment-javaLoopTreatment\\:efficient, mergeGenerateIsWeakeningGoal-mergeGenerateIsWeakeningGoal\\:off, methodExpansion-methodExpansion\\:modularOnly, modelFields-modelFields\\:treatAsAxiom, moreSeqRules-moreSeqRules\\:on, permissions-permissions\\:off, programRules-programRules\\:Java, reach-reach\\:on, runtimeExceptions-runtimeExceptions\\:ban, sequences-sequences\\:on, wdChecks-wdChecks\\:off, wdOperator-wdOperator\\:L -[StrategyProperty]LOOP_OPTIONS_KEY=LOOP_SCOPE_INV_TACLET -[StrategyProperty]INF_FLOW_CHECK_PROPERTY=INF_FLOW_CHECK_FALSE -[SMTSettings]UseBuiltUniqueness=false -[SMTSettings]explicitTypeHierarchy=false -[SMTSettings]instantiateHierarchyAssumptions=true -[StrategyProperty]NON_LIN_ARITH_OPTIONS_KEY=NON_LIN_ARITH_DEF_OPS -[SMTSettings]SelectedTaclets= -[StrategyProperty]DEP_OPTIONS_KEY=DEP_ON -[StrategyProperty]AUTO_INDUCTION_OPTIONS_KEY=AUTO_INDUCTION_OFF -[Strategy]MaximumNumberOfAutomaticApplications=10000 -[StrategyProperty]STOPMODE_OPTIONS_KEY=STOPMODE_DEFAULT -[StrategyProperty]CLASS_AXIOM_OPTIONS_KEY=CLASS_AXIOM_DELAYED -[SMTSettings]useConstantsForBigOrSmallIntegers=true -[StrategyProperty]MPS_OPTIONS_KEY=MPS_MERGE -[StrategyProperty]SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY=SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF -[Strategy]Timeout=-1 -[StrategyProperty]SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY=SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER -[StrategyProperty]QUERY_NEW_OPTIONS_KEY=QUERY_OFF -[SMTSettings]useUninterpretedMultiplication=true -[NewSMT]sqrtSMTTranslation=SMT -[StrategyProperty]BLOCK_OPTIONS_KEY=BLOCK_CONTRACT_INTERNAL -[StrategyProperty]METHOD_OPTIONS_KEY=METHOD_CONTRACT -[StrategyProperty]USER_TACLETS_OPTIONS_KEY3=USER_TACLETS_OFF -[NewSMT]identifier=OPEN -[SMTSettings]maxGenericSorts=2 -[StrategyProperty]OSS_OPTIONS_KEY=OSS_ON -[NewSMT]Axiomatisations=false -[StrategyProperty]SPLITTING_OPTIONS_KEY=SPLITTING_DELAYED -[SMTSettings]integersMinimum=-2147483645 -[StrategyProperty]VBT_PHASE=VBT_SYM_EX -[SMTSettings]integersMaximum=2147483645 -" -} + "Choice" : { + "JavaCard" : "JavaCard:on", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "finalFields" : "finalFields:immutable", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:arithmeticSemanticsIgnoringOF", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:on", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "soundDefaultContracts" : "soundDefaultContracts:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + }, + "Labels" : { + "UseOriginLabels" : true + }, + "NewSMT" : { + "Axiomatisations" : "false", + "NoTypeHierarchy" : "false", + "Presburger" : "false", + "identifier" : "OPEN", + "sqrtSMTTranslation" : "SMT" + }, + "SMTSettings" : { + "SelectedTaclets" : [ + + ], + "UseBuiltUniqueness" : false, + "explicitTypeHierarchy" : false, + "instantiateHierarchyAssumptions" : true, + "integersMaximum" : 2147483645, + "integersMinimum" : -2147483645, + "invariantForall" : false, + "maxGenericSorts" : 2, + "useConstantsForBigOrSmallIntegers" : true, + "useUninterpretedMultiplication" : true + }, + "Strategy" : { + "ActiveStrategy" : "Modular JavaDL Strategy", + "MaximumNumberOfAutomaticApplications" : 10000, + "Timeout" : -1, + "options" : { + "AUTO_INDUCTION_OPTIONS_KEY" : "AUTO_INDUCTION_OFF", + "BLOCK_OPTIONS_KEY" : "BLOCK_CONTRACT_INTERNAL", + "CLASS_AXIOM_OPTIONS_KEY" : "CLASS_AXIOM_DELAYED", + "DEP_OPTIONS_KEY" : "DEP_ON", + "LOOP_OPTIONS_KEY" : "LOOP_SCOPE_INV_TACLET", + "METHOD_OPTIONS_KEY" : "METHOD_CONTRACT", + "MPS_OPTIONS_KEY" : "MPS_MERGE", + "NON_LIN_ARITH_OPTIONS_KEY" : "NON_LIN_ARITH_DEF_OPS", + "OSS_OPTIONS_KEY" : "OSS_ON", + "QUANTIFIERS_OPTIONS_KEY" : "QUANTIFIERS_NON_SPLITTING_WITH_PROGS", + "QUERYAXIOM_OPTIONS_KEY" : "QUERYAXIOM_ON", + "QUERY_NEW_OPTIONS_KEY" : "QUERY_OFF", + "SPLITTING_OPTIONS_KEY" : "SPLITTING_DELAYED", + "STOPMODE_OPTIONS_KEY" : "STOPMODE_DEFAULT", + "SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER", + "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF", + "USER_TACLETS_OPTIONS_KEY1" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY2" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY3" : "USER_TACLETS_OFF", + "VBT_PHASE" : "VBT_SYM_EX" + } + } +} + -\proofObligation { - "name": "disjointArrayRangeAllFields1", - "class": "de.uka.ilkd.key.taclettranslation.lemma.TacletProofObligationInput", - } + +\proofObligation +// +{ + "class" : "de.uka.ilkd.key.taclettranslation.lemma.TacletProofObligationInput", + "name" : "disjointArrayRangeAllFields1" +} \proof { (keyLog "0" (keyUser "Julian" ) (keyVersion "80a871ca3bac8bb405ecc216fcb6fa9ef6f8a395")) +(keyLog "1" (keyUser "weigl" ) (keyVersion "1df32008ebda9fe2684e1a5eb5e44bdd4c398d8f")) +(keyLog "2" (keyUser "weigl" ) (keyVersion "1df32008ebda9fe2684e1a5eb5e44bdd4c398d8f")) -(autoModeTime "0") +(autoModeTime "15") (branch "dummy ID" (rule "equiv_right" (formula "1") (newnames "f_o1,f_o2,f_lower2,f_upper2") (userinteraction)) (branch "Case '->'" (rule "notRight" (formula "2")) (rule "andLeft" (formula "1")) - (rule "equalityToElementOf" (formula "3") (inst "ov=ov") (inst "fv=fv") (userinteraction)) + (rule "equalityToElementOf" (formula "3") (inst "fv=fv") (inst "ov=ov") (userinteraction)) (builtin "One Step Simplification" (formula "3")) (rule "eqSymm" (formula "1")) (rule "inEqSimp_commuteLeq" (formula "2")) @@ -108,6 +145,8 @@ (rule "commute_or_2" (formula "3") (term "0,0,0,0")) (rule "commute_or_2" (formula "3") (term "0,0,0")) (builtin "One Step Simplification" (formula "3")) + (rule "castDel" (formula "3") (term "0,0,0,0,0")) + (builtin "One Step Simplification" (formula "3")) (rule "polySimp_addComm1" (formula "3") (term "1")) (rule "add_literals" (formula "3") (term "0,1")) (rule "add_zero_left" (formula "3") (term "1")) @@ -131,16 +170,16 @@ (rule "polySimp_pullOutFactor1b" (formula "3") (term "0")) (rule "add_literals" (formula "3") (term "1,1,0")) (rule "times_zero_1" (formula "3") (term "1,0")) - (rule "add_zero_right" (formula "3") (term "0")) + (rule "add_literals" (formula "3") (term "0")) (rule "leq_literals" (formula "3")) (rule "closeFalse" (formula "3")) ) (branch "Case '<-'" - (rule "equalityToElementOfRight" (formula "2") (inst "ov=ov") (inst "fv=fv") (userinteraction)) + (rule "equalityToElementOfRight" (formula "2") (inst "fv=fv") (inst "ov=ov") (userinteraction)) (builtin "One Step Simplification" (formula "2")) (rule "notLeft" (formula "1")) - (rule "allRight" (formula "2") (inst "sk=ov_0")) - (rule "allRight" (formula "2") (inst "sk=fv_0")) + (rule "allRight" (formula "2") (inst "sk=ov_0:java.lang.Object")) + (rule "allRight" (formula "2") (inst "sk=fv_0:Field")) (rule "notRight" (formula "2")) (rule "eqSymm" (formula "2") (term "0")) (rule "inEqSimp_commuteLeq" (formula "2") (term "1")) @@ -150,7 +189,7 @@ (rule "applyEq" (formula "2") (term "0") (ifseqformula "1")) (rule "elementOfArrayRange" (formula "2") (inst "iv=iv")) (rule "andLeft" (formula "2")) - (rule "exLeft" (formula "3") (inst "sk=iv_0")) + (rule "exLeft" (formula "3") (inst "sk=iv_0:int")) (rule "andLeft" (formula "3")) (rule "andLeft" (formula "3")) (rule "eqSymm" (formula "2")) diff --git a/key.core/tacletProofs/locSet/Taclet_equalityOfSingleton.proof b/key.core/tacletProofs/locSet/Taclet_equalityOfSingleton.proof index 8a7048c354d..8a74e9e34a7 100644 --- a/key.core/tacletProofs/locSet/Taclet_equalityOfSingleton.proof +++ b/key.core/tacletProofs/locSet/Taclet_equalityOfSingleton.proof @@ -1,12 +1,12 @@ \profile "Java Profile"; -\settings // Proof-Settings-Config-File -{ - "Choice" : { +\settings { + "Choice" : { "JavaCard" : "JavaCard:on", "Strings" : "Strings:on", "assertions" : "assertions:on", "bigint" : "bigint:on", + "finalFields" : "finalFields:immutable", "floatRules" : "floatRules:strictfpOnly", "initialisation" : "initialisation:disableStaticInitialisation", "intRules" : "intRules:arithmeticSemanticsIgnoringOF", @@ -25,17 +25,17 @@ "soundDefaultContracts" : "soundDefaultContracts:on", "wdChecks" : "wdChecks:off", "wdOperator" : "wdOperator:L" - }, - "Labels" : { + }, + "Labels" : { "UseOriginLabels" : true - }, - "NewSMT" : { + }, + "NewSMT" : { - }, - "SMTSettings" : { - "SelectedTaclets" : [ + }, + "SMTSettings" : { + "SelectedTaclets" : [ - ], + ], "UseBuiltUniqueness" : false, "explicitTypeHierarchy" : false, "instantiateHierarchyAssumptions" : true, @@ -45,17 +45,16 @@ "maxGenericSorts" : 2, "useConstantsForBigOrSmallIntegers" : true, "useUninterpretedMultiplication" : true - }, - "Strategy" : { - "ActiveStrategy" : "JavaCardDLStrategy", + }, + "Strategy" : { + "ActiveStrategy" : "Modular JavaDL Strategy", "MaximumNumberOfAutomaticApplications" : 500, "Timeout" : -1, - "options" : { + "options" : { "AUTO_INDUCTION_OPTIONS_KEY" : "AUTO_INDUCTION_OFF", "BLOCK_OPTIONS_KEY" : "BLOCK_EXPAND", "CLASS_AXIOM_OPTIONS_KEY" : "CLASS_AXIOM_FREE", "DEP_OPTIONS_KEY" : "DEP_OFF", - "INF_FLOW_CHECK_PROPERTY" : "INF_FLOW_CHECK_FALSE", "LOOP_OPTIONS_KEY" : "LOOP_INVARIANT", "METHOD_OPTIONS_KEY" : "METHOD_EXPAND", "MPS_OPTIONS_KEY" : "MPS_MERGE", @@ -72,24 +71,27 @@ "USER_TACLETS_OPTIONS_KEY2" : "USER_TACLETS_OFF", "USER_TACLETS_OPTIONS_KEY3" : "USER_TACLETS_OFF", "VBT_PHASE" : "VBT_SYM_EX" - } - } - } + } + } +} + + \proofObligation -// Proof-Obligation settings -{ +// +{ "class" : "de.uka.ilkd.key.taclettranslation.lemma.TacletProofObligationInput", "name" : "equalityOfSingleton" - } +} \proof { (keyLog "0" (keyUser "ulbrich" ) (keyVersion "af00212456641ec51f1d89b225061fe018faa149")) +(keyLog "1" (keyUser "weigl" ) (keyVersion "1df32008ebda9fe2684e1a5eb5e44bdd4c398d8f")) -(autoModeTime "163") +(autoModeTime "175") (branch "dummy ID" -(rule "equalityToElementOf" (formula "1") (term "0") (inst "ov=ov") (inst "fv=fv") (userinteraction)) +(rule "equalityToElementOf" (formula "1") (term "0") (newnames "f_o1,f_f1,f_o2,f_f2") (inst "fv=fv") (inst "ov=ov") (userinteraction)) (rule "eqSymm" (formula "1") (term "0,1")) (rule "eqSymm" (formula "1") (term "1,1")) (rule "elementOfSingleton" (formula "1") (term "1,0,0,0")) @@ -117,18 +119,20 @@ (rule "eqSymm" (formula "2") (term "1,0")) (rule "commute_or" (formula "2") (term "0")) (builtin "One Step Simplification" (formula "2")) + (rule "castDel" (formula "2") (term "1")) (rule "replace_known_left" (formula "4") (term "0") (ifseqformula "2")) (builtin "One Step Simplification" (formula "4")) (rule "applyEqRigid" (formula "1") (term "1,0,1,0,0,0") (ifseqformula "2")) (rule "shift_paren_or" (formula "3") (term "0,0")) (builtin "One Step Simplification" (formula "3")) + (rule "castDel" (formula "3") (term "0")) (rule "eqSymm" (formula "3")) (rule "close" (formula "4") (ifseqformula "3")) ) (branch "Case '<-'" (rule "andLeft" (formula "1")) - (rule "allRight" (formula "3") (inst "sk=ov_0")) - (rule "allRight" (formula "3") (inst "sk=fv_0")) + (rule "allRight" (formula "3") (inst "sk=ov_0:java.lang.Object")) + (rule "allRight" (formula "3") (inst "sk=fv_0:Field")) (rule "applyEqRigid" (formula "3") (term "1,1,1") (ifseqformula "1")) (rule "applyEqRigid" (formula "3") (term "1,0,1") (ifseqformula "2")) (builtin "One Step Simplification" (formula "3")) diff --git a/key.core/tacletProofs/seqPerm/Taclet_seqPermFromSwap.proof b/key.core/tacletProofs/seqPerm/Taclet_seqPermFromSwap.proof index 7b2eb8e4a2f..4a4710620e3 100644 --- a/key.core/tacletProofs/seqPerm/Taclet_seqPermFromSwap.proof +++ b/key.core/tacletProofs/seqPerm/Taclet_seqPermFromSwap.proof @@ -1,75 +1,112 @@ \profile "Java Profile"; \settings { -"#Proof-Settings-Config-File -#Wed Apr 12 13:30:07 CEST 2023 -[Labels]UseOriginLabels=true -[StrategyProperty]QUERYAXIOM_OPTIONS_KEY=QUERYAXIOM_ON -[SMTSettings]invariantForall=false -[Strategy]ActiveStrategy=JavaCardDLStrategy -[StrategyProperty]USER_TACLETS_OPTIONS_KEY1=USER_TACLETS_OFF -[StrategyProperty]QUANTIFIERS_OPTIONS_KEY=QUANTIFIERS_NON_SPLITTING_WITH_PROGS -[StrategyProperty]USER_TACLETS_OPTIONS_KEY2=USER_TACLETS_OFF -[Choice]DefaultChoices=JavaCard-JavaCard\\:on, Strings-Strings\\:on, assertions-assertions\\:safe, bigint-bigint\\:on, floatRules-floatRules\\:strictfpOnly, initialisation-initialisation\\:disableStaticInitialisation, intRules-intRules\\:arithmeticSemanticsIgnoringOF, integerSimplificationRules-integerSimplificationRules\\:full, javaLoopTreatment-javaLoopTreatment\\:efficient, mergeGenerateIsWeakeningGoal-mergeGenerateIsWeakeningGoal\\:off, methodExpansion-methodExpansion\\:modularOnly, modelFields-modelFields\\:showSatisfiability, moreSeqRules-moreSeqRules\\:on, permissions-permissions\\:off, programRules-programRules\\:Java, reach-reach\\:on, runtimeExceptions-runtimeExceptions\\:ban, sequences-sequences\\:on, wdChecks-wdChecks\\:off, wdOperator-wdOperator\\:L -[StrategyProperty]LOOP_OPTIONS_KEY=LOOP_INVARIANT -[StrategyProperty]INF_FLOW_CHECK_PROPERTY=INF_FLOW_CHECK_FALSE -[SMTSettings]UseBuiltUniqueness=false -[SMTSettings]explicitTypeHierarchy=false -[SMTSettings]instantiateHierarchyAssumptions=true -[StrategyProperty]NON_LIN_ARITH_OPTIONS_KEY=NON_LIN_ARITH_COMPLETION -[SMTSettings]SelectedTaclets= -[StrategyProperty]DEP_OPTIONS_KEY=DEP_ON -[StrategyProperty]AUTO_INDUCTION_OPTIONS_KEY=AUTO_INDUCTION_OFF -[Strategy]MaximumNumberOfAutomaticApplications=2000 -[StrategyProperty]STOPMODE_OPTIONS_KEY=STOPMODE_DEFAULT -[StrategyProperty]CLASS_AXIOM_OPTIONS_KEY=CLASS_AXIOM_FREE -[SMTSettings]useConstantsForBigOrSmallIntegers=true -[StrategyProperty]MPS_OPTIONS_KEY=MPS_MERGE -[StrategyProperty]SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY=SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF -[Strategy]Timeout=-1 -[StrategyProperty]SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY=SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER -[StrategyProperty]QUERY_NEW_OPTIONS_KEY=QUERY_OFF -[SMTSettings]useUninterpretedMultiplication=true -[StrategyProperty]BLOCK_OPTIONS_KEY=BLOCK_CONTRACT_INTERNAL -[StrategyProperty]METHOD_OPTIONS_KEY=METHOD_CONTRACT -[StrategyProperty]USER_TACLETS_OPTIONS_KEY3=USER_TACLETS_OFF -[SMTSettings]maxGenericSorts=2 -[StrategyProperty]OSS_OPTIONS_KEY=OSS_ON -[StrategyProperty]SPLITTING_OPTIONS_KEY=SPLITTING_DELAYED -[SMTSettings]integersMinimum=-2147483645 -[StrategyProperty]VBT_PHASE=VBT_SYM_EX -[SMTSettings]integersMaximum=2147483645 -" -} + "Choice" : { + "JavaCard" : "JavaCard:on", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "finalFields" : "finalFields:immutable", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:arithmeticSemanticsIgnoringOF", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:showSatisfiability", + "moreSeqRules" : "moreSeqRules:on", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "soundDefaultContracts" : "soundDefaultContracts:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + }, + "Labels" : { + "UseOriginLabels" : true + }, + "NewSMT" : { + + }, + "SMTSettings" : { + "SelectedTaclets" : [ + + ], + "UseBuiltUniqueness" : false, + "explicitTypeHierarchy" : false, + "instantiateHierarchyAssumptions" : true, + "integersMaximum" : 2147483645, + "integersMinimum" : -2147483645, + "invariantForall" : false, + "maxGenericSorts" : 2, + "useConstantsForBigOrSmallIntegers" : true, + "useUninterpretedMultiplication" : true + }, + "Strategy" : { + "ActiveStrategy" : "Modular JavaDL Strategy", + "MaximumNumberOfAutomaticApplications" : 2000, + "Timeout" : -1, + "options" : { + "AUTO_INDUCTION_OPTIONS_KEY" : "AUTO_INDUCTION_OFF", + "BLOCK_OPTIONS_KEY" : "BLOCK_CONTRACT_INTERNAL", + "CLASS_AXIOM_OPTIONS_KEY" : "CLASS_AXIOM_FREE", + "DEP_OPTIONS_KEY" : "DEP_ON", + "LOOP_OPTIONS_KEY" : "LOOP_INVARIANT", + "METHOD_OPTIONS_KEY" : "METHOD_CONTRACT", + "MPS_OPTIONS_KEY" : "MPS_MERGE", + "NON_LIN_ARITH_OPTIONS_KEY" : "NON_LIN_ARITH_COMPLETION", + "OSS_OPTIONS_KEY" : "OSS_ON", + "QUANTIFIERS_OPTIONS_KEY" : "QUANTIFIERS_NON_SPLITTING_WITH_PROGS", + "QUERYAXIOM_OPTIONS_KEY" : "QUERYAXIOM_ON", + "QUERY_NEW_OPTIONS_KEY" : "QUERY_OFF", + "SPLITTING_OPTIONS_KEY" : "SPLITTING_DELAYED", + "STOPMODE_OPTIONS_KEY" : "STOPMODE_DEFAULT", + "SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER", + "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF", + "USER_TACLETS_OPTIONS_KEY1" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY2" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY3" : "USER_TACLETS_OFF", + "VBT_PHASE" : "VBT_SYM_EX" + } + } +} + + -\proofObligation { - "name": "seqPermFromSwap", - "class": "de.uka.ilkd.key.taclettranslation.lemma.TacletProofObligationInput", - } +\proofObligation +// +{ + "class" : "de.uka.ilkd.key.taclettranslation.lemma.TacletProofObligationInput", + "name" : "seqPermFromSwap" +} \proof { (keyLog "0" (keyUser "Julian" ) (keyVersion "80a871ca3bac8bb405ecc216fcb6fa9ef6f8a395")) +(keyLog "1" (keyUser "weigl" ) (keyVersion "1df32008ebda9fe2684e1a5eb5e44bdd4c398d8f")) -(autoModeTime "0") +(autoModeTime "849") (branch "dummy ID" (rule "impRight" (formula "1") (newnames "f_t1,f_t2,v_iv,v_jv,f_s2,f_s1")) (rule "orRight" (formula "2")) (rule "andLeft" (formula "1")) (rule "notRight" (formula "4")) -(rule "exLeft" (formula "3") (inst "sk=v_iv_1") (userinteraction)) -(rule "exLeft" (formula "3") (inst "sk=v_jv_1") (userinteraction)) +(rule "exLeft" (formula "3") (inst "sk=v_iv_1:int") (userinteraction)) +(rule "exLeft" (formula "3") (inst "sk=v_jv_1:int") (userinteraction)) (rule "andLeft" (formula "3")) (rule "andLeft" (formula "3")) (rule "andLeft" (formula "3")) (rule "andLeft" (formula "3")) (rule "defOfSeqSwap" (formula "7") (term "1") (inst "uSub=uSub") (userinteraction)) -(rule "seqPermDefLeft" (formula "1") (inst "s=s") (inst "iv=iv") (userinteraction)) +(rule "seqPermDefLeft" (formula "1") (inst "iv=iv") (inst "s=s") (userinteraction)) (rule "andLeft" (formula "1")) -(rule "seqPermDef" (formula "10") (inst "s=s") (inst "iv=iv") (userinteraction)) +(rule "seqPermDef" (formula "10") (inst "iv=iv") (inst "s=s") (userinteraction)) (rule "andRight" (formula "10") (userinteraction)) -(branch - (rule "exLeft" (formula "2") (inst "sk=s_0")) +(branch "Case 1" + (rule "exLeft" (formula "2") (inst "sk=s_0:Seq")) (rule "andLeft" (formula "2")) (rule "andLeft" (formula "2")) (rule "eqSymm" (formula "1")) @@ -125,8 +162,8 @@ (rule "closeFalse" (formula "11")) ) ) -(branch - (rule "exLeft" (formula "2") (inst "sk=s_1") (userinteraction)) +(branch "Case 2" + (rule "exLeft" (formula "2") (inst "sk=s_1:Seq") (userinteraction)) (rule "andLeft" (formula "2")) (rule "andLeft" (formula "2")) (rule "exRightHide" (formula "12") (inst "t=seqDef{int u;}(Z(0(#)), @@ -137,11 +174,11 @@ \\then (any::seqGet(s_1, v_iv_1)) \\else (any::seqGet(s_1, - u))))") (userinteraction)) + u)))):Seq") (userinteraction)) (rule "andRight" (formula "12") (userinteraction)) - (branch + (branch "Case 1" (rule "andRight" (formula "12") (userinteraction)) - (branch + (branch "Case 1" (rule "eqSymm" (formula "1")) (rule "eqSymm" (formula "11")) (rule "replace_known_left" (formula "11") (term "1,0,0,2,0") (ifseqformula "10")) @@ -218,10 +255,10 @@ (rule "closeFalse" (formula "9")) ) ) - (branch + (branch "Case 2" (rule "seqNPermDefLeft" (formula "3") (inst "iv=iv") (inst "jv=jv") (userinteraction)) (rule "seqNPermDefReplace" (formula "13") (inst "iv=iv") (inst "jv=jv") (userinteraction)) - (rule "allRight" (formula "13") (inst "sk=iv_2") (userinteraction)) + (rule "allRight" (formula "13") (inst "sk=iv_2:int") (userinteraction)) (rule "impRight" (formula "13") (userinteraction)) (rule "andLeft" (formula "1")) (rule "lenOfSeqDef" (formula "2") (term "1")) @@ -271,12 +308,12 @@ (rule "cut_direct" (formula "1") (term "1,0") (userinteraction)) (branch "CUT: iv_2 < s_1.length TRUE" (builtin "One Step Simplification" (formula "2")) - (rule "exLeft" (formula "2") (inst "sk=jv_1") (userinteraction)) + (rule "exLeft" (formula "2") (inst "sk=jv_1:int") (userinteraction)) (rule "andLeft" (formula "2")) (rule "andLeft" (formula "2")) (rule "cut" (inst "cutFormula=jv_1 = v_iv_1") (userinteraction)) (branch "CUT: jv_1 = v_iv_1 TRUE" - (rule "exRightHide" (formula "22") (inst "t=v_jv_1") (userinteraction)) + (rule "exRightHide" (formula "22") (inst "t=v_jv_1:int") (userinteraction)) (rule "replace_known_left" (formula "22") (term "0,0") (ifseqformula "18") (userinteraction)) (rule "cut_direct" (formula "22") (term "1,0") (userinteraction)) (branch "CUT: v_jv_1 <= f_s1.length + -1 TRUE" @@ -427,7 +464,7 @@ (branch "CUT: jv_1 = v_iv_1 FALSE" (rule "cut" (inst "cutFormula=jv_1 = v_jv_1") (userinteraction)) (branch "CUT: jv_1 = v_jv_1 TRUE" - (rule "exRightHide" (formula "23") (inst "t=v_iv_1") (userinteraction)) + (rule "exRightHide" (formula "23") (inst "t=v_iv_1:int") (userinteraction)) (rule "eqSymm" (formula "21")) (rule "eqSymm" (formula "10")) (rule "eqSymm" (formula "1")) @@ -712,8 +749,8 @@ ) ) ) - (branch - (rule "allRight" (formula "12") (inst "sk=iv_0")) + (branch "Case 2" + (rule "allRight" (formula "12") (inst "sk=iv_0:int")) (rule "impRight" (formula "12")) (rule "andLeft" (formula "1")) (rule "eqSymm" (formula "13")) @@ -886,31 +923,79 @@ (rule "inEqSimp_commuteGeq" (formula "8") (term "1,0")) (rule "inEqSimp_contradInEq1" (formula "8") (term "1,0") (ifseqformula "15")) (rule "inEqSimp_homoInEq1" (formula "8") (term "0,1,0")) + (rule "castDel" (formula "8") (term "1,1,0,1")) + (rule "castDel" (formula "8") (term "0,1,0,0,1,0")) + (rule "castDel" (formula "8") (term "1,1,1,0")) + (rule "castDel" (formula "8") (term "0,0,0")) (rule "polySimp_pullOutFactor1b" (formula "8") (term "0,0,1,0")) (rule "add_literals" (formula "8") (term "1,1,0,0,1,0")) (rule "times_zero_1" (formula "8") (term "1,0,0,1,0")) - (rule "add_zero_right" (formula "8") (term "0,0,1,0")) + (rule "add_literals" (formula "8") (term "0,0,1,0")) (rule "leq_literals" (formula "8") (term "0,1,0")) (builtin "One Step Simplification" (formula "8")) + (rule "applyEq" (formula "17") (term "1,1,2,2,0") (ifseqformula "1")) + (rule "applyEqRigid" (formula "13") (term "0") (ifseqformula "1")) + (rule "applyEq" (formula "10") (term "1,1,1,0") (ifseqformula "6")) + (rule "applyEqRigid" (formula "3") (term "0,0,0") (ifseqformula "6")) + (rule "applyEq" (formula "3") (term "1,0") (ifseqformula "6")) + (rule "applyEqRigid" (formula "4") (term "1") (ifseqformula "6")) + (rule "applyEq" (formula "16") (term "1,0,2,0") (ifseqformula "1")) (rule "inEqSimp_contradInEq1" (formula "8") (term "0") (ifseqformula "2")) (rule "qeq_literals" (formula "8") (term "0,0")) (builtin "One Step Simplification" (formula "8")) + (rule "commute_or" (formula "10") (term "0")) (rule "shift_paren_or" (formula "9") (term "0,0")) + (rule "commute_or_2" (formula "9") (term "0")) + (rule "commute_or_2" (formula "9") (term "0,0")) + (rule "commute_or" (formula "10") (term "1,1,0")) + (rule "commute_or" (formula "9") (term "0,0,0")) + (rule "commute_or_2" (formula "9") (term "0,0")) + (rule "cnf_rightDist" (formula "10") (term "0")) + (rule "distr_forallAnd" (formula "10")) + (rule "andLeft" (formula "10")) + (rule "commute_or_2" (formula "10") (term "0")) + (rule "shift_paren_or" (formula "11") (term "0")) + (rule "commute_or_2" (formula "11") (term "0,0")) + (rule "inEqSimp_or_tautInEq1" (formula "11") (term "0")) + (rule "inEqSimp_homoInEq1" (formula "11") (term "1,0")) + (rule "polySimp_pullOutFactor1" (formula "11") (term "0,1,0")) + (rule "add_literals" (formula "11") (term "1,0,1,0")) + (rule "times_zero_1" (formula "11") (term "0,1,0")) + (rule "leq_literals" (formula "11") (term "1,0")) + (builtin "One Step Simplification" (formula "11")) + (rule "true_left" (formula "11")) + (rule "shift_paren_or" (formula "10") (term "0,0")) + (rule "commute_or" (formula "10") (term "0,0,0")) + (rule "inEqSimp_or_tautInEq1" (formula "10") (term "0,0")) + (rule "add_literals" (formula "10") (term "1,1,0,0")) + (rule "qeq_literals" (formula "10") (term "1,0,0")) + (builtin "One Step Simplification" (formula "10")) + (rule "true_left" (formula "10")) + (rule "ifthenelse_to_or_left" (formula "9") (term "0,0,0,0")) + (rule "eqSymm" (formula "9") (term "1,1,0,0,0,0")) + (rule "eqSymm" (formula "9") (term "1,0,0,0,0,0")) (rule "commute_or" (formula "9") (term "0,0,0")) - (rule "ifthenelse_to_or_left" (formula "9") (term "1,0")) - (rule "eqSymm" (formula "9") (term "1,0,1,0")) - (rule "eqSymm" (formula "9") (term "1,1,1,0")) + (rule "commute_or_2" (formula "9") (term "0,0")) + (rule "commute_or_2" (formula "9") (term "0")) + (rule "commute_or" (formula "9") (term "1,1,0")) + (rule "commute_or" (formula "9") (term "0,1,0")) (rule "cnf_rightDist" (formula "9") (term "0")) (rule "distr_forallAnd" (formula "9")) (rule "andLeft" (formula "9")) + (rule "shift_paren_or" (formula "10") (term "0")) (rule "shift_paren_or" (formula "9") (term "0")) - (rule "commute_or_2" (formula "9") (term "0")) - (builtin "One Step Simplification" (formula "9") (ifInst "" (formula "19"))) + (builtin "One Step Simplification" (formula "9")) + (rule "castDel" (formula "9") (term "0,1,0,0")) + (rule "castDel" (formula "9") (term "0,0,0,0")) + (rule "castDel" (formula "9") (term "1,1,0,1")) + (rule "castDel" (formula "9") (term "0,1,0")) + (rule "replace_known_right" (formula "9") (term "1") (ifseqformula "17")) + (builtin "One Step Simplification" (formula "9")) (rule "inEqSimp_commuteGeq" (formula "9") (term "1")) - (rule "inEqSimp_contradInEq1" (formula "9") (term "0,0") (ifseqformula "15")) + (rule "inEqSimp_contradInEq1" (formula "9") (term "0,0") (ifseqformula "13")) (rule "qeq_literals" (formula "9") (term "0,0,0")) (builtin "One Step Simplification" (formula "9")) - (rule "inEqSimp_contradInEq1" (formula "9") (term "1") (ifseqformula "17")) + (rule "inEqSimp_contradInEq1" (formula "9") (term "1") (ifseqformula "15")) (rule "inEqSimp_homoInEq1" (formula "9") (term "0,1")) (rule "polySimp_pullOutFactor1b" (formula "9") (term "0,0,1")) (rule "add_literals" (formula "9") (term "1,1,0,0,1")) @@ -918,11 +1003,15 @@ (rule "add_zero_right" (formula "9") (term "0,0,1")) (rule "leq_literals" (formula "9") (term "0,1")) (builtin "One Step Simplification" (formula "9")) - (rule "applyEq" (formula "19") (term "1,1,0") (ifseqformula "9")) - (rule "applyEqRigid" (formula "19") (term "0") (ifseqformula "8")) - (rule "applyEqRigid" (formula "19") (term "1,0") (ifseqformula "9")) - (builtin "One Step Simplification" (formula "19")) - (rule "closeTrue" (formula "19")) + (rule "applyEqRigid" (formula "13") (term "0") (ifseqformula "9")) + (rule "applyEq" (formula "16") (term "1,1,0") (ifseqformula "9")) + (rule "applyEqRigid" (formula "15") (term "1,1,2,0") (ifseqformula "9")) + (rule "applyEq" (formula "14") (term "1,1") (ifseqformula "9")) + (rule "applyEqRigid" (formula "15") (term "0") (ifseqformula "8")) + (rule "applyEq" (formula "14") (term "1,0,2,2,0") (ifseqformula "9")) + (rule "applyEq" (formula "15") (term "1,0") (ifseqformula "9")) + (builtin "One Step Simplification" (formula "15")) + (rule "closeTrue" (formula "15")) ) (branch "f_s2.length >= 0 FALSE" (rule "eqSymm" (formula "5")) @@ -958,6 +1047,11 @@ (rule "commute_or_2" (formula "7") (term "0")) (builtin "One Step Simplification" (formula "7")) (rule "inEqSimp_commuteGeq" (formula "7") (term "1,0")) + (rule "castDel" (formula "7") (term "1,1,0,1")) + (rule "castDel" (formula "7") (term "1,1,0")) + (rule "castDel" (formula "7") (term "0,0,0")) + (rule "applyEq" (formula "9") (term "1,1,1,0") (ifseqformula "5")) + (rule "applyEqRigid" (formula "3") (term "1") (ifseqformula "5")) (rule "inEqSimp_contradInEq1" (formula "7") (term "0,0") (ifseqformula "12")) (rule "qeq_literals" (formula "7") (term "0,0,0")) (builtin "One Step Simplification" (formula "7")) @@ -969,65 +1063,308 @@ (rule "add_literals" (formula "7") (term "0,0,0")) (rule "leq_literals" (formula "7") (term "0,0")) (builtin "One Step Simplification" (formula "7")) + (rule "commute_or" (formula "9") (term "0")) (rule "shift_paren_or" (formula "8") (term "0,0")) + (rule "commute_or_2" (formula "8") (term "0")) + (rule "commute_or_2" (formula "8") (term "0,0")) + (rule "commute_or" (formula "9") (term "1,1,0")) (rule "commute_or" (formula "8") (term "0,0,0")) - (rule "ifthenelse_to_or_left" (formula "8") (term "1,0")) - (rule "eqSymm" (formula "8") (term "1,0,1,0")) - (rule "eqSymm" (formula "8") (term "1,1,1,0")) - (rule "cnf_rightDist" (formula "8") (term "0")) - (rule "distr_forallAnd" (formula "8")) - (rule "andLeft" (formula "8")) + (rule "commute_or_2" (formula "8") (term "0,0")) + (rule "cnf_rightDist" (formula "9") (term "0")) + (rule "distr_forallAnd" (formula "9")) + (rule "andLeft" (formula "9")) (rule "commute_or_2" (formula "9") (term "0")) + (rule "shift_paren_or" (formula "10") (term "0")) + (rule "commute_or_2" (formula "10") (term "0,0")) + (rule "inEqSimp_or_tautInEq1" (formula "10") (term "0")) + (rule "inEqSimp_homoInEq1" (formula "10") (term "1,0")) + (rule "polySimp_pullOutFactor1" (formula "10") (term "0,1,0")) + (rule "add_literals" (formula "10") (term "1,0,1,0")) + (rule "times_zero_1" (formula "10") (term "0,1,0")) + (rule "leq_literals" (formula "10") (term "1,0")) + (builtin "One Step Simplification" (formula "10")) + (rule "true_left" (formula "10")) (rule "shift_paren_or" (formula "9") (term "0,0")) (rule "commute_or" (formula "9") (term "0,0,0")) - (rule "ifthenelse_split" (formula "19") (term "0,1,1,0")) - (branch "v_jv_1 = iv_0 TRUE" - (rule "castedGetAny" (formula "20") (term "1,1,0")) - (rule "applyEq" (formula "17") (term "1,1") (ifseqformula "1")) - (rule "replace_known_left" (formula "20") (term "0,1,0") (ifseqformula "17")) - (builtin "One Step Simplification" (formula "20")) - (rule "applyEq" (formula "20") (term "0") (ifseqformula "8")) - (rule "applyEqRigid" (formula "20") (term "1,0") (ifseqformula "1")) - (builtin "One Step Simplification" (formula "20")) - (rule "closeTrue" (formula "20")) - ) - (branch "v_jv_1 = iv_0 FALSE" - (rule "castedGetAny" (formula "20") (term "1,1,0")) - (rule "ifthenelse_split" (formula "2") (term "0")) - (branch "f_s2.length >= 1 TRUE" - (rule "replace_known_left" (formula "21") (term "0,1,0") (ifseqformula "3")) - (builtin "One Step Simplification" (formula "21")) - (rule "allLeft" (formula "10") (inst "t=iv_0")) - (rule "eqSymm" (formula "10") (term "1,0,0,0")) - (rule "eqSymm" (formula "10") (term "1,0,0")) - (rule "replace_known_right" (formula "10") (term "1") (ifseqformula "22")) - (builtin "One Step Simplification" (formula "10") (ifInst "" (formula "20")) (ifInst "" (formula "21"))) - (rule "inEqSimp_commuteGeq" (formula "10") (term "1")) - (rule "inEqSimp_contradInEq1" (formula "10") (term "1") (ifseqformula "3")) - (rule "inEqSimp_homoInEq1" (formula "10") (term "0,1")) - (rule "polySimp_pullOutFactor1b" (formula "10") (term "0,0,1")) - (rule "add_literals" (formula "10") (term "1,1,0,0,1")) - (rule "times_zero_1" (formula "10") (term "1,0,0,1")) - (rule "add_zero_right" (formula "10") (term "0,0,1")) - (rule "leq_literals" (formula "10") (term "0,1")) - (builtin "One Step Simplification" (formula "10")) - (rule "inEqSimp_contradInEq1" (formula "10") (ifseqformula "1")) - (rule "qeq_literals" (formula "10") (term "0")) - (builtin "One Step Simplification" (formula "10")) - (rule "closeFalse" (formula "10")) + (rule "inEqSimp_or_tautInEq1" (formula "9") (term "0,0")) + (rule "add_literals" (formula "9") (term "1,1,0,0")) + (rule "qeq_literals" (formula "9") (term "1,0,0")) + (builtin "One Step Simplification" (formula "9")) + (rule "true_left" (formula "9")) + (rule "ifthenelse_to_or_left" (formula "8") (term "0,0,0,0")) + (rule "eqSymm" (formula "8") (term "1,1,0,0,0,0")) + (rule "eqSymm" (formula "8") (term "1,0,0,0,0,0")) + (rule "commute_or" (formula "8") (term "0,0,0")) + (rule "commute_or_2" (formula "8") (term "0,0")) + (rule "commute_or_2" (formula "8") (term "0")) + (rule "commute_or" (formula "8") (term "0,1,0")) + (rule "commute_or" (formula "8") (term "1,1,0")) + (rule "cnf_rightDist" (formula "8") (term "0")) + (rule "distr_forallAnd" (formula "8")) + (rule "andLeft" (formula "8")) + (rule "shift_paren_or" (formula "8") (term "0")) + (builtin "One Step Simplification" (formula "8")) + (rule "castDel" (formula "8") (term "0,1,0,0")) + (rule "castDel" (formula "8") (term "1,1,0,1")) + (rule "castDel" (formula "8") (term "0,0,0,0")) + (rule "castDel" (formula "8") (term "0,1,0")) + (rule "inEqSimp_commuteGeq" (formula "8") (term "1,0")) + (rule "inEqSimp_contradInEq1" (formula "8") (term "0,0,0") (ifseqformula "13")) + (rule "qeq_literals" (formula "8") (term "0,0,0,0")) + (builtin "One Step Simplification" (formula "8")) + (rule "inEqSimp_contradInEq1" (formula "8") (term "1,0") (ifseqformula "15")) + (rule "inEqSimp_homoInEq1" (formula "8") (term "0,1,0")) + (rule "polySimp_pullOutFactor1b" (formula "8") (term "0,0,1,0")) + (rule "add_literals" (formula "8") (term "1,1,0,0,1,0")) + (rule "times_zero_1" (formula "8") (term "1,0,0,1,0")) + (rule "add_literals" (formula "8") (term "0,0,1,0")) + (rule "leq_literals" (formula "8") (term "0,1,0")) + (builtin "One Step Simplification" (formula "8")) + (rule "commute_or" (formula "8")) + (rule "shift_paren_or" (formula "9") (term "0")) + (rule "commute_or_2" (formula "9") (term "0,0")) + (rule "shift_paren_or" (formula "9") (term "0,0,0")) + (rule "ifthenelse_split" (formula "2") (term "0")) + (branch "geq(seqLen(f_s2), Z(1(#))) TRUE" + (rule "replace_known_left" (formula "19") (term "0,1,0") (ifseqformula "3")) + (builtin "One Step Simplification" (formula "19")) + (rule "inEqSimp_subsumption1" (formula "5") (ifseqformula "2")) + (rule "leq_literals" (formula "5") (term "0")) + (builtin "One Step Simplification" (formula "5")) + (rule "true_left" (formula "5")) + (rule "equalityToSeqGetAndSeqLenLeft" (formula "16") (inst "iv=iv")) + (rule "andLeft" (formula "16")) + (rule "lenOfSeqDef" (formula "17") (term "1,1,0,0")) + (rule "polySimp_elimSub" (formula "17") (term "1,1,1,0,0")) + (rule "mul_literals" (formula "17") (term "1,1,1,1,0,0")) + (rule "add_zero_right" (formula "17") (term "1,1,1,0,0")) + (rule "getOfSeqDef" (formula "17") (term "0,1,0")) + (rule "castDel" (formula "17") (term "2,0,1,0")) + (rule "castDel" (formula "17") (term "1,0,1,0")) + (rule "add_zero_right" (formula "17") (term "0,0,1,0,1,0")) + (rule "add_zero_right" (formula "17") (term "0,0,2,1,0,1,0")) + (rule "add_zero_right" (formula "17") (term "1,2,2,1,0,1,0")) + (rule "polySimp_elimSub" (formula "17") (term "1,1,0,0,1,0")) + (rule "mul_literals" (formula "17") (term "1,1,1,0,0,1,0")) + (rule "add_zero_right" (formula "17") (term "1,1,0,0,1,0")) + (rule "lenOfSeqDef" (formula "16") (term "0")) + (rule "polySimp_elimSub" (formula "16") (term "1,0")) + (rule "times_zero_2" (formula "16") (term "1,1,0")) + (rule "add_zero_right" (formula "16") (term "1,0")) + (rule "lenOfSeqDefEQ" (formula "16") (term "1") (ifseqformula "18")) + (rule "polySimp_elimSub" (formula "16") (term "1,1")) + (rule "mul_literals" (formula "16") (term "1,1,1")) + (rule "add_zero_right" (formula "16") (term "1,1")) + (rule "inEqSimp_ltToLeq" (formula "17") (term "0,1,1,0,0")) + (rule "add_zero_right" (formula "17") (term "0,0,1,1,0,0")) + (rule "polySimp_mulComm0" (formula "17") (term "1,0,0,1,1,0,0")) + (rule "inEqSimp_ltToLeq" (formula "17") (term "1,0,0,1,0")) + (rule "polySimp_mulComm0" (formula "17") (term "1,0,0,1,0,0,1,0")) + (rule "inEqSimp_ltToLeq" (formula "16") (term "0,0")) + (rule "add_zero_right" (formula "16") (term "0,0,0")) + (rule "polySimp_mulComm0" (formula "16") (term "1,0,0,0")) + (rule "inEqSimp_ltToLeq" (formula "17") (term "1,0,0")) + (rule "polySimp_mulComm0" (formula "17") (term "1,0,0,1,0,0")) + (rule "inEqSimp_commuteLeq" (formula "17") (term "0,0,0")) + (rule "inEqSimp_commuteLeq" (formula "17") (term "0,0,0,1,0")) + (rule "inEqSimp_commuteLeq" (formula "16") (term "0,1")) + (rule "applyEq" (formula "17") (term "0,1,0,0,1,0,0") (ifseqformula "16")) + (rule "inEqSimp_sepPosMonomial0" (formula "17") (term "1,0,0,1,0")) + (rule "polySimp_mulComm0" (formula "17") (term "1,1,0,0,1,0")) + (rule "polySimp_rightDist" (formula "17") (term "1,1,0,0,1,0")) + (rule "polySimp_mulLiterals" (formula "17") (term "1,1,1,0,0,1,0")) + (rule "mul_literals" (formula "17") (term "0,1,1,0,0,1,0")) + (rule "polySimp_elimOne" (formula "17") (term "1,1,1,0,0,1,0")) + (rule "inEqSimp_sepNegMonomial0" (formula "16") (term "0,0")) + (rule "polySimp_mulLiterals" (formula "16") (term "0,0,0")) + (rule "polySimp_elimOne" (formula "16") (term "0,0,0")) + (rule "replace_known_left" (formula "16") (term "0,0") (ifseqformula "2")) + (builtin "One Step Simplification" (formula "16")) + (rule "eqSymm" (formula "16")) + (builtin "One Step Simplification" (formula "16")) + (rule "eqSymm" (formula "16") (term "1")) + (rule "inEqSimp_sepPosMonomial0" (formula "17") (term "1,0,0")) + (rule "polySimp_mulComm0" (formula "17") (term "1,1,0,0")) + (rule "polySimp_rightDist" (formula "17") (term "1,1,0,0")) + (rule "polySimp_mulLiterals" (formula "17") (term "1,1,1,0,0")) + (rule "mul_literals" (formula "17") (term "0,1,1,0,0")) + (rule "polySimp_elimOne" (formula "17") (term "1,1,1,0,0")) + (rule "inEqSimp_contradEq7" (formula "16") (term "1") (ifseqformula "2")) + (rule "mul_literals" (formula "16") (term "1,0,0,1")) + (rule "add_literals" (formula "16") (term "0,0,1")) + (rule "leq_literals" (formula "16") (term "0,1")) + (builtin "One Step Simplification" (formula "16")) + (rule "replace_known_left" (formula "17") (term "0,1,1,1,0,0") (ifseqformula "16")) + (builtin "One Step Simplification" (formula "17")) + (rule "inEqSimp_subsumption1" (formula "16") (ifseqformula "2")) + (rule "leq_literals" (formula "16") (term "0")) + (builtin "One Step Simplification" (formula "16")) + (rule "true_left" (formula "16")) + (rule "getOfSeqDefEQ" (formula "16") (term "1,1,0") (ifseqformula "17")) + (rule "castDel" (formula "16") (term "1,1,1,0")) + (rule "castDel" (formula "16") (term "2,1,1,0")) + (rule "add_zero_right" (formula "16") (term "0,0,1,1,1,0")) + (rule "add_zero_right" (formula "16") (term "1,2,2,1,1,1,0")) + (rule "add_zero_right" (formula "16") (term "0,0,2,1,1,1,0")) + (rule "eqSymm" (formula "16") (term "1,0")) + (rule "polySimp_elimSub" (formula "16") (term "1,1,0,0,1,0")) + (rule "mul_literals" (formula "16") (term "1,1,1,0,0,1,0")) + (rule "add_zero_right" (formula "16") (term "1,1,0,0,1,0")) + (rule "inEqSimp_ltToLeq" (formula "16") (term "1,0,0,1,0")) + (rule "polySimp_mulComm0" (formula "16") (term "1,0,0,1,0,0,1,0")) + (rule "inEqSimp_commuteLeq" (formula "16") (term "0,0,0,1,0")) + (rule "inEqSimp_sepPosMonomial0" (formula "16") (term "1,0,0,1,0")) + (rule "polySimp_mulComm0" (formula "16") (term "1,1,0,0,1,0")) + (rule "polySimp_rightDist" (formula "16") (term "1,1,0,0,1,0")) + (rule "mul_literals" (formula "16") (term "0,1,1,0,0,1,0")) + (rule "polySimp_mulLiterals" (formula "16") (term "1,1,1,0,0,1,0")) + (rule "polySimp_elimOne" (formula "16") (term "1,1,1,0,0,1,0")) + (builtin "One Step Simplification" (formula "16")) + (rule "true_left" (formula "16")) + (rule "lenNonNegative" (formula "15") (term "0")) + (rule "inEqSimp_commuteLeq" (formula "15")) + (rule "inEqSimp_subsumption1" (formula "15") (ifseqformula "2")) + (rule "leq_literals" (formula "15") (term "0")) + (builtin "One Step Simplification" (formula "15")) + (rule "true_left" (formula "15")) + (rule "lenNonNegative" (formula "5") (term "0")) + (rule "inEqSimp_commuteLeq" (formula "5")) + (rule "applyEq" (formula "5") (term "0") (ifseqformula "6")) + (rule "inEqSimp_subsumption1" (formula "5") (ifseqformula "2")) + (rule "leq_literals" (formula "5") (term "0")) + (builtin "One Step Simplification" (formula "5")) + (rule "true_left" (formula "5")) + (rule "equalityToSeqGetAndSeqLenLeft" (formula "11") (inst "iv=iv")) + (rule "andLeft" (formula "11")) + (rule "inEqSimp_ltToLeq" (formula "12") (term "1,0,0")) + (rule "polySimp_mulComm0" (formula "12") (term "1,0,0,1,0,0")) + (rule "inEqSimp_commuteLeq" (formula "12") (term "0,0,0")) + (rule "applyEq" (formula "11") (term "0,0") (ifseqformula "13")) + (builtin "One Step Simplification" (formula "11")) + (rule "true_left" (formula "11")) + (rule "applyEq" (formula "11") (term "0,0,1,0") (ifseqformula "12")) + (builtin "One Step Simplification" (formula "11")) + (rule "true_left" (formula "11")) + (rule "seqGetAlphaCast" (formula "16") (term "1,2,2,0")) + (rule "castDel" (formula "16") (term "0")) + (builtin "One Step Simplification" (formula "16")) + (rule "true_left" (formula "16")) + (rule "lenNonNegative" (formula "4") (term "0")) + (rule "inEqSimp_commuteLeq" (formula "4")) + (rule "applyEqRigid" (formula "4") (term "0") (ifseqformula "5")) + (rule "inEqSimp_subsumption1" (formula "4") (ifseqformula "2")) + (rule "leq_literals" (formula "4") (term "0")) + (builtin "One Step Simplification" (formula "4")) + (rule "true_left" (formula "4")) + (rule "seqGetAlphaCast" (formula "16") (term "1,2,0")) + (rule "castDel" (formula "16") (term "0")) + (builtin "One Step Simplification" (formula "16")) + (rule "true_left" (formula "16")) + (rule "ifthenelse_split" (formula "18") (term "0,1,0")) + (branch "v_jv_1 = iv_0 TRUE" + (rule "castedGetAny" (formula "19") (term "1,0")) + (rule "applyEqRigid" (formula "14") (term "0") (ifseqformula "1")) + (rule "applyEqRigid" (formula "9") (term "0,1") (ifseqformula "1")) + (rule "eqSymm" (formula "9") (term "1")) + (rule "replace_known_right" (formula "9") (term "1") (ifseqformula "17")) + (builtin "One Step Simplification" (formula "9")) + (rule "applyEqRigid" (formula "15") (term "1,1") (ifseqformula "1")) + (rule "applyEqRigid" (formula "15") (term "1,1,2,0") (ifseqformula "1")) + (rule "applyEq" (formula "17") (term "0") (ifseqformula "8")) + (rule "applyEqRigid" (formula "17") (term "1,0") (ifseqformula "1")) + (builtin "One Step Simplification" (formula "17")) + (rule "closeTrue" (formula "17")) ) - (branch "f_s2.length >= 1 FALSE" - (rule "inEqSimp_homoInEq1" (formula "2")) - (rule "times_zero_2" (formula "2") (term "1,0")) - (rule "add_zero_right" (formula "2") (term "0")) - (rule "inEqSimp_sepPosMonomial0" (formula "2")) - (rule "mul_literals" (formula "2") (term "1")) - (rule "inEqSimp_contradInEq0" (formula "1") (ifseqformula "2")) - (rule "qeq_literals" (formula "1") (term "0")) - (builtin "One Step Simplification" (formula "1")) - (rule "closeFalse" (formula "1")) + (branch "v_jv_1 = iv_0 FALSE" + (rule "castedGetAny" (formula "19") (term "1,0")) + (rule "seqGetAlphaCast" (formula "7") (term "1,0")) + (rule "castedGetAny" (formula "7") (term "0")) + (builtin "One Step Simplification" (formula "7")) + (rule "true_left" (formula "7")) + (rule "seqGetAlphaCast" (formula "7") (term "0")) + (rule "castDel" (formula "7") (term "0")) + (builtin "One Step Simplification" (formula "7")) + (rule "true_left" (formula "7")) + (rule "seqGetAlphaCast" (formula "8") (term "0,0")) + (rule "castDel" (formula "8") (term "0")) + (builtin "One Step Simplification" (formula "8")) + (rule "true_left" (formula "8")) + (rule "cut_direct" (formula "8") (term "1")) + (branch "CUT: v_jv_1 = v_iv_1 TRUE" + (builtin "One Step Simplification" (formula "9")) + (rule "true_left" (formula "9")) + (rule "applyEqRigid" (formula "13") (term "0") (ifseqformula "8")) + (rule "applyEqRigid" (formula "17") (term "0") (ifseqformula "8")) + (rule "applyEq" (formula "15") (term "1,1,2,0") (ifseqformula "8")) + (rule "applyEqRigid" (formula "14") (term "1,1") (ifseqformula "8")) + (rule "applyEqRigid" (formula "9") (term "1,1,0,0") (ifseqformula "8")) + (builtin "One Step Simplification" (formula "9")) + (rule "applyEq" (formula "14") (term "1,0,2,2,0") (ifseqformula "8")) + (rule "applyEqRigid" (formula "7") (term "1,1") (ifseqformula "8")) + (rule "seqGetAlphaCast" (formula "16") (term "1")) + (rule "castDel" (formula "1") (term "0")) + (builtin "One Step Simplification" (formula "1")) + (rule "true_left" (formula "1")) + (rule "allLeft" (formula "9") (inst "t=iv_0:int")) + (rule "eqSymm" (formula "9") (term "1,0")) + (rule "replace_known_right" (formula "9") (term "0,0,0") (ifseqformula "17")) + (builtin "One Step Simplification" (formula "9") (ifInst "" (formula "16"))) + (rule "inEqSimp_commuteGeq" (formula "9") (term "1")) + (rule "inEqSimp_contradInEq1" (formula "9") (term "0") (ifseqformula "1")) + (rule "qeq_literals" (formula "9") (term "0,0")) + (builtin "One Step Simplification" (formula "9")) + (rule "inEqSimp_contradInEq1" (formula "9") (ifseqformula "3")) + (rule "andLeft" (formula "9")) + (rule "inEqSimp_homoInEq1" (formula "9")) + (rule "polySimp_pullOutFactor1b" (formula "9") (term "0")) + (rule "add_literals" (formula "9") (term "1,1,0")) + (rule "times_zero_1" (formula "9") (term "1,0")) + (rule "add_literals" (formula "9") (term "0")) + (rule "leq_literals" (formula "9")) + (rule "closeFalse" (formula "9")) + ) + (branch "CUT: v_jv_1 = v_iv_1 FALSE" + (builtin "One Step Simplification" (formula "8")) + (rule "seqGetAlphaCast" (formula "20") (term "1")) + (rule "castDel" (formula "1") (term "0")) + (builtin "One Step Simplification" (formula "1")) + (rule "true_left" (formula "1")) + (rule "allLeft" (formula "9") (inst "t=iv_0:int")) + (rule "eqSymm" (formula "9") (term "1,0,0")) + (rule "eqSymm" (formula "9") (term "1,0")) + (rule "replace_known_right" (formula "9") (term "0,0,0,0") (ifseqformula "21")) + (builtin "One Step Simplification" (formula "9") (ifInst "" (formula "19")) (ifInst "" (formula "20"))) + (rule "inEqSimp_commuteGeq" (formula "9") (term "1")) + (rule "inEqSimp_contradInEq1" (formula "9") (term "1") (ifseqformula "3")) + (rule "inEqSimp_homoInEq1" (formula "9") (term "0,1")) + (rule "polySimp_pullOutFactor1b" (formula "9") (term "0,0,1")) + (rule "add_literals" (formula "9") (term "1,1,0,0,1")) + (rule "times_zero_1" (formula "9") (term "1,0,0,1")) + (rule "add_zero_right" (formula "9") (term "0,0,1")) + (rule "leq_literals" (formula "9") (term "0,1")) + (builtin "One Step Simplification" (formula "9")) + (rule "inEqSimp_contradInEq0" (formula "1") (ifseqformula "9")) + (rule "qeq_literals" (formula "1") (term "0")) + (builtin "One Step Simplification" (formula "1")) + (rule "closeFalse" (formula "1")) + ) ) ) + (branch "geq(seqLen(f_s2), Z(1(#))) FALSE" + (rule "inEqSimp_geqRight" (formula "17")) + (rule "mul_literals" (formula "1") (term "1,0,0")) + (rule "add_literals" (formula "1") (term "0,0")) + (rule "add_zero_left" (formula "1") (term "0")) + (rule "inEqSimp_homoInEq1" (formula "3")) + (rule "mul_literals" (formula "3") (term "1,0")) + (rule "add_zero_right" (formula "3") (term "0")) + (rule "inEqSimp_sepPosMonomial0" (formula "3")) + (rule "mul_literals" (formula "3") (term "1")) + (rule "inEqSimp_contradInEq0" (formula "2") (ifseqformula "3")) + (rule "qeq_literals" (formula "2") (term "0")) + (builtin "One Step Simplification" (formula "2")) + (rule "closeFalse" (formula "2")) + ) ) (branch "f_s2.length >= 0 FALSE" (rule "eqSymm" (formula "4")) diff --git a/key.core/tacletProofs/seqPerm/Taclet_seqPermRefl.proof b/key.core/tacletProofs/seqPerm/Taclet_seqPermRefl.proof index 55f78890439..60083b385b8 100644 --- a/key.core/tacletProofs/seqPerm/Taclet_seqPermRefl.proof +++ b/key.core/tacletProofs/seqPerm/Taclet_seqPermRefl.proof @@ -1,66 +1,103 @@ \profile "Java Profile"; \settings { -"#Proof-Settings-Config-File -#Wed Apr 12 13:30:14 CEST 2023 -[Labels]UseOriginLabels=true -[StrategyProperty]QUERYAXIOM_OPTIONS_KEY=QUERYAXIOM_OFF -[SMTSettings]invariantForall=false -[Strategy]ActiveStrategy=JavaCardDLStrategy -[StrategyProperty]USER_TACLETS_OPTIONS_KEY1=USER_TACLETS_OFF -[StrategyProperty]QUANTIFIERS_OPTIONS_KEY=QUANTIFIERS_NON_SPLITTING_WITH_PROGS -[StrategyProperty]USER_TACLETS_OPTIONS_KEY2=USER_TACLETS_OFF -[Choice]DefaultChoices=JavaCard-JavaCard\\:off, Strings-Strings\\:on, assertions-assertions\\:safe, bigint-bigint\\:on, floatRules-floatRules\\:strictfpOnly, initialisation-initialisation\\:disableStaticInitialisation, intRules-intRules\\:arithmeticSemanticsIgnoringOF, integerSimplificationRules-integerSimplificationRules\\:full, javaLoopTreatment-javaLoopTreatment\\:efficient, mergeGenerateIsWeakeningGoal-mergeGenerateIsWeakeningGoal\\:off, methodExpansion-methodExpansion\\:modularOnly, modelFields-modelFields\\:treatAsAxiom, moreSeqRules-moreSeqRules\\:on, permissions-permissions\\:off, programRules-programRules\\:Java, reach-reach\\:on, runtimeExceptions-runtimeExceptions\\:ban, sequences-sequences\\:on, wdChecks-wdChecks\\:off, wdOperator-wdOperator\\:L -[StrategyProperty]LOOP_OPTIONS_KEY=LOOP_INVARIANT -[StrategyProperty]INF_FLOW_CHECK_PROPERTY=INF_FLOW_CHECK_FALSE -[SMTSettings]UseBuiltUniqueness=false -[SMTSettings]explicitTypeHierarchy=false -[SMTSettings]instantiateHierarchyAssumptions=true -[StrategyProperty]NON_LIN_ARITH_OPTIONS_KEY=NON_LIN_ARITH_NONE -[SMTSettings]SelectedTaclets= -[StrategyProperty]DEP_OPTIONS_KEY=DEP_ON -[StrategyProperty]AUTO_INDUCTION_OPTIONS_KEY=AUTO_INDUCTION_OFF -[Strategy]MaximumNumberOfAutomaticApplications=10000 -[StrategyProperty]STOPMODE_OPTIONS_KEY=STOPMODE_DEFAULT -[StrategyProperty]CLASS_AXIOM_OPTIONS_KEY=CLASS_AXIOM_FREE -[SMTSettings]useConstantsForBigOrSmallIntegers=true -[StrategyProperty]MPS_OPTIONS_KEY=MPS_MERGE -[StrategyProperty]SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY=SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF -[Strategy]Timeout=-1 -[StrategyProperty]SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY=SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER -[StrategyProperty]QUERY_NEW_OPTIONS_KEY=QUERY_RESTRICTED -[SMTSettings]useUninterpretedMultiplication=true -[StrategyProperty]BLOCK_OPTIONS_KEY=BLOCK_CONTRACT_INTERNAL -[StrategyProperty]METHOD_OPTIONS_KEY=METHOD_CONTRACT -[StrategyProperty]USER_TACLETS_OPTIONS_KEY3=USER_TACLETS_OFF -[SMTSettings]maxGenericSorts=2 -[StrategyProperty]OSS_OPTIONS_KEY=OSS_ON -[StrategyProperty]SPLITTING_OPTIONS_KEY=SPLITTING_DELAYED -[SMTSettings]integersMinimum=-2147483645 -[StrategyProperty]VBT_PHASE=VBT_SYM_EX -[SMTSettings]integersMaximum=2147483645 -" -} + "Choice" : { + "JavaCard" : "JavaCard:off", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "finalFields" : "finalFields:immutable", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:arithmeticSemanticsIgnoringOF", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:on", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "soundDefaultContracts" : "soundDefaultContracts:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + }, + "Labels" : { + "UseOriginLabels" : true + }, + "NewSMT" : { + + }, + "SMTSettings" : { + "SelectedTaclets" : [ + + ], + "UseBuiltUniqueness" : false, + "explicitTypeHierarchy" : false, + "instantiateHierarchyAssumptions" : true, + "integersMaximum" : 2147483645, + "integersMinimum" : -2147483645, + "invariantForall" : false, + "maxGenericSorts" : 2, + "useConstantsForBigOrSmallIntegers" : true, + "useUninterpretedMultiplication" : true + }, + "Strategy" : { + "ActiveStrategy" : "Modular JavaDL Strategy", + "MaximumNumberOfAutomaticApplications" : 10000, + "Timeout" : -1, + "options" : { + "AUTO_INDUCTION_OPTIONS_KEY" : "AUTO_INDUCTION_OFF", + "BLOCK_OPTIONS_KEY" : "BLOCK_CONTRACT_INTERNAL", + "CLASS_AXIOM_OPTIONS_KEY" : "CLASS_AXIOM_FREE", + "DEP_OPTIONS_KEY" : "DEP_ON", + "LOOP_OPTIONS_KEY" : "LOOP_INVARIANT", + "METHOD_OPTIONS_KEY" : "METHOD_CONTRACT", + "MPS_OPTIONS_KEY" : "MPS_MERGE", + "NON_LIN_ARITH_OPTIONS_KEY" : "NON_LIN_ARITH_NONE", + "OSS_OPTIONS_KEY" : "OSS_ON", + "QUANTIFIERS_OPTIONS_KEY" : "QUANTIFIERS_NON_SPLITTING_WITH_PROGS", + "QUERYAXIOM_OPTIONS_KEY" : "QUERYAXIOM_OFF", + "QUERY_NEW_OPTIONS_KEY" : "QUERY_RESTRICTED", + "SPLITTING_OPTIONS_KEY" : "SPLITTING_DELAYED", + "STOPMODE_OPTIONS_KEY" : "STOPMODE_DEFAULT", + "SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER", + "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF", + "USER_TACLETS_OPTIONS_KEY1" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY2" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY3" : "USER_TACLETS_OFF", + "VBT_PHASE" : "VBT_SYM_EX" + } + } +} + -\proofObligation { - "name": "seqPermRefl", - "class": "de.uka.ilkd.key.taclettranslation.lemma.TacletProofObligationInput", - } + +\proofObligation +// +{ + "class" : "de.uka.ilkd.key.taclettranslation.lemma.TacletProofObligationInput", + "name" : "seqPermRefl" +} \proof { (keyLog "0" (keyUser "Julian" ) (keyVersion "80a871ca3bac8bb405ecc216fcb6fa9ef6f8a395")) +(keyLog "1" (keyUser "weigl" ) (keyVersion "1df32008ebda9fe2684e1a5eb5e44bdd4c398d8f")) -(autoModeTime "0") +(autoModeTime "14") (branch "dummy ID" -(rule "seqPermDef" (formula "1") (newnames "f_s") (inst "s=s") (inst "iv=iv") (userinteraction)) +(rule "seqPermDef" (formula "1") (newnames "f_s") (inst "iv=iv") (inst "s=s") (userinteraction)) (rule "andRight" (formula "1") (userinteraction)) -(branch +(branch "Case 1" (builtin "One Step Simplification" (formula "1")) (rule "closeTrue" (formula "1")) ) -(branch - (rule "exRightHide" (formula "1") (inst "t=seqDef{int i;}(Z(0(#)), seqLen(f_s), i)") (userinteraction)) +(branch "Case 2" + (rule "exRightHide" (formula "1") (inst "t=seqDef{int i;}(Z(0(#)), seqLen(f_s), i):Seq") (userinteraction)) (rule "eqSymm" (formula "1") (term "1,0,1")) (rule "lenOfSeqDef" (formula "1") (term "0,0,0")) (rule "polySimp_elimSub" (formula "1") (term "1,0,0,0")) @@ -137,7 +174,7 @@ (rule "cut_direct" (formula "2") (term "0")) (branch "CUT: seqNPerm(seqDef{int i;}(0, f_s.length, i)) TRUE" (builtin "One Step Simplification" (formula "3")) - (rule "allRight" (formula "3") (inst "sk=iv_0")) + (rule "allRight" (formula "3") (inst "sk=iv_0:int")) (rule "orRight" (formula "3")) (rule "orRight" (formula "3")) (rule "inEqSimp_geqRight" (formula "4")) @@ -166,7 +203,7 @@ ) (branch "CUT: seqNPerm(seqDef{int i;}(0, f_s.length, i)) FALSE" (rule "seqNPermDefReplace" (formula "2") (inst "iv=iv") (inst "jv=jv") (userinteraction)) - (rule "allRight" (formula "2") (inst "sk=iv_0")) + (rule "allRight" (formula "2") (inst "sk=iv_0:int")) (rule "impRight" (formula "2")) (rule "andLeft" (formula "1")) (rule "getOfSeqDef" (formula "4") (term "0,1,0")) @@ -286,10 +323,15 @@ (rule "inEqSimp_commuteGeq" (formula "1") (term "1")) (rule "inEqSimp_contradInEq1" (formula "1") (term "1") (ifseqformula "4")) (rule "inEqSimp_homoInEq1" (formula "1") (term "0,1")) + (builtin "One Step Simplification" (formula "6")) + (rule "false_right" (formula "6")) + (rule "castDel" (formula "1") (term "0,0")) + (rule "castDel" (formula "1") (term "1,1,1")) + (rule "castDel" (formula "1") (term "0,1,0,0,1")) (rule "polySimp_pullOutFactor1b" (formula "1") (term "0,0,1")) (rule "add_literals" (formula "1") (term "1,1,0,0,1")) (rule "times_zero_1" (formula "1") (term "1,0,0,1")) - (rule "add_zero_right" (formula "1") (term "0,0,1")) + (rule "add_literals" (formula "1") (term "0,0,1")) (rule "leq_literals" (formula "1") (term "0,1")) (builtin "One Step Simplification" (formula "1")) (rule "inEqSimp_contradInEq0" (formula "3") (ifseqformula "1")) @@ -316,7 +358,7 @@ (rule "seqDef_lower_equals_upper" (formula "4") (term "0")) (rule "seqNPermDefReplace" (formula "4") (inst "iv=iv") (inst "jv=jv") (userinteraction)) (builtin "One Step Simplification" (formula "4")) - (rule "allRight" (formula "4") (inst "sk=iv_0")) + (rule "allRight" (formula "4") (inst "sk=iv_0:int")) (rule "impRight" (formula "4")) (rule "andLeft" (formula "1")) (rule "inEqSimp_ltToLeq" (formula "2")) diff --git a/key.core/tacletProofs/seqPerm/Taclet_seqSwapPreservesSeqPerm.proof b/key.core/tacletProofs/seqPerm/Taclet_seqSwapPreservesSeqPerm.proof index 99d0ec441cc..3e617fa98ff 100644 --- a/key.core/tacletProofs/seqPerm/Taclet_seqSwapPreservesSeqPerm.proof +++ b/key.core/tacletProofs/seqPerm/Taclet_seqSwapPreservesSeqPerm.proof @@ -1,12 +1,12 @@ \profile "Java Profile"; -\settings // Proof-Settings-Config-File -{ +\settings { "Choice" : { "JavaCard" : "JavaCard:off", "Strings" : "Strings:on", "assertions" : "assertions:safe", "bigint" : "bigint:on", + "finalFields" : "finalFields:immutable", "floatRules" : "floatRules:strictfpOnly", "initialisation" : "initialisation:disableStaticInitialisation", "intRules" : "intRules:arithmeticSemanticsIgnoringOF", @@ -21,28 +21,80 @@ "reach" : "reach:on", "runtimeExceptions" : "runtimeExceptions:ban", "sequences" : "sequences:on", + "soundDefaultContracts" : "soundDefaultContracts:on", "wdChecks" : "wdChecks:off", "wdOperator" : "wdOperator:L" - } - } + }, + "Labels" : { + "UseOriginLabels" : true + }, + "NewSMT" : { + + }, + "SMTSettings" : { + "SelectedTaclets" : [ + + ], + "UseBuiltUniqueness" : false, + "explicitTypeHierarchy" : false, + "instantiateHierarchyAssumptions" : true, + "integersMaximum" : 2147483645, + "integersMinimum" : -2147483645, + "invariantForall" : false, + "maxGenericSorts" : 2, + "useConstantsForBigOrSmallIntegers" : true, + "useUninterpretedMultiplication" : true + }, + "Strategy" : { + "ActiveStrategy" : "Modular JavaDL Strategy", + "MaximumNumberOfAutomaticApplications" : 2000, + "Timeout" : -1, + "options" : { + "AUTO_INDUCTION_OPTIONS_KEY" : "AUTO_INDUCTION_OFF", + "BLOCK_OPTIONS_KEY" : "BLOCK_CONTRACT_INTERNAL", + "CLASS_AXIOM_OPTIONS_KEY" : "CLASS_AXIOM_FREE", + "DEP_OPTIONS_KEY" : "DEP_ON", + "LOOP_OPTIONS_KEY" : "LOOP_INVARIANT", + "METHOD_OPTIONS_KEY" : "METHOD_CONTRACT", + "MPS_OPTIONS_KEY" : "MPS_MERGE", + "NON_LIN_ARITH_OPTIONS_KEY" : "NON_LIN_ARITH_COMPLETION", + "OSS_OPTIONS_KEY" : "OSS_ON", + "QUANTIFIERS_OPTIONS_KEY" : "QUANTIFIERS_NON_SPLITTING_WITH_PROGS", + "QUERYAXIOM_OPTIONS_KEY" : "QUERYAXIOM_ON", + "QUERY_NEW_OPTIONS_KEY" : "QUERY_OFF", + "SPLITTING_OPTIONS_KEY" : "SPLITTING_DELAYED", + "STOPMODE_OPTIONS_KEY" : "STOPMODE_DEFAULT", + "SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER", + "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF", + "USER_TACLETS_OPTIONS_KEY1" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY2" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY3" : "USER_TACLETS_OFF", + "VBT_PHASE" : "VBT_SYM_EX" + } + } +} + + -\proofObligation // Proof-Obligation settings +\proofObligation +// { "class" : "de.uka.ilkd.key.taclettranslation.lemma.TacletProofObligationInput", "name" : "seqSwapPreservesSeqPerm" - } +} \proof { (keyLog "0" (keyUser "wolfram" ) (keyVersion "c8b5d84c8b26505e96801636fd7dcce6a7f28f5e")) +(keyLog "1" (keyUser "weigl" ) (keyVersion "1df32008ebda9fe2684e1a5eb5e44bdd4c398d8f")) -(autoModeTime "0") +(autoModeTime "148") (branch "dummy ID" (rule "impRight" (formula "1") (newnames "f_x,f_s,f_y")) (rule "andLeft" (formula "1")) (rule "andLeft" (formula "1")) (rule "andLeft" (formula "1")) -(rule "seqPermDef" (formula "5") (inst "s=s") (inst "iv=iv") (userinteraction)) +(rule "seqPermDef" (formula "5") (inst "iv=iv") (inst "s=s") (userinteraction)) (rule "andRight" (formula "5") (userinteraction)) (branch "Case 1" (rule "eqSymm" (formula "5")) @@ -57,7 +109,7 @@ \\then (f_y) \\else (\\if (u = f_y) \\then (f_x) - \\else (u)))") (userinteraction)) + \\else (u))):Seq") (userinteraction)) (rule "inEqSimp_ltToLeq" (formula "4")) (rule "inEqSimp_commuteLeq" (formula "1")) (rule "inEqSimp_commuteLeq" (formula "3")) @@ -107,7 +159,7 @@ ) (branch "Case 2" (rule "seqNPermDefReplace" (formula "5") (inst "iv=iv") (inst "jv=jv") (userinteraction)) - (rule "allRight" (formula "5") (inst "sk=iv_0")) + (rule "allRight" (formula "5") (inst "sk=iv_0:int")) (rule "impRight" (formula "5")) (rule "andLeft" (formula "1")) (rule "getOfSeqDef" (formula "7") (term "0,1,0")) @@ -223,84 +275,152 @@ (rule "inEqSimp_commuteGeq" (formula "1") (term "1,0")) (rule "inEqSimp_contradInEq1" (formula "1") (term "1,0,0") (ifseqformula "7")) (rule "inEqSimp_homoInEq1" (formula "1") (term "0,1,0,0")) + (rule "castDel" (formula "1") (term "1,1,1,0,0")) + (rule "castDel" (formula "1") (term "0,1,0,0,1,0,0")) + (rule "castDel" (formula "1") (term "1,1,0")) + (rule "castDel" (formula "1") (term "0,0,0,0")) + (rule "eqSymm" (formula "10") (term "1,0,1,0")) (rule "polySimp_pullOutFactor1b" (formula "1") (term "0,0,1,0,0")) (rule "add_literals" (formula "1") (term "1,1,0,0,1,0,0")) (rule "times_zero_1" (formula "1") (term "1,0,0,1,0,0")) (rule "add_zero_right" (formula "1") (term "0,0,1,0,0")) (rule "leq_literals" (formula "1") (term "0,1,0,0")) (builtin "One Step Simplification" (formula "1")) + (rule "inEqSimp_ltToLeq" (formula "10") (term "1,0,0,1,0")) + (rule "polySimp_mulComm0" (formula "10") (term "1,0,0,1,0,0,1,0")) + (rule "polySimp_addComm1" (formula "10") (term "0,1,0,0,1,0")) + (rule "inEqSimp_commuteLeq" (formula "10") (term "0,0,0,1,0")) + (rule "inEqSimp_sepNegMonomial0" (formula "10") (term "1,0,0,1,0")) + (rule "polySimp_mulLiterals" (formula "10") (term "0,1,0,0,1,0")) + (rule "polySimp_elimOne" (formula "10") (term "0,1,0,0,1,0")) (rule "inEqSimp_contradInEq1" (formula "1") (term "0,0") (ifseqformula "6")) (rule "qeq_literals" (formula "1") (term "0,0,0")) (builtin "One Step Simplification" (formula "1")) - (rule "commute_or" (formula "1")) - (rule "shift_paren_or" (formula "2") (term "0,0")) - (rule "shift_paren_or" (formula "2") (term "0,0,0")) - (rule "commute_or" (formula "2") (term "0,0,0,0")) - (rule "ifthenelse_to_or_left2" (formula "2") (term "1,0")) - (rule "eqSymm" (formula "2") (term "0,1,0,1,0")) - (rule "commute_or" (formula "2") (term "0,1,0")) - (rule "cnf_rightDist" (formula "2") (term "0")) - (rule "distr_forallAnd" (formula "2")) - (rule "andLeft" (formula "2")) - (rule "commute_or_2" (formula "3") (term "0")) + (rule "getOfSwap" (formula "10") (term "0,1,0,1,0")) + (rule "ifthenelse_negated" (formula "10") (term "0,1,0,1,0")) + (rule "inEqSimp_ltToLeq" (formula "10") (term "1,0,0,1,0,1,0")) + (rule "polySimp_mulComm0" (formula "10") (term "1,0,0,1,0,0,1,0,1,0")) + (rule "polySimp_addComm1" (formula "10") (term "0,1,0,0,1,0,1,0")) + (rule "inEqSimp_ltToLeq" (formula "10") (term "1,0,0,0,1,0,1,0")) + (rule "polySimp_mulComm0" (formula "10") (term "1,0,0,1,0,0,0,1,0,1,0")) + (rule "polySimp_addComm1" (formula "10") (term "0,1,0,0,0,1,0,1,0")) + (rule "inEqSimp_commuteLeq" (formula "10") (term "0,0,0,0,0,1,0,1,0")) + (rule "replace_known_left" (formula "10") (term "0,0,0,0,0,1,0,1,0") (ifseqformula "6")) + (builtin "One Step Simplification" (formula "10")) + (rule "inEqSimp_commuteLeq" (formula "10") (term "0,0,0,0,1,0,1,0")) + (rule "replace_known_left" (formula "10") (term "0,0,0,0,1,0,1,0") (ifseqformula "8")) + (builtin "One Step Simplification" (formula "10")) + (rule "inEqSimp_sepNegMonomial0" (formula "10") (term "1,0,0,1,0,1,0")) + (rule "polySimp_mulLiterals" (formula "10") (term "0,1,0,0,1,0,1,0")) + (rule "polySimp_elimOne" (formula "10") (term "0,1,0,0,1,0,1,0")) + (rule "replace_known_left" (formula "10") (term "1,0,0,1,0,1,0") (ifseqformula "9")) + (builtin "One Step Simplification" (formula "10")) + (rule "inEqSimp_sepNegMonomial0" (formula "10") (term "0,0,1,0,1,0")) + (rule "polySimp_mulLiterals" (formula "10") (term "0,0,0,1,0,1,0")) + (rule "polySimp_elimOne" (formula "10") (term "0,0,0,1,0,1,0")) + (rule "replace_known_left" (formula "10") (term "0,0,1,0,1,0") (ifseqformula "7")) + (builtin "One Step Simplification" (formula "10")) + (rule "nnf_ex2all" (formula "10")) + (rule "nnf_notAnd" (formula "1") (term "0")) + (rule "nnf_notAll" (formula "1") (term "1,0")) + (rule "nnf_notAnd" (formula "1") (term "0,0")) + (rule "nnf_imp2or" (formula "1") (term "0,0,1,0")) + (rule "nnf_notOr" (formula "1") (term "0,1,0")) + (builtin "One Step Simplification" (formula "1")) + (rule "commute_or" (formula "4") (term "0")) + (rule "commute_or" (formula "2")) + (rule "shift_paren_or" (formula "3") (term "0,0")) + (rule "commute_or" (formula "1") (term "0,0")) + (rule "commute_or" (formula "4") (term "0,1,0")) + (rule "cnf_rightDist" (formula "4") (term "0")) + (rule "distr_forallAnd" (formula "4")) + (rule "andLeft" (formula "4")) + (rule "commute_or_2" (formula "5") (term "0")) + (rule "shift_paren_or" (formula "4") (term "0")) + (rule "commute_or_2" (formula "4") (term "0,0")) + (rule "inEqSimp_or_tautInEq0" (formula "4") (term "0,0,0")) + (rule "add_literals" (formula "4") (term "1,1,0,0,0")) + (rule "qeq_literals" (formula "4") (term "1,0,0,0")) + (builtin "One Step Simplification" (formula "4")) + (rule "true_left" (formula "4")) + (rule "shift_paren_or" (formula "4") (term "0,0")) + (rule "commute_or" (formula "4") (term "0,0,0")) + (rule "shift_paren_or" (formula "3") (term "0,0,0")) + (rule "ifthenelse_to_or_left2" (formula "3") (term "1,0")) + (rule "eqSymm" (formula "3") (term "0,1,0,1,0")) + (rule "commute_or" (formula "3") (term "0,1,0")) + (rule "cnf_rightDist" (formula "3") (term "0")) + (rule "distr_forallAnd" (formula "3")) + (rule "andLeft" (formula "3")) + (rule "commute_or_2" (formula "4") (term "0")) + (builtin "One Step Simplification" (formula "4")) + (rule "castDel" (formula "4") (term "0,1,1")) + (rule "castDel" (formula "4") (term "0,0")) + (rule "castDel" (formula "4") (term "0,1,0,1")) + (rule "castDel" (formula "4") (term "0,0,0,0,1")) + (rule "castDel" (formula "4") (term "0,1,0,0,1")) + (rule "inEqSimp_commuteGeq" (formula "4") (term "1,1")) + (rule "inEqSimp_commuteGeq" (formula "4") (term "1,0,1")) + (rule "inEqSimp_contradInEq1" (formula "4") (term "1,0,0,1") (ifseqformula "6")) + (rule "qeq_literals" (formula "4") (term "0,1,0,0,1")) + (builtin "One Step Simplification" (formula "4")) + (rule "inEqSimp_contradInEq1" (formula "4") (term "1,1") (ifseqformula "7")) + (rule "inEqSimp_homoInEq1" (formula "4") (term "0,1,1")) + (rule "polySimp_pullOutFactor1b" (formula "4") (term "0,0,1,1")) + (rule "add_literals" (formula "4") (term "1,1,0,0,1,1")) + (rule "times_zero_1" (formula "4") (term "1,0,0,1,1")) + (rule "add_literals" (formula "4") (term "0,0,1,1")) + (rule "leq_literals" (formula "4") (term "0,1,1")) + (builtin "One Step Simplification" (formula "4")) + (rule "shift_paren_or" (formula "4")) + (rule "shift_paren_or" (formula "3") (term "0")) (builtin "One Step Simplification" (formula "3")) - (rule "inEqSimp_commuteGeq" (formula "3") (term "1,1")) - (rule "inEqSimp_commuteGeq" (formula "3") (term "1,0,1")) - (rule "inEqSimp_contradInEq1" (formula "3") (term "1,1") (ifseqformula "6")) - (rule "inEqSimp_homoInEq1" (formula "3") (term "0,1,1")) - (rule "polySimp_pullOutFactor1b" (formula "3") (term "0,0,1,1")) - (rule "add_literals" (formula "3") (term "1,1,0,0,1,1")) - (rule "times_zero_1" (formula "3") (term "1,0,0,1,1")) - (rule "add_literals" (formula "3") (term "0,0,1,1")) - (rule "leq_literals" (formula "3") (term "0,1,1")) + (rule "castDel" (formula "3") (term "0,1,0")) + (rule "castDel" (formula "3") (term "0,1,0,0")) + (rule "castDel" (formula "3") (term "0,1,0,0,0")) + (rule "castDel" (formula "3") (term "0,0,0,0,0")) + (rule "inEqSimp_commuteGeq" (formula "3") (term "1,0")) + (rule "inEqSimp_commuteGeq" (formula "3") (term "1,0,0")) + (rule "inEqSimp_contradInEq1" (formula "3") (term "1,0,0,0") (ifseqformula "10")) + (rule "qeq_literals" (formula "3") (term "0,1,0,0,0")) (builtin "One Step Simplification" (formula "3")) - (rule "inEqSimp_contradInEq1" (formula "3") (term "0,0,1") (ifseqformula "5")) - (rule "qeq_literals" (formula "3") (term "0,0,0,1")) + (rule "inEqSimp_contradInEq1" (formula "3") (term "1,0,0") (ifseqformula "11")) + (rule "inEqSimp_homoInEq1" (formula "3") (term "0,1,0,0")) + (rule "polySimp_pullOutFactor1b" (formula "3") (term "0,0,1,0,0")) + (rule "add_literals" (formula "3") (term "1,1,0,0,1,0,0")) + (rule "times_zero_1" (formula "3") (term "1,0,0,1,0,0")) + (rule "add_zero_right" (formula "3") (term "0,0,1,0,0")) + (rule "leq_literals" (formula "3") (term "0,1,0,0")) (builtin "One Step Simplification" (formula "3")) - (rule "shift_paren_or" (formula "3")) - (rule "commute_or" (formula "3") (term "0")) - (rule "shift_paren_or" (formula "2") (term "0")) - (builtin "One Step Simplification" (formula "2")) - (rule "inEqSimp_commuteGeq" (formula "2") (term "1,0")) - (rule "inEqSimp_commuteGeq" (formula "2") (term "1,0,0")) - (rule "inEqSimp_contradInEq1" (formula "2") (term "0,0,0,0") (ifseqformula "9")) - (rule "qeq_literals" (formula "2") (term "0,0,0,0,0")) - (builtin "One Step Simplification" (formula "2")) - (rule "inEqSimp_contradInEq1" (formula "2") (term "1,0,0") (ifseqformula "10")) - (rule "inEqSimp_homoInEq1" (formula "2") (term "0,1,0,0")) - (rule "polySimp_pullOutFactor1b" (formula "2") (term "0,0,1,0,0")) - (rule "add_literals" (formula "2") (term "1,1,0,0,1,0,0")) - (rule "times_zero_1" (formula "2") (term "1,0,0,1,0,0")) - (rule "add_zero_right" (formula "2") (term "0,0,1,0,0")) - (rule "leq_literals" (formula "2") (term "0,1,0,0")) - (builtin "One Step Simplification" (formula "2")) - (rule "commute_or_2" (formula "2")) - (rule "ifthenelse_split" (formula "6") (term "0")) - (branch "f_s.length ≥ 1 TRUE" - (rule "replace_known_left" (formula "1") (term "0,0,1") (ifseqformula "6")) - (builtin "One Step Simplification" (formula "1")) - (rule "replace_known_left" (formula "2") (term "0,0,1") (ifseqformula "6")) - (builtin "One Step Simplification" (formula "2")) - (rule "inEqSimp_contradInEq1" (formula "1") (term "1") (ifseqformula "9")) - (rule "inEqSimp_homoInEq1" (formula "1") (term "0,1")) - (rule "polySimp_pullOutFactor1b" (formula "1") (term "0,0,1")) - (rule "add_literals" (formula "1") (term "1,1,0,0,1")) - (rule "times_zero_1" (formula "1") (term "1,0,0,1")) - (rule "add_zero_right" (formula "1") (term "0,0,1")) - (rule "leq_literals" (formula "1") (term "0,1")) - (builtin "One Step Simplification" (formula "1")) - (rule "notLeft" (formula "1")) - (rule "replace_known_right" (formula "2") (term "1,0") (ifseqformula "11")) + (rule "commute_or_2" (formula "3")) + (rule "commute_or" (formula "4") (term "0")) + (rule "commute_and_2" (formula "1") (term "0,1,0")) + (rule "commute_and" (formula "1") (term "0,0,1,0")) + (rule "ifthenelse_split" (formula "7") (term "0")) + (branch "geq(seqLen(f_s), Z(1(#))) TRUE" + (rule "replace_known_left" (formula "5") (term "0,1,1,0,0") (ifseqformula "7")) + (builtin "One Step Simplification" (formula "5")) + (rule "replace_known_left" (formula "2") (term "0,0,1") (ifseqformula "7")) (builtin "One Step Simplification" (formula "2")) - (rule "inEqSimp_contradInEq1" (formula "1") (term "1") (ifseqformula "10")) - (rule "inEqSimp_homoInEq1" (formula "1") (term "0,1")) - (rule "polySimp_pullOutFactor1b" (formula "1") (term "0,0,1")) - (rule "add_literals" (formula "1") (term "1,1,0,0,1")) - (rule "times_zero_1" (formula "1") (term "1,0,0,1")) - (rule "add_zero_right" (formula "1") (term "0,0,1")) - (rule "leq_literals" (formula "1") (term "0,1")) - (builtin "One Step Simplification" (formula "1")) - (rule "inEqSimp_contradInEq1" (formula "2") (term "1") (ifseqformula "6")) + (rule "replace_known_left" (formula "3") (term "0,0,1") (ifseqformula "7")) + (builtin "One Step Simplification" (formula "3")) + (rule "inEqSimp_contradInEq1" (formula "4") (term "1") (ifseqformula "8")) + (rule "inEqSimp_homoInEq1" (formula "4") (term "0,1")) + (rule "polySimp_pullOutFactor1b" (formula "4") (term "0,0,1")) + (rule "add_literals" (formula "4") (term "1,1,0,0,1")) + (rule "times_zero_1" (formula "4") (term "1,0,0,1")) + (rule "add_literals" (formula "4") (term "0,0,1")) + (rule "leq_literals" (formula "4") (term "0,1")) + (builtin "One Step Simplification" (formula "4")) + (rule "inEqSimp_contradInEq1" (formula "3") (term "1") (ifseqformula "12")) + (rule "inEqSimp_homoInEq1" (formula "3") (term "0,1")) + (rule "polySimp_pullOutFactor1b" (formula "3") (term "0,0,1")) + (rule "add_literals" (formula "3") (term "1,1,0,0,1")) + (rule "times_zero_1" (formula "3") (term "1,0,0,1")) + (rule "add_literals" (formula "3") (term "0,0,1")) + (rule "leq_literals" (formula "3") (term "0,1")) + (builtin "One Step Simplification" (formula "3")) + (rule "inEqSimp_contradInEq1" (formula "2") (term "1") (ifseqformula "10")) (rule "inEqSimp_homoInEq1" (formula "2") (term "0,1")) (rule "polySimp_pullOutFactor1b" (formula "2") (term "0,0,1")) (rule "add_literals" (formula "2") (term "1,1,0,0,1")) @@ -308,28 +428,54 @@ (rule "add_zero_right" (formula "2") (term "0,0,1")) (rule "leq_literals" (formula "2") (term "0,1")) (builtin "One Step Simplification" (formula "2")) - (rule "replace_known_left" (formula "1") (term "0,1") (ifseqformula "2")) - (builtin "One Step Simplification" (formula "1")) - (rule "applyEq" (formula "11") (term "0") (ifseqformula "2")) - (rule "eqSymm" (formula "11")) - (rule "close" (formula "11") (ifseqformula "1")) + (rule "notLeft" (formula "2")) + (rule "replace_known_right" (formula "3") (term "1") (ifseqformula "12")) + (builtin "One Step Simplification" (formula "3")) + (rule "replace_known_left" (formula "2") (term "0,1") (ifseqformula "3")) + (builtin "One Step Simplification" (formula "2")) + (rule "applyEqRigid" (formula "11") (term "1,1") (ifseqformula "2")) + (rule "applyEq" (formula "7") (term "1,1") (ifseqformula "3")) + (rule "applyEqRigid" (formula "9") (term "0") (ifseqformula "2")) + (rule "applyEq" (formula "5") (term "0") (ifseqformula "3")) + (rule "applyEq" (formula "1") (term "1,1,0,0,0,0,0,1,0") (ifseqformula "2")) + (rule "applyEqRigid" (formula "8") (term "0") (ifseqformula "3")) + (rule "eqSymm" (formula "8")) + (rule "close" (formula "8") (ifseqformula "2")) ) - (branch "f_s.length ≥ 1 FALSE" + (branch "geq(seqLen(f_s), Z(1(#))) FALSE" + (rule "replace_known_right" (formula "5") (term "0,1,1,0,0") (ifseqformula "12")) + (builtin "One Step Simplification" (formula "5")) + (rule "replace_known_right" (formula "2") (term "0,0,1") (ifseqformula "12")) + (builtin "One Step Simplification" (formula "2")) + (rule "replace_known_right" (formula "3") (term "0,0,1") (ifseqformula "12")) + (builtin "One Step Simplification" (formula "3")) + (rule "inEqSimp_geqRight" (formula "12")) + (rule "mul_literals" (formula "1") (term "1,0,0")) + (rule "add_literals" (formula "1") (term "0,0")) + (rule "add_zero_left" (formula "1") (term "0")) + (rule "inEqSimp_commuteLeq" (formula "3") (term "1")) + (rule "replace_known_left" (formula "3") (term "1") (ifseqformula "9")) + (builtin "One Step Simplification" (formula "3")) + (rule "true_left" (formula "3")) + (rule "inEqSimp_commuteLeq" (formula "3") (term "1")) + (rule "replace_known_left" (formula "3") (term "1") (ifseqformula "10")) + (builtin "One Step Simplification" (formula "3")) + (rule "true_left" (formula "3")) (rule "inEqSimp_homoInEq1" (formula "6")) (rule "times_zero_2" (formula "6") (term "1,0")) (rule "add_zero_right" (formula "6") (term "0")) (rule "inEqSimp_sepPosMonomial0" (formula "6")) (rule "mul_literals" (formula "6") (term "1")) - (rule "inEqSimp_contradInEq1" (formula "6") (ifseqformula "5")) - (rule "qeq_literals" (formula "6") (term "0")) - (builtin "One Step Simplification" (formula "6")) - (rule "closeFalse" (formula "6")) + (rule "inEqSimp_contradInEq0" (formula "5") (ifseqformula "6")) + (rule "qeq_literals" (formula "5") (term "0")) + (builtin "One Step Simplification" (formula "5")) + (rule "closeFalse" (formula "5")) ) ) ) (branch "Case 2" (rule "lenOfSeqDef" (formula "5") (term "1,1,0,0") (userinteraction)) - (rule "allRight" (formula "5") (inst "sk=iv_0") (userinteraction)) + (rule "allRight" (formula "5") (inst "sk=iv_0:int") (userinteraction)) (rule "impRight" (formula "5") (userinteraction)) (rule "andLeft" (formula "1")) (rule "eqSymm" (formula "7")) diff --git a/key.core/tacletProofs/seqPerm2/Taclet_schiffl_lemma_2.proof b/key.core/tacletProofs/seqPerm2/Taclet_schiffl_lemma_2.proof index 27d1feea12b..32c5d82cce4 100644 --- a/key.core/tacletProofs/seqPerm2/Taclet_schiffl_lemma_2.proof +++ b/key.core/tacletProofs/seqPerm2/Taclet_schiffl_lemma_2.proof @@ -404,14 +404,4 @@ instantiate hide var=iv with=(v_y_0); instantiate hide var=jv with=(jv_1); instantiate hide var=v_r with=(seqSwap(seqSwap(s_0, v_x_0, jv_0), v_y_0, jv_1)); tryclose branch; -rule seqNPermSwapNPerm formula=(seqNPerm(s_0)); -instantiate hide var=iv with=(v_x_0); -instantiate hide var=jv with=(jv_0); -rule impLeft; -tryclose branch; -rule seqNPermSwapNPerm formula=(seqNPerm(seqSwap(s_0,v_x_0,jv_0))); -instantiate hide var=iv with=(v_y_0); -instantiate hide var=jv with=(jv_1); -instantiate hide var=v_r with=(seqSwap(seqSwap(s_0, v_x_0, jv_0), v_y_0, jv_1)); -tryclose branch; } \ No newline at end of file diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/rules/RuleSet.java b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/RuleSet.java index 73a341b5e6e..e5b36ec4f58 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/rules/RuleSet.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/RuleSet.java @@ -3,6 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package org.key_project.prover.rules; +import org.key_project.logic.HasMeta; import org.key_project.logic.Name; import org.key_project.logic.Named; @@ -14,7 +15,7 @@ /// /// Rulesets had been originally called heuristics. /// -public record RuleSet(Name name) implements Named { +public record RuleSet(Name name) implements Named, HasMeta { /// creates a ruleset /// /// @param name the [Name] of the ruleset @@ -44,4 +45,9 @@ public boolean equals(@Nullable Object other) { /// toString public String toString() { return name.toString(); } + + @Override + public String getMetaKey() { + return "heuristic/" + name; + } } diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/rules/Taclet.java b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/Taclet.java index 9a8c547a060..2ef428d12a6 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/rules/Taclet.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/Taclet.java @@ -44,7 +44,7 @@ public abstract class Taclet implements Rule { protected final @Nullable SyntaxElement find; /// The restriction(s) for applying this update. [ApplicationRestriction]. - protected final @NonNull ApplicationRestriction applicationRestriction; + protected final ApplicationRestriction applicationRestriction; /// the assumes sequent of the taclet protected final Sequent assumesSequent; @@ -75,7 +75,7 @@ public abstract class Taclet implements Rule { /// list /// of all variables that may appear free in the instantiation of the schemavariable (a bit more /// complicated for rewrite taclets, see paper of M:Giese) - protected final ImmutableMap<@NonNull SchemaVariable, org.key_project.prover.rules.TacletPrefix> prefixMap; + protected final ImmutableMap prefixMap; /// cache; contains set of all bound variables protected @Nullable ImmutableSet boundVariables = null; @@ -101,10 +101,10 @@ public abstract class Taclet implements Rule { // but all at once for a given term. /// The taclet matcher - protected @NonNull TacletMatcher matcher; + protected TacletMatcher matcher; /// The taclet executor - protected @NonNull TacletExecutor, ? extends @NonNull RuleApp> executor; + protected TacletExecutor, ? extends RuleApp> executor; /// creates a Taclet (originally known as Schematic Theory Specific Rules) /// @@ -121,7 +121,7 @@ protected Taclet(Name name, SyntaxElement find, TacletApplPart applPart, ImmutableList goalTemplates, ImmutableList ruleSets, TacletAttributes attrs, - ImmutableMap<@NonNull SchemaVariable, TacletPrefix> prefixMap, ChoiceExpr choices, + ImmutableMap prefixMap, ChoiceExpr choices, ImmutableSet tacletAnnotations) { this.tacletAnnotations = tacletAnnotations; this.name = name; @@ -167,7 +167,7 @@ public boolean hasTrigger() { } @RequiresCalledMethods(value = "this", methods = "createAndInitializeMatcher") - public final TacletMatcher getMatcher() { + public final @Nullable TacletMatcher getMatcher() { return matcher; } @@ -227,13 +227,13 @@ public ImmutableList getVariableConditions() { /// @return the name of the Taclet @Override - public @NonNull Name name() { + public Name name() { return name; } /// @return the display name of the taclet, or, if not specified -- the canonical name @Override - public @NonNull String displayName() { + public String displayName() { return displayName; } @@ -243,7 +243,7 @@ public Sequent assumesSequent() { } /// @return the application restrictions of the Taclet. - public ApplicationRestriction applicationRestriction() { + public @Nullable ApplicationRestriction applicationRestriction() { return applicationRestriction; } @@ -266,7 +266,7 @@ public ImmutableList goalTemplates() { return goalTemplates; } - public ImmutableMap<@NonNull SchemaVariable, TacletPrefix> prefixMap() { + public ImmutableMap prefixMap() { return prefixMap; } @@ -440,8 +440,8 @@ public String toString() { } @SuppressWarnings("unchecked") - public @NonNull > TacletExecutor<@NonNull G, ?> getExecutor() { - return (TacletExecutor<@NonNull G, ?>) executor; + public > TacletExecutor<@NonNull G, ?> getExecutor() { + return (TacletExecutor) executor; } public abstract Taclet setName(String name); diff --git a/key.ncore/src/main/java/org/key_project/logic/Choice.java b/key.ncore/src/main/java/org/key_project/logic/Choice.java index 09c1d2a9482..c4ab2bb05a7 100644 --- a/key.ncore/src/main/java/org/key_project/logic/Choice.java +++ b/key.ncore/src/main/java/org/key_project/logic/Choice.java @@ -13,7 +13,7 @@ /// A choice is represented by a string, where the category is separated by the option with a colon. /// /// Choices can be declared within KeY files. They influence the activation of taclets. -public class Choice implements Named { +public class Choice implements Named, HasMeta { private final @NonNull Name name; private final @NonNull String category; @@ -58,4 +58,9 @@ public int hashCode() { public String toString() { return name.toString(); } + + @Override + public String getMetaKey() { + return "choice/" + name; + } } diff --git a/key.ncore/src/main/java/org/key_project/logic/HasMeta.java b/key.ncore/src/main/java/org/key_project/logic/HasMeta.java new file mode 100644 index 00000000000..36ecf0f508c --- /dev/null +++ b/key.ncore/src/main/java/org/key_project/logic/HasMeta.java @@ -0,0 +1,24 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.logic; + +import org.jspecify.annotations.Nullable; + +/// Mark items of the namespace which can have entries in the {@link +/// de.uka.ilkd.key.logic.MetaSpace}. +/// +/// @author weigl +public interface HasMeta { + String getMetaKey(); + + default @Nullable String getDocumentation() { + return null; + } + + record OptionCategory(String name) implements HasMeta { + public String getMetaKey() { + return "category/" + name; + } + } +} diff --git a/key.ncore/src/main/java/org/key_project/logic/HasOrigin.java b/key.ncore/src/main/java/org/key_project/logic/HasOrigin.java deleted file mode 100644 index 50b2b5f1477..00000000000 --- a/key.ncore/src/main/java/org/key_project/logic/HasOrigin.java +++ /dev/null @@ -1,21 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package org.key_project.logic; - -import org.jspecify.annotations.Nullable; - -/// Classes with this interface provides a simple human-readable String where they came from. -/// -/// @author Alexander Weigl -/// @version 1 (12/30/21) -public interface HasOrigin { - /// Information about the origin of the rule. - /// - /// Should be a human-readable location where the user can find the declaration of the rule. - /// - /// This field is set by the parser with \[url]:\[lineNumber] - default @Nullable String getOrigin() { - return null; - } -} diff --git a/key.ncore/src/main/java/org/key_project/logic/op/Operator.java b/key.ncore/src/main/java/org/key_project/logic/op/Operator.java index 0a3d0c99ac1..d05a643c630 100644 --- a/key.ncore/src/main/java/org/key_project/logic/op/Operator.java +++ b/key.ncore/src/main/java/org/key_project/logic/op/Operator.java @@ -3,13 +3,10 @@ * SPDX-License-Identifier: GPL-2.0-only */ package org.key_project.logic.op; -import org.key_project.logic.Named; -import org.key_project.logic.SyntaxElement; -import org.key_project.logic.Term; -import org.key_project.logic.TermCreationException; +import org.key_project.logic.*; import org.key_project.logic.sort.Sort; -public interface Operator extends Named, SyntaxElement { +public interface Operator extends Named, HasMeta, SyntaxElement { /// the arity of this operator int arity(); @@ -41,4 +38,9 @@ default boolean hasModifier(Modifier mod) { /// /// @throws TermCreationException if a construction error was recognised void validTopLevelException(T term) throws TermCreationException; + + @Override + default String getMetaKey() { + return "operator/" + name(); + } } diff --git a/key.ncore/src/main/java/org/key_project/logic/sort/AbstractSort.java b/key.ncore/src/main/java/org/key_project/logic/sort/AbstractSort.java index d536defdf29..e1b9781a04b 100644 --- a/key.ncore/src/main/java/org/key_project/logic/sort/AbstractSort.java +++ b/key.ncore/src/main/java/org/key_project/logic/sort/AbstractSort.java @@ -5,18 +5,11 @@ import org.key_project.logic.Name; -import org.jspecify.annotations.Nullable; - - /// Abstract base class for implementations of the Sort interface. public abstract class AbstractSort implements Sort { private final Name name; private final boolean isAbstract; - /// Documentation for this sort given by the associated documentation comment. - /// //@see de.uka.ilkd.key.nparser.KeYParser.One_sort_declContext#doc - private @Nullable String documentation; - protected AbstractSort(Name name, boolean isAbstract) { this.name = name; this.isAbstract = isAbstract; @@ -40,13 +33,4 @@ public final String toString() { public String declarationString() { return name.toString(); } - - public void setDocumentation(@Nullable String documentation) { - this.documentation = documentation; - } - - @Override - public @Nullable String getDocumentation() { - return documentation; - } } diff --git a/key.ncore/src/main/java/org/key_project/logic/sort/Sort.java b/key.ncore/src/main/java/org/key_project/logic/sort/Sort.java index 68799506339..bc29701c640 100644 --- a/key.ncore/src/main/java/org/key_project/logic/sort/Sort.java +++ b/key.ncore/src/main/java/org/key_project/logic/sort/Sort.java @@ -3,14 +3,13 @@ * SPDX-License-Identifier: GPL-2.0-only */ package org.key_project.logic.sort; -import org.key_project.logic.HasOrigin; +import org.key_project.logic.HasMeta; import org.key_project.logic.LogicServices; import org.key_project.logic.Named; import org.key_project.util.collection.ImmutableSet; -import org.jspecify.annotations.Nullable; -public interface Sort extends Named, HasOrigin { +public interface Sort extends Named, HasMeta { /// @return the direct supersorts of this sort. Not supported by `NullSort`. ImmutableSet extendsSorts(); @@ -27,9 +26,10 @@ default ImmutableSet extendsSorts(Service String declarationString(); - /// Returns a human explainable text describing this sort. This field is typical set by the - /// parser, who captures the documentation comments. - default @Nullable String getDocumentation() { return null; } + @Override + default String getMetaKey() { + return "sort/" + name(); + } /// Whether this sort is or contains an uninstantiated generic sort. boolean containsGenericSort(); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/core/Log.java b/key.ui/src/main/java/de/uka/ilkd/key/core/Log.java index 5fd6dd3d249..00f9a9fc7bc 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/core/Log.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/core/Log.java @@ -55,6 +55,9 @@ public static void configureLogging(@Nullable Integer verbosity) { .getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); if (verbosity != null) { Appender consoleAppender = root.getAppender("STDOUT"); + if (consoleAppender == null) { + return; + } consoleAppender.clearAllFilters(); var filter = new ThresholdFilter(); consoleAppender.addFilter(filter); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTree.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTree.java deleted file mode 100644 index 6918c7339ba..00000000000 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTree.java +++ /dev/null @@ -1,40 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.gui; - -import javax.swing.JTree; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; - -/** - * This class is used by {@link InfoView} to display its contents. - * - * @author Kai Wallisch - */ -public class InfoTree extends JTree { - - /** - * - */ - private static final long serialVersionUID = 2018185104131516569L; - - InfoTree() { - DefaultMutableTreeNode root = new DefaultMutableTreeNode(); - root.add(new InfoTreeNode("No proof loaded", - "In this pane, the available logical rules will be displayed and/or explained.")); - setModel(new DefaultTreeModel(root)); - setShowsRootHandles(true); - setRootVisible(false); - } - - /* - * This function is expected to return only {@link InfoTreeNode} instances. The super method - * returns {@link DefaultMutableTreeNode} instances. - */ - @Override - public InfoTreeNode getLastSelectedPathComponent() { - return (InfoTreeNode) super.getLastSelectedPathComponent(); - } - -} diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTreeModel.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTreeModel.java deleted file mode 100644 index e5c2656b37e..00000000000 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTreeModel.java +++ /dev/null @@ -1,220 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.gui; - -import java.util.*; -import javax.swing.tree.DefaultTreeModel; - -import de.uka.ilkd.key.proof.Goal; -import de.uka.ilkd.key.proof.mgt.RuleJustification; -import de.uka.ilkd.key.rule.BuiltInRule; -import de.uka.ilkd.key.rule.NoPosTacletApp; -import de.uka.ilkd.key.rule.OneStepSimplifier; -import de.uka.ilkd.key.rule.Taclet; -import de.uka.ilkd.key.util.MiscTools; -import de.uka.ilkd.key.util.XMLResources; - -import org.key_project.logic.Name; - -/** - * Extension of {@link DefaultTreeModel} used by {@link InfoTree}. - * - * @author Kai Wallisch - */ -public class InfoTreeModel extends DefaultTreeModel { - - /** - * - */ - private static final long serialVersionUID = 2093787874117871875L; - private static final String LEMMAS = "Lemmas"; - private static final String TACLET_BASE = "Taclet Base"; - - public InfoTreeModel(Goal goal, XMLResources xmlResources, MainWindow mainWindow) { - super(new InfoTreeNode()); - insertAsLast(new RulesNode(xmlResources.getRuleExplanations(), goal), (InfoTreeNode) root); - insertAsLast(new TermLabelsNode(mainWindow, xmlResources.getTermLabelExplanations()), - (InfoTreeNode) root); - insertAsLast(new FunctionsNode(xmlResources.getFunctionExplanations()), - (InfoTreeNode) root); - } - - private void insertAsLast(InfoTreeNode ins, InfoTreeNode parent) { - insertNodeInto(ins, parent, parent.getChildCount()); - } - - private class FunctionsNode extends InfoTreeNode { - - /** - * - */ - private static final long serialVersionUID = -5546552277804988834L; - private static final String COLLECTION = - "This node stands for a category of symbols; expand it to browse the symbols " - + "in the category."; - private static final String DEFAULT_FUNCTIONS_LABEL = - "Display descriptions for documented interpreted function and predicate symbols."; - - FunctionsNode(Properties functionExplanations) { - super("Function Symbols", DEFAULT_FUNCTIONS_LABEL); - - Map categoryMap = new HashMap<>(); - - List sortedKeys = - new ArrayList<>(functionExplanations.stringPropertyNames()); - java.util.Collections.sort(sortedKeys); - - for (String key : sortedKeys) { - String[] parts = key.split("/", 2); - if (parts.length == 1) { - // no "/" - insertAsLast(new InfoTreeNode(key, functionExplanations), this); - } else { - String category = parts[0]; - InfoTreeNode categoryNode = categoryMap.get(category); - if (categoryNode == null) { - categoryNode = new InfoTreeNode(category, COLLECTION); - categoryMap.put(category, categoryNode); - insertAsLast(categoryNode, this); - } - String description = functionExplanations.getProperty(key); - insertAsLast(new InfoTreeNode(parts[1], description), categoryNode); - } - } - } - } - - private class TermLabelsNode extends InfoTreeNode { - - /** - * - */ - private static final long serialVersionUID = 7447092361863294242L; - - TermLabelsNode(MainWindow mainWindow, Properties termLabelExplanations) { - super("Term Labels", "Show descriptions for currently available term labels."); - - List labelNames = mainWindow.getSortedTermLabelNames(); - for (Name name : labelNames) { - insertAsLast(new InfoTreeNode(name.toString(), termLabelExplanations), this); - } - } - } - - private class RulesNode extends InfoTreeNode { - - /** - * - */ - private static final long serialVersionUID = 7622830441420768861L; - - RulesNode(Properties ruleExplanations, Goal goal) { - super("Rules", "Browse descriptions for currently available rules."); - - InfoTreeNode builtInRoot = new InfoTreeNode("Built-In", ruleExplanations); - insertAsLast(builtInRoot, this); - InfoTreeNode axiomTacletRoot = new InfoTreeNode(TACLET_BASE, ruleExplanations); - insertAsLast(axiomTacletRoot, this); - InfoTreeNode proveableTacletsRoot = new InfoTreeNode(LEMMAS, ruleExplanations); - insertAsLast(proveableTacletsRoot, this); - - if (goal != null && goal.proof() != null && goal.proof().mgt() != null) { - for (final BuiltInRule br : goal.ruleAppIndex().builtInRuleAppIndex() - .builtInRuleIndex().rules()) { - insertAsLast(new InfoTreeNode(br, ruleExplanations), builtInRoot); - } - Set set = goal.ruleAppIndex().tacletIndex().allNoPosTacletApps(); - OneStepSimplifier simplifier = MiscTools.findOneStepSimplifier(goal.proof()); - if (simplifier != null && !simplifier.isShutdown()) { - set.addAll(simplifier.getCapturedTaclets()); - } - - for (final NoPosTacletApp app : sort(set)) { - RuleJustification just = goal.proof().mgt().getJustification(app); - if (just == null) { - continue; // do not break system because of this - } - if (just.isAxiomJustification()) { - insertAndGroup(new InfoTreeNode(app.taclet()), axiomTacletRoot, - ruleExplanations); - } else { - insertAndGroup(new InfoTreeNode(app.taclet()), proveableTacletsRoot, - ruleExplanations); - } - } - } - - axiomTacletRoot - .setUserObject(TACLET_BASE + " (" + getChildCount(axiomTacletRoot) + ")"); - proveableTacletsRoot - .setUserObject(LEMMAS + " (" + getChildCount(proveableTacletsRoot) + ")"); - } - - private int getChildCount(InfoTreeNode root) { - int res = 0; - for (int i = 0; i < root.getChildCount(); i++) { - final InfoTreeNode child = (InfoTreeNode) root.getChildAt(i); - // there is no deeper nesting - final int grandchildren = child.getChildCount(); - res += grandchildren == 0 ? 1 : grandchildren; - } - return res; - } - - /** - * groups subsequent insertions with the same name under a new node - */ - private void insertAndGroup(InfoTreeNode ins, InfoTreeNode parent, - Properties ruleExplanations) { - InfoTreeNode insNode = ins; - if (parent.getChildCount() > 0) { - InfoTreeNode lastNode = - (InfoTreeNode) parent.getChildAt(parent.getChildCount() - 1); - if (getName(insNode).equals(getName(lastNode))) { - if (lastNode.getChildCount() == 0) { - removeNodeFromParent(lastNode); - InfoTreeNode oldParent = parent; - parent = new InfoTreeNode(getName(insNode), ruleExplanations); - insNode.setTitleToAltName(); - lastNode.setTitleToAltName(); - insertAsLast(parent, oldParent); - insertAsLast(lastNode, parent); - } else { - parent = lastNode; - insNode.setTitleToAltName(); - } - } - } - insertAsLast(ins, parent); - } - - private String getName(InfoTreeNode t1) { - if (t1.getUserObject() instanceof Taclet) { - return ((Taclet) t1.getUserObject()).displayName(); - } else { - String title = t1.toString(); - - // strip number of taclets - int parenIdx = title.lastIndexOf('('); - if (parenIdx >= 0) { - return title.substring(0, parenIdx - 1).intern(); - } else { - return title; - } - } - } - - private List sort(Set set) { - final ArrayList l = new ArrayList<>(set); - - l.sort((o1, o2) -> { - final Taclet t1 = o1.taclet(); - final Taclet t2 = o2.taclet(); - return t1.displayName().compareTo(t2.displayName()); - }); - return l; - } - } - -} diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTreeNode.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTreeNode.java deleted file mode 100644 index 86909fc9f95..00000000000 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoTreeNode.java +++ /dev/null @@ -1,97 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.gui; - -import java.util.Properties; -import javax.swing.tree.DefaultMutableTreeNode; - -import de.uka.ilkd.key.pp.LogicPrinter; -import de.uka.ilkd.key.pp.NotationInfo; -import de.uka.ilkd.key.rule.BuiltInRule; -import de.uka.ilkd.key.rule.Rule; -import de.uka.ilkd.key.rule.Taclet; - -/** - * Every node of {@link InfoTree} is an instance of this class. - * - * @author Kai Wallisch - */ -public class InfoTreeNode extends DefaultMutableTreeNode { - - private static final long serialVersionUID = 4187650510339169399L; - // the original rule name - private final String altName; - private String description; - - private Rule rule; - - /* - * This constructor should only be used for the invisible root node of {@link InfoTreeModel}. - */ - InfoTreeNode() { - super("root node"); - altName = null; - description = "This is the root node of InfoTreeModel. It should not be visible."; - } - - /** - * @param title The name of the node. - * @param explanations An XML resource containing node descriptions. - */ - InfoTreeNode(String title, Properties explanations) { - super(title); - - altName = null; - String desc = explanations.getProperty(title); - - if (desc == null) { - description = "No description available for " + title + "."; - } else { - description = desc; - } - - } - - InfoTreeNode(Taclet taclet) { - super(taclet.displayName()); - this.rule = taclet; - altName = taclet.name().toString(); - LogicPrinter lp = LogicPrinter.purePrinter(new NotationInfo(), null); - lp.printTaclet(taclet); - description = lp.result() + "\n\n Defined at:" + taclet.getOrigin() - + "\n\n under options:" + taclet.getChoices(); - } - - InfoTreeNode(String title, String description) { - super(title); - altName = null; - this.description = description; - } - - public InfoTreeNode(BuiltInRule br, Properties ruleExplanations) { - this(br.displayName(), ruleExplanations); - rule = br; - description = "Defined at: " + br.getOrigin(); - } - - String getTitle() { - return (String) getUserObject(); - } - - /** - * switch title to alternative name (i.e., internal rule name) - */ - void setTitleToAltName() { - assert altName != null; - userObject = altName; - } - - String getDescription() { - return description; - } - - public Rule getRule() { - return rule; - } -} diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoView.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoView.java index 46ba554d74a..c3f767d97c4 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoView.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoView.java @@ -7,52 +7,106 @@ import java.awt.event.ComponentListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.*; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.swing.*; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.MutableTreeNode; +import com.google.common.collect.Multimap; +import com.google.common.collect.MultimapBuilder; import de.uka.ilkd.key.core.KeYMediator; import de.uka.ilkd.key.core.KeYSelectionEvent; import de.uka.ilkd.key.core.KeYSelectionListener; -import de.uka.ilkd.key.core.KeYSelectionModel; +import de.uka.ilkd.key.gui.InfoView.InfoNodeFactory.InfoTreeNode; import de.uka.ilkd.key.gui.extension.api.ContextMenuKind; import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension; import de.uka.ilkd.key.gui.extension.api.TabPanel; import de.uka.ilkd.key.gui.extension.impl.KeYGuiExtensionFacade; import de.uka.ilkd.key.gui.fonticons.IconFactory; +import de.uka.ilkd.key.gui.utilities.LexerHighlighter; +import de.uka.ilkd.key.logic.MetaSpace; +import de.uka.ilkd.key.logic.label.TermLabelManager; +import de.uka.ilkd.key.logic.op.ParametricFunctionDecl; +import de.uka.ilkd.key.logic.sort.ParametricSortDecl; +import de.uka.ilkd.key.logic.sort.SortAlias; +import de.uka.ilkd.key.nparser.KeyAst; +import de.uka.ilkd.key.pp.LogicPrinter; +import de.uka.ilkd.key.pp.NotationInfo; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.event.ProofDisposedEvent; import de.uka.ilkd.key.proof.event.ProofDisposedListener; -import de.uka.ilkd.key.rule.Rule; -import de.uka.ilkd.key.util.ThreadUtilities; -import de.uka.ilkd.key.util.XMLResources; +import de.uka.ilkd.key.proof.init.InitConfig; +import de.uka.ilkd.key.proof.mgt.RuleJustification; +import de.uka.ilkd.key.rule.BuiltInRule; +import de.uka.ilkd.key.rule.NoPosTacletApp; +import de.uka.ilkd.key.rule.OneStepSimplifier; +import de.uka.ilkd.key.rule.Taclet; +import de.uka.ilkd.key.scripts.ProofScriptCommand; +import de.uka.ilkd.key.scripts.ProofScriptEngine; +import de.uka.ilkd.key.util.MiscTools; + +import org.key_project.logic.Choice; +import org.key_project.logic.HasMeta; +import org.key_project.logic.Name; +import org.key_project.logic.Namespace; +import org.key_project.logic.op.Function; +import org.key_project.logic.sort.Sort; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.rules.RuleSet; +import org.key_project.util.collection.ImmutableList; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * Class for info contents displayed in {@link MainWindow}. * - * @author Kai Wallisch + * @author Kai Wallisch + * @author weigl */ +@NullMarked public class InfoView extends JSplitPane implements TabPanel { - - private static final long serialVersionUID = -6944612837850368411L; public static final Icon INFO_ICON = IconFactory.INFO_VIEW.get(MainWindow.TAB_ICON_SIZE); - private final InfoTree infoTree; - private final InfoViewContentPane contentPane; - private final XMLResources xmlResources; + private final JTree infoTree = new JTree(); + private final JTextPane contentPane = createInfoArea(); private final ProofDisposedListener proofDisposedListener; - private final KeYSelectionListener selectionListener = new InfoViewSelectionListener(); - private Node lastShownGoalNode; - private MainWindow mainWindow; + private final InfoNodeFactory nodeFactory = new InfoNodeFactory(); + + private LexerHighlighter lexerHighlighter = new LexerHighlighter.KeYLexerHighlighter(); + + + private final KeYSelectionListener selectionListener = new KeYSelectionListener() { + public void selectedProofChanged(KeYSelectionEvent e) { + SwingUtilities.invokeLater(() -> { + if (mediator.getSelectedGoal() != null) { + updateModel(mediator.getSelectedGoal()); + } else if (mediator.getSelectedProof() != null) { + try { + updateModel(mediator.getSelectedProof().openGoals().head()); + } catch (NoSuchElementException ex) { + // nothing possible to do + } + } + }); + } + }; + + private @Nullable Node lastShownGoalNode; private KeYMediator mediator; - public InfoView() { + public InfoView(KeYMediator mediator) { super(VERTICAL_SPLIT); - xmlResources = new XMLResources(); + + setMediator(mediator); // initial placement of the divider setDividerLocation(300); @@ -63,18 +117,13 @@ public InfoView() { // Setting a name for this causes PreferenceSaver to include this class. setName("infoViewPane"); - infoTree = new InfoTree(); - infoTree.addTreeSelectionListener(new TreeSelectionListener() { - @Override - public void valueChanged(TreeSelectionEvent e) { - InfoTreeNode node = infoTree.getLastSelectedPathComponent(); - if (node != null) { - contentPane.setNode(node); - } else { - contentPane.clear(); - } - } - }); + + DefaultMutableTreeNode root = new DefaultMutableTreeNode(); + root.add(nodeFactory.create("No proof loaded", + "In this pane, the available logical rules will be displayed and/or explained.")); + infoTree.setModel(new DefaultTreeModel(root)); + infoTree.setShowsRootHandles(true); + infoTree.setRootVisible(false); lastShownGoalNode = null; @@ -125,7 +174,8 @@ public void mousePressed(MouseEvent e) { private void checkPopup(MouseEvent e) { if (e.isPopupTrigger()) { - Rule selected = infoTree.getLastSelectedPathComponent().getRule(); + Object selected = + ((InfoTreeNode) infoTree.getLastSelectedPathComponent()).getUserObject(); JPopupMenu menu = KeYGuiExtensionFacade.createContextMenu( ContextMenuKind.INFO_TREE, selected, mediator); if (menu.getComponentCount() > 0) { @@ -135,26 +185,32 @@ private void checkPopup(MouseEvent e) { } }); - - contentPane = new InfoViewContentPane(); + infoTree.addTreeSelectionListener(e -> { + InfoTreeNode node = (InfoTreeNode) infoTree.getLastSelectedPathComponent(); + if (node != null) { + contentPane.setText(node.getDescription()); + lexerHighlighter.highlightPaneMarkdown(contentPane); + } else { + contentPane.setText(""); + } + }); setLeftComponent(new JScrollPane(infoTree)); - setRightComponent(contentPane); + setRightComponent(new JScrollPane(contentPane)); KeYGuiExtensionFacade.installKeyboardShortcuts(mediator, this, KeYGuiExtension.KeyboardShortcuts.INFO_VIEW); } - public InfoView(MainWindow window, KeYMediator mediator) { - this(); - setMainWindow(window); - setMediator(mediator); - } - + @Override + public void updateUI() { + // create new lexer highlighter for updating dark/light color + lexerHighlighter = new LexerHighlighter.KeYLexerHighlighter(); + super.updateUI(); + } public void setMediator(KeYMediator m) { - assert m != null; if (mediator != null) { mediator.removeKeYSelectionListener(selectionListener); } @@ -162,9 +218,6 @@ public void setMediator(KeYMediator m) { mediator = m; } - public void setMainWindow(MainWindow w) { - mainWindow = w; - } @Override public String getTitle() { @@ -181,52 +234,301 @@ public JComponent getComponent() { return this; } - private void updateModel(Goal g) { + private void updateModel(@Nullable Goal g) { if (g == null || lastShownGoalNode != g.node()) { if (lastShownGoalNode != null) { lastShownGoalNode.proof().removeProofDisposedListener(proofDisposedListener); } - final InfoTreeModel model; if (g != null) { - model = new InfoTreeModel(g, xmlResources, mainWindow); + infoTree.setModel(new DefaultTreeModel(nodeFactory.createInfoTreeRoot(g))); g.proof().addProofDisposedListener(proofDisposedListener); lastShownGoalNode = g.node(); } else { - model = null; + infoTree.setModel(null); lastShownGoalNode = null; } - contentPane.clear(); - infoTree.setModel(model); + contentPane.setText(""); } } - private class InfoViewSelectionListener implements KeYSelectionListener { + private JTextPane createInfoArea() { + var description = new JTextPane(); + description.setEditable(false); + description.setBorder(BorderFactory.createTitledBorder("")); + description.setCaretPosition(0); + return description; + } + - /** - * focused node has changed - */ - @Override - public void selectedNodeChanged(KeYSelectionEvent e) { + public static class InfoNodeFactory { + private static final String LEMMAS = "Lemmas"; + private static final String TACLET_BASE = "Taclet Base"; + + private static final String COLLECTION = + "This node stands for a category of symbols; expand it to browse the symbols " + + "in the category."; + private static final String DEFAULT_FUNCTIONS_LABEL = + "Display descriptions for documented interpreted function and predicate symbols."; + + + private DefaultMutableTreeNode createInfoTreeRoot(Goal g) { + InfoTreeNode root = create( + "This is the root node of InfoTreeModel. It should not be visible.", ""); + + MetaSpace docs = g.proof().getServices().getNamespaces().docs(); + + root.add(createNodeRules(docs, g)); + root.add(createNodeTermLabels(docs, g.proof())); + root.add(createNodeFunctions(docs, g.proof().getNamespaces().functions())); + root.add(createNodeTacletOptions(docs, g.proof().getInitConfig())); + root.add(createNodeChoices(docs, g.proof().getNamespaces().choices())); + root.add(createNodeRS("Parametric Funcions", docs, g.proof().getNamespaces().parametricFunctions().allElements())); + root.add(createNodeRS("Parametric Sorts", docs, g.proof().getNamespaces().parametricSorts().allElements())); + root.add(createNodeRS("Rule Sets", docs, g.proof().getNamespaces().ruleSets().allElements())); + root.add(createNodeAliases(docs, g.proof().getNamespaces().sortAliases().allElements())); + root.add(createNodeRS("Variables",docs, g.proof().getNamespaces().variables().allElements())); + root.add(createNodeRS("Program Variables", docs, g.proof().getNamespaces().programVariables().allElements())); + root.add(createNodeScripts(docs)); + return root; } - /** - * the selected proof has changed (e.g. a new proof has been loaded) - */ - @Override - public void selectedProofChanged(KeYSelectionEvent e) { - final KeYSelectionModel selectionModel = e.getSource(); - Runnable action = () -> { - if (isVisible()) { - if (selectionModel.getSelectedProof() == null) { - updateModel(null); - } else if (selectionModel.getSelectedGoal() != null) { - // keep old view if an inner node has been selected - updateModel(selectionModel.getSelectedGoal()); - } + private MutableTreeNode createNodeAliases(MetaSpace docs, Collection sortAliases) { + var tlRoot = create("Sort Alias", ""); + for (var alias : sortAliases) { + tlRoot.add(new InfoTreeNode(alias.name().toString(), + () -> "Alias of " + alias.aliasedSort() + "\n" + docs.findDocumentation(alias.aliasedSort()))); + } + return tlRoot; + } + + private MutableTreeNode createNodeRS(String title, MetaSpace docs, Collection ruleSets) { + var tlRoot = create(title, ""); + for (var element : ruleSets) { + tlRoot.add(new InfoTreeNode(element.toString(), () -> docs.findDocumentation(element))); + } + return tlRoot; + } + + private MutableTreeNode createNodePS(MetaSpace docs, Namespace sorts) { + var tlRoot = create("Parametric Sorts", ""); + for (var element : sorts.allElements()) { + tlRoot.add(new InfoTreeNode(element.toString(), () -> docs.findDocumentation(element))); + } + return tlRoot; + } + + private MutableTreeNode createNodePF(MetaSpace docs, Namespace funcs) { + var tlRoot = create("Parametric Functions", ""); + for (var element : funcs.allElements()) { + tlRoot.add(new InfoTreeNode(element.toString(), () -> docs.findDocumentation(element))); + } + return tlRoot; + } + + private InfoTreeNode createNodeChoices(MetaSpace docs, Namespace choices) { + var tlRoot = create("Choices", "Browse descriptions for currently available choices"); + Multimap map = MultimapBuilder.hashKeys().arrayListValues(4).build(); + choices.allElements().forEach((c) -> + map.put(c.category(), new InfoTreeNode(c.name().toString(), () -> docs.findDocumentation(c)))); + for (var s : map.keySet()) { + var cat = new InfoTreeNode(s, () -> docs.findDocumentation(new HasMeta.OptionCategory(s))); + map.get(s).forEach(cat::add); + tlRoot.add(cat); + } + return tlRoot; + } + + private InfoTreeNode createNodeScripts(MetaSpace docs) { + var tlRoot = create("Proof Script Commands", "Browse descriptions for currently available proof script commands."); + ProofScriptEngine.loadCommands().forEach((key, value) -> { + tlRoot.add(new InfoTreeNode(key, () -> value.getDocumentation())); + }); + return tlRoot; + } + + private InfoTreeNode createNodeRules(MetaSpace docs, Goal g) { + var tlRoot = create("Rules", "Browse descriptions for currently available rules."); + + List set = + new ArrayList<>(g.ruleAppIndex().tacletIndex().allNoPosTacletApps()); + OneStepSimplifier simplifier = MiscTools.findOneStepSimplifier(g.proof()); + if (simplifier != null && !simplifier.isShutdown()) { + set.addAll(simplifier.getCapturedTaclets()); + } + set.sort(Comparator.comparing(RuleApp::displayName)); + + tlRoot.add(createNodeBuiltInRules(docs, g)); + tlRoot.add(createNodeAxiom(docs, + set.stream().filter(it -> { + RuleJustification just = g.proof().mgt().getJustification(it); + return just != null && just.isAxiomJustification(); + }))); + + tlRoot.add(createNodeLemmas(docs, set.stream().filter(it -> { + RuleJustification just = g.proof().mgt().getJustification(it); + return just != null && !just.isAxiomJustification(); + }))); + + return tlRoot; + } + + private MutableTreeNode createNodeBuiltInRules(MetaSpace docs, Goal g) { + InfoTreeNode builtInRoot = create("Built-In", + "Some logical rules are implemented in Java code. This is because their semantics " + + + "cannot easily be expressed in KeY's Taclet language."); + ImmutableList rules = + g.ruleAppIndex().builtInRuleAppIndex().builtInRuleIndex().rules(); + for (BuiltInRule br : rules) { + builtInRoot.add(create(br, docs)); + } + return builtInRoot; + } + + private MutableTreeNode createNodeAxiom(MetaSpace docs, Stream seq) { + InfoTreeNode axiomTacletRoot = create(TACLET_BASE, """ + Most logical rules are implemented as Taclets. + + Taclets are schematic logical rules formulated in the Taclet Language.\s + The language is defined and explained in the KeY book. + """); + Map> ruleAppIndex = new TreeMap<>(); + seq.forEach(it -> ruleAppIndex.computeIfAbsent(it.displayName(), k -> new ArrayList<>()) + .add(it)); + + ruleAppIndex.forEach((key, value) -> { + if (value.size() > 1) { + InfoTreeNode group = create("%s (%d)".formatted(key, value.size()), ""); + axiomTacletRoot.add(group); + value.forEach(it -> group.add(create(it.rule(), docs))); + } else { + value.forEach(it -> axiomTacletRoot.add(create(it.rule(), docs))); } - }; - ThreadUtilities.invokeOnEventQueue(action); + }); + var count = ruleAppIndex.values().stream().mapToInt(List::size).sum(); + axiomTacletRoot.setUserObject("%s (%d)".formatted(TACLET_BASE, count)); + return axiomTacletRoot; + } + + private MutableTreeNode createNodeLemmas(MetaSpace docs, Stream seq) { + InfoTreeNode proveableTacletsRoot = create(LEMMAS, + """ + Taclets which have been introduced using File->Load User-Defined Taclets are filed here. + + Loading User Defined Taclets opens side branches on which the soundness of the lemma taclets must be established. + """); + seq.forEach(it -> proveableTacletsRoot.add(create(it.rule(), docs))); + return proveableTacletsRoot; } + private MutableTreeNode createNodeTermLabels(MetaSpace docs, Proof proof) { + var tlRoot = + create("Term Labels", "Show descriptions for currently available term labels."); + var mgr = TermLabelManager.getTermLabelManager(proof.getServices()); + var factories = mgr.getFactories(); + + var labelNames = new ArrayList<>(factories.keySet()); + labelNames.sort(Comparator.comparing(Name::toString)); + + for (Name name : labelNames) { + tlRoot.add(new InfoTreeNode(name.toString(), + () -> factories.get(name).getDocumentation())); + } + return tlRoot; + } + + private InfoTreeNode createNodeFunctions(MetaSpace docs, Namespace functions) { + var fnRoot = create("Function Symbols", DEFAULT_FUNCTIONS_LABEL); + var fnByName = create("By Name", DEFAULT_FUNCTIONS_LABEL); + var fnByReturnType = create("By Return Type", DEFAULT_FUNCTIONS_LABEL); + + fnRoot.add(fnByName); + fnRoot.add(fnByReturnType); + + var seq = new ArrayList<>(functions.allElements()); + seq.sort(Comparator.comparing(it -> it.name().toString())); + + var byReturn = new TreeMap>( + Comparator.comparing(it -> it.name().toString())); + + for (var fn : seq) { + var fnName = "%s(%s) : %s".formatted( + fn.name(), + fn.argSorts().stream().map(it -> it.name().toString()) + .collect(Collectors.joining(", ")), + fn.sort().name()); + var fnSort = fn.sort(); + + // flat list: + Supplier stringSupplier = () -> docs.findDocumentation(fn); + fnByName.add(new InfoTreeNode(fnName, stringSupplier)); + + // by return type + byReturn.putIfAbsent(fnSort, new ArrayList<>()); + byReturn.get(fnSort).add(new InfoTreeNode(fnName, stringSupplier)); + } + + for (var entry : byReturn.entrySet()) { + var node = create(entry.getKey().name().toString(), ""); + entry.getValue().forEach(node::add); + fnByReturnType.add(node); + } + + return fnRoot; + } + + private InfoTreeNode createNodeTacletOptions(MetaSpace docs, InitConfig initConfig) { + InfoTreeNode localRoot = + create("Active Taclet Options", "Shows the activated Taclet options"); + for (Choice activatedChoice : initConfig.getActivatedChoices()) { + localRoot.add( + create(activatedChoice.name().toString(), + docs.findDocumentation(activatedChoice))); + } + return localRoot; + } + + + public InfoTreeNode create(Taclet taclet, MetaSpace metaSpace) { + LogicPrinter lp = LogicPrinter.purePrinter(new NotationInfo(), null); + lp.printTaclet(taclet); + String doc = metaSpace.findDocumentation(taclet); + String origin = metaSpace.findOrigin(taclet); + + return create(taclet.name().toString(), + () -> (doc != null ? doc + "\n\n" : "") + + ("```key\n%s\n```\n\n".formatted(lp.result())) + + ("Defined at: %s \n under options: (%s)".formatted(origin, + taclet.getChoices()))); + } + + public InfoTreeNode create(BuiltInRule br, MetaSpace docs) { + var description = "Defined at in Java class" + br.getClass(); + return create(br.displayName(), () -> Stream.of(docs.findDocumentation(br), description) + .filter(Objects::nonNull) + .collect(Collectors.joining("\n\n"))); + } + + public InfoTreeNode create(String title, String description) { + return create(title, () -> description); + } + + public InfoTreeNode create(String title, Supplier description) { + return new InfoTreeNode(title, description); + } + + + public static class InfoTreeNode extends DefaultMutableTreeNode { + private final Supplier<@Nullable String> description; + + public InfoTreeNode(String name, Supplier<@Nullable String> description) { + super(name); + this.description = description; + } + + public @Nullable String getDescription() { + return description.get(); + } + } } } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoViewContentPane.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoViewContentPane.java deleted file mode 100644 index 3f61f68933e..00000000000 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/InfoViewContentPane.java +++ /dev/null @@ -1,42 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.gui; - -import javax.swing.BorderFactory; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; - -/** - * This class is used to display descriptions in {@link InfoView}. - * - * @author Kai Wallisch - */ -public class InfoViewContentPane extends JScrollPane { - - /** - * - */ - private static final long serialVersionUID = -7609483136106706196L; - private final JTextArea description; - - InfoViewContentPane() { - description = new JTextArea("", 15, 30); - description.setEditable(false); - description.setLineWrap(true); - description.setWrapStyleWord(true); - setViewportView(description); - } - - public void setNode(InfoTreeNode node) { - setBorder(BorderFactory.createTitledBorder(node.getTitle())); - description.setText(node.getDescription()); - description.setCaretPosition(0); - } - - public void clear() { - setBorder(BorderFactory.createTitledBorder("Description")); - description.setText(""); - } - -} diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooserLoadingOptions.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooserLoadingOptions.java index c6e35409d7e..73a8a919a25 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooserLoadingOptions.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/KeYFileChooserLoadingOptions.java @@ -3,21 +3,24 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.gui; -import java.util.Arrays; -import java.util.Objects; +import java.util.ArrayList; +import java.util.Map; import java.util.ServiceLoader; import javax.swing.*; +import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension; +import de.uka.ilkd.key.gui.extension.impl.KeYGuiExtensionFacade; import de.uka.ilkd.key.gui.settings.SettingsPanel; -import de.uka.ilkd.key.proof.init.AbstractProfile; import de.uka.ilkd.key.proof.init.DefaultProfileResolver; import de.uka.ilkd.key.proof.init.Profile; +import de.uka.ilkd.key.settings.Configuration; import net.miginfocom.layout.AC; import net.miginfocom.layout.CC; import net.miginfocom.layout.LC; import net.miginfocom.swing.MigLayout; import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.NonNull; public class KeYFileChooserLoadingOptions extends JPanel { private final JLabel lblProfile = new JLabel("Profile:"); @@ -39,6 +42,11 @@ public class KeYFileChooserLoadingOptions extends JPanel { Mark this checkbox to only load the selected Java file. """); + private final Map additionalOptionPanels = + KeYGuiExtensionFacade.createAdditionalOptionPanels(); + + + private KeYGuiExtension.@Nullable OptionPanel currentOptionPanel = null; public KeYFileChooserLoadingOptions(KeYFileChooser chooser) { setLayout(new MigLayout(new LC().fillX().wrapAfter(3).maxWidth("400"), @@ -48,16 +56,23 @@ public KeYFileChooserLoadingOptions(KeYFileChooser chooser) { lblProfileInfo.setWrapStyleWord(true); lblProfileInfo.setLineWrap(true); - var items = ServiceLoader.load(DefaultProfileResolver.class) - .stream().map(it -> it.get().getDefaultProfile()) - .map(ProfileWrapper::new) - .toArray(ProfileWrapper[]::new); + var profiles = + new ArrayList<>(ServiceLoader.load(DefaultProfileResolver.class) + .stream().map(it -> it.get().getDefaultProfile()) + .map(ProfileWrapper::new) + .toList()); + + final var legacyMode = new ProfileWrapper("Respect profile given in file", "", + "Usable on KeY file which defines \\profile inside the file. " + + "If no KeY file is loaded, falls back to legacy behavior", + null); + + profiles.addFirst(legacyMode); + + var items = profiles.toArray(ProfileWrapper[]::new); + cboProfile.setModel(new DefaultComboBoxModel<>(items)); - cboProfile.setSelectedItem( - Arrays.stream(items) - .filter(it -> it.profile.equals(AbstractProfile.getDefaultProfile())) - .findFirst() - .orElse(null)); + cboProfile.setSelectedItem(legacyMode); cboProfile.addItemListener(evt -> updateProfileInfo()); updateProfileInfo(); @@ -78,34 +93,56 @@ private void updateProfileInfo() { } private void updateProfileInfo(@Nullable ProfileWrapper selectedItem) { + if (currentOptionPanel != null) { + currentOptionPanel.deinstall(this); + } + if (selectedItem == null) { lblProfileInfo.setText(""); } else { - lblProfileInfo.setText(selectedItem.profile.description()); + lblProfileInfo.setText(selectedItem.description()); + if (additionalOptionPanels.containsKey(selectedItem.profile)) { + currentOptionPanel = additionalOptionPanels.get(selectedItem.profile); + currentOptionPanel.install(this); + } } } public @Nullable Profile getSelectedProfile() { - var selected = getSelectedProfileName(); - var items = ServiceLoader.load(DefaultProfileResolver.class) - .stream().filter(it -> Objects.equals(selected, it.get().getProfileName())) - .findFirst(); - return items.map(it -> it.get().getDefaultProfile()) - .orElse(null); + var selected = (ProfileWrapper) cboProfile.getSelectedItem(); + if (selected == null) { + return null; + } + return selected.profile(); + } + + public @Nullable Configuration getAdditionalProfileOptions() { + if (currentOptionPanel == null) { + return null; + } + return currentOptionPanel.getResult(); } public @Nullable String getSelectedProfileName() { - return ((ProfileWrapper) cboProfile.getSelectedItem()).profile().ident(); + final var selectedItem = (ProfileWrapper) cboProfile.getSelectedItem(); + if (selectedItem == null) + return null; + return selectedItem.ident(); } public boolean isOnlyLoadSingleJavaFile() { return lblSingleJava.isSelected(); } - record ProfileWrapper(Profile profile) { + record ProfileWrapper(String name, String ident, String description, + @Nullable Profile profile) { + ProfileWrapper(Profile profile) { + this(profile.displayName(), profile.ident(), profile.description(), profile); + } + @Override - public String toString() { - return profile.displayName(); + public @NonNull String toString() { + return name; } } } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/MainWindow.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/MainWindow.java index 77bc4ab4aff..218695387d4 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/MainWindow.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/MainWindow.java @@ -56,11 +56,9 @@ import de.uka.ilkd.key.gui.sourceview.SourceViewFrame; import de.uka.ilkd.key.gui.utilities.LruCached; import de.uka.ilkd.key.proof.*; +import de.uka.ilkd.key.proof.init.Profile; import de.uka.ilkd.key.proof.io.ProblemLoader; -import de.uka.ilkd.key.settings.FeatureSettings; -import de.uka.ilkd.key.settings.GeneralSettings; -import de.uka.ilkd.key.settings.ProofIndependentSettings; -import de.uka.ilkd.key.settings.ViewSettings; +import de.uka.ilkd.key.settings.*; import de.uka.ilkd.key.smt.SolverTypeCollection; import de.uka.ilkd.key.smt.solvertypes.SolverType; import de.uka.ilkd.key.ui.AbstractMediatorUserInterfaceControl; @@ -81,6 +79,7 @@ import com.formdev.flatlaf.FlatLightLaf; import com.formdev.flatlaf.util.SystemInfo; import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -323,10 +322,10 @@ private MainWindow() { proofListView = new JScrollPane(proofList); notificationManager = new NotificationManager(mediator, this); - recentFileMenu = new RecentFileMenu(mediator); + recentFileMenu = new RecentFileMenu(this); proofTreeView = new ProofTreeView(mediator); - infoView = new InfoView(this, mediator); + infoView = new InfoView(mediator); strategySelectionView = new StrategySelectionView(this, mediator); openGoalsView = new GoalList(mediator); @@ -1390,8 +1389,11 @@ public NotificationManager getNotificationManager() { * * @see RecentFileMenu#addRecentFile(String) */ - public void addRecentFile(@NonNull String absolutePath) { - recentFileMenu.addRecentFile(absolutePath); + public void addRecentFile(@NonNull String absolutePath, + @Nullable Profile profile, + boolean singleJava, + @Nullable Configuration additionalOption) { + recentFileMenu.addRecentFile(absolutePath, profile, singleJava, additionalOption); } public void openExamples() { diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/MainWindowTabbedPane.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/MainWindowTabbedPane.java index 5e24a53fe68..28a93432cbc 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/MainWindowTabbedPane.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/MainWindowTabbedPane.java @@ -32,7 +32,7 @@ public class MainWindowTabbedPane extends JTabbedPane { assert mainWindow != null; proofTreeView = new ProofTreeView(mediator); - InfoView infoView = new InfoView(mainWindow, mediator); + InfoView infoView = new InfoView(mediator); StrategySelectionView strategySelectionView = new StrategySelectionView(mainWindow, mediator); GoalList openGoalsView = new GoalList(mediator); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/RecentFileMenu.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/RecentFileMenu.java index 61af8cacd0c..9e0018fcf2c 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/RecentFileMenu.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/RecentFileMenu.java @@ -3,19 +3,21 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.gui; -import java.awt.event.ActionListener; -import java.io.*; +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.stream.Collectors; +import java.util.*; import javax.swing.*; -import de.uka.ilkd.key.core.KeYMediator; +import de.uka.ilkd.key.gui.actions.KeyAction; import de.uka.ilkd.key.gui.fonticons.IconFactory; +import de.uka.ilkd.key.nparser.ParsingFacade; +import de.uka.ilkd.key.proof.init.DefaultProfileResolver; +import de.uka.ilkd.key.proof.init.Profile; import de.uka.ilkd.key.settings.Configuration; import de.uka.ilkd.key.settings.PathConfig; @@ -23,6 +25,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static de.uka.ilkd.key.gui.actions.QuickSaveAction.QUICK_SAVE_PATH; + /** * This class offers a mechanism to manage recent files; it adds the necessary menu items to a menu * or even can provide that menu itself. also it offers a way to read the recent files from a @@ -40,6 +44,8 @@ public class RecentFileMenu { */ private static final int MAX_RECENT_FILES = 8; + private final MainWindow mainWindow; + /** * this is the maximal number of recent files. */ @@ -50,19 +56,10 @@ public class RecentFileMenu { */ private final JMenu menu; - /** - * the actionListener to be notified of mouse-clicks or other actionevents on the menu items - */ - private final ActionListener lissy; - - /** - * recent files, unique by path - */ - private final Map pathToRecentFile = new LinkedHashMap<>(); /** * Mapping from menu item to entry */ - private final HashMap menuItemToRecentFile; + private final List recentFiles = new ArrayList<>(); private RecentFileEntry mostRecentFile; @@ -71,97 +68,77 @@ public class RecentFileMenu { * * @param mediator Key mediator */ - public RecentFileMenu(final KeYMediator mediator) { + public RecentFileMenu(final MainWindow mediator) { + this.mainWindow = mediator; this.menu = new JMenu("Recent Files"); - this.lissy = e -> { - String absPath = getAbsolutePath((JMenuItem) e.getSource()); - Path file = Paths.get(absPath); - - // special case proof bundles -> allow to select the proof to load - if (ProofSelectionDialog.isProofBundle(file)) { - Path proofPath = ProofSelectionDialog.chooseProofToLoad(file); - if (proofPath == null) { - // canceled by user! - } else { - mediator.getUI().loadProofFromBundle(file, proofPath); - } - } else { - mediator.getUI().loadProblem(file); - } - }; this.maxNumberOfEntries = MAX_RECENT_FILES; - this.menuItemToRecentFile = new LinkedHashMap<>(); - - menu.setEnabled(menu.getItemCount() != 0); + // menu.setEnabled(menu.getItemCount() != 0); menu.setIcon(IconFactory.recentFiles(16)); loadFrom(PathConfig.getRecentFileStorage()); } private void insertFirstEntry(RecentFileEntry entry) { - menu.insert(entry.getMenuItem(), 0); + menu.insert(entry.createMenuItem(), 0); mostRecentFile = entry; + recentFiles.addFirst(entry); } /** * add path to the menu */ - private void addNewToModelAndView(final String path) { + private void addNewToModelAndView(final String path, + @Nullable Profile profile, + boolean singleJava, @Nullable Configuration additionalOption) { // do not add quick save location to recent files - if (de.uka.ilkd.key.gui.actions.QuickSaveAction.QUICK_SAVE_PATH.endsWith(path)) { + if (QUICK_SAVE_PATH.endsWith(path)) { return; } if (new File(path).exists()) { - final RecentFileEntry entry = new RecentFileEntry(path); - pathToRecentFile.put(entry.getAbsolutePath(), entry); + var entry = new RecentFileEntry(path, profile != null ? profile.ident() : null, + singleJava, additionalOption); + insertFirstEntry(entry); // Recalculate unique names - final String[] paths = pathToRecentFile.keySet().toArray(String[]::new); + final String[] paths = + recentFiles.stream().map(RecentFileEntry::getAbsolutePath).toArray(String[]::new); final ShortUniqueFileNames.Name[] names = ShortUniqueFileNames.makeUniqueNames(paths); + // Set the names - for (ShortUniqueFileNames.Name name : names) { - pathToRecentFile.get(name.getPath()).setName(name.getName()); + for (int i = 0; i < names.length; i++) { + var text = names[i].toString(); + recentFiles.get(i).createMenuItem().getAction().putValue(Action.NAME, text); } - - // Insert the menu item - final JMenuItem item = entry.getMenuItem(); - menuItemToRecentFile.put(item, entry); - item.addActionListener(lissy); - - insertFirstEntry(entry); } } - /** - * - */ - private String getAbsolutePath(JMenuItem item) { - return menuItemToRecentFile.get(item).getAbsolutePath(); - } - - private void addRecentFileNoSave(final String path) { + private void addRecentFileNoSave(final String path, + @Nullable Profile profile, + boolean singleJava, + @Nullable Configuration additionalOption) { LOGGER.trace("Adding file: {}", path); - final RecentFileEntry existingEntry = pathToRecentFile.get(path); + + Optional existingEntry = recentFiles.stream() + .filter(it -> path.equals(it.getAbsolutePath())).findFirst(); // Add the path to the recentFileList: // check whether this path is already there - if (existingEntry != null) { - menu.remove(existingEntry.getMenuItem()); - insertFirstEntry(existingEntry); + if (existingEntry.isPresent()) { + var entry = existingEntry.get(); + recentFiles.remove(entry); + menu.remove(entry.createMenuItem()); + insertFirstEntry(entry); return; } // if appropriate, remove the last entry. if (menu.getItemCount() == maxNumberOfEntries) { - final JMenuItem item = menu.getItem(menu.getItemCount() - 1); - final RecentFileEntry entry = menuItemToRecentFile.get(item); - menuItemToRecentFile.remove(entry.getMenuItem()); - pathToRecentFile.remove(entry.getAbsolutePath()); - menu.remove(entry.getMenuItem()); + var lastEntry = recentFiles.removeLast(); + menu.remove(lastEntry.createMenuItem()); } - addNewToModelAndView(path); + addNewToModelAndView(path, profile, singleJava, additionalOption); menu.setEnabled(menu.getItemCount() != 0); } @@ -172,9 +149,12 @@ private void addRecentFileNoSave(final String path) { * the end. (set the maximum number with the {@link #setMaxNumberOfEntries(int i)} method). * * @param path the path of the file. + * @param singleJava */ - public void addRecentFile(final String path) { - addRecentFileNoSave(path); + public void addRecentFile(final String path, + @Nullable Profile profile, boolean singleJava, + @Nullable Configuration additionalOption) { + addRecentFileNoSave(path, profile, singleJava, additionalOption); save(); } @@ -204,14 +184,23 @@ public JMenu getMenu() { */ public final void loadFrom(Path filename) { try { - var c = Configuration.load(filename); - c.getStringList("recentFiles").forEach(this::addRecentFileNoSave); + var file = ParsingFacade.parseConfigurationFile(filename); + List recent = file.asConfigurationList(); + this.recentFiles.clear(); + for (var c : recent) { + final var e = new RecentFileEntry(c); + if (mostRecentFile != null) { + mostRecentFile = e; + } + recentFiles.add(e); + menu.add(e.createMenuItem()); + } } catch (FileNotFoundException ex) { - LOGGER.debug("Could not read RecentFileList. Did not find file {}", filename); + LOGGER.info("Could not read RecentFileList. Did not find file {}", filename); } catch (IOException ioe) { - LOGGER.debug("Could not read RecentFileList. Some IO Error occured ", ioe); - } catch (Throwable t) { - LOGGER.debug("Could not read RecentFileList. Some Error occured ", t); + LOGGER.error("Could not read RecentFileList. Some IO Error occured ", ioe); + } catch (Exception ioe) { + LOGGER.error("Could not read RecentFileList.", ioe); } } @@ -228,14 +217,11 @@ public String getMostRecent() { * exists) and then re-written so no information will be lost. */ public void store(Path filename) { - Configuration c = new Configuration(); - var seq = menuItemToRecentFile.values().stream() - .map(RecentFileEntry::getAbsolutePath) - .collect(Collectors.toList()); - c.set("recentFiles", seq); - + List config = + recentFiles.stream().map(RecentFileEntry::asConfiguration).toList(); try (var fin = Files.newBufferedWriter(filename)) { - c.save(fin, ""); + var writer = new Configuration.ConfigurationWriter(fin); + writer.printValue(config); } catch (IOException ex) { LOGGER.info("Could not write recent files list ", ex); } @@ -245,37 +231,107 @@ public void save() { store(PathConfig.getRecentFileStorage()); } - private static class RecentFileEntry { - /** - * full path - */ - private final String absolutePath; - /** - * the associated menu item - */ - private final JMenuItem menuItem; - - public RecentFileEntry(String absolutePath) { - this.menuItem = new JMenuItem(); - this.menuItem.setToolTipText(absolutePath); - this.absolutePath = absolutePath; + public class RecentFileEntry { + public static final String KEY_PATH = "path"; + public static final String KEY_PROFILE = "profile"; + public static final String KEY_OPTIONS = "options"; + private static final String KEY_LOAD_SINGLE_JAVA = "singleJava"; + + private @Nullable JMenuItem menuItem; + + private final String path; + private final @Nullable String profile; + private final boolean singleJava; + private final @Nullable Configuration additionalOption; + + public RecentFileEntry( + String path, + @Nullable String profile, + boolean singleJava, + @Nullable Configuration additionalOption) { + this.additionalOption = additionalOption; + this.path = path; + this.profile = profile; + this.singleJava = singleJava; } - public String getAbsolutePath() { - return absolutePath; + public RecentFileEntry(Configuration options) { + this(Objects.requireNonNull(options.getString(KEY_PATH)), + options.getString(KEY_PROFILE), + options.getBool(KEY_LOAD_SINGLE_JAVA, false), + options.getTable(KEY_OPTIONS)); } - public void setName(String name) { - this.menuItem.setText(name); + public Configuration asConfiguration() { + Configuration config = new Configuration(); + config.set(KEY_PATH, path); + config.set(KEY_PROFILE, (Object) profile); + config.set(KEY_LOAD_SINGLE_JAVA, singleJava); + config.set(KEY_OPTIONS, additionalOption); + return config; } - public JMenuItem getMenuItem() { + public String getAbsolutePath() { + return path; + } + + public JMenuItem createMenuItem() { + if (menuItem == null) { + menuItem = new JMenuItem(new RecentFileAction(this)); + } return menuItem; } + } + + private class RecentFileAction extends KeyAction { + private final RecentFileEntry fileEntry; + + public RecentFileAction(RecentFileEntry fileEntry) { + this.fileEntry = fileEntry; + setName(fileEntry.getAbsolutePath()); + setTooltip(fileEntry.getAbsolutePath()); + } @Override - public String toString() { - return absolutePath; + public void actionPerformed(ActionEvent actionEvent) { + String absPath = fileEntry.getAbsolutePath(); + Path file = Paths.get(absPath); + + // special case proof bundles -> allow to select the proof to load + if (ProofSelectionDialog.isProofBundle(file)) { + Path proofPath = ProofSelectionDialog.chooseProofToLoad(file); + if (proofPath == null) { + // canceled by user! + } else { + mainWindow.loadProofFromBundle(file, proofPath); + } + } else { + String profileName = fileEntry.profile; + var selectedProfile = + ServiceLoader.load(DefaultProfileResolver.class) + .stream() + .filter(it -> it.get().getProfileName().equals(profileName)) + .findFirst() + .map(it -> it.get().getDefaultProfile()); + + + if (profileName != null && selectedProfile.isEmpty()) { + JOptionPane.showMessageDialog(mainWindow, + "Could not find previous selected profile %s.".formatted(profileName)); + return; + } + + var profile = selectedProfile.orElse(null); + var additionalProfileOptions = fileEntry.additionalOption; + + mainWindow.loadProblem(file, pl -> { + if (profile != null) { + pl.setProfileOfNewProofs(profile); + //pl.setAdditionalProfileOptions(additionalProfileOptions); + } + pl.setLoadSingleJavaFile(fileEntry.singleJava); + }); + } } } } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/WindowUserInterfaceControl.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/WindowUserInterfaceControl.java index 3b530ba32c0..a5ac60a5c51 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/WindowUserInterfaceControl.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/WindowUserInterfaceControl.java @@ -97,9 +97,12 @@ public boolean isAutoModeSupported(Proof proof) { public void loadProblem(Path file, Consumer configure) { - mainWindow.addRecentFile(file.toAbsolutePath().toString()); ProblemLoader problemLoader = getProblemLoader(file, null, null, null, getMediator()); configure.accept(problemLoader); + mainWindow.addRecentFile(file.toAbsolutePath().toString(), + problemLoader.getProfileOfNewProofs(), + problemLoader.isLoadSingleJavaFile(), + null); problemLoader.runAsynchronously(); } @@ -112,16 +115,14 @@ public void loadProblem(Path file, Consumer configure) { */ public void loadProblem(Path file, @Nullable List classPath, @Nullable Path bootClassPath, @Nullable List includes) { - mainWindow.addRecentFile(file.toAbsolutePath().toString()); + mainWindow.addRecentFile(file.toAbsolutePath().toString(), null, false, null); ProblemLoader problemLoader = getProblemLoader(file, classPath, bootClassPath, includes, getMediator()); problemLoader.runAsynchronously(); } public void loadProblem(Path file, Profile profile) { - loadProblem(file, (pl) -> { - pl.setProfileOfNewProofs(profile); - }); + loadProblem(file, (pl) -> pl.setProfileOfNewProofs(profile)); } @Override @@ -131,7 +132,7 @@ public void loadProblem(Path file) { @Override public void loadProofFromBundle(Path proofBundle, Path proofFilename) { - mainWindow.addRecentFile(proofBundle.toAbsolutePath().toString()); + mainWindow.addRecentFile(proofBundle.toAbsolutePath().toString(), null, false, null); ProblemLoader problemLoader = getProblemLoader(proofBundle, null, null, null, getMediator()); problemLoader.setProofPath(proofFilename); @@ -369,7 +370,8 @@ public AbstractProblemLoader load(Profile profile, Path file, List classPa boolean forceNewProfileOfNewProofs, Consumer callback) throws ProblemLoaderException { if (file != null) { - mainWindow.getRecentFiles().addRecentFile(file.toAbsolutePath().toString()); + mainWindow.getRecentFiles().addRecentFile(file.toAbsolutePath().toString(), profile, + false, null); } try { getMediator().stopInterface(true); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java index c0682f40938..b2ede4142d7 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenFileAction.java @@ -10,6 +10,7 @@ import de.uka.ilkd.key.core.Main; import de.uka.ilkd.key.gui.KeYFileChooser; +import de.uka.ilkd.key.gui.KeYFileChooserLoadingOptions; import de.uka.ilkd.key.gui.MainWindow; import de.uka.ilkd.key.gui.ProofSelectionDialog; import de.uka.ilkd.key.gui.fonticons.IconFactory; @@ -29,7 +30,7 @@ public OpenFileAction(MainWindow mainWindow) { public void actionPerformed(ActionEvent e) { KeYFileChooser fc = new KeYFileChooser(lastSelectedPath); fc.setDialogTitle("Select file to load proof or problem"); - var options = fc.addLoadingOptions(); + KeYFileChooserLoadingOptions options = fc.addLoadingOptions(); fc.addBookmarkPanel(); fc.prepare(); fc.setFileFilter(KeYFileChooser.DEFAULT_FILTER); @@ -64,9 +65,11 @@ public void actionPerformed(ActionEvent e) { } var selectedProfile = options.getSelectedProfile(); + var additionalProfileOptions = options.getAdditionalProfileOptions(); mainWindow.loadProblem(file, pl -> { if (selectedProfile != null) { pl.setProfileOfNewProofs(selectedProfile); + //pl.setAdditionalProfileOptions(additionalProfileOptions); } pl.setLoadSingleJavaFile(options.isOnlyLoadSingleJavaFile()); }); diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenSingleJavaFileAction.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenSingleJavaFileAction.java index c97ab4b2aed..4206b2da39f 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenSingleJavaFileAction.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/actions/OpenSingleJavaFileAction.java @@ -39,7 +39,8 @@ public void actionPerformed(ActionEvent e) { if (result == JFileChooser.APPROVE_OPTION) { Path file = fc.getSelectedFile().toPath(); - mainWindow.addRecentFile(file.toAbsolutePath().toString()); + mainWindow.addRecentFile(file.toAbsolutePath().toString(), + null, true, null); WindowUserInterfaceControl ui = mainWindow.getUserInterface(); ProblemLoader pl = ui.getProblemLoader(file, Collections.emptyList(), null, diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java index b84924b1591..3b22ff07ce5 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/api/KeYGuiExtension.java @@ -7,24 +7,25 @@ import java.lang.annotation.RetentionPolicy; import java.util.Collection; import java.util.List; +import java.util.function.Supplier; import javax.swing.Action; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JToolBar; import de.uka.ilkd.key.core.KeYMediator; -import de.uka.ilkd.key.gui.GoalList; -import de.uka.ilkd.key.gui.InfoView; -import de.uka.ilkd.key.gui.MainWindow; -import de.uka.ilkd.key.gui.StrategySelectionView; +import de.uka.ilkd.key.gui.*; import de.uka.ilkd.key.gui.keyshortcuts.KeyStrokeManager; import de.uka.ilkd.key.gui.nodeviews.SequentView; import de.uka.ilkd.key.gui.prooftree.ProofTreeView; import de.uka.ilkd.key.gui.settings.SettingsProvider; import de.uka.ilkd.key.gui.sourceview.SourceView; import de.uka.ilkd.key.pp.PosInSequent; +import de.uka.ilkd.key.proof.init.Profile; +import de.uka.ilkd.key.settings.Configuration; -import org.jspecify.annotations.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.NullMarked; /** * A marker interface for extension of the KeY GUI. Every extension should implement this interface @@ -38,6 +39,7 @@ * @author Alexander Weigl * @version 1 (07.04.19) */ +@NullMarked public interface KeYGuiExtension { @Retention(RetentionPolicy.RUNTIME) @interface Info { @@ -73,8 +75,6 @@ public interface KeYGuiExtension { /** * Loading priority of this extension. Baseline is zero - * - * @return */ int priority() default 0; @@ -102,8 +102,7 @@ interface MainMenu { * @return non-null, emptiable list of actions. * @see de.uka.ilkd.key.gui.actions.KeyAction */ - @NonNull - List getMainMenuActions(@NonNull MainWindow mainWindow); + List getMainMenuActions(MainWindow mainWindow); } /** @@ -139,8 +138,7 @@ interface LeftPanel { * @param window parent of this extension * @param mediator the current mediator */ - @NonNull - Collection getPanels(@NonNull MainWindow window, @NonNull KeYMediator mediator); + Collection getPanels(MainWindow window, KeYMediator mediator); } /** @@ -163,10 +161,8 @@ interface ContextMenu { * @return non-null, emptiable list of actions. * @see de.uka.ilkd.key.gui.actions.KeyAction */ - @NonNull - List getContextActions(@NonNull KeYMediator mediator, - @NonNull ContextMenuKind kind, - @NonNull T underlyingObject); + List getContextActions(KeYMediator mediator, ContextMenuKind kind, + @Nullable T underlyingObject); } /** @@ -181,7 +177,6 @@ interface Toolbar { * @param mainWindow the parent of the toolbar * @return non-null */ - @NonNull JToolBar getToolbar(MainWindow mainWindow); } @@ -244,9 +239,6 @@ interface KeyboardShortcuts { String SOURCE_VIEW = SourceView.class.getName(); /** - * @param - * @param mediator - * @param component * @return non-null settings provider */ Collection getShortcuts(KeYMediator mediator, String componentId, @@ -266,11 +258,50 @@ interface TermInfo { * @param pos the position of the term whose info shall be shown. * @return this extension's term information. */ - @NonNull - List getTermInfoStrings(@NonNull MainWindow mainWindow, @NonNull PosInSequent pos); + List getTermInfoStrings(MainWindow mainWindow, PosInSequent pos); default int getTermLabelPriority() { return 0; } } + + /// A {@link LoadOptionPanel} provides additional UI components in the file selection dialog + /// dependent on the selected profile. + /// + /// Implementing this interface requires to provide an {@link OptionPanel}, and associated + /// {@link Profile}. + /// + /// @author weigl + interface LoadOptionPanel extends Supplier { + Profile getProfile(); + } + + /// A provider of UI components for additional options w.r.t. specific profiles. + /// **Lifecycle:** For each {@link Profile} an {@link OptionPanel} is constructed, when the + /// {@link KeYFileChooser} + /// is instantiated. *On selected of a profile*, the current {@link OptionPanel} is + /// `deinstall`ed, and the + /// {@link OptionPanel} for the selected profile is `install`ed. + /// + /// @author weigl + /// @see KeYFileChooserLoadingOptions + interface OptionPanel { + /// Installs the UI components in the given {@link KeYFileChooserLoadingOptions} instance. + /// UI components + /// can be reused, to keep the temporary state. + /// {@link KeYFileChooserLoadingOptions} uses the {@link net.miginfocom.swing.MigLayout} to + /// manage the layout. + void install(KeYFileChooserLoadingOptions panel); + + /// Removes all *installed* UI components from the panel. + void deinstall(KeYFileChooserLoadingOptions panel); + + /// Returning an arbitrary object, representing the selected option in the UI components. + /// The object needs to compatible with the assigned profile in {@link LoadOptionPanel}. + /// + /// @see Profile#prepareInitConfig(InitConfig, Object) + @SuppressWarnings("JavadocReference") + @Nullable + Configuration getResult(); + } } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java index a3f270f62ee..908886557db 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/extension/impl/KeYGuiExtensionFacade.java @@ -17,9 +17,14 @@ import de.uka.ilkd.key.gui.actions.KeyAction; import de.uka.ilkd.key.gui.extension.api.ContextMenuKind; import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension; +import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension.LoadOptionPanel; +import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension.OptionPanel; import de.uka.ilkd.key.gui.extension.api.TabPanel; import de.uka.ilkd.key.pp.PosInSequent; import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.init.Profile; + +import org.jspecify.annotations.Nullable; import org.jspecify.annotations.Nullable; @@ -237,7 +242,7 @@ public static List getContextMenuExtensions() { * @param mediator the KeY mediator * @return populated context menu */ - public static JPopupMenu createContextMenu(ContextMenuKind kind, Object underlyingObject, + public static JPopupMenu createContextMenu(ContextMenuKind kind, T underlyingObject, KeYMediator mediator) { JPopupMenu menu = new JPopupMenu(); if (underlyingObject instanceof Proof proof) { @@ -401,6 +406,19 @@ public static Stream getTermInfoStrings(MainWindow mainWindow, PosInSequ .flatMap(it -> it.getTermInfoStrings(mainWindow, mousePos).stream()); } + /** + * Helper methods that finds matches {@link Profile} and {@link OptionPanel} together. + * This information are provided by {@link LoadOptionPanel} interface. + */ + public static Map createAdditionalOptionPanels() { + List items = getExtensionInstances(LoadOptionPanel.class); + HashMap map = HashMap.newHashMap(4); + for (LoadOptionPanel item : items) { + map.put(item.getProfile(), item.get()); + } + return map; + } + /** * Disables the clazz from further loading. *

diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/InnerNodeView.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/InnerNodeView.java index 2ea3152d913..1166fe79f2b 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/InnerNodeView.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/InnerNodeView.java @@ -15,6 +15,7 @@ import de.uka.ilkd.key.gui.MainWindow; import de.uka.ilkd.key.gui.colors.ColorSettings; +import de.uka.ilkd.key.gui.utilities.LexerHighlighter; import de.uka.ilkd.key.pp.*; import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; @@ -56,7 +57,7 @@ public final class InnerNodeView extends SequentView implements ProofDisposedLis private final InnerNodeViewListener listener; - private JTextArea tacletInfo = new JTextArea(); + private JTextPane tacletInfo = new JTextPane(); private Node node; private final RuleApp ruleApp; @@ -244,9 +245,13 @@ public synchronized void printSequent() { } private void updateTacletInfo() { - tacletInfo.setText( + final var tacletDescription = TacletDescriber.getTacletDescription(getMainWindow().getMediator(), ruleApp, - getLineWidth())); + getLineWidth()); + tacletInfo.setText(tacletDescription); + LexerHighlighter lh = new LexerHighlighter.KeYLexerHighlighter(); + lh.highlightPaneAll(tacletInfo, tacletDescription.indexOf('\n'), -1); + tacletInfo.setBackground(getBackground()); tacletInfo.setBorder(new CompoundBorder(new MatteBorder(3, 0, 0, 0, Color.black), new EmptyBorder(new Insets(4, 0, 0, 0)))); @@ -260,7 +265,7 @@ public void makeTacletInfoVisible(boolean visible) { tacletInfo.setVisible(visible); } - public JTextArea getTacletInfo() { + public JTextPane getTacletInfo() { return tacletInfo; } diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java new file mode 100644 index 00000000000..5504aef26b4 --- /dev/null +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/profileloading/WDLoadDialogOptionPanel.java @@ -0,0 +1,118 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.gui.profileloading; + +import java.awt.*; +import javax.swing.*; + +import de.uka.ilkd.key.gui.KeYFileChooserLoadingOptions; +import de.uka.ilkd.key.gui.extension.api.KeYGuiExtension; +import de.uka.ilkd.key.proof.init.Profile; +import de.uka.ilkd.key.settings.Configuration; +import de.uka.ilkd.key.wd.WdProfile; + +import net.miginfocom.layout.CC; +import org.checkerframework.checker.nullness.qual.Nullable; + +/// Additional UI components for the selection of the WD semantics. +/// +/// @author weigl +@KeYGuiExtension.Info(experimental = false) +public class WDLoadDialogOptionPanel implements KeYGuiExtension, KeYGuiExtension.LoadOptionPanel { + @Override + public OptionPanel get() { + return new WDLoadDialogOptionPanelImpl(); + } + + @Override + public Profile getProfile() { + return WdProfile.INSTANCE; + } + + public static class WDLoadDialogOptionPanelImpl implements OptionPanel { + private final JRadioButton rdbWDL = new JRadioButton("L"); + private final JRadioButton rdbWDY = new JRadioButton("Y"); + private final JRadioButton rdbWDD = new JRadioButton("D"); + + private final JLabel lblHeader = new JLabel("WD options"); + private final JLabel lblSemantics = new JLabel("Semantics:"); + private final JSeparator sepHeader = new JSeparator(); + + private static final String DESCRIPTION_L_WD_SEMANTIC = """ + More intuitive for software developers and along the lines of + runtime assertion semantics. Well-Definedness checks will be + stricter using this operator, since the order of terms/formulas + matters. It is based on McCarthy logic. + Cf. "Are the Logical Foundations of Verifying Compiler + Prototypes Matching User Expectations?" by Patrice Chalin. + """; + + private static final String DESCRIPTION_D_WD_SEMANTIC = """ + Complete and along the lines of classical logic, where the + order of terms/formulas is irrelevant. This operator is + equivalent to the D-operator, but more efficient. + Cf. "Efficient Well-Definedness Checking" by Ádám Darvas, + Farhad Mehta, and Arsenii Rudich. + """; + + + private static final String DESCRIPTION_Y_WD_SEMANTIC = """ + Complete and along the lines of classical logic, where the + order of terms/formulas is irrelevant. This operator is not as + strict as the L-operator, based on strong Kleene logic. To be + used with care, since formulas may blow up exponentially. + Cf. "Well Defined B" by Patrick Behm, Lilian Burdy, and + Jean-Marc Meynadier + """; + + public WDLoadDialogOptionPanelImpl() { + lblHeader.setFont(lblHeader.getFont().deriveFont(Font.BOLD)); + + rdbWDL.setToolTipText(DESCRIPTION_L_WD_SEMANTIC); + rdbWDD.setToolTipText(DESCRIPTION_D_WD_SEMANTIC); + rdbWDY.setToolTipText(DESCRIPTION_Y_WD_SEMANTIC); + + ButtonGroup btnGrp = new ButtonGroup(); + btnGrp.add(rdbWDD); + btnGrp.add(rdbWDL); + btnGrp.add(rdbWDY); + + rdbWDL.setSelected(true); + } + + @Override + public void install(KeYFileChooserLoadingOptions panel) { + panel.add(lblHeader); + panel.add(sepHeader, new CC().wrap().span(2).growX()); + + panel.add(lblSemantics); + panel.add(rdbWDD, new CC().span(2).split(3)); + panel.add(rdbWDY); + panel.add(rdbWDL); + } + + @Override + public void deinstall(KeYFileChooserLoadingOptions panel) { + panel.remove(lblHeader); + panel.remove(sepHeader); + panel.remove(lblSemantics); + panel.remove(rdbWDL); + panel.remove(rdbWDD); + panel.remove(rdbWDY); + } + + @Override + public @Nullable Configuration getResult() { + Configuration configuration = new Configuration(); + configuration.set("wdOperator", "wdOperator:L"); + if (rdbWDD.isSelected()) { + configuration.set("wdOperator", "wdOperator:D"); + } + if (rdbWDY.isSelected()) { + configuration.set("wdOperator", "wdOperator:Y"); + } + return configuration; + } + } +} diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/utilities/LexerHighlighter.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/utilities/LexerHighlighter.java new file mode 100644 index 00000000000..ed1f0ff80ab --- /dev/null +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/utilities/LexerHighlighter.java @@ -0,0 +1,202 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.gui.utilities; + +import java.awt.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.*; +import javax.swing.text.*; + +import de.uka.ilkd.key.gui.colors.ColorSettings; +import de.uka.ilkd.key.nparser.ParsingFacade; + +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.Token; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +import static de.uka.ilkd.key.nparser.KeYLexer.*; + +/** + * Utilities for highlighting of text based on ANTLR-based Lexers. + * + * @author Alexander Weigl + * @version 1 (2/17/26) + */ +@NullMarked +public abstract class LexerHighlighter { + protected abstract @Nullable AttributeSet getStyle(int tokenType); + + private final StyleContext styleContext = new StyleContext(); + + protected AttributeSet define(Color fgColor, boolean bold, boolean italic) { + AttributeSet aset = + styleContext.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, fgColor); + aset = styleContext.addAttribute(aset, StyleConstants.FontFamily, Font.MONOSPACED); + aset = styleContext.addAttribute(aset, StyleConstants.Bold, bold); + aset = styleContext.addAttribute(aset, StyleConstants.Italic, italic); + return aset; + } + + public final void highlightPaneMarkdown(JTextPane contentPane) { + String text = contentPane.getText(); + Pattern pattern = getMarkdownPattern(); + + Matcher match = pattern.matcher(text); + var sd = contentPane.getStyledDocument(); + + var prefixLength = getPatternPrefixLength(); + while (match.find()) { + var lexer = ParsingFacade.createLexer(CharStreams.fromString(match.group(1))); + var toks = lexer.getAllTokens(); + int startIdx = match.start() + prefixLength; + for (var tok : toks) { + highlightToken(sd, startIdx, tok); + } + } + contentPane.invalidate(); + contentPane.repaint(); + contentPane.repaint(); + } + + protected abstract int getPatternPrefixLength(); + + public final void highlightPaneAll(JTextPane contentPane, int startIdx, int stopIdx) { + String text = contentPane.getText(); + + if (stopIdx < 0) { + stopIdx = text.length(); + } + + text = text.substring(startIdx, stopIdx); + + var sd = contentPane.getStyledDocument(); + var lexer = ParsingFacade.createLexer(CharStreams.fromString(text)); + var toks = lexer.getAllTokens(); + for (var tok : toks) { + highlightToken(sd, startIdx, tok); + } + contentPane.invalidate(); + contentPane.repaint(); + contentPane.repaint(); + } + + public final void highlightPaneAll(JTextPane contentPane) { + highlightPaneAll(contentPane, 0, -1); + } + + + private void highlightToken(StyledDocument sd, int startIdx, Token tok) { + var attribute = getStyle(tok.getType()); + sd.setCharacterAttributes(startIdx + tok.getStartIndex(), + 1 + tok.getStopIndex() - tok.getStartIndex(), + attribute, true); + } + + protected abstract Pattern getMarkdownPattern(); + + public static class KeYLexerHighlighter extends LexerHighlighter { + public static final ColorSettings.ColorProperty COLOR_KEYWORD = + ColorSettings.define("infotree.syntax.keyword", "", Color.BLUE, Color.ORANGE); + + public static final ColorSettings.ColorProperty COLOR_IDENTIFIER = + ColorSettings.define("infotree.syntax.identifier", "", Color.BLACK, Color.WHITE); + + public static final ColorSettings.ColorProperty COLOR_COMMENT = + ColorSettings.define("infotree.syntax.comment", "", Color.GREEN, Color.GREEN); + + public static final ColorSettings.ColorProperty COLOR_OPERATORS = + ColorSettings.define("infotree.syntax.operators", "", Color.BLACK, Color.ORANGE); + + public static final ColorSettings.ColorProperty COLOR_ERROR = + ColorSettings.define("infotree.syntax.error", "", Color.RED, Color.WHITE); + + public static final ColorSettings.ColorProperty COLOR_LITERALS = + ColorSettings.define("infotree.syntax.literals", "", Color.GREEN, Color.GREEN); + + public static final ColorSettings.ColorProperty COLOR_MODALITY = + ColorSettings.define("infotree.syntax.modality", "", Color.PINK, Color.PINK); + + + private final AttributeSet STYLE_OPERATORS = define(COLOR_OPERATORS.get(), false, false); + private final AttributeSet STYLE_ERROR = define(COLOR_ERROR.get(), false, false); + private final AttributeSet STYLE_LITERALS = define(COLOR_LITERALS.get(), false, true); + private final AttributeSet STYLE_KEYWORDS = define(COLOR_KEYWORD.get(), true, false); + private final AttributeSet STYLE_IDENTIFIER = define(COLOR_IDENTIFIER.get(), true, false); + private final AttributeSet STYLE_COMMENT = define(COLOR_COMMENT.get(), false, true); + private final AttributeSet STYLE_MODALITY = define(COLOR_COMMENT.get(), false, true); + private final AttributeSet STYLE_DEFAULT = define(COLOR_IDENTIFIER.get(), false, false); + + + @Override + protected @Nullable AttributeSet getStyle(int tokType) { + return switch (tokType) { + case TERMLABEL, MODIFIABLE, PROGRAMVARIABLES, STORE_TERM_IN, STORE_STMT_IN, + HAS_INVARIANT, GET_INVARIANT, GET_FREE_INVARIANT, GET_VARIANT, + IS_LABELED, SAME_OBSERVER, VARCOND, APPLY_UPDATE_ON_RIGID, + DEPENDINGON, DISJOINTMODULONULL, DROP_EFFECTLESS_ELEMENTARIES, + DROP_EFFECTLESS_STORES, SIMPLIFY_IF_THEN_ELSE_UPDATE, ENUM_CONST, + FREELABELIN, HASSORT, FIELDTYPE, FINAL, ELEMSORT, HASLABEL, + HASSUBFORMULAS, ISARRAY, ISARRAYLENGTH, ISCONSTANT, ISENUMTYPE, + ISINDUCTVAR, ISLOCALVARIABLE, ISOBSERVER, DIFFERENT, METADISJOINT, + ISTHISREFERENCE, DIFFERENTFIELDS, ISREFERENCE, ISREFERENCEARRAY, + ISSTATICFIELD, ISMODELFIELD, ISINSTRICTFP, ISSUBTYPE, EQUAL_UNIQUE, + NEW, NEW_TYPE_OF, NEW_DEPENDING_ON, NEW_LOCAL_VARS, HAS_ELEMENTARY_SORT, + NEWLABEL, CONTAINS_ASSIGNMENT, NOT_, NOTFREEIN, SAME, STATIC, + STATICMETHODREFERENCE, MAXEXPANDMETHOD, STRICT, TYPEOF, INSTANTIATE_GENERIC, + FORALL, EXISTS, SUBST, IF, IFEX, THEN, ELSE, INCLUDE, + INCLUDELDTS, CLASSPATH, BOOTCLASSPATH, NODEFAULTCLASSES, JAVASOURCE, + WITHOPTIONS, OPTIONSDECL, KEYSETTINGS, PROFILE, + SAMEUPDATELEVEL, INSEQUENTSTATE, ANTECEDENTPOLARITY, SUCCEDENTPOLARITY, + CLOSEGOAL, HEURISTICSDECL, NONINTERACTIVE, DISPLAYNAME, + HELPTEXT, REPLACEWITH, ADDRULES, ADDPROGVARS, HEURISTICS, + FIND, ADD, ASSUMES, TRIGGER, AVOID, PREDICATES, + FUNCTIONS, DATATYPES, TRANSFORMERS, UNIQUE, FREE, + RULES, AXIOMS, PROBLEM, CHOOSECONTRACT, PROOFOBLIGATION, + PROOF, PROOFSCRIPT, CONTRACTS, INVARIANTS, LEMMA, + IN_TYPE, IS_ABSTRACT_OR_INTERFACE, IS_FINAL, CONTAINERTYPE, + SCHEMAVAR, FORMULA, + COMMENT_END, DOC_COMMENT, ML_COMMENT, MODALITYD, MODALITYB, + MODALITYBB, MODAILITYGENERIC1, MODAILITYGENERIC2, MODAILITYGENERIC3, + MODAILITYGENERIC4, MODAILITYGENERIC5, MODAILITYGENERIC6, MODAILITYGENERIC7, + MODALITYD_END, MODALITYD_STRING, MODALITYD_CHAR, MODALITYG_END, + MODALITYB_END, MODALITYBB_END, MODALOPERATOR, PROGRAM -> + STYLE_KEYWORDS; + + case MODALITY -> STYLE_MODALITY; + + case AT, PARALLEL, OR, AND, NOT, IMP, + EQUALS, NOT_EQUALS, SEQARROW, EXP, TILDE, PERCENT, + STAR, MINUS, PLUS, GREATER, GREATEREQUAL, + LESS, LESSEQUAL, LGUILLEMETS, RGUILLEMETS, EQV, + UTF_PRECEDES, UTF_IN, UTF_EMPTY, UTF_UNION, UTF_INTERSECT, + UTF_SUBSET_EQ, UTF_SUBSEQ, UTF_SETMINUS, SEMI, SLASH, + COLON, DOUBLECOLON, ASSIGN, DOT, DOTRANGE, COMMA, + LPAREN, RPAREN, LBRACE, RBRACE, LBRACKET, RBRACKET, + EMPTYBRACKETS -> + STYLE_OPERATORS; + case ERROR_UKNOWN_ESCAPE, ERROR_CHAR -> STYLE_ERROR; + case IDENT -> STYLE_IDENTIFIER; + case COMMENT, SL_COMMENT -> STYLE_COMMENT; + case CHAR_LITERAL, QUOTED_STRING_LITERAL, TRUE, FALSE, + STRING_LITERAL, BIN_LITERAL, HEX_LITERAL, INT_LITERAL, FLOAT_LITERAL, + DOUBLE_LITERAL, REAL_LITERAL -> + STYLE_LITERALS; + default -> STYLE_DEFAULT; + }; + } + + @Override + protected int getPatternPrefixLength() { + return "```key".length(); + } + + @Override + protected Pattern getMarkdownPattern() { + return Pattern.compile("```key(.*?)```", + Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE); + } + } +} diff --git a/key.ui/src/main/java/de/uka/ilkd/key/util/XMLResources.java b/key.ui/src/main/java/de/uka/ilkd/key/util/XMLResources.java deleted file mode 100644 index 3c50b745530..00000000000 --- a/key.ui/src/main/java/de/uka/ilkd/key/util/XMLResources.java +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.util; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * An instance of this class loads several XML files, whose contents are displayed in - * {@link de.uka.ilkd.key.gui.InfoView}. - * - * @author Kai Wallisch - */ -public class XMLResources { - - private static final String RULE_RESOURCE = "/de/uka/ilkd/key/gui/help/ruleExplanations.xml"; - private static final Logger LOGGER = LoggerFactory.getLogger(XMLResources.class); - protected final Properties ruleExplanations; - - private static final String LABEL_RESOURCE = - "/de/uka/ilkd/key/gui/help/termLabelExplanations.xml"; - protected final Properties termLabelExplanations; - - static final String FUNCTION_RESOURCE = "/de/uka/ilkd/key/gui/help/functionExplanations.xml"; - protected final Properties functionExplanations; - - public XMLResources() { - ruleExplanations = getResource(RULE_RESOURCE); - termLabelExplanations = getResource(LABEL_RESOURCE); - functionExplanations = getResource(FUNCTION_RESOURCE); - } - - public Properties getRuleExplanations() { - return ruleExplanations; - } - - public Properties getTermLabelExplanations() { - return termLabelExplanations; - } - - public Properties getFunctionExplanations() { - return functionExplanations; - } - - private static Properties getResource(String xmlFile) { - Properties ret = new Properties(); - - try (InputStream is = XMLResources.class.getResourceAsStream(xmlFile)) { - if (is == null) { - throw new FileNotFoundException("Descriptions file " + xmlFile + " not found."); - } - ret.loadFromXML(is); - } catch (IOException e) { - LOGGER.error("Cannot not load help messages in info view", e); - } - - return ret; - } - -} diff --git a/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension b/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension index fff85bf2d6d..646d2f4c102 100644 --- a/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension +++ b/key.ui/src/main/resources/META-INF/services/de.uka.ilkd.key.gui.extension.api.KeYGuiExtension @@ -8,4 +8,5 @@ de.uka.ilkd.key.gui.LogView de.uka.ilkd.key.gui.plugins.javac.JavacExtension de.uka.ilkd.key.gui.utilities.HeapStatusExt de.uka.ilkd.key.gui.JmlEnabledKeysIndicator -de.uka.ilkd.key.gui.extension.impl.ProfileNameInStatusBar \ No newline at end of file +de.uka.ilkd.key.gui.extension.impl.ProfileNameInStatusBar +de.uka.ilkd.key.gui.profileloading.WDLoadDialogOptionPanel \ No newline at end of file diff --git a/key.ui/src/main/resources/de/uka/ilkd/key/gui/help/functionExplanations.xml b/key.ui/src/main/resources/de/uka/ilkd/key/gui/help/functionExplanations.xml deleted file mode 100644 index 7fafa339ec6..00000000000 --- a/key.ui/src/main/resources/de/uka/ilkd/key/gui/help/functionExplanations.xml +++ /dev/null @@ -1,180 +0,0 @@ - - - - - - Put descriptions for JavaDL function and predicate symbols in here. - - -The length of an array is not stored on the heap but is an inherent property of the object reference which denotes the array. -Hence, this functions takes only one argument: the object reference whose length (as an array) is to be retrieved. -This function always results in a non-negative value. - -This predicate is true if the described array update is valid in Java. - -Java has the peculiarity of covariant array types. They allow an array assignment to fail at runtime (with an ArrayStoreException). This predicate deals with the issue in the logic. - -(tbd) - - -This function turns an integer into a field reference. - -Integers are used to access the entries of entries within arrays stored on the heap. This function provides the injection of the integer domain into that of the type Field. It is ensured that this image of arr is disjoint from any defined field constant. - -The array access a[i], for instance for an int-array a, becomes int::select(heap, a, arr(i)). - -tbd -tbd -tbd -tbd -tbd -tbd -tbd -tbd - -This program variable holds to the current heap state. Its type is Heap. Any assignment statement in a modality modifies the value of this program variable and any expression reading from the heap within a Java modality refers to the heap stored in this program variable. - -This predicate takes an argument of type Heap. It is true if the following conditions hold for its the argument: -1. Every location contains a reference to a created (in this heap) object or null. -2. Every location set stored on the heap contains only created objects. -3. Every location belonging to a declared Java field holds a value compatible with its type. -4. Only finitely many objects are created on the heap. - -This function modifies a heap by changing the value in one location. -It takes four arguments: -1. The heap h which is to be modified -2. The object o reference of the location which is to be modified -3. The field of the location which is to be modified -4. The value v which is to be written in the designated location. -The result is a heap which coincides with h in all locations but in (o,f), where v is stored. -In the theory of arrays, store is somtimes called "write". -The field java.lang.Object::$created cannot be updated using store; use "create". - -This function modifies a heap by changing the createdness of one object. -It takes two arguments: -1. The heap h which is to be modified -2. The object reference o for the object which is to be set created. -The result is a heap which coincides with h in all locations but in (o,java.lang.Object::$created), which has been set to true. -There is no means to modify a heap by setting the createdness of an object to false. - -tbd - -This function modifies a heap by changing the value in one location. -It takes three arguments: -1. The heap h which is to be modified -2. The location set s whose locations are to be modified -4. The value v which is to be written in the designated locations. -The result is a heap which coincides with h in all locations but in the locations in s where v is stored. -The field java.lang.Object::$created> cannot be updated using memset; use "create". - -tbd - -The empty location set which does not contain any elements. - -The unique location set containing all locations, i.e. elementOf(o, f, allLocs) will always return true for an arbitrary Field f and Object o. - -Converts a single location to a locations set with one element. - -Union between two location sets. - -Intersection between two location sets. - -Realizes relative complement (a.k.a. set difference) between two locations sets. It takes as arguments two location sets and returns another location set which contains all elements from the first argument except those that are elements of the second argument. - -Takes as argument a term of type LocSet, which may contain a free variable. The term represents a family of locations sets, which is parameterized by the unbound variable. The returned location set is the union over all members of the parameterized family. - -The set that contains all locations which belong to the object o given as argument. - -A location (a,b) is in the set allFields(o) iff a=o. -In JML, the function corresponds to o.*. - -The set of all locations that belong to a particular field f given as argument. - -A location (a,b) is in the set allObjects(f) iff b=f. - -tbd - -The set of locations which are fresh (that is not created) w.r.t. the heap h given as argument. -A location (a,b) is in the set freshLocs(h) iff o.$created@h = FALSE. - -tbd - -tbd - -This is the set theoretic membership predicate to be used for location sets. - -It takes three arguments: The first two (an Object and a Field) make up the location and the third is the location set against which membership is tested. - -This is the set theoretic subset predicate to be used for location sets. - -A location set A is subset of another location set B iff every element of A is also element of B. - -This binary predicate models disjointness of location sets. - -disjoint(A,B) is true iff A and B have an empty intersection, -it is thus equivalent to intersect(A,B) = empty. - -tbd - -Retrieve the mapping value of a key. -A unique value, which is returned by mapGet in case no mapping value is declared for the specified key. -Generalized quantifier for maps. This is a generic constructor for maps. -The empty map, which does not contain any entries. -A map, which contains only one entry. -Takes as arguments two maps and creates a new map from their entries. In case their domains overlap, entries of the second map are used for keys from the intersection. -Converts a sequence to a map. The map domain consists of exactly those integers, which are inside the sequence bounds. -Adds an entry to a map or overwrites an existing one. -Removes an entry from a map. -Returns the number of entries of a map. -Returns true iff the specified map contains a finite amount of entries. -Takes two arguments: key ∈ any and map ∈ Map. Returns true iff key is in the domain of map. -Returns true iff the domain of the specified map contains only objects that are $created in the implicit heap (additional non-object values may also be part of the domain). This can be used in a JML specification as an invariant to ensure, that non-created objects are not (yet) part of the domain of a map. - -Return the length of a sequence. -Return the element at a position within a sequence. The type read from the sequence is part of the function name. -Return the first index in a sequence that holds a value. -The underspecified error value if a sequence is accessed outside its idnex range. -The empty sequence. -A singleton sequence that has the argument as only entry. -Concatenates two sequences. -Takes a subsequence from a sequence. -The first argument is the original sequence, -the second is the first index to consider (inclusive) and -the third is the last index to consider (!exclusive!). - -Reverses a sequence. The result has the same entries as the argument but in reverse order. -This function binds an integer variable and evaluates an expression over this variable for a range of values to obtain the entries of a sequence. - -The sequence - seqDef{int i;}(-2, 3, i*i) -has, for instance, the entries - [ 4, 1, 0, 1, 4 ]. - -The first and second argument give the range over which the variable goes. Again, the right-hand bound is exclusive. - -seqDef is related to the lambda operator in lambda calculus. - - -Takes a sequence and two indices. The elements at the specified indices are exchanged in the resulting sequence. In case one of the indices is out of bounds, the sequence is left unchanged. -Takes a sequence and removes the element at the specified index. In case the index is out of bounds, the sequence is left unchanged. -Takes a sequence of naturals (zero included) and treats it as a permutation. The resulting sequence is the inverse permutation of the original one. -Convert a Java array to a JavaDL sequence. - -Return the (unique) ordered pair of two specified elements. -Return the first element of an ordered pair. -Return the second element of an ordered pair. - -A boolean function which is true iff the dynamic type of its argument is precisely the type which is part of the function name. - -A boolean function which is true iff the dynamic type of its argument is a subtype of the type which is part of the function name. - -tbd - -A constant holding the object reference pointing to the Java null object. -Quite the same as the keyword "null" in Java. - -tbd - -tbd - - diff --git a/key.ui/src/main/resources/de/uka/ilkd/key/gui/help/ruleExplanations.xml b/key.ui/src/main/resources/de/uka/ilkd/key/gui/help/ruleExplanations.xml deleted file mode 100644 index a2f5e92de30..00000000000 --- a/key.ui/src/main/resources/de/uka/ilkd/key/gui/help/ruleExplanations.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - These properties define the help comments which are to be displayed - in the view pane when selecting tree elements for built-in rules. - - - -Some logical rules are implemented in Java code. This is because their semantics cannot easily be expressed in KeY's Taclet language. - - - -Most logical rules are implemented as Taclets. - -Taclets are schematic logical rules formulated in the Taclet Language. -The language is defined and explained in the KeY book. - - - -Taclets which have been introduced using File->Load User-Defined Taclets are filed here. - -Loading User Defined Taclets opens side branches on which the soundness of the lemma taclets must be established. - - - -When symbolic execution reaches a method call, the according method can be approximated by its specified contract (more precisely, one or more of its contracts). - -This rule gives rise to three or four subgoals: -1. Pre: It must be established that the pre-condition of the method holds prior to the method call. - -2. Post: The method terminates normally, the post-condition of the method can be assumed and symbolic execution continues. - -3. Exceptional Post: The method terminates abruptly with an exception, the exceptional post-condition is assumed, and symbolic execution continues with this exception thrown. - -4. Null reference: The receiver of the call can be null. This case is considered on this branch. If KeY can figure out automatically that this cannot be the case, this branch is suppressed. - - - -The QueryExpand rule allows to apply contracts or to symbolically execute a query -expression in the logic. It replaces the query expression by a new constant and -constructs a box formula in the antecedent 'defining' the constant as the result of -a method call. The method call is encoded directly as a method call in the box modality. -The query is invoked in a context equal to the container type of the query method. - - -The One Step Simplifier (OSS) aggregates the application of simplification rules into a single rule. This is done to make the calculus more efficient. - -You can activate/deactivate the simplifier by toggling the menu entry Options->One Step Simplifier. An active OSS makes the proof faster, a deactivated more transparent. - -In particular, the OSS performs normalisation and simplification on updated terms: - * Updates on terms without modality are resolved. - * Updates without effects are dropped. - * Sequential updates are merged into one parallel update. - -Technical Information: -The OSS aggregates the rules from the following heuristics (-> Taclet Base): - concrete, - update_elim, - update_apply_on_update, - update_apply - update_join, - elimQuantifier - - - -Methods and model fields may be annotated with an accessible clause. This defines a dependency contract describing the heap locations its value may depend on. - -If the heap changes in locations the symbol does not depend on, its value remains unchanged. This rules adds an according implication for a heap-dependent symbol to the sequent's antecedent. - -In automatic strategy, this rule is applied lazily (only once all other means of advancing the proof have been exhausted) to avoid endless loops. - - -Like methods, statement blocks can be annotated with contracts. The application of the Block Contract rules then gives rise to subgoals which roughly correspond to those of the Use Operation Contract rule (see there). -Three properties have to be shown: - -1. Validity of block contract - -2. Precondition of contract holds - -3. Postcondition holds after block terminates - - - -Loops can be handled by expanding or by using a loop invariant. -An invariant can be created manually or supplied by the JML specification. -Use of this rule creates three subgoals, two of which are new proof obligations: - -1. It must be shown that the loop invariant is initially valid. - -2. The loop body needs to preserve the invariant. - -In the third subgoal, the loop invariant can be used. - - - - diff --git a/key.ui/src/main/resources/de/uka/ilkd/key/gui/help/termLabelExplanations.xml b/key.ui/src/main/resources/de/uka/ilkd/key/gui/help/termLabelExplanations.xml deleted file mode 100644 index 86bb2ffa51d..00000000000 --- a/key.ui/src/main/resources/de/uka/ilkd/key/gui/help/termLabelExplanations.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - These properties define the help comments which are to be displayed - in the view pane when selecting term label tree elements. - - - -The term label SC is used to indicate that a logical operator has originally been "shortcut" operator. - -For instance, both conjunction operators in JML (i.e., && and &) are translated to the same function in JavaDL. To differentiate between the two, the translation of && adds the label SC. - -This is relevant for welldefinedness checks. - - - -This label saves a term's origin in the JML specification as well as the origins of all of its subterms and former subterms. - -For example, if the file "Example.java" contains the clause "requires R" at line 20, then every JavaDL term that is generated from R will have the origin -"requires @ Example.java @ line 20". - -Origin labels are not printed in the sequent view. To see a term's origin, you can mouse over it while holding the ALT button. If you want more detailed information, left click on the term and then on "Show Origin". - - - diff --git a/key.util/build.gradle b/key.util/build.gradle index 5b6c81ff6c9..cfe26a0db9c 100644 --- a/key.util/build.gradle +++ b/key.util/build.gradle @@ -10,7 +10,7 @@ dependencies { // we also export these dependency into src/test/java. testFixturesApi(project(':key.util')) - testFixturesApi(platform("org.junit:junit-bom:5.14.2")) + testFixturesApi(platform("org.junit:junit-bom:5.14.3")) testFixturesApi("org.junit.jupiter:junit-jupiter-api") testFixturesApi("org.junit.jupiter:junit-jupiter-params") testFixturesApi("org.assertj:assertj-core:3.27.7") @@ -19,8 +19,8 @@ dependencies { testFixturesApi("ch.qos.logback:logback-classic:1.5.32") // test fixtures - testFixturesApi("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.0") - testFixturesApi("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.0") + testFixturesApi("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.2") + testFixturesApi("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.2") def eisop_version = "3.49.3-eisop1" testFixturesCompileOnly( "io.github.eisop:checker-qual:$eisop_version") diff --git a/key.util/src/main/java/org/key_project/util/collection/ImmutableSet.java b/key.util/src/main/java/org/key_project/util/collection/ImmutableSet.java index 7eab97f1b7a..1786e0e32c6 100644 --- a/key.util/src/main/java/org/key_project/util/collection/ImmutableSet.java +++ b/key.util/src/main/java/org/key_project/util/collection/ImmutableSet.java @@ -43,6 +43,12 @@ public interface ImmutableSet return DefaultImmutableSet.nil(); } + /// Creates an immutable set populated with the given values. + static ImmutableSet from(Collection values) { + var set = ImmutableSet.empty(); + return set.add(values); + } + /** * @return a {@code Set} containing the same elements as this {@code ImmutableSet} */ diff --git a/keyext.caching/src/main/java/de/uka/ilkd/key/proof/reference/ReferenceSearcher.java b/keyext.caching/src/main/java/de/uka/ilkd/key/proof/reference/ReferenceSearcher.java index 3138256f05b..f5a63f9ece4 100644 --- a/keyext.caching/src/main/java/de/uka/ilkd/key/proof/reference/ReferenceSearcher.java +++ b/keyext.caching/src/main/java/de/uka/ilkd/key/proof/reference/ReferenceSearcher.java @@ -54,10 +54,13 @@ public static ClosedBy findPreviousProof(List previousProofs, Node newNod var newTacletIndex = newNode.proof().allGoals().head().ruleAppIndex().tacletIndex(); Set newTaclets = newTacletIndex.allNoPosTacletApps(); var tacletsOk = true; - for (var taclet : tacletIndex.allNoPosTacletApps().stream() - .filter(x -> x.taclet().getOrigin() != null - && x.taclet().getOrigin().contains(proofFile)) - .toList()) { + final var list = tacletIndex.allNoPosTacletAppsStream() + .filter(x -> { + var origin = p.getServices().getNamespaces().docs().findOrigin(x.taclet()); + return origin != null && origin.contains(proofFile); + }) + .toList(); + for (NoPosTacletApp taclet : list) { if (newTaclets.stream().noneMatch(newTaclet -> Objects .equals(taclet.taclet().toString(), newTaclet.taclet().toString()))) { tacletsOk = false;