diff --git a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/PrepareInfFlowContractPreBranchesMacro.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/PrepareInfFlowContractPreBranchesMacro.java index 1d7a99fcfb0..e0daa0ac5c4 100644 --- a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/PrepareInfFlowContractPreBranchesMacro.java +++ b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/PrepareInfFlowContractPreBranchesMacro.java @@ -10,13 +10,13 @@ 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.strategy.AbstractFeatureStrategy; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaAbstractFeatureStrategy; import org.key_project.logic.Name; import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.Strategy; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; @@ -24,6 +24,8 @@ import org.jspecify.annotations.NonNull; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.hasLabel; + /** * The macro UseInformationFlowContractMacro applies all applicable information flow contracts. @@ -68,7 +70,7 @@ public String getDescription() { * This strategy accepts all rule apps for which the rule name starts with a string in the * admitted set and rejects everything else. */ - protected static class RemovePostStrategy extends AbstractFeatureStrategy { + protected static class RemovePostStrategy extends JavaAbstractFeatureStrategy { private final Name NAME = new Name("RemovePostStrategy"); diff --git a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/SelfcompositionStateExpansionMacro.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/SelfcompositionStateExpansionMacro.java index 9ea985e7727..47f476a2c36 100644 --- a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/SelfcompositionStateExpansionMacro.java +++ b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/SelfcompositionStateExpansionMacro.java @@ -63,7 +63,7 @@ protected Set getAdmittedRuleNames() { } @Override - protected Strategy<@NonNull Goal> createStrategy(Proof proof, + protected org.key_project.prover.strategy.Strategy<@NonNull Goal> createStrategy(Proof proof, PosInOccurrence posInOcc) { return new SelfCompExpansionStrategy(getAdmittedRuleNames()); } @@ -111,7 +111,7 @@ protected boolean allowOSS() { * This strategy accepts all rule apps for which the rule name is in the admitted set or has * INF_FLOW_UNFOLD_PREFIX as a prefix and rejects everything else. */ - private class SelfCompExpansionStrategy implements Strategy { + private class SelfCompExpansionStrategy implements JavaStrategy { private final Name NAME = new Name( SelfcompositionStateExpansionMacro.SelfCompExpansionStrategy.class.getSimpleName()); @@ -135,7 +135,7 @@ public Name name() { if ((admittedRuleNames.contains(name) || name.startsWith(INF_FLOW_UNFOLD_PREFIX)) && ruleApplicationInContextAllowed(ruleApp, pio, goal)) { ModularJavaDLStrategyFactory strategyFactory = new ModularJavaDLStrategyFactory(); - Strategy<@NonNull Goal> dlStrategy = + org.key_project.prover.strategy.Strategy<@NonNull Goal> dlStrategy = strategyFactory.create(goal.proof(), new StrategyProperties()); RuleAppCost costs = dlStrategy.computeCost(ruleApp, pio, goal, mState); if ("orLeft".equals(name)) { @@ -155,7 +155,7 @@ public boolean isApprovedApp(RuleApp app, PosInOccurrence pio, @Override public void instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, - RuleAppCostCollector collector) { + org.key_project.prover.strategy.RuleAppCostCollector collector) { } @Override diff --git a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/UseInformationFlowContractMacro.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/UseInformationFlowContractMacro.java index 21029865992..4d8ec128bfd 100644 --- a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/UseInformationFlowContractMacro.java +++ b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/macros/UseInformationFlowContractMacro.java @@ -15,13 +15,13 @@ 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.strategy.RuleAppCostCollector; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import org.key_project.logic.Name; import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.RuleAppCostCollector; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; @@ -167,7 +167,7 @@ private String getAppRuleName(Node parent) { * This strategy accepts all rule apps for which the rule name starts with a string in the * admitted set and rejects everything else. */ - protected class PropExpansionStrategy implements Strategy { + protected class PropExpansionStrategy implements JavaStrategy { private final Name NAME = new Name(UseInformationFlowContractMacro.PropExpansionStrategy.class.getSimpleName()); diff --git a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/proof/InfFlowCheckInfo.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/proof/InfFlowCheckInfo.java index e8219e1a354..8501bf9f860 100644 --- a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/proof/InfFlowCheckInfo.java +++ b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/proof/InfFlowCheckInfo.java @@ -7,8 +7,9 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.StrategyInfoUndoMethod; import de.uka.ilkd.key.strategy.StrategyProperties; -import de.uka.ilkd.key.util.properties.Properties; -import de.uka.ilkd.key.util.properties.Properties.Property; + +import org.key_project.util.Properties; +import org.key_project.util.Properties.Property; /// Helper class to access Information Flow information in the [StrategySettings] diff --git a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/InfFlowBlockContractInternalRule.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/InfFlowBlockContractInternalRule.java index 6214233d0be..079c63a7c69 100644 --- a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/InfFlowBlockContractInternalRule.java +++ b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/InfFlowBlockContractInternalRule.java @@ -26,7 +26,6 @@ import de.uka.ilkd.key.logic.JTerm; import de.uka.ilkd.key.logic.ProgramElementName; import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.label.ParameterlessTermLabel; import de.uka.ilkd.key.logic.op.JFunction; import de.uka.ilkd.key.logic.op.LocationVariable; @@ -44,6 +43,7 @@ import de.uka.ilkd.key.speclang.BlockContract; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Function; import org.key_project.prover.sequent.PosInOccurrence; @@ -93,7 +93,7 @@ private InfFlowBlockContractInternalRule() { @Override public BlockContractInternalBuiltInRuleApp createApp( - PosInOccurrence occurrence, TermServices services) { + PosInOccurrence occurrence, LogicServices services) { return new InfFlowBlockContractInternalBuiltInRuleApp(this, occurrence); } diff --git a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/InfFlowWhileInvariantRule.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/InfFlowWhileInvariantRule.java index 1b830aeb74d..bb03faaa98f 100644 --- a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/InfFlowWhileInvariantRule.java +++ b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/InfFlowWhileInvariantRule.java @@ -33,6 +33,7 @@ import de.uka.ilkd.key.speclang.LoopSpecification; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.Namespace; import org.key_project.logic.op.Function; @@ -60,8 +61,8 @@ public Name name() { @Override public InfFlowLoopInvariantBuiltInRuleApp createApp(PosInOccurrence pos, - TermServices services) { - return new InfFlowLoopInvariantBuiltInRuleApp(this, pos, services); + LogicServices services) { + return new InfFlowLoopInvariantBuiltInRuleApp(this, pos, (TermServices) services); } @Override diff --git a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/executor/InfFlowContractAppTacletExecutor.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/executor/InfFlowContractAppTacletExecutor.java index bbae380ea03..aa3bba6527e 100644 --- a/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/executor/InfFlowContractAppTacletExecutor.java +++ b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/executor/InfFlowContractAppTacletExecutor.java @@ -12,7 +12,6 @@ import de.uka.ilkd.key.proof.StrategyInfoUndoMethod; import de.uka.ilkd.key.rule.TacletApp; import de.uka.ilkd.key.rule.executor.javadl.RewriteTacletExecutor; -import de.uka.ilkd.key.util.properties.Properties; import org.key_project.logic.LogicServices; import org.key_project.prover.rules.instantiation.MatchResultInfo; @@ -20,6 +19,7 @@ import org.key_project.prover.sequent.Semisequent; import org.key_project.prover.sequent.SequentChangeInfo; import org.key_project.prover.sequent.SequentFormula; +import org.key_project.util.Properties; import org.key_project.util.collection.ImmutableList; import org.jspecify.annotations.NonNull; diff --git a/key.core.testgen/src/main/java/de/uka/ilkd/key/testgen/macros/TestGenMacro.java b/key.core.testgen/src/main/java/de/uka/ilkd/key/testgen/macros/TestGenMacro.java index e14b6cffab1..e0f5e6b4ea4 100644 --- a/key.core.testgen/src/main/java/de/uka/ilkd/key/testgen/macros/TestGenMacro.java +++ b/key.core.testgen/src/main/java/de/uka/ilkd/key/testgen/macros/TestGenMacro.java @@ -12,7 +12,6 @@ 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.strategy.Strategy; import de.uka.ilkd.key.testgen.TestGenerationSettings; import org.key_project.logic.Name; @@ -20,6 +19,7 @@ import org.key_project.prover.rules.Rule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.Strategy; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; diff --git a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/macro/WellDefinednessMacro.java b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/macro/WellDefinednessMacro.java index 8fb45517b5a..ea26aa70a72 100644 --- a/key.core.wd/src/main/java/de/uka/ilkd/key/wd/macro/WellDefinednessMacro.java +++ b/key.core.wd/src/main/java/de/uka/ilkd/key/wd/macro/WellDefinednessMacro.java @@ -10,8 +10,7 @@ import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.init.ContractPO; import de.uka.ilkd.key.proof.init.FunctionalOperationContractPO; -import de.uka.ilkd.key.strategy.RuleAppCostCollector; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import de.uka.ilkd.key.wd.*; import de.uka.ilkd.key.wd.po.*; @@ -19,6 +18,8 @@ import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.RuleAppCostCollector; +import org.key_project.prover.strategy.Strategy; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; @@ -96,7 +97,7 @@ public boolean canApplyTo(Proof proof, ImmutableList goals, * This strategy accepts all rule apps for which the rule name is a Well-Definedness rule and * rejects everything else. */ - private static class WellDefinednessStrategy implements Strategy { + private static class WellDefinednessStrategy implements JavaStrategy { private static final Name NAME = new Name(WellDefinednessStrategy.class.getSimpleName()); diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/instantiation_model/TacletFindModel.java b/key.core/src/main/java/de/uka/ilkd/key/control/instantiation_model/TacletFindModel.java index 45b44920df5..0e3a3e7a389 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/instantiation_model/TacletFindModel.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/instantiation_model/TacletFindModel.java @@ -71,7 +71,7 @@ public class TacletFindModel extends AbstractTableModel { /** * Create new data model for tree. * - * @param app the TacletApp where to get the necessary entries + * @param app the ITacletApp where to get the necessary entries * @param services services. * @param nss universal namespace of variables, minimum for input in a row. * @param scm the abbreviation map. diff --git a/key.core/src/main/java/de/uka/ilkd/key/control/instantiation_model/TacletInstantiationModel.java b/key.core/src/main/java/de/uka/ilkd/key/control/instantiation_model/TacletInstantiationModel.java index a3ec8dc4749..8b3ca62eea1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/control/instantiation_model/TacletInstantiationModel.java +++ b/key.core/src/main/java/de/uka/ilkd/key/control/instantiation_model/TacletInstantiationModel.java @@ -216,7 +216,7 @@ public void setManualInput(int i, String s) { } /** - * replaces the TacletApp of this ApplyTacletDialogModel by an TacletApp where all name + * replaces the ITacletApp of this ApplyTacletDialogModel by an ITacletApp where all name * conflicts are resolved and thus the parser is enabled to accept variables from the context or * the prefix of the Taclet. * diff --git a/key.core/src/main/java/de/uka/ilkd/key/ldt/IntegerLDT.java b/key.core/src/main/java/de/uka/ilkd/key/ldt/IntegerLDT.java index d0c78262fec..97cf6b6eada 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/ldt/IntegerLDT.java +++ b/key.core/src/main/java/de/uka/ilkd/key/ldt/IntegerLDT.java @@ -19,6 +19,7 @@ import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.util.Debug; +import org.key_project.ldt.IIntLdt; import org.key_project.logic.Name; import org.key_project.logic.op.Function; import org.key_project.util.ExtList; @@ -34,7 +35,7 @@ * convert java number types to their logic counterpart. */ @SuppressWarnings("unused") -public final class IntegerLDT extends LDT { +public final class IntegerLDT extends LDT implements IIntLdt { private static final Logger LOGGER = LoggerFactory.getLogger(IntegerLDT.class); public static final Name NAME = new Name("int"); diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/VariableNamer.java b/key.core/src/main/java/de/uka/ilkd/key/logic/VariableNamer.java index f08e2a066b5..252ff3ee8bd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/VariableNamer.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/VariableNamer.java @@ -445,7 +445,7 @@ public ProgramElementName getTemporaryNameProposal(String basename) { @Override public String getProposal(TacletApp app, SchemaVariable var, Services services, Node undoAnchor, ImmutableList previousProposals) { - // determine posOfDeclaration from TacletApp + // determine posOfDeclaration from ITacletApp ContextStatementBlockInstantiation cie = app.instantiations().getContextInstantiation(); PosInProgram posOfDeclaration = (cie == null ? null : cie.prefix()); diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/AbstractBlastingMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/AbstractBlastingMacro.java index eb0d46a61bf..a6a500876b6 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/AbstractBlastingMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/AbstractBlastingMacro.java @@ -26,8 +26,7 @@ import de.uka.ilkd.key.rule.OneStepSimplifier; import de.uka.ilkd.key.speclang.ClassAxiom; import de.uka.ilkd.key.speclang.RepresentsAxiom; -import de.uka.ilkd.key.strategy.RuleAppCostCollector; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import org.key_project.logic.Name; import org.key_project.logic.op.Function; @@ -41,6 +40,8 @@ import org.key_project.prover.sequent.Semisequent; import org.key_project.prover.sequent.Sequent; import org.key_project.prover.sequent.SequentFormula; +import org.key_project.prover.strategy.RuleAppCostCollector; +import org.key_project.prover.strategy.Strategy; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; @@ -204,7 +205,7 @@ private static void addFormulas(List result, } } - private class SemanticsBlastingStrategy implements Strategy { + private class SemanticsBlastingStrategy implements JavaStrategy { @Override public @NonNull Name name() { diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/AbstractPropositionalExpansionMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/AbstractPropositionalExpansionMacro.java index 564f43ba0dd..da86a03850c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/AbstractPropositionalExpansionMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/AbstractPropositionalExpansionMacro.java @@ -62,7 +62,7 @@ public String getCategory() { protected abstract boolean allowOSS(); @Override - protected Strategy<@NonNull Goal> createStrategy(Proof proof, + protected org.key_project.prover.strategy.Strategy<@NonNull Goal> createStrategy(Proof proof, PosInOccurrence posInOcc) { return new PropExpansionStrategy(proof.getActiveStrategy(), getAdmittedRuleNames(), allowOSS()); @@ -86,14 +86,15 @@ protected boolean ruleApplicationInContextAllowed(RuleApp ruleApp, * This strategy accepts all rule apps for which the rule name is in the admitted set and * rejects everything else. */ - private static class PropExpansionStrategy implements Strategy { + private static class PropExpansionStrategy implements JavaStrategy { private final Name NAME = new Name(PropExpansionStrategy.class.getSimpleName()); private final Set admittedRuleNames; - private final Strategy<@NonNull Goal> delegate; + private final org.key_project.prover.strategy.Strategy<@NonNull Goal> delegate; private final boolean allowOSS; - public PropExpansionStrategy(Strategy<@NonNull Goal> delegate, + public PropExpansionStrategy( + org.key_project.prover.strategy.Strategy<@NonNull Goal> delegate, Set admittedRuleNames, boolean allowOSS) { this.delegate = delegate; @@ -135,7 +136,7 @@ public boolean isApprovedApp(RuleApp app, PosInOccurrence pio, @Override public void instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, - RuleAppCostCollector collector) { + org.key_project.prover.strategy.RuleAppCostCollector collector) { } @Override diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/AutoMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/AutoMacro.java index 2f80ffddd68..8084fe52d4c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/AutoMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/AutoMacro.java @@ -18,12 +18,12 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.rule.Taclet; -import de.uka.ilkd.key.strategy.Strategy; import org.key_project.logic.Name; import org.key_project.prover.rules.Rule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.Strategy; import org.jspecify.annotations.NonNull; diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/AutoPilotPrepareProofMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/AutoPilotPrepareProofMacro.java index d8a9479466d..f7dc8abeb0c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/AutoPilotPrepareProofMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/AutoPilotPrepareProofMacro.java @@ -77,10 +77,10 @@ public static boolean isAdmittedRule(Rule rule) { return false; } - private static class AutoPilotStrategy implements Strategy { + private static class AutoPilotStrategy implements JavaStrategy { private static final Name NAME = new Name("Autopilot filter strategy"); - private final Strategy<@NonNull Goal> delegate; + private final org.key_project.prover.strategy.Strategy<@NonNull Goal> delegate; /** the modality cache used by this strategy */ private final ModalityCache modalityCache = new ModalityCache(); @@ -145,7 +145,7 @@ public boolean isApprovedApp(RuleApp app, PosInOccurrence pio, Goal goal) { @Override public void instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, - RuleAppCostCollector collector) { + org.key_project.prover.strategy.RuleAppCostCollector collector) { delegate.instantiateApp(app, pio, goal, collector); } @@ -157,7 +157,7 @@ public boolean isStopAtFirstNonCloseableGoal() { } @Override - protected Strategy<@NonNull Goal> createStrategy(Proof proof, + protected org.key_project.prover.strategy.Strategy<@NonNull Goal> createStrategy(Proof proof, PosInOccurrence posInOcc) { return new AutoPilotStrategy(proof); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/FilterStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/macros/FilterStrategy.java index 23ae1159502..390db5b3fe5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/FilterStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/FilterStrategy.java @@ -6,19 +6,20 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.TacletApp; -import de.uka.ilkd.key.strategy.RuleAppCostCollector; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.RuleAppCostCollector; +import org.key_project.prover.strategy.Strategy; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.TopRuleAppCost; import org.jspecify.annotations.NonNull; -public abstract class FilterStrategy implements Strategy<@NonNull Goal> { +public abstract class FilterStrategy implements JavaStrategy { private final Strategy<@NonNull Goal> delegate; diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/FinishSymbolicExecutionMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/FinishSymbolicExecutionMacro.java index e16fb45b1b2..87c2f5e53f9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/FinishSymbolicExecutionMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/FinishSymbolicExecutionMacro.java @@ -7,13 +7,14 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.rule.Taclet; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import org.key_project.logic.Name; import org.key_project.prover.rules.Rule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.Strategy; import org.jspecify.annotations.NonNull; @@ -21,7 +22,8 @@ * The macro FinishSymbolicExecutionMacro continues automatic rule application until there is no * more modality on the sequent. *

- * This is done by implementing a delegation {@link Strategy} which assigns to any rule application + * This is done by implementing a delegation {@link JavaStrategy} which assigns to any rule + * application * infinite costs if there is no modality on the sequent. * * @author mattias ulbrich diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/FinishSymbolicExecutionUntilMergePointMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/FinishSymbolicExecutionUntilMergePointMacro.java index 91179776abe..93c5deb466d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/FinishSymbolicExecutionUntilMergePointMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/FinishSymbolicExecutionUntilMergePointMacro.java @@ -20,7 +20,7 @@ import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.rule.merge.MergeRule; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import de.uka.ilkd.key.util.mergerule.MergeRuleUtils; import org.key_project.logic.Name; @@ -31,6 +31,7 @@ import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.prover.sequent.Semisequent; import org.key_project.prover.sequent.SequentFormula; +import org.key_project.prover.strategy.Strategy; import org.key_project.util.collection.ImmutableArray; import org.key_project.util.collection.ImmutableList; @@ -42,7 +43,8 @@ * more modality on the sequent. *

* - * This is done by implementing a delegation {@link Strategy} which assigns to any rule application + * This is done by implementing a delegation {@link JavaStrategy} which assigns to any rule + * application * infinite costs if there is no modality on the sequent. * * @author Mattias Ulbrich diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/OneStepProofMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/OneStepProofMacro.java index 998f34c17f6..75f19330e14 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/OneStepProofMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/OneStepProofMacro.java @@ -6,13 +6,14 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.strategy.RuleAppCostCollector; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import org.key_project.logic.Name; import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.RuleAppCostCollector; +import org.key_project.prover.strategy.Strategy; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; @@ -66,7 +67,7 @@ protected boolean allowParallel() { * */ - private static class OneStepStrategy implements Strategy<@NonNull Goal> { + private static class OneStepStrategy implements JavaStrategy { private static final Name NAME = new Name(OneStepStrategy.class.getSimpleName()); private int counter; diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/StrategyProofMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/StrategyProofMacro.java index f1de8368d6f..51fc98cd5f8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/StrategyProofMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/StrategyProofMacro.java @@ -13,7 +13,7 @@ import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.prover.impl.AutoProvers; import de.uka.ilkd.key.strategy.FocussedRuleApplicationManager; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import org.key_project.prover.engine.GoalChooser; import org.key_project.prover.engine.ProofSearchInformation; @@ -21,6 +21,7 @@ import org.key_project.prover.engine.ProverTaskListener; import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.prover.strategy.RuleApplicationManager; +import org.key_project.prover.strategy.Strategy; import org.key_project.util.collection.ImmutableList; import org.jspecify.annotations.NonNull; @@ -33,11 +34,11 @@ * {@link #createStrategy(Proof, PosInOccurrence)}. * * This class is aware of Position in occurrences and can also be applied to inner nodes. Both - * {@link RuleApplicationManager} and {@link Strategy} are changed for the course of the + * {@link RuleApplicationManager} and {@link JavaStrategy} are changed for the course of the * macro but are restored afterwards using a {@link ProverTaskListener}. * * @see ProverTaskListener - * @see Strategy + * @see JavaStrategy */ public abstract class StrategyProofMacro extends AbstractProofMacro { diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/SymbolicExecutionOnlyMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/SymbolicExecutionOnlyMacro.java index e152e6aeadf..29f568f896c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/SymbolicExecutionOnlyMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/SymbolicExecutionOnlyMacro.java @@ -15,7 +15,6 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.rule.*; -import de.uka.ilkd.key.strategy.Strategy; import org.key_project.logic.Name; import org.key_project.logic.Term; @@ -26,6 +25,7 @@ import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.prover.sequent.Sequent; import org.key_project.prover.sequent.SequentFormula; +import org.key_project.prover.strategy.Strategy; import org.key_project.util.Streams; import org.jspecify.annotations.NonNull; diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/TranscendentalFloatSMTMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/TranscendentalFloatSMTMacro.java index 43f188b30b7..94184f2ccdd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/TranscendentalFloatSMTMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/TranscendentalFloatSMTMacro.java @@ -9,9 +9,9 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.strategy.Strategy; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.Strategy; import org.jspecify.annotations.NonNull; diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java index 75e90d518d5..923c1349778 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java @@ -24,10 +24,7 @@ import de.uka.ilkd.key.rule.inst.SVInstantiations; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.strategy.QueueRuleApplicationManager; -import de.uka.ilkd.key.strategy.Strategy; import de.uka.ilkd.key.util.properties.MapProperties; -import de.uka.ilkd.key.util.properties.Properties; -import de.uka.ilkd.key.util.properties.Properties.Property; import org.key_project.logic.PosInTerm; import org.key_project.logic.op.Function; @@ -43,6 +40,9 @@ import org.key_project.prover.sequent.SequentFormula; import org.key_project.prover.strategy.DelegationBasedRuleApplicationManager; import org.key_project.prover.strategy.RuleApplicationManager; +import org.key_project.prover.strategy.Strategy; +import org.key_project.util.Properties; +import org.key_project.util.Properties.Property; import org.key_project.util.collection.ImmutableList; import org.jspecify.annotations.Nullable; @@ -466,7 +466,7 @@ public void removeFormula(PosInOccurrence p) { * puts the NoPosTacletApp to the set of TacletApps at the node of the goal and to the current * RuleAppIndex. * - * @param app the TacletApp + * @param app the ITacletApp */ public void addNoPosTacletApp(NoPosTacletApp app) { node().addNoPosTacletApp(app); @@ -474,11 +474,11 @@ public void addNoPosTacletApp(NoPosTacletApp app) { } /** - * creates a new TacletApp and puts it to the set of TacletApps at the node of the goal and to + * creates a new ITacletApp and puts it to the set of TacletApps at the node of the goal and to * the current RuleAppIndex. * - * @param rule the Taclet of the TacletApp to create - * @param insts the given instantiations of the TacletApp to be created + * @param rule the Taclet of the ITacletApp to create + * @param insts the given instantiations of the ITacletApp to be created */ public void addTaclet(Taclet rule, SVInstantiations insts, boolean isAxiom) { NoPosTacletApp tacletApp = diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java index 8ae695ff3ef..0fa728f04b4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/Proof.java @@ -31,7 +31,6 @@ import de.uka.ilkd.key.settings.GeneralSettings; import de.uka.ilkd.key.settings.ProofIndependentSettings; import de.uka.ilkd.key.settings.ProofSettings; -import de.uka.ilkd.key.strategy.Strategy; import de.uka.ilkd.key.strategy.StrategyFactory; import de.uka.ilkd.key.strategy.StrategyProperties; @@ -40,6 +39,7 @@ import org.key_project.prover.proof.ProofObject; import org.key_project.prover.sequent.Sequent; import org.key_project.prover.sequent.SequentFormula; +import org.key_project.prover.strategy.Strategy; import org.key_project.util.collection.ImmutableList; import org.key_project.util.lookup.Lookup; diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/StrategyInfoUndoMethod.java b/key.core/src/main/java/de/uka/ilkd/key/proof/StrategyInfoUndoMethod.java index 1c07406f242..224de0457fd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/StrategyInfoUndoMethod.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/StrategyInfoUndoMethod.java @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package de.uka.ilkd.key.proof; -import de.uka.ilkd.key.util.properties.Properties; +import org.key_project.util.Properties; /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/TacletAppIndex.java b/key.core/src/main/java/de/uka/ilkd/key/proof/TacletAppIndex.java index 5fb578ff9ce..98d41a7a40a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/TacletAppIndex.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/TacletAppIndex.java @@ -456,7 +456,7 @@ public String toString() { + tacletIndex; } - // helper because IList is no IList + // helper because IList is no IList private static ImmutableList prepend(ImmutableList l1, ImmutableList l2) { for (NoPosTacletApp aL2 : l2) { diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/delayedcut/DelayedCutProcessor.java b/key.core/src/main/java/de/uka/ilkd/key/proof/delayedcut/DelayedCutProcessor.java index ce0404e909e..c6f109bd55e 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/delayedcut/DelayedCutProcessor.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/delayedcut/DelayedCutProcessor.java @@ -367,7 +367,7 @@ private void check(Goal goal, final RuleApp app, throw new RuntimeException("Cannot apply taclet-app"); } return; - // ImmutableList list = + // ImmutableList list = // goal.ruleAppIndex().getTacletAppAt(new TacletFilter() { // // @Override 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 18ba05413ed..0afde8dd567 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 @@ -33,7 +33,7 @@ import de.uka.ilkd.key.speclang.Contract; import de.uka.ilkd.key.speclang.SLEnvInput; import de.uka.ilkd.key.speclang.njml.JmlFacade; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import de.uka.ilkd.key.strategy.StrategyProperties; import org.key_project.util.collection.Pair; @@ -713,7 +713,7 @@ private ReplayResult replayProof(Proof proof) { StrategyProperties newProps = proof.getSettings().getStrategySettings().getActiveStrategyProperties(); newProps.setProperty(StrategyProperties.OSS_OPTIONS_KEY, StrategyProperties.OSS_ON); - Strategy.updateStrategySettings(proof, newProps); + JavaStrategy.updateStrategySettings(proof, newProps); OneStepSimplifier.refreshOSS(proof); replayer = new IntermediateProofReplayer(this, proof, parserResult); @@ -747,7 +747,7 @@ private ReplayResult replayProof(Proof proof) { StrategyProperties newProps = proof.getSettings().getStrategySettings().getActiveStrategyProperties(); newProps.setProperty(StrategyProperties.OSS_OPTIONS_KEY, ossStatus); - Strategy.updateStrategySettings(proof, newProps); + JavaStrategy.updateStrategySettings(proof, newProps); OneStepSimplifier.refreshOSS(proof); result = new ReplayResult(status, errors, lastTouchedNode); diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/replay/AbstractProofReplayer.java b/key.core/src/main/java/de/uka/ilkd/key/proof/replay/AbstractProofReplayer.java index 8cb619911eb..d97c1143752 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/replay/AbstractProofReplayer.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/replay/AbstractProofReplayer.java @@ -229,7 +229,7 @@ private TacletApp constructTacletApp(Node originalStep, Goal currGoal) { originalTacletApp = tacletApp; } assert originalTacletApp != null - : "Tried to construct TacletApp for a rule that is not a taclet"; + : "Tried to construct ITacletApp for a rule that is not a taclet"; final String tacletName = originalTacletApp.rule().name().toString(); diff --git a/key.core/src/main/java/de/uka/ilkd/key/prover/impl/PerfScope.java b/key.core/src/main/java/de/uka/ilkd/key/prover/impl/PerfScope.java index 3c1eca189b6..cc4dce619f8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/prover/impl/PerfScope.java +++ b/key.core/src/main/java/de/uka/ilkd/key/prover/impl/PerfScope.java @@ -46,9 +46,9 @@ public class PerfScope { new Pair<>("Semi Taclet app index update update", SemisequentTacletAppIndex.PERF_UPDATE), new Pair<>("Taclet app index create all", TacletAppIndex.PERF_CREATE_ALL), new Pair<>("Goal update listeners", Goal.PERF_UPDATE_LISTENERS), - new Pair<>("TacletApp execute", TacletApp.PERF_EXECUTE), - new Pair<>("TacletApp pre", TacletApp.PERF_PRE), - new Pair<>("TacletApp Goal setSequent", TacletApp.PERF_SET_SEQUENT), + new Pair<>("ITacletApp execute", TacletApp.PERF_EXECUTE), + new Pair<>("ITacletApp pre", TacletApp.PERF_PRE), + new Pair<>("ITacletApp Goal setSequent", TacletApp.PERF_SET_SEQUENT), new Pair<>("NoFindTacletExecutor apply", NoFindTacletExecutor.PERF_APPLY), new Pair<>("NoFindTacletExecutor setSequent", NoFindTacletExecutor.PERF_SET_SEQUENT), new Pair<>("NoFindTacletExecutor term labels", NoFindTacletExecutor.PERF_TERM_LABELS), diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractExternalSolverRuleApp.java b/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractExternalSolverRuleApp.java index 49345ec5def..30c681fe1a5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractExternalSolverRuleApp.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractExternalSolverRuleApp.java @@ -4,6 +4,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package de.uka.ilkd.key.rule; + import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.util.collection.ImmutableList; diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractLoopInvariantRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractLoopInvariantRule.java index 5cbe769607b..5e6c0169ac4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractLoopInvariantRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/AbstractLoopInvariantRule.java @@ -24,6 +24,7 @@ import de.uka.ilkd.key.speclang.LoopSpecification; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.Namespace; import org.key_project.logic.op.Function; @@ -147,8 +148,8 @@ public boolean isApplicableOnSubTerms() { } @Override - public IBuiltInRuleApp createApp(PosInOccurrence pos, TermServices services) { - return new LoopInvariantBuiltInRuleApp(this, pos, services); + public IBuiltInRuleApp createApp(PosInOccurrence pos, LogicServices services) { + return new LoopInvariantBuiltInRuleApp(this, pos, (TermServices) services); } @Override diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/BlockContractExternalRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/BlockContractExternalRule.java index 82b1ed9c3a7..021a5808140 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/BlockContractExternalRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/BlockContractExternalRule.java @@ -9,7 +9,6 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.JTerm; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.label.TermLabelState; import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.proof.Goal; @@ -25,6 +24,7 @@ import de.uka.ilkd.key.speclang.Contract; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Function; import org.key_project.prover.rules.RuleAbortException; @@ -189,7 +189,7 @@ protected void setLastInstantiation(Instantiation lastInstantiation) { } @Override - public IBuiltInRuleApp createApp(PosInOccurrence pos, TermServices services) { + public IBuiltInRuleApp createApp(PosInOccurrence pos, LogicServices services) { return new BlockContractExternalBuiltInRuleApp(this, pos); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/BlockContractInternalRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/BlockContractInternalRule.java index 95b46b6936f..2e7d13e3b32 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/BlockContractInternalRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/BlockContractInternalRule.java @@ -9,7 +9,6 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.JTerm; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.label.TermLabelState; import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.logic.op.ProgramVariable; @@ -22,6 +21,7 @@ import de.uka.ilkd.key.speclang.BlockContract; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Function; import org.key_project.prover.rules.RuleAbortException; @@ -202,7 +202,7 @@ protected void setLastInstantiation(Instantiation lastInstantiation) { @Override public BlockContractInternalBuiltInRuleApp createApp( - final PosInOccurrence occurrence, TermServices services) { + final PosInOccurrence occurrence, LogicServices services) { return new BlockContractInternalBuiltInRuleApp<>(this, occurrence); } 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 47178489497..407844afc0d 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 @@ -4,13 +4,11 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package de.uka.ilkd.key.rule; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.proof.Goal; -import org.key_project.prover.rules.RuleApp; +import org.key_project.logic.LogicServices; import org.key_project.prover.rules.RuleExecutor; import org.key_project.prover.sequent.PosInOccurrence; -import org.key_project.util.collection.ImmutableList; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; @@ -21,21 +19,9 @@ * has to ensure that the goal split is done only iff the application was successful. */ @NullMarked -public interface BuiltInRule extends Rule, RuleExecutor { +public interface BuiltInRule extends org.key_project.prover.rules.IBuiltInRule, Rule { - /** - * Returning true iff a rule is applicable at the given position. - * This does not necessarily mean that a rule application will change the goal - * (this decision is made due to performance reasons) - */ - boolean isApplicable(Goal goal, @Nullable PosInOccurrence pio); - - boolean isApplicableOnSubTerms(); - - IBuiltInRuleApp createApp(@Nullable PosInOccurrence pos, TermServices services); - - @Override - ImmutableList apply(Goal goal, RuleApp ruleApp); + IBuiltInRuleApp createApp(@Nullable PosInOccurrence pos, LogicServices services); @Override default RuleExecutor getExecutor() { diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/EqualityModuloProofIrrelevancy.java b/key.core/src/main/java/de/uka/ilkd/key/rule/EqualityModuloProofIrrelevancy.java index 19d54b5475d..3ef0b46b137 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/EqualityModuloProofIrrelevancy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/EqualityModuloProofIrrelevancy.java @@ -544,13 +544,13 @@ public static int hashCodeModProofIrrelevancy(org.key_project.prover.rules.Tacle } - // TacletApp + // ITacletApp /** * test for equality modulo proof irrelevancy for the given arguments * - * @param _this the first TacletApp - * @param that the second TacletApp + * @param _this the first ITacletApp + * @param that the second ITacletApp * @return true if both arguments are equal modulo proof irrelevancy */ public static boolean equalsModProofIrrelevancy(TacletApp _this, TacletApp that) { diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/ExternalSolverRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/ExternalSolverRule.java index f987576c41a..f72bf85302d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/ExternalSolverRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/ExternalSolverRule.java @@ -4,9 +4,9 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package de.uka.ilkd.key.rule; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.proof.Goal; +import org.key_project.logic.LogicServices; import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.util.collection.ImmutableList; @@ -28,7 +28,7 @@ AbstractExternalSolverRuleApp createApp( String successfulSolverName, ImmutableList unsatCore); @Override - IBuiltInRuleApp createApp(PosInOccurrence pos, TermServices services); + IBuiltInRuleApp createApp(PosInOccurrence pos, LogicServices services); @Override diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/IBuiltInRuleApp.java b/key.core/src/main/java/de/uka/ilkd/key/rule/IBuiltInRuleApp.java index 8126717bdff..94229270564 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/IBuiltInRuleApp.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/IBuiltInRuleApp.java @@ -9,19 +9,13 @@ import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.proof.Goal; -import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.util.collection.ImmutableList; import org.jspecify.annotations.NullMarked; @NullMarked -public interface IBuiltInRuleApp extends RuleApp { - - /** - * returns the built-in rule of this rule application - */ - BuiltInRule rule(); +public interface IBuiltInRuleApp extends org.key_project.prover.rules.IBuiltInRuleApp { /** * Tries to complete the rule application from the available information. Attention: Do neither @@ -35,18 +29,14 @@ public interface IBuiltInRuleApp extends RuleApp { IBuiltInRuleApp forceInstantiate(Goal goal); - List getHeapContext(); + IBuiltInRuleApp setAssumesInsts(ImmutableList ifInsts); + + IBuiltInRuleApp replacePos(PosInOccurrence newPos); /** - * returns true if tryToInstantiate is able to complete the app - * - * @return true if tryToInstantiate is able to complete the app + * returns the built-in rule of this rule application */ - boolean isSufficientlyComplete(); - - ImmutableList assumesInsts(); - - IBuiltInRuleApp setAssumesInsts(ImmutableList ifInsts); + BuiltInRule rule(); - IBuiltInRuleApp replacePos(PosInOccurrence newPos); + List getHeapContext(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/JmlAssertRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/JmlAssertRule.java index e3a2ab0efe5..fe77ae52eda 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/JmlAssertRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/JmlAssertRule.java @@ -24,6 +24,7 @@ import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLAssertStatement.Kind; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Modality; import org.key_project.prover.rules.RuleAbortException; @@ -109,7 +110,7 @@ public boolean isApplicableOnSubTerms() { } @Override - public IBuiltInRuleApp createApp(PosInOccurrence occurrence, TermServices services) { + public IBuiltInRuleApp createApp(PosInOccurrence occurrence, LogicServices services) { return new JmlAssertBuiltInRuleApp(this, occurrence); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/LoopApplyHeadRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/LoopApplyHeadRule.java index 715651b5be6..14f9321505a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/LoopApplyHeadRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/LoopApplyHeadRule.java @@ -10,13 +10,13 @@ import de.uka.ilkd.key.logic.JTerm; import de.uka.ilkd.key.logic.JavaBlock; import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.op.Transformer; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.metaconstruct.ForToWhileTransformation; import de.uka.ilkd.key.speclang.LoopContract; import de.uka.ilkd.key.speclang.LoopContractImpl; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Modality; import org.key_project.prover.rules.RuleAbortException; @@ -123,7 +123,7 @@ public String toString() { } @Override - public IBuiltInRuleApp createApp(@Nullable PosInOccurrence pos, TermServices services) { + public IBuiltInRuleApp createApp(@Nullable PosInOccurrence pos, LogicServices services) { return new LoopApplyHeadBuiltInRuleApp(this, pos); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/LoopContractExternalRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/LoopContractExternalRule.java index 753e42b518c..4b69223fbd4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/LoopContractExternalRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/LoopContractExternalRule.java @@ -9,7 +9,6 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.JTerm; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.label.TermLabelState; import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.logic.op.Transformer; @@ -26,6 +25,7 @@ import de.uka.ilkd.key.speclang.LoopContract; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Function; import org.key_project.prover.rules.RuleAbortException; @@ -190,7 +190,7 @@ protected void setLastInstantiation(Instantiation lastInstantiation) { @Override public LoopContractExternalBuiltInRuleApp createApp(PosInOccurrence pos, - TermServices services) { + LogicServices services) { return new LoopContractExternalBuiltInRuleApp<>(this, pos); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/LoopContractInternalRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/LoopContractInternalRule.java index db15fd05732..e1773d7b426 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/LoopContractInternalRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/LoopContractInternalRule.java @@ -9,7 +9,6 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.JTerm; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.label.TermLabelState; import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.proof.Goal; @@ -21,6 +20,7 @@ import de.uka.ilkd.key.speclang.LoopContract; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Function; import org.key_project.prover.rules.RuleAbortException; @@ -262,7 +262,7 @@ protected void setLastInstantiation(Instantiation lastInstantiation) { @Override public LoopContractInternalBuiltInRuleApp createApp(final PosInOccurrence occurrence, - TermServices services) { + LogicServices services) { return new LoopContractInternalBuiltInRuleApp(this, occurrence); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/NoPosTacletApp.java b/key.core/src/main/java/de/uka/ilkd/key/rule/NoPosTacletApp.java index e780a3d9fbb..ef1dcfcfb69 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/NoPosTacletApp.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/NoPosTacletApp.java @@ -90,7 +90,7 @@ public static NoPosTacletApp createNoPosTacletApp(Taclet taclet, MatchResultInfo } /** - * Create TacletApp with immutable "instantiations", i.e. this instantiations must not be + * Create ITacletApp with immutable "instantiations", i.e. this instantiations must not be * modified later (e.g. by "addInstantiation"). However, this information is currently only used * to decide about introduction of metavariables. Immutable instantiations are important for the * "addrules" part of taclets. @@ -129,7 +129,7 @@ private NoPosTacletApp(org.key_project.prover.rules.Taclet taclet, } /** - * adds a new instantiation to this TacletApp + * adds a new instantiation to this ITacletApp * * @param sv the SchemaVariable to be instantiated * @param se the SyntaxElement (usually a {@link Term} or {@link ProgramElement}) @@ -138,7 +138,7 @@ private NoPosTacletApp(org.key_project.prover.rules.Taclet taclet, * saving a proof; this is usually needed for new names as their creation * is not always deterministic * @param services the Services for access to the logic signature and more - * @return the new TacletApp + * @return the new ITacletApp */ @Override public TacletApp addInstantiation(SchemaVariable sv, SyntaxElement se, boolean interesting, @@ -167,7 +167,7 @@ public TacletApp addInstantiation(SVInstantiations svi, Services services) { /** * creates a new Taclet application containing all the instantiations given by the - * SVInstantiations and forget the ones in this TacletApp + * SVInstantiations and forget the ones in this ITacletApp * * @param svi the SVInstantiations whose entries are the needed instantiations * @return the new Taclet application @@ -225,7 +225,7 @@ protected Set contextVars(SchemaVariable sv) { * } * * - * @return TacletApp with the resulting instantiations or null + * @return ITacletApp with the resulting instantiations or null */ public NoPosTacletApp matchFind(PosInOccurrence pos, LogicServices services) { return matchFind(null, pos, services); diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/ObserverToUpdateRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/ObserverToUpdateRule.java index c7d814fa13a..cf8cde4c4a7 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/ObserverToUpdateRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/ObserverToUpdateRule.java @@ -16,7 +16,6 @@ import de.uka.ilkd.key.logic.JTerm; import de.uka.ilkd.key.logic.JavaBlock; import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.label.TermLabelManager; import de.uka.ilkd.key.logic.label.TermLabelState; import de.uka.ilkd.key.logic.op.IObserverFunction; @@ -30,6 +29,7 @@ import de.uka.ilkd.key.rule.UseOperationContractRule.Instantiation; import de.uka.ilkd.key.util.Union; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; @@ -110,7 +110,7 @@ public IBuiltInRuleApp createApp(PosInOccurrence pos) { } @Override - public IBuiltInRuleApp createApp(PosInOccurrence pos, TermServices services) { + public IBuiltInRuleApp createApp(PosInOccurrence pos, LogicServices services) { return new DefaultBuiltInRuleApp(this, pos); } 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 a16f6088158..83bf4d2148e 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 @@ -8,7 +8,6 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.JTerm; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.label.TermLabel; import de.uka.ilkd.key.logic.label.TermLabelManager; import de.uka.ilkd.key.logic.label.TermLabelState; @@ -28,6 +27,7 @@ import de.uka.ilkd.key.strategy.StrategyProperties; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.PosInTerm; import org.key_project.logic.Term; @@ -330,7 +330,7 @@ private SequentFormula simplifyPos(Goal goal, protocol.add(app); } return result; - // TODO Idea: return new Pair(null, null); + // TODO Idea: return new Pair(null, null); } return null; } @@ -794,7 +794,7 @@ public String toString() { } @Override - public OneStepSimplifierRuleApp createApp(PosInOccurrence pos, TermServices services) { + public OneStepSimplifierRuleApp createApp(PosInOccurrence pos, LogicServices services) { return new OneStepSimplifierRuleApp(this, pos); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/PosTacletApp.java b/key.core/src/main/java/de/uka/ilkd/key/rule/PosTacletApp.java index 8a31c0d3059..92af5e02691 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/PosTacletApp.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/PosTacletApp.java @@ -94,7 +94,7 @@ private PosTacletApp(FindTaclet taclet, SVInstantiations instantiations, * __OPTIMIZE__ If this method is needed more than once caching the result should be considered. * * @return the set of the logicvariables that are bound for the indicated application position - * of the TacletApp. + * of the ITacletApp. */ private static Set varsBoundAboveFindPos(Taclet taclet, PosInOccurrence pos) { @@ -149,11 +149,11 @@ private static SVInstantiations resolveCollisionWithContext(Taclet taclet, /** - * adds a new instantiation to this TacletApp + * adds a new instantiation to this ITacletApp * * @param sv the SchemaVariable to be instantiated * @param term the Term the SchemaVariable is instantiated with - * @return the new TacletApp + * @return the new ITacletApp */ @Override public TacletApp addInstantiation(SchemaVariable sv, SyntaxElement term, boolean interesting, @@ -171,7 +171,7 @@ public TacletApp addInstantiation(SchemaVariable sv, SyntaxElement term, boolean /** * creates a new Taclet application containing all the instantiations given by the - * SVInstantiations and the ones of this TacletApp + * SVInstantiations and the ones of this ITacletApp * * @param svi the SVInstantiations whose entries are the needed instantiations * @return the new Taclet application 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 60f08e1732a..198dcef1745 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 @@ -25,8 +25,8 @@ import de.uka.ilkd.key.rule.inst.SVInstantiations; import de.uka.ilkd.key.rule.tacletbuilder.RewriteTacletBuilder; import de.uka.ilkd.key.util.MiscTools; -import de.uka.ilkd.key.util.properties.Properties.Property; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.Namespace; import org.key_project.logic.op.Function; @@ -39,6 +39,7 @@ import org.key_project.prover.sequent.PIOPathIterator; import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.prover.sequent.SequentFormula; +import org.key_project.util.Properties.Property; import org.key_project.util.collection.ImmutableArray; import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.Pair; @@ -695,7 +696,7 @@ public Long getTimeOfQuery(JTerm t, Goal goal) { } @Override - public DefaultBuiltInRuleApp createApp(PosInOccurrence pos, TermServices services) { + public DefaultBuiltInRuleApp createApp(PosInOccurrence pos, LogicServices services) { return new DefaultBuiltInRuleApp(this, pos); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/SetStatementRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/SetStatementRule.java index 91b8d189f00..3818928f161 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/SetStatementRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/SetStatementRule.java @@ -13,12 +13,12 @@ import de.uka.ilkd.key.logic.JTerm; import de.uka.ilkd.key.logic.JavaBlock; import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.op.Transformer; import de.uka.ilkd.key.logic.op.UpdateApplication; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Modality; import org.key_project.prover.rules.RuleAbortException; @@ -74,7 +74,7 @@ public boolean isApplicableOnSubTerms() { } @Override - public IBuiltInRuleApp createApp(PosInOccurrence occurrence, TermServices services) { + public IBuiltInRuleApp createApp(PosInOccurrence occurrence, LogicServices services) { return new SetStatementBuiltInRuleApp(this, occurrence); } 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 f9614811e0f..7c77cbc1f26 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 @@ -52,7 +52,7 @@ * The find part of a taclet is used to attached the rule to a term in the sequent of the current * goal. Therefore the term of the sequent has to match the schema as found in the taclet's find * part. The taclet is then attached to this term, more precise not the taclet itself, but an - * application object of this taclet (see {@link TacletApp TacletApp}. When + * application object of this taclet (see {@link TacletApp ITacletApp}. When * this attached taclet application object is applied, the new goals are constructed as described by * the goal descriptions. For example
*
@@ -74,7 +74,7 @@ * looking where it can be applied, these tasks have to be done in advance. For example by one of * the following classes {@link de.uka.ilkd.key.proof.RuleAppIndex RuleAppIndex} or * {@link de.uka.ilkd.key.proof.TacletAppIndex TacletAppIndex} or - * {@link TacletApp TacletApp} + * {@link TacletApp ITacletApp} *

*/ public abstract class Taclet extends org.key_project.prover.rules.Taclet implements Rule { diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/TacletApp.java b/key.core/src/main/java/de/uka/ilkd/key/rule/TacletApp.java index adb10680cfd..331d5cce088 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/TacletApp.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/TacletApp.java @@ -34,7 +34,7 @@ import org.key_project.logic.op.QuantifiableVariable; import org.key_project.logic.op.sv.SchemaVariable; import org.key_project.logic.sort.Sort; -import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.rules.ITacletApp; import org.key_project.prover.rules.instantiation.*; import org.key_project.prover.sequent.*; import org.key_project.util.collection.*; @@ -45,7 +45,7 @@ import static org.key_project.logic.op.Function.FunctionKind.*; /** - * A TacletApp object contains information required for a concrete application. These information + * A ITacletApp object contains information required for a concrete application. These information * may consist of *
    *
  • instantiations of the schemavariables
  • @@ -55,7 +55,7 @@ * the information is complete or at least sufficient (can be completed using meta variables) * complete, so that is can be applied. */ -public abstract class TacletApp implements RuleApp { +public abstract class TacletApp implements ITacletApp { public static final AtomicLong PERF_EXECUTE = new AtomicLong(); public static final AtomicLong PERF_SET_SEQUENT = new AtomicLong(); public static final AtomicLong PERF_PRE = new AtomicLong(); @@ -91,7 +91,7 @@ public abstract class TacletApp implements RuleApp { protected boolean updateContextFixed = false; /** - * constructs a TacletApp for the given taclet, with an empty instantiation map + * constructs a ITacletApp for the given taclet, with an empty instantiation map */ TacletApp(org.key_project.prover.rules.Taclet taclet) { this(taclet, de.uka.ilkd.key.rule.inst.SVInstantiations.EMPTY_SVINSTANTIATIONS, null); @@ -422,6 +422,11 @@ protected ImmutableSet calculateNonInstantiatedGenericSorts() { return missingSorts; } + @Override + public ITacletApp addCheckedInstantiation(SchemaVariable sv, Term term, LogicServices services, + boolean interesting) { + return addCheckedInstantiation(sv, (JTerm) term, (Services) services, interesting); + } /** * creates a new Tacletapp where the SchemaVariable sv is instantiated with the given term. @@ -432,7 +437,7 @@ protected ImmutableSet calculateNonInstantiatedGenericSorts() { * @param services the services object * @param interesting whether instantiations for this schema variable should be kept in the list * of "interesting" instantiations - * @return the new TacletApp + * @return the new ITacletApp */ public TacletApp addCheckedInstantiation(SchemaVariable sv, JTerm term, Services services, boolean interesting) { @@ -466,6 +471,7 @@ public TacletApp addCheckedInstantiation(SchemaVariable sv, JTerm term, Services * * @return ImmutableSet with SchemaVariables that have not been instantiated yet */ + @Override public @NonNull ImmutableSet uninstantiatedVars() { return calculateNonInstantiatedSV(); } @@ -513,7 +519,7 @@ public final TacletApp tryToInstantiateAsMuchAsPossible(Services services) { } /** - * @return A TacletApp with this.sufficientlyComplete() or null + * @return A ITacletApp with this.sufficientlyComplete() or null */ public final @Nullable TacletApp tryToInstantiate(Services services) { TacletApp app = instantiationHelper(true, services); @@ -785,7 +791,7 @@ public TacletApp createSkolemConstants(Goal goal) { } /** - * adds a new instantiation to this TacletApp. This method does not check (beside some very + * adds a new instantiation to this ITacletApp. This method does not check (beside some very * rudimentary tests) if the instantiation is possible. If you cannot guarantee that adding the * entry (sv, se) will result in a valid taclet instantiation, you have to use * {@link #addCheckedInstantiation(SchemaVariable, ProgramElement, Services, boolean)} instead @@ -1002,18 +1008,19 @@ private ImmutableList createSemisequentList( } /** - * returns a new PosTacletApp that is equal to this TacletApp except that the position is set to + * returns a new PosTacletApp that is equal to this ITacletApp except that the position is set + * to * the given PosInOccurrence. * *

    * CAUTION: If you call this method, consider to call * {@link NoPosTacletApp#matchFind(PosInOccurrence, LogicServices)} * first (if applicable) as - * otherwise the TacletApp may become invalid. (This happened sometimes during interactive + * otherwise the ITacletApp may become invalid. (This happened sometimes during interactive * proofs). * * @param pos the PosInOccurrence of the newl created PosTacletApp - * @return the new TacletApp + * @return the new ITacletApp */ public PosTacletApp setPosInOccurrence(PosInOccurrence pos, Services services) { @@ -1027,12 +1034,13 @@ public PosTacletApp setPosInOccurrence(PosInOccurrence pos, /** * @return true iff the if-instantiation list is not null or no if sequent is needed */ + @Override public boolean assumesInstantionsComplete() { return assumesFormulaInstantiations != null || taclet().assumesSequent().isEmpty(); } /** - * compares the given Object with this one and returns true iff both are from type TacletApp + * compares the given Object with this one and returns true iff both are from type ITacletApp * with equal taclets, instantiations and positions. */ @Override @@ -1067,12 +1075,13 @@ public String toString() { /** * checks if there are name conflicts (i.e. there are two matched bound SchemaVariable that are - * matched to variables with an equal name); if yes a new TacletApp is returned that equals this - * TacletApp except that the name conflict is resolved by replacing the instantiation of one of + * matched to variables with an equal name); if yes a new ITacletApp is returned that equals + * this + * ITacletApp except that the name conflict is resolved by replacing the instantiation of one of * the conflict-causing SchemaVariables by a bound SchemaVariable with a new name; if the check - * is negative, the same TacletApp is returned. + * is negative, the same ITacletApp is returned. * - * @return a conflict resolved TacletApp, remainder equal to this TacletApp + * @return a conflict resolved ITacletApp, remainder equal to this ITacletApp */ public TacletApp prepareUserInstantiation(Services services) { TacletApp result = this; @@ -1089,7 +1098,7 @@ public TacletApp prepareUserInstantiation(Services services) { /** * creates a new variable namespace by adding names of the instantiations of the schema - * variables in the context of the given schema variable and (if the TacletApp's prefix has the + * variables in the context of the given schema variable and (if the ITacletApp's prefix has the * context flag set) by adding names of the logic variables of the context. * * @param sv the schema variable to be considered 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 aca630071a6..f7a5f2c100b 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 @@ -26,6 +26,7 @@ import de.uka.ilkd.key.speclang.DependencyContract; import de.uka.ilkd.key.speclang.HeapContext; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.PosInTerm; import org.key_project.logic.Term; @@ -654,7 +655,7 @@ public UseDependencyContractApp createApp(PosInOccurrence pos) { } @Override - public UseDependencyContractApp createApp(PosInOccurrence pos, TermServices services) { + public UseDependencyContractApp createApp(PosInOccurrence pos, LogicServices services) { return new UseDependencyContractApp(this, pos); } 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 cd2b805df0f..4674aa891b3 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 @@ -35,6 +35,7 @@ import de.uka.ilkd.key.speclang.FunctionalOperationContract; import de.uka.ilkd.key.speclang.HeapContext; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Function; import org.key_project.prover.rules.RuleApp; @@ -574,7 +575,7 @@ public ContractRuleApp createApp(PosInOccurrence pos) { } @Override - public ContractRuleApp createApp(PosInOccurrence pos, TermServices services) { + public ContractRuleApp createApp(PosInOccurrence pos, LogicServices services) { return new ContractRuleApp(this, pos); } 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 cb5e488824c..8c090747d06 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 @@ -30,6 +30,7 @@ import de.uka.ilkd.key.speclang.LoopSpecification; import de.uka.ilkd.key.util.MiscTools; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Function; import org.key_project.logic.op.Modality; @@ -131,8 +132,8 @@ public String toString() { @Override - public LoopInvariantBuiltInRuleApp createApp(PosInOccurrence pos, TermServices services) { - return new LoopInvariantBuiltInRuleApp<>(this, pos, services); + public LoopInvariantBuiltInRuleApp createApp(PosInOccurrence pos, LogicServices services) { + return new LoopInvariantBuiltInRuleApp<>(this, pos, (TermServices) services); } /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/AntecTacletExecutor.java b/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/AntecTacletExecutor.java index 380dd540935..43b48f1d270 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/AntecTacletExecutor.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/AntecTacletExecutor.java @@ -71,7 +71,7 @@ protected void applyReplacewith(TacletGoalTemplate gt, TermLabelState termLabelS * match took place * @param matchCond the {@link MatchResultInfo} with all required instantiations * @param goal the Goal where the taclet is applied to - * @param ruleApp the {@link RuleApp} (a TacletApp) describing the current ongoing taclet + * @param ruleApp the {@link RuleApp} (a ITacletApp) describing the current ongoing taclet * application * @param services the {@link Services} encapsulating all Java model information */ diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/FindTacletExecutor.java b/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/FindTacletExecutor.java index f3338e2d47a..0f78dc292db 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/FindTacletExecutor.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/executor/javadl/FindTacletExecutor.java @@ -169,7 +169,7 @@ public final ImmutableList apply(@NonNull Goal goal, @NonNull RuleApp rule * creates a new position information object, describing where to add the formulas or * {@code null} if it should just be added to the beginning * - * @param tacletApp a TacletApp with application information + * @param tacletApp a ITacletApp with application information * @param gt the TacletGoalTemplate to be applied * @param currentSequent the current sequent (the one of the new goal) * @return the PosInOccurrence object describing where to add the formula 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 2431f4a3926..c3a5b0cecaf 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 @@ -194,7 +194,7 @@ protected void applyAddrule(ImmutableList> additionalRules; private final boolean exclusive; - public AdditionalRulesStrategy(Strategy delegate, String additionalRules, boolean exclusive) { + public AdditionalRulesStrategy(Strategy delegate, String additionalRules, + boolean exclusive) { super(delegate); this.additionalRules = parseAddRules(additionalRules); this.exclusive = exclusive; diff --git a/key.core/src/main/java/de/uka/ilkd/key/scripts/AutoCommand.java b/key.core/src/main/java/de/uka/ilkd/key/scripts/AutoCommand.java index be75fcf2067..c27d20bbb87 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/scripts/AutoCommand.java +++ b/key.core/src/main/java/de/uka/ilkd/key/scripts/AutoCommand.java @@ -16,12 +16,12 @@ import de.uka.ilkd.key.scripts.meta.*; import de.uka.ilkd.key.settings.StrategySettings; import de.uka.ilkd.key.strategy.FocussedBreakpointRuleApplicationManager; -import de.uka.ilkd.key.strategy.Strategy; import de.uka.ilkd.key.strategy.StrategyProperties; import org.key_project.prover.engine.ProofSearchInformation; import org.key_project.prover.engine.ProverCore; import org.key_project.prover.strategy.RuleApplicationManager; +import org.key_project.prover.strategy.Strategy; import org.key_project.util.collection.ImmutableList; import org.jspecify.annotations.NullMarked; @@ -97,7 +97,7 @@ public void execute(ScriptCommandAst args) throws ScriptException, InterruptedEx SetCommand.updateStrategySettings(state(), activeStrategyProperties); - final Strategy originalStrategy = state.getProof().getActiveStrategy(); + final Strategy originalStrategy = state.getProof().getActiveStrategy(); if (arguments.additionalRules != null) { state.getProof().setActiveStrategy( new AdditionalRulesStrategy(originalStrategy, arguments.additionalRules, false)); diff --git a/key.core/src/main/java/de/uka/ilkd/key/scripts/SetCommand.java b/key.core/src/main/java/de/uka/ilkd/key/scripts/SetCommand.java index 8a55d458608..86302f704b4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/scripts/SetCommand.java +++ b/key.core/src/main/java/de/uka/ilkd/key/scripts/SetCommand.java @@ -17,10 +17,11 @@ import de.uka.ilkd.key.scripts.meta.Option; import de.uka.ilkd.key.scripts.meta.OptionalVarargs; import de.uka.ilkd.key.settings.ProofSettings; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import de.uka.ilkd.key.strategy.StrategyFactory; import de.uka.ilkd.key.strategy.StrategyProperties; +import org.key_project.prover.strategy.Strategy; import org.key_project.util.lookup.Property; import org.jspecify.annotations.Nullable; @@ -74,7 +75,7 @@ public void execute(ScriptCommandAst arguments) throws ScriptException, Interrup newProps.setProperty(StrategyProperties.OSS_OPTIONS_KEY, args.oneStepSimplification ? StrategyProperties.OSS_ON : StrategyProperties.OSS_OFF); - Strategy.updateStrategySettings(proof, newProps); + JavaStrategy.updateStrategySettings(proof, newProps); OneStepSimplifier.refreshOSS(proof); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/smt/SMTRule.java b/key.core/src/main/java/de/uka/ilkd/key/smt/SMTRule.java index fedbd37d1a2..2045229a523 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/smt/SMTRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/smt/SMTRule.java @@ -4,11 +4,11 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package de.uka.ilkd.key.smt; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.AbstractExternalSolverRuleApp; import de.uka.ilkd.key.rule.ExternalSolverRule; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; @@ -49,7 +49,7 @@ public AbstractExternalSolverRuleApp createApp @Override - public SMTRuleApp createApp(PosInOccurrence pos, TermServices services) { + public SMTRuleApp createApp(PosInOccurrence pos, LogicServices services) { return new SMTRuleApp(this, null, ""); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/CombinationCost.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/CombinationCost.java deleted file mode 100644 index db3a1f3b808..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/CombinationCost.java +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2, - * or (at your option) any later version. - * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy; - -/** - * Costs whose meaning spans more than one component strategy — the theory-combination - * constants, as opposed to the theory-internal holders ({@link FOLCost}, the integer holders, - * {@link SymExCost}, {@link StringCost}, {@link JavaCardDLCost}, {@link HeapSelectCost}). - * - *

    - * A constant is admitted here through one of two mechanisms: - *

    - *
      - *
    1. Conflict-dispatched rule sets: the same rule set is bound by two strategies, and - * {@link ModularJavaDLStrategy}#resolveConflict dispatches between the two bindings by the focus - * term (integer-typed focus → Integer half, otherwise FOL half). The two bindings are two halves of - * ONE combination decision, so their base costs must agree. Currently: {@code apply_equations} and - * {@code apply_equations_andOr} (the third conflict case, {@code order_terms}, needs no constant - * here — both halves anchor it at {@code CostBand.NORMALIZE}).
    2. - *
    3. Cost-sum couplings: one taclet carries rule sets owned by different - * strategies, so the dispatch sums their contributions and the tuned quantity is the sum, not - * either summand (e.g. the {@code applyEq} taclet, see {@link #APPLY_SELECT_EQ_EFFECTIVE}).
    4. - *
    - * - *

    - * A theory-local rule may also reference a constant here when sharing the level is the documented - * intent (e.g. {@code conjNormalForm} at {@link #CNF_CONVERSION}), so that retuning the - * combination level moves the coupled rule with it. - *

    - * - *

    - * Values are byte-identical to the literals they replace; verify changes with a full runAllProofs - * (as for {@link org.key_project.prover.strategy.costbased.CostBand}). - *

    - */ -final class CombinationCost { - private CombinationCost() {} - - /** - * Demodulation: use an oriented equation as a rewrite rule, only in the decreasing direction - * of the reduction ordering (see the {@code TermSmallerThanFeature} / - * {@code MonomialsSmallerThanFeature} guards at the call sites; right ≺ left). The FOL half - * instantiates this with the generic term ordering, the Integer half with the monomial - * ordering. The orientation step itself ({@code order_terms}) sits at - * {@code CostBand.NORMALIZE}. Deliberately its own level — not {@code EXECUTE}, which - * is reserved for symbolic execution. - */ - static final long ORDERED_REWRITING = -4000; - - /** - * Priority at which CNF conversion runs: {@code conjNormalForm} (associativity, commutation, - * distribution, if-then-else expansion — the fine ordering among these comes from the - * {@code cnf_*} co-rule-sets, {@link FOLCost#CNF_RESTRUCTURE}) and ordered rewriting within - * and/or clause contexts ({@code apply_equations_andOr}, conflict-dispatched). - */ - static final long CNF_CONVERSION = -150; - - /** - * Effective cost of replacing a select term via the {@code applyEq} taclet: the taclet carries - * BOTH {@code apply_equations} (FOL/Integer, {@link #ORDERED_REWRITING}) and - * {@code apply_select_eq} (JavaCardDL, {@link HeapSelectCost#APPLY_SELECT_EQ}), so the - * dispatch sums the two contributions. This constant is the tuned target of that sum; - * {@link HeapSelectCost#APPLY_SELECT_EQ} is derived from it. - */ - static final long APPLY_SELECT_EQ_EFFECTIVE = -5700; -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/CostReuse.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/CostReuse.java index 747ecb7191c..498e5f810f7 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/CostReuse.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/CostReuse.java @@ -13,11 +13,12 @@ import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.strategy.feature.AbstractNonDuplicateAppFeature; import de.uka.ilkd.key.strategy.feature.NonDuplicateAppFeature; -import de.uka.ilkd.key.strategy.feature.RuleSetDispatchFeature; import org.key_project.prover.rules.Taclet; +import org.key_project.prover.strategy.Strategy; import org.key_project.prover.strategy.costbased.CostClassifiable; import org.key_project.prover.strategy.costbased.CostLocality; +import org.key_project.prover.strategy.costbased.feature.*; import org.key_project.prover.strategy.costbased.feature.Feature; import org.key_project.prover.strategy.costbased.feature.StableCost; import org.key_project.prover.strategy.costbased.feature.VolatileCost; diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/FIFOStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/FIFOStrategy.java index 0b314811aed..a9aedbe8e7a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/FIFOStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/FIFOStrategy.java @@ -22,7 +22,7 @@ * Trivial implementation of the Strategy interface that uses only the goal time to determine the * cost of a RuleApp. */ -public class FIFOStrategy implements Strategy { +public class FIFOStrategy implements JavaStrategy { private static final Name NAME = new Name("FIFO"); @@ -60,14 +60,15 @@ public boolean isApprovedApp(RuleApp app, PosInOccurrence pio, @Override public void instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, - RuleAppCostCollector collector) {} + org.key_project.prover.strategy.RuleAppCostCollector collector) {} @Override public Name name() { return NAME; } - public static final Strategy INSTANCE = new FIFOStrategy(); + public static final org.key_project.prover.strategy.Strategy INSTANCE = + new FIFOStrategy(); public static class Factory implements StrategyFactory { @Override @@ -76,7 +77,8 @@ public Name name() { } @Override - public Strategy create(Proof proof, StrategyProperties properties) { + public org.key_project.prover.strategy.Strategy create(Proof proof, + StrategyProperties properties) { return INSTANCE; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/FOLStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/FOLStrategy.java index 33a8751eb0d..6df67d23d22 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/FOLStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/FOLStrategy.java @@ -12,7 +12,6 @@ import de.uka.ilkd.key.logic.op.Quantifier; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.rule.BuiltInRule; import de.uka.ilkd.key.rule.OneStepSimplifier; import de.uka.ilkd.key.strategy.feature.*; import de.uka.ilkd.key.strategy.quantifierHeuristics.*; @@ -29,13 +28,12 @@ import org.key_project.logic.Name; import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.proof.rulefilter.SetRuleFilter; +import org.key_project.prover.rules.IBuiltInRule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; -import org.key_project.prover.strategy.costbased.CostBand; -import org.key_project.prover.strategy.costbased.MutableState; -import org.key_project.prover.strategy.costbased.RuleAppCost; -import org.key_project.prover.strategy.costbased.TopRuleAppCost; +import org.key_project.prover.strategy.ComponentStrategy; +import org.key_project.prover.strategy.costbased.*; import org.key_project.prover.strategy.costbased.feature.*; import org.key_project.prover.strategy.costbased.feature.instantiator.ChoicePoint; import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; @@ -44,7 +42,8 @@ import org.jspecify.annotations.NonNull; -import static de.uka.ilkd.key.strategy.FOLCost.*; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.*; +import static org.key_project.prover.strategy.costbased.FOLCost.*; /// Strategy for general FOL rules. This does not consider other /// theories like integers or Java-specific functions. @@ -52,7 +51,7 @@ /// In particular, instantiation of quantifiers is not supported by this /// strategy, as the current E-matching depends on the theory of integers. /// For that reason, instantiation can be found [JFOLStrategy]. -public class FOLStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class FOLStrategy extends JavaAbstractFeatureStrategy implements ComponentStrategy { public static final Name NAME = new Name("FOL Strategy"); protected final StrategyProperties strategyProperties; @@ -64,7 +63,7 @@ public class FOLStrategy extends AbstractFeatureStrategy implements ComponentStr private final Feature approvalF; private final Feature instantiationF; - protected final ArithTermFeatures tf; + protected final JavaArithTermFeatures tf; protected final FormulaTermFeatures ff; public FOLStrategy(Proof proof, StrategyProperties strategyProperties) { @@ -72,7 +71,7 @@ public FOLStrategy(Proof proof, StrategyProperties strategyProperties) { this.strategyProperties = strategyProperties.clone(); - this.tf = new ArithTermFeatures(getServices().getTypeConverter().getIntegerLDT()); + this.tf = new JavaArithTermFeatures(getServices().getTypeConverter().getIntegerLDT()); this.ff = new FormulaTermFeatures(this.tf); costComputationDispatcher = setupCostComputationF(); @@ -121,7 +120,8 @@ private RuleSetDispatchFeature setupCostComputationF() { ifZero(MatchedAssumesFeature.INSTANCE, NoSelfApplicationFeature.INSTANCE)); bindRuleSet(d, "find_term_not_in_assumes", ifZero(MatchedAssumesFeature.INSTANCE, - not(contains(AssumptionProjection.create(0), FocusProjection.INSTANCE)))); + not(contains(AssumptionProjection.create(0), FocusProjection.INSTANCE, + StaticFeatureCollection::eq)))); bindRuleSet(d, "update_elim", add(CostBand.ELIMINATE.cost(), @@ -434,7 +434,7 @@ private void setupQuantifierInstantiationApproval(RuleSetDispatchFeature d) { bindRuleSet(d, "gamma", add(isInstantiated("t"), not(sum(varInst, HeuristicInstantiation.forOption(triggerTreatment()), - not(eq(instOf("t"), varInst)))), + not(StaticFeatureCollection.eq(instOf("t"), varInst)))), InstantiationCostScalerFeature.create( InstantiationCost.create(instOf("t"), triggerTreatment()), longConst(0)))); @@ -443,7 +443,7 @@ private void setupQuantifierInstantiationApproval(RuleSetDispatchFeature d) { bindRuleSet(d, "triggered", add(isTriggerVariableInstantiated(), not(sum(splitInst, TriggeredInstantiations.create(false), - not(eq(instOfTriggerVariable(), splitInst)))))); + not(StaticFeatureCollection.eq(instOfTriggerVariable(), splitInst)))))); } else { bindRuleSet(d, "gamma", inftyConst()); bindRuleSet(d, "triggered", inftyConst()); @@ -658,7 +658,7 @@ private boolean normalSplitting() { } @Override - public boolean isResponsibleFor(BuiltInRule rule) { + public boolean isResponsibleFor(IBuiltInRule rule) { return rule instanceof OneStepSimplifier; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/FormulaTermFeatures.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/FormulaTermFeatures.java index ff3cf8204a4..275557e6429 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/FormulaTermFeatures.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/FormulaTermFeatures.java @@ -10,12 +10,13 @@ import de.uka.ilkd.key.strategy.termfeature.ContainsExecutableCodeTermFeature; import org.key_project.logic.op.Function; +import org.key_project.prover.strategy.IFormulaTermFeatures; import org.key_project.prover.strategy.costbased.termfeature.OperatorClassTF; import org.key_project.prover.strategy.costbased.termfeature.TermFeature; -class FormulaTermFeatures extends StaticFeatureCollection { +class FormulaTermFeatures extends StaticFeatureCollection implements IFormulaTermFeatures { - public FormulaTermFeatures(ArithTermFeatures tf) { + public FormulaTermFeatures(JavaArithTermFeatures tf) { forF = extendsTrans(JavaDLTheory.FORMULA); orF = op(Junctor.OR); andF = op(Junctor.AND); @@ -98,4 +99,134 @@ public FormulaTermFeatures(ArithTermFeatures tf) { final TermFeature cutAllowed; final TermFeature cutAllowedBelowQuantifier; final TermFeature cutPriority; + + @Override + public TermFeature forF() { + return forF; + } + + @Override + public TermFeature orF() { + return orF; + } + + @Override + public TermFeature andF() { + return andF; + } + + @Override + public TermFeature impF() { + return impF; + } + + @Override + public TermFeature notF() { + return notF; + } + + @Override + public TermFeature propJunctor() { + return propJunctor; + } + + @Override + public TermFeature ifThenElse() { + return ifThenElse; + } + + @Override + public TermFeature notExecutable() { + return notExecutable; + } + + @Override + public TermFeature notContainsExecutable() { + return notContainsExecutable; + } + + @Override + public TermFeature quantifiedFor() { + return quantifiedFor; + } + + @Override + public TermFeature quantifiedOr() { + return quantifiedOr; + } + + @Override + public TermFeature quantifiedAnd() { + return quantifiedAnd; + } + + @Override + public TermFeature atom() { + return atom; + } + + @Override + public TermFeature literal() { + return literal; + } + + @Override + public TermFeature clause() { + return clause; + } + + @Override + public TermFeature clauseSet() { + return clauseSet; + } + + @Override + public TermFeature quantifiedClauseSet() { + return quantifiedClauseSet; + } + + @Override + public TermFeature pureLitConjDisj() { + return pureLitConjDisj; + } + + @Override + public TermFeature quantifiedPureLitConjDisj() { + return quantifiedPureLitConjDisj; + } + + @Override + public TermFeature elemUpdate() { + return elemUpdate; + } + + @Override + public TermFeature update() { + return update; + } + + @Override + public TermFeature program() { + return program; + } + + @Override + public TermFeature modalOperator() { + return modalOperator; + } + + @Override + public TermFeature cutAllowed() { + return cutAllowed; + } + + @Override + public TermFeature cutAllowedBelowQuantifier() { + return cutAllowedBelowQuantifier; + } + + @Override + public TermFeature cutPriority() { + return cutPriority; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerArithmeticCosts.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerArithmeticCosts.java deleted file mode 100644 index 66ab2bab827..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerArithmeticCosts.java +++ /dev/null @@ -1,127 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2, - * or (at your option) any later version. - * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy; - -/* - * Theory-internal cost constants for the integer arithmetic strategy, grouped by the arithmetic - * sub-theory they belong to. The grouping deliberately anticipates a future split of - * IntegerStrategy into separate sub-strategies (polynomial / linear / non-linear / div-mod): each - * holder is meant to move with its sub-strategy. Cross-theory levels stay in - * {@link org.key_project.prover.strategy.costbased.CostBand}; only the arithmetic-internal ordering - * lives here. All values are byte-identical to the literals they replace. - * - * The file is named after the integer-arithmetic *theory*; a plain "IntegerCost(s)" would suggest - * an integer-valued cost type (an implementation of RuleAppCost) rather than a holder of cost - * constants. - */ - -/** Polynomial normal-form canonicalisation (Buchberger normalisation) — the "basic" substrate. */ -final class PolynomialCost { - private PolynomialCost() {} - - /** elimSubNeg, homo, pullOutFactor, elimOneLeft/Right. */ - static final long EXPAND = -120; - static final long MUL_ORDER = -100; - static final long MUL_ASSOC = -80; - static final long ADD_ORDER = -60; - static final long ADD_ASSOC = -10; - /** polySimp_dist base; the distLeft sub-case is {@code DISTRIBUTE + 20}. */ - static final long DISTRIBUTE = -35; - static final long PULLOUT_GCD = -2250; -} - - -/** - * Polynomial equation solving (Gaussian / Gröbner). These {@code polySimp_*} rule sets - * live - * here rather than in {@link PolynomialCost} on purpose: they do not just canonicalise a term, they - * derive from and apply equations, so they belong to the "linear" (solving) layer next to - * {@link LinearInequationCost}. - */ -final class LinearEquationCost { - private LinearEquationCost() {} - - // The base costs of apply_equations / apply_equations_andOr are combination-shared with - // FOLStrategy (conflict-dispatched; the Integer halves use the monomial ordering as - // demodulation guard): see CombinationCost.ORDERED_REWRITING and - // CombinationCost.CNF_CONVERSION. - - /** polySimp_balance, polySimp_normalise. */ - static final long BALANCE = -30; - /** - * polySimp_applyEq — a small tie-break rider on top of the general demodulation cost - * {@link CombinationCost#ORDERED_REWRITING} (the {@code apply_eq_monomials} taclet carries both - * rule sets, so the effective cost is their sum). The rigid variant polySimp_applyEqRigid is - * written {@code APPLY_EQ_MONOMIAL_TIEBREAK + 1} at the call site; that +1 is only an - * (uninteresting) tie-break between the two rules, a step-3 candidate to flatten. Step-3 idea: - * test whether this specialised variant is needed at all, or should just be a small delta - * preferring the original {@code apply_equations} rules. - */ - static final long APPLY_EQ_MONOMIAL_TIEBREAK = 1; -} - - -/** Linear inequation solving — the Omega / Fourier-Motzkin machinery ({@code inEqSimp_*}). */ -final class LinearInequationCost { - private LinearInequationCost() {} - - static final long PROPAGATION = -2400; - static final long SATURATE = -1900; - /** General GCD normalisation of inequations — confluent, hence safe to apply eagerly. */ - static final long PULLOUT_GCD_CONFLUENT = -2150; - static final long FOR_NORMALISATION = -1100; - static final long MOVE_LEFT = -90; - static final long MAKE_NON_STRICT = -80; - static final long CONTRAD = -60; - static final long COMMUTE = -40; - static final long STRENGTHEN = -30; - static final long ANTISYMM = -20; - /** - * Faster antecedent-specialised GCD pull-out, but not confluent (the result can depend - * on application order), hence pinned near baseline so it fires only opportunistically — in - * contrast to the eager {@link #PULLOUT_GCD_CONFLUENT}. - */ - static final long PULLOUT_GCD_ANTEC_NONCONFLUENT = -10; -} - - -/** Non-linear arithmetic — cross-multiplication, sign cases, root inferences (Model Search). */ -final class NonlinearArithmeticCost { - private NonlinearArithmeticCost() {} - - /** - * inEqSimp_nonLin (cross-multiplication) base; case-distinction offsets are - * {@code MULTIPLY + n}. - */ - static final long MULTIPLY = 1000; - /** - * Divide an inequation by a factor of known sign/bound to bound the quotient (the - * {@code divide_inEq*} taclets) — the inverse of cross-multiplication. Kept clearly more eager - * than {@link #MULTIPLY}, since dividing/reducing is safer and more productive than - * multiplying. - */ - static final long DIVIDE_INEQUATION = -1400; - static final long SPLIT_EQ = -100; -} - - -/** Division / modulo and DefOps expansion ({@code polyDivision}, {@code defOps_*}). */ -final class DivModCost { - private DivModCost() {} - - static final long POLY_DIVISION = -2250; - static final long EXPAND_MODULO = -600; - /** extra cost for defOps_div/jdiv applied below a modality. */ - static final long BELOW_MODALITY = 200; - static final long EXPAND_RANGES = -8000; - static final long MOD_HOMO_EQ = -5000; - static final long EXPAND_NUMERIC_OP = -500; - /** defOps_jdiv_inline for a literal numerator (eager, concrete division). */ - static final long INLINE = -5000; - /** literal-only division / modulo (defOps_mod, off-mode jdiv_inline). */ - static final long MOD = -4000; - /** modulo expansion for a polynomial (non-literal) modulus (defOps_mod). */ - static final long MOD_EXPAND = -3500; -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategyFactory.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategyFactory.java index 60861d8cdea..a596e9b3e5c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategyFactory.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategyFactory.java @@ -11,7 +11,7 @@ import org.key_project.logic.Name; -/// Factory for [IntegerStrategy]. Additionally, handles all strategy settings +/// Factory for [JavaIntegerStrategy]. Additionally, handles all strategy settings /// relevant to integers. public class IntegerStrategyFactory implements StrategyFactory { public static final String TOOL_TIP_ARITHMETIC_BASE = """ @@ -52,8 +52,10 @@ private static OneOfStrategyPropertyDefinition getArithmeticTreatment() { } @Override - public IntegerStrategy create(Proof proof, StrategyProperties strategyProperties) { - return new IntegerStrategy(proof, strategyProperties); + public JavaIntegerStrategy create(Proof proof, StrategyProperties strategyProperties) { + var tf = new JavaArithTermFeatures(proof.getServices().getTypeConverter().getIntegerLDT()); + var ff = new FormulaTermFeatures(tf); + return new JavaIntegerStrategy(tf, ff, proof, strategyProperties); } @Override @@ -64,6 +66,6 @@ public StrategySettingsDefinition getSettingsDefinition() { @Override public Name name() { - return IntegerStrategy.NAME; + return JavaIntegerStrategy.NAME; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntroducedSymbolBy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/IntroducedSymbolBy.java index ba43e7fbb41..ee601039787 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntroducedSymbolBy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/IntroducedSymbolBy.java @@ -18,6 +18,8 @@ import org.key_project.prover.strategy.costbased.feature.Feature; import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + public class IntroducedSymbolBy extends BinaryTacletAppFeature { private final Name ruleSetName; private final Name schemaVar; @@ -38,7 +40,8 @@ protected IntroducedSymbolBy(ProjectionToTerm termWithTopLevelOpToCheck, N } @Override - protected boolean filter(TacletApp app, PosInOccurrence pos, Goal goal, MutableState mState) { + protected boolean filter(@MonotonicNonNull TacletApp app, PosInOccurrence pos, Goal goal, + MutableState mState) { final Node root = goal.proof().root(); Node n = goal.node(); diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/JFOLStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JFOLStrategy.java index b826abfca9b..2b026ec1156 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/JFOLStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JFOLStrategy.java @@ -7,15 +7,18 @@ import de.uka.ilkd.key.ldt.IntegerLDT; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.strategy.feature.RuleSetDispatchFeature; import de.uka.ilkd.key.strategy.quantifierHeuristics.ClausesSmallerThanFeature; import de.uka.ilkd.key.strategy.termProjection.FocusProjection; import org.key_project.logic.Name; import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; import org.key_project.prover.strategy.costbased.feature.SumFeature; import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.anonHeapTermFeature; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.literalsSmallerThan; + /// This strategy extends the classical [FOLStrategy] with heuristics /// for quantifier instantiation based on E-matching, which involves /// normalization of quantified formulas, as well as term features depending on diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/JFOLStrategyFactory.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JFOLStrategyFactory.java index 9254925c824..e09c92064bd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/JFOLStrategyFactory.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JFOLStrategyFactory.java @@ -50,7 +50,8 @@ public class JFOLStrategyFactory implements StrategyFactory { + "The previous behaviour; use only if a proof was tuned to it."; @Override - public Strategy create(Proof proof, StrategyProperties strategyProperties) { + public org.key_project.prover.strategy.Strategy create(Proof proof, + StrategyProperties strategyProperties) { return new JFOLStrategy(proof, strategyProperties); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/AbstractFeatureStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaAbstractFeatureStrategy.java similarity index 81% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/AbstractFeatureStrategy.java rename to key.core/src/main/java/de/uka/ilkd/key/strategy/JavaAbstractFeatureStrategy.java index 0c8f0ebcbe1..8fa35c5f0b2 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/AbstractFeatureStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaAbstractFeatureStrategy.java @@ -8,7 +8,6 @@ import de.uka.ilkd.key.logic.NamespaceSet; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.strategy.feature.RuleSetDispatchFeature; import de.uka.ilkd.key.strategy.feature.instantiator.ForEachCP; import de.uka.ilkd.key.strategy.feature.instantiator.OneOfCP; import de.uka.ilkd.key.strategy.feature.instantiator.SVInstantiationCP; @@ -18,15 +17,11 @@ import org.key_project.logic.Namespace; import org.key_project.prover.proof.rulefilter.IHTacletFilter; import org.key_project.prover.proof.rulefilter.TacletFilter; -import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; -import org.key_project.prover.sequent.PosInOccurrence; -import org.key_project.prover.strategy.costbased.MutableState; -import org.key_project.prover.strategy.costbased.RuleAppCost; -import org.key_project.prover.strategy.costbased.TopRuleAppCost; +import org.key_project.prover.strategy.AbstractFeatureStrategy; import org.key_project.prover.strategy.costbased.feature.ConditionalFeature; import org.key_project.prover.strategy.costbased.feature.Feature; -import org.key_project.prover.strategy.costbased.feature.instantiator.BackTrackingManager; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; import org.key_project.prover.strategy.costbased.termProjection.TermBuffer; import org.key_project.prover.strategy.costbased.termfeature.TermFeature; @@ -35,12 +30,12 @@ import org.jspecify.annotations.NonNull; -public abstract class AbstractFeatureStrategy extends StaticFeatureCollection - implements Strategy { +public abstract class JavaAbstractFeatureStrategy extends AbstractFeatureStrategy + implements JavaStrategy { private final Proof proof; - protected AbstractFeatureStrategy(Proof proof) { + protected JavaAbstractFeatureStrategy(Proof proof) { this.proof = proof; } @@ -113,27 +108,6 @@ protected void clearRuleSetBindings(RuleSetDispatchFeature d, String ruleSet) { d.clear(getHeuristic(ruleSet)); } - - @Override - public void instantiateApp(RuleApp app, PosInOccurrence pio, - Goal goal, - RuleAppCostCollector collector) { - final MutableState mState = new MutableState(); - final BackTrackingManager btManager = mState.getBacktrackingManager(); - btManager.setup(app); - do { - final RuleAppCost cost = instantiateApp(app, pio, goal, mState); - if (cost instanceof TopRuleAppCost) { - continue; - } - final RuleApp res = btManager.getResultingapp(); - if (res == app || res == null) { - continue; - } - collector.collect(res, cost); - } while (btManager.backtrack()); - } - /** * returns the service instance for access to {@link de.uka.ilkd.key.ldt.LDT}s * diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaArithTermFeatures.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaArithTermFeatures.java new file mode 100644 index 00000000000..ed437806060 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaArithTermFeatures.java @@ -0,0 +1,40 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package de.uka.ilkd.key.strategy; + +import de.uka.ilkd.key.ldt.IntegerLDT; +import de.uka.ilkd.key.logic.op.Equality; + +import org.key_project.logic.op.Function; +import org.key_project.prover.strategy.ArithTermFeatures; +import org.key_project.prover.strategy.costbased.termfeature.TermFeature; + +class JavaArithTermFeatures extends ArithTermFeatures { + + public JavaArithTermFeatures(IntegerLDT numbers) { + super(numbers, Equality.EQUALS); + C = numbers.getCharSymbol(); + + jmod = numbers.getJModulo(); + jdiv = numbers.getJDivision(); + + jmodF = op(jmod); + jdivF = op(jdiv); + + charLiteral = op(C); + + notContainsDivMod = rec(any(), add(add(not(divF), not(modF)), add(not(jdivF), not(jmodF)))); + } + + + final Function C; + final Function jmod; + final Function jdiv; + + final TermFeature jmodF; + final TermFeature jdivF; + + final TermFeature charLiteral; +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLCosts.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLCosts.java index 72bd6ce521c..361bdbb5cdc 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLCosts.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLCosts.java @@ -12,6 +12,8 @@ * that split and moves with it). */ +import org.key_project.prover.strategy.costbased.CombinationCost; + /** * JavaCardDL-theory-internal ordering costs, used by {@link JavaCardDLStrategy} (the axiom / * observer / comprehension / induction reasoning; the heap/select pipeline has its own @@ -87,7 +89,7 @@ private JavaCardDLCost() {} *

    * Combination-relevant, not purely local: this ladder is tuned relative to the * demodulation cost {@link CombinationCost#ORDERED_REWRITING}: {@link #APPLY_SELECT_EQ} is the - * JavaCardDL-side remainder of the tuned sum {@link CombinationCost#APPLY_SELECT_EQ_EFFECTIVE} + * JavaCardDL-side remainder of the tuned sum {@link APPLY_SELECT_EQ_EFFECTIVE} * (the {@code applyEq} taclet carries both rule sets, so the dispatch sums the contributions). *

    * @@ -105,15 +107,24 @@ private HeapSelectCost() {} /** {@code pull_out_select} otherwise. */ static final long PULL_OUT_SELECT = -1900; + /** + * Effective cost of replacing a select term via the {@code applyEq} taclet: the taclet carries + * BOTH {@code apply_equations} (FOL/Integer, {@link CombinationCost#ORDERED_REWRITING}) and + * {@code apply_select_eq} (JavaCardDL, {@link HeapSelectCost#APPLY_SELECT_EQ}), so the + * dispatch sums the two contributions. This constant is the tuned target of that sum; + * {@link HeapSelectCost#APPLY_SELECT_EQ} is derived from it. + */ + static public final long APPLY_SELECT_EQ_EFFECTIVE = -5700; + /** * {@code apply_select_eq}: replace a not-yet-simplified select by the skolem constant of its * pull-out. The {@code applyEq} taclet carries both {@code apply_equations} and * {@code apply_select_eq}, so the effective cost is the SUM of the two bindings; the tuned - * quantity is {@link CombinationCost#APPLY_SELECT_EQ_EFFECTIVE} and this constant is the + * quantity is {@link APPLY_SELECT_EQ_EFFECTIVE} and this constant is the * JavaCardDL-side remainder (currently −1700). */ static final long APPLY_SELECT_EQ = - CombinationCost.APPLY_SELECT_EQ_EFFECTIVE - CombinationCost.ORDERED_REWRITING; + APPLY_SELECT_EQ_EFFECTIVE - CombinationCost.ORDERED_REWRITING; /** {@code simplify_select}: simplify the select term in the pulled-out equation. */ static final long SIMPLIFY_SELECT = -5600; diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java index 8087b1d3407..bcc1b5adbe6 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java @@ -12,7 +12,6 @@ import de.uka.ilkd.key.logic.op.Equality; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.rule.BuiltInRule; import de.uka.ilkd.key.rule.QueryExpand; import de.uka.ilkd.key.rule.UseDependencyContractRule; import de.uka.ilkd.key.strategy.feature.*; @@ -25,9 +24,11 @@ import org.key_project.logic.op.Function; import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.proof.rulefilter.SetRuleFilter; +import org.key_project.prover.rules.IBuiltInRule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.ComponentStrategy; import org.key_project.prover.strategy.costbased.CostBand; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; @@ -42,13 +43,15 @@ import static de.uka.ilkd.key.strategy.HeapSelectCost.*; import static de.uka.ilkd.key.strategy.JavaCardDLCost.*; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.*; /// This strategy is the catch-all for Java related features that are either /// cross-cutting or one of the features that do not fit well into any other /// strategy. /// /// Do not create directly, instead use [JavaCardDLStrategyFactory]. -public class JavaCardDLStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class JavaCardDLStrategy extends JavaAbstractFeatureStrategy + implements ComponentStrategy { public static final AtomicLong PERF_COMPUTE = new AtomicLong(); public static final AtomicLong PERF_APPROVE = new AtomicLong(); public static final AtomicLong PERF_INSTANTIATE = new AtomicLong(); @@ -66,7 +69,7 @@ public class JavaCardDLStrategy extends AbstractFeatureStrategy implements Compo private final HeapLDT heapLDT; - private final ArithTermFeatures tf; + private final JavaArithTermFeatures tf; private final FormulaTermFeatures ff; @@ -76,7 +79,7 @@ protected JavaCardDLStrategy(Proof proof, StrategyProperties strategyProperties) this.strategyProperties = strategyProperties.clone(); - this.tf = new ArithTermFeatures(getServices().getTypeConverter().getIntegerLDT()); + this.tf = new JavaArithTermFeatures(getServices().getTypeConverter().getIntegerLDT()); this.ff = new FormulaTermFeatures(this.tf); costComputationDispatcher = setupCostComputationF(); @@ -95,9 +98,7 @@ protected final RuleSetDispatchFeature getCostComputationDispatcher() { @Override public Set getResponsibilities(StrategyAspect aspect) { - var set = new HashSet(); - set.addAll(getDispatcher(aspect).ruleSets()); - return set; + return new HashSet<>(getDispatcher(aspect).ruleSets()); } @Override @@ -290,7 +291,8 @@ private RuleSetDispatchFeature setupCostComputationF() { bindRuleSet(d, "induction_var", inftyConst()); } else { bindRuleSet(d, "induction_var", ifZero( - applyTF(instOf("uSub"), IsInductionVariable.INSTANCE), longConst(0), inftyConst())); + applyTF(StaticFeatureCollection.instOf("uSub"), IsInductionVariable.INSTANCE), + longConst(0), inftyConst())); } return d; @@ -422,7 +424,7 @@ private Feature isSkolemConstantUsedElsewhereInSequent() { final TermBuffer sf = new TermBuffer(); return add(sequentContainsNoPrograms(), sum(sf, SequentFormulasGenerator.sequent(), - or(eq(sf, FocusFormulaProjection.INSTANCE), + or(StaticFeatureCollection.eq(sf, FocusFormulaProjection.INSTANCE), not(ContainsTermFeature.create(sf, instOf("auxiliarySK")))))); } @@ -507,8 +509,10 @@ private RuleSetDispatchFeature setupApprovalDispatcher() { let(firstObject, instOf("o"), let(secondObject, instOf("o2"), sum(succedentFormula, SequentFormulasGenerator.succedent(), not(applyTF(succedentFormula, - or(opSub(Equality.EQUALS, eq(firstObject), eq(secondObject)), - opSub(Equality.EQUALS, eq(secondObject), eq(firstObject))))))))); + or(opSub(Equality.EQUALS, StaticFeatureCollection.eq(firstObject), + StaticFeatureCollection.eq(secondObject)), + opSub(Equality.EQUALS, StaticFeatureCollection.eq(secondObject), + StaticFeatureCollection.eq(firstObject))))))))); bindRuleSet(d, "inReachableStateImplication", NonDuplicateAppModPositionFeature.INSTANCE); bindRuleSet(d, "limitObserver", NonDuplicateAppModPositionFeature.INSTANCE); bindRuleSet(d, "partialInvAxiom", NonDuplicateAppModPositionFeature.INSTANCE); @@ -553,7 +557,8 @@ private void setupClassAxiomApproval(final RuleSetDispatchFeature d) { * the outer 'not' then ensures that the costs are infinite in the first and 0 in * the latter case */ - not(sum(tb, HeapGenerator.INSTANCE, not(eq(instOf("sv_heap"), tb))))); + not(sum(tb, HeapGenerator.INSTANCE, not( + StaticFeatureCollection.eq(StaticFeatureCollection.instOf("sv_heap"), tb))))); if (classAxiomDelayedApplication()) { bindRuleSet(d, "classAxiom", add(sequentContainsNoPrograms(), @@ -688,7 +693,7 @@ public boolean isStopAtFirstNonCloseableGoal() { } @Override - public boolean isResponsibleFor(BuiltInRule rule) { + public boolean isResponsibleFor(IBuiltInRule rule) { return rule instanceof QueryExpand || rule instanceof UseDependencyContractRule; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaIntegerStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaIntegerStrategy.java new file mode 100644 index 00000000000..600a60a7ae7 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaIntegerStrategy.java @@ -0,0 +1,319 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package de.uka.ilkd.key.strategy; + + +import de.uka.ilkd.key.logic.NamespaceSet; +import de.uka.ilkd.key.logic.op.Junctor; +import de.uka.ilkd.key.proof.Goal; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.strategy.feature.*; +import de.uka.ilkd.key.strategy.termProjection.*; +import de.uka.ilkd.key.strategy.termfeature.EqTermFeature; +import de.uka.ilkd.key.strategy.termgenerator.MultiplesModEquationsGenerator; +import de.uka.ilkd.key.strategy.termgenerator.RootsGenerator; +import de.uka.ilkd.key.strategy.termgenerator.SuperTermGenerator; + +import org.key_project.ldt.IIntLdt; +import org.key_project.logic.Name; +import org.key_project.logic.Namespace; +import org.key_project.logic.Term; +import org.key_project.logic.op.Operator; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.rules.RuleSet; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.ArithTermFeatures; +import org.key_project.prover.strategy.ComponentStrategy; +import org.key_project.prover.strategy.IFormulaTermFeatures; +import org.key_project.prover.strategy.IntegerStrategy; +import org.key_project.prover.strategy.costbased.DivModCost; +import org.key_project.prover.strategy.costbased.RuleAppCost; +import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; +import org.key_project.prover.strategy.costbased.feature.SumFeature; +import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; +import org.key_project.prover.strategy.costbased.termProjection.TermBuffer; +import org.key_project.prover.strategy.costbased.termfeature.TermFeature; +import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; + +import org.jspecify.annotations.NonNull; + + +/// This strategy implements reasoning for integer arithmetics. In particular, +/// it supports linear integer arithmetics via Gaussian elimination, +/// Fourier-Motzkin; and non-linear integer reasoning via cross-multiplication +/// and Gröbner basis. +/// +/// Do not create directly, instead use [IntegerStrategyFactory]. +public class JavaIntegerStrategy extends IntegerStrategy implements ComponentStrategy { + private final Proof proof; + + /// Caps how often a cross multiplication is applied on a branch. + /// Justified by empirical measurements. Candidate to be exposed in + /// a settings strategy pane (not the strategy pane) + private static final int BRANCH_MULT_CAP = 8; + + public JavaIntegerStrategy(ArithTermFeatures tf, IFormulaTermFeatures ff, Proof proof, + StrategyProperties strategyProperties) { + super(tf, ff, StrategyProperties.NON_LIN_ARITH_COMPLETION.equals( + strategyProperties.getProperty(StrategyProperties.NON_LIN_ARITH_OPTIONS_KEY)), + StrategyProperties.NON_LIN_ARITH_COMPLETION.equals( + strategyProperties.getProperty(StrategyProperties.NON_LIN_ARITH_OPTIONS_KEY)) + || StrategyProperties.NON_LIN_ARITH_DEF_OPS.equals( + strategyProperties + .getProperty(StrategyProperties.NON_LIN_ARITH_OPTIONS_KEY)), + strategyProperties.getProperty(StrategyProperties.STOPMODE_OPTIONS_KEY) + .equals(StrategyProperties.STOPMODE_NONCLOSE), + new JavaFeatureConstants(), proof.getServices().getTypeConverter().getIntegerLDT()); + this.proof = proof; + init(); + } + + @Override + protected void setupApprovalDispatcher(RuleSetDispatchFeature d) { + super.setupApprovalDispatcher(d); + + bindRuleSet(d, "defOps_jdiv", NonDuplicateAppModPositionFeature.INSTANCE); + } + + // ////////////////////////////////////////////////////////////////////////// + // ////////////////////////////////////////////////////////////////////////// + // + // Axiomatisation and algorithms for further arithmetic operations: + // division, modulus, modular Java operations + // + // ////////////////////////////////////////////////////////////////////////// + // ////////////////////////////////////////////////////////////////////////// + + protected void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { + super.setupDefOpsPrimaryCategories(d); + if (arith != ArithTreatment.BASIC) { + bindRuleSet(d, "defOps_jdiv", + SumFeature.createSum(NonDuplicateAppModPositionFeature.INSTANCE, + applyTF("divNum", tf.polynomial), applyTF("divDenom", tf.polynomial), + applyTF("divNum", tf.notContainsDivMod), + applyTF("divDenom", tf.notContainsDivMod), + ifZero(isBelow(ff.modalOperator()), longConst(DivModCost.BELOW_MODALITY)))); + + bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), + applyTF("divDenom", tf.polynomial), longConst(DivModCost.INLINE))); + } else { + bindRuleSet(d, "defOps_jdiv", inftyConst()); + bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), + applyTF("divDenom", tf.literal), longConst(DivModCost.MOD))); + } + } + + @Override + protected Feature getBranchCountFeatureFor(String prefix) { + return BranchMultiplicationCountFeature.atMost(prefix, BRANCH_MULT_CAP); + } + + @Override + protected Feature createReducibleMonomialFeature(ProjectionToTerm dividend, + ProjectionToTerm divisor) { + return ReducibleMonomialsFeature.createReducible(dividend, divisor); + } + + @Override + protected Feature createTrivialMonomialLCRFeature(ProjectionToTerm a, + ProjectionToTerm b) { + return TrivialMonomialLCRFeature.create(a, b); + } + + @Override + protected ProjectionToTerm createReduceMonomialsProjection( + ProjectionToTerm dividend, ProjectionToTerm divisor) { + return ReduceMonomialsProjection.create(dividend, divisor); + } + + @Override + protected ProjectionToTerm createMonomialColumnOp(ProjectionToTerm leftCoefficient, + ProjectionToTerm polynomial) { + return MonomialColumnOp.create(leftCoefficient, polynomial); + } + + @Override + protected Feature createMonomialsSmallerThanFeature(ProjectionToTerm left, + ProjectionToTerm right, IIntLdt numbers) { + return MonomialsSmallerThanFeature.create(left, right, numbers); + } + + @Override + protected Feature createAtomSmallerThanFeature(String left, String right, IIntLdt numbers) { + return AtomsSmallerThanFeature.create(instOf(left), instOf(right), numbers); + } + + @Override + protected ProjectionToTerm createRoundingUpDividePolynomialsProjection( + ProjectionToTerm leftCoefficient, ProjectionToTerm polynomial) { + return DividePolynomialsProjection.createRoundingUp(leftCoefficient, polynomial); + } + + @Override + protected ProjectionToTerm createRoundingDownDividePolynomialsProjection( + ProjectionToTerm leftCoefficient, ProjectionToTerm polynomial) { + return DividePolynomialsProjection.createRoundingDown(leftCoefficient, polynomial); + } + + @Override + protected ProjectionToTerm createCoeffGcdProjection(ProjectionToTerm monomialLeft, + ProjectionToTerm monomialRight) { + return CoeffGcdProjection.create(monomialLeft, monomialRight); + } + + @Override + protected Feature createExactlyBoundedInEquationMultFeature( + ProjectionToTerm mult1Candidate, ProjectionToTerm mult2Candidate, + TermFeature targetCandidate) { + return new IsBoundedByInequationFeature(mult1Candidate, mult2Candidate, + targetCandidate); + } + + @Override + protected Feature createTotalyBoundedInEquationMultFeature( + ProjectionToTerm mult1Candidate, ProjectionToTerm mult2Candidate, + ProjectionToTerm targetCandidate) { + return InEquationMultFeature.totallyBounded(mult1Candidate, mult2Candidate, + targetCandidate); + } + + @Override + protected Feature createLtPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right) { + return PolynomialValuesCmpFeature.lt(left, right); + } + + @Override + protected Feature createLtPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right, ProjectionToTerm leftCoeff, + ProjectionToTerm rightCoeff) { + return PolynomialValuesCmpFeature.lt(left, right, leftCoeff, rightCoeff); + } + + @Override + protected Feature createLeqPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right) { + return PolynomialValuesCmpFeature.leq(left, right); + } + + @Override + protected Feature createLeqPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right, ProjectionToTerm leftCoeff, + ProjectionToTerm rightCoeff) { + return PolynomialValuesCmpFeature.leq(left, right, leftCoeff, rightCoeff); + } + + @Override + protected Feature createEqPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right) { + return PolynomialValuesCmpFeature.eq(left, right); + } + + @Override + protected Feature createEqPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right, ProjectionToTerm leftCoeff, + ProjectionToTerm rightCoeff) { + return PolynomialValuesCmpFeature.eq(left, right, leftCoeff, rightCoeff); + } + + @Override + protected Feature createDividesPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right) { + return PolynomialValuesCmpFeature.divides(left, right); + } + + @Override + protected TermFeature createEqTermFeature(TermBuffer t) { + return EqTermFeature.create(t); + } + + @Override + protected Feature directlyBelowSymbolAtIndex(Operator symbol, int index) { + return directlyBelowSymbolAtIndex(op(symbol), index); + } + + protected Feature directlyBelowSymbolAtIndex(TermFeature symbolTF, int index) { + final var oneUp = FocusProjection.create(1); + if (index == -1) { + return add(not(TopLevelFindFeature.ANTEC_OR_SUCC), applyTF(oneUp, symbolTF)); + } + return add(not(TopLevelFindFeature.ANTEC_OR_SUCC), + ifZero(applyTF(oneUp, symbolTF), eq(sub(oneUp, index), FocusProjection.INSTANCE), + inftyConst())); + } + + @Override + protected TermGenerator createMultiplesModEquationsGenerator( + ProjectionToTerm source, ProjectionToTerm target) { + return MultiplesModEquationsGenerator.create(source, target); + } + + @Override + protected Term zTerm(String num) { + return proof.getServices().getTermBuilder().zTerm(num); + } + + @Override + protected ProjectionToTerm opTerm(Operator op, ProjectionToTerm subTerm0, + ProjectionToTerm subTerm1) { + return TermConstructionProjection.create(op, new ProjectionToTerm[] { subTerm0, subTerm1 }); + } + + @Override + protected Feature createTermSmallerThanFeature(ProjectionToTerm left, + ProjectionToTerm right) { + return TermSmallerThanFeature.create(left, right); + } + + @Override + protected Feature createMonomialSmallerThan(String left, String right, IIntLdt numbers) { + return MonomialsSmallerThanFeature.create(instOf(left), instOf(right), numbers); + } + + @Override + protected TermGenerator createRootsGenerator(ProjectionToTerm powerRelation) { + return RootsGenerator.create(powerRelation, proof.getServices()); + } + + @Override + protected Operator or() { + return Junctor.OR; + } + + @Override + protected Operator and() { + return Junctor.AND; + } + + @Override + protected TermGenerator upwardsWithIndexSuperGenerator(TermFeature cond) { + return SuperTermGenerator.upwardsWithIndex(cond, proof.getServices()); + } + + @Override + protected RuleSet getHeuristic(String p_name) { + final NamespaceSet nss = proof.getNamespaces(); + final Namespace<@NonNull RuleSet> ns = nss.ruleSets(); + final RuleSet h = ns.lookup(new Name(p_name)); + + assert h != null : "Did not find the rule set " + p_name; + + return h; + } + + @Override + protected Feature isBelow(TermFeature t) { + final de.uka.ilkd.key.strategy.termProjection.TermBuffer superTerm = + new de.uka.ilkd.key.strategy.termProjection.TermBuffer(); + return not(sum(superTerm, SuperTermGenerator.upwards(any(), proof.getServices()), + not(applyTF(superTerm, t)))); + } + + @Override + public RuleAppCost computeCost(RuleApp app, PosInOccurrence pos, Goal goal) { + return null; + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaStrategy.java new file mode 100644 index 00000000000..d9424c10e37 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaStrategy.java @@ -0,0 +1,41 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package de.uka.ilkd.key.strategy; + +import de.uka.ilkd.key.proof.Goal; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.settings.ProofSettings; + +import org.key_project.prover.rules.RuleSet; +import org.key_project.prover.strategy.Strategy; + + +/** + * Generic interface for evaluating the cost of a RuleApp with regard to a specific strategy + */ +public interface JavaStrategy extends Strategy { + /** + * Updates the {@link JavaStrategy} for the given {@link Proof} by setting the + * {@link JavaStrategy}'s + * {@link StrategyProperties} to the given ones. + * + * @param proof The {@link Proof} the strategy of which should be updated. + * @param p The new {@link StrategyProperties} + */ + static void updateStrategySettings(Proof proof, StrategyProperties p) { + final org.key_project.prover.strategy.Strategy strategy = + proof.getActiveStrategy(); + ProofSettings.DEFAULT_SETTINGS.getStrategySettings().setStrategy(strategy.name()); + ProofSettings.DEFAULT_SETTINGS.getStrategySettings().setActiveStrategyProperties(p); + + proof.getSettings().getStrategySettings().setStrategy(strategy.name()); + proof.getSettings().getStrategySettings().setActiveStrategyProperties(p); + + proof.setActiveStrategy(strategy); + } + + @Override + default boolean isResponsibleFor(RuleSet rs) { return false; } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/LocSetStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/LocSetStrategy.java index 4defb36632e..15e716bdbb9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/LocSetStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/LocSetStrategy.java @@ -7,40 +7,52 @@ import java.util.HashSet; import java.util.Set; +import de.uka.ilkd.key.java.TypeConverter; +import de.uka.ilkd.key.logic.NamespaceSet; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.rule.BuiltInRule; import de.uka.ilkd.key.strategy.feature.MatchedAssumesFeature; import de.uka.ilkd.key.strategy.feature.PolynomialValuesCmpFeature; -import de.uka.ilkd.key.strategy.feature.RuleSetDispatchFeature; import de.uka.ilkd.key.strategy.termProjection.FocusFormulaProjection; +import de.uka.ilkd.key.strategy.termgenerator.SuperTermGenerator; import org.key_project.logic.Name; +import org.key_project.logic.Namespace; import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.IBuiltInRule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.AbstractFeatureStrategy; +import org.key_project.prover.strategy.ComponentStrategy; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; +import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; +import org.key_project.prover.strategy.costbased.termfeature.TermFeature; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; /// Strategy for location sets /// Do not create directly; use [SetStrategyFactory] instead. -public class LocSetStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class LocSetStrategy extends AbstractFeatureStrategy + implements ComponentStrategy { public static final Name NAME = new Name("LocSet Strategy"); private final RuleSetDispatchFeature costComputationDispatcher; private final boolean stopAtFirstNonCloseableGoal; private final LocSetTermFeatures lsf; + private final Proof proof; public LocSetStrategy(Proof proof, StrategyProperties strategyProperties) { - super(proof); + this.proof = proof; + TypeConverter typeConverter = proof.getServices().getTypeConverter(); this.lsf = new LocSetTermFeatures( - getServices().getTypeConverter().getLDT(de.uka.ilkd.key.ldt.SetLDT.class), - getServices().getTypeConverter().getLocSetLDT(), - getServices().getTypeConverter().getHeapLDT()); + typeConverter.getLDT(de.uka.ilkd.key.ldt.SetLDT.class), + typeConverter.getLocSetLDT(), + typeConverter.getHeapLDT()); costComputationDispatcher = setupCostComputationF(); stopAtFirstNonCloseableGoal = @@ -144,7 +156,27 @@ public Set getResponsibilities(StrategyAspect aspect) { } @Override - public boolean isResponsibleFor(BuiltInRule rule) { + public boolean isResponsibleFor(IBuiltInRule rule) { return false; } + + + @Override + protected RuleSet getHeuristic(String p_name) { + final NamespaceSet nss = proof.getNamespaces(); + final Namespace<@NonNull RuleSet> ns = nss.ruleSets(); + final RuleSet h = ns.lookup(new Name(p_name)); + + assert h != null : "Did not find the rule set " + p_name; + + return h; + } + + @Override + protected Feature isBelow(TermFeature t) { + final de.uka.ilkd.key.strategy.termProjection.TermBuffer superTerm = + new de.uka.ilkd.key.strategy.termProjection.TermBuffer(); + return not(sum(superTerm, SuperTermGenerator.upwards(any(), proof.getServices()), + not(applyTF(superTerm, t)))); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/ModularJavaDLStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/ModularJavaDLStrategy.java index a82f41790c2..aa0cfe09baa 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/ModularJavaDLStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/ModularJavaDLStrategy.java @@ -10,10 +10,8 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.strategy.ComponentStrategy.StrategyAspect; import de.uka.ilkd.key.strategy.feature.MatchedAssumesFeature; import de.uka.ilkd.key.strategy.feature.NonDuplicateAppFeature; -import de.uka.ilkd.key.strategy.feature.RuleSetDispatchFeature; import de.uka.ilkd.key.strategy.termProjection.FocusProjection; import org.key_project.logic.Name; @@ -22,12 +20,15 @@ import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.ComponentStrategy; +import org.key_project.prover.strategy.ComponentStrategy.StrategyAspect; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.TopRuleAppCost; import org.key_project.prover.strategy.costbased.feature.AutomatedRuleFeature; import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; import org.jspecify.annotations.NonNull; @@ -42,15 +43,15 @@ /// a conflict resolution [#resolveConflict(RuleSetDispatchFeature, RuleSet, List)]. /// /// Do not create directly. Use [ModularJavaDLStrategyFactory] instead. -public class ModularJavaDLStrategy extends AbstractFeatureStrategy { +public class ModularJavaDLStrategy extends JavaAbstractFeatureStrategy { public static final Name NAME = new Name("Modular JavaDL Strategy"); /// List of component strategies. Order is not strictly important. - private final List strategies = new ArrayList<>(); + private final List> strategies = new ArrayList<>(); private final StrategyProperties strategyProperties; private final Feature reduceInstTillMaxF; - private final ArithTermFeatures tf; + private final JavaArithTermFeatures tf; private final Feature totalCost; /// the feature evaluated by [#instantiateApp]; built once, see constructor private final Feature totalInstCost; @@ -60,12 +61,12 @@ public class ModularJavaDLStrategy extends AbstractFeatureStrategy { /// the conflict-resolution cost dispatcher; kept for {@link #costRuleSetDispatchers} private final RuleSetDispatchFeature conflictCostDispatcher; - public ModularJavaDLStrategy(Proof proof, List componentStrategies, + public ModularJavaDLStrategy(Proof proof, List> componentStrategies, StrategyProperties properties) { super(proof); strategies.addAll(componentStrategies); this.strategyProperties = (StrategyProperties) properties.clone(); - this.tf = new ArithTermFeatures(getServices().getTypeConverter().getIntegerLDT()); + this.tf = new JavaArithTermFeatures(getServices().getTypeConverter().getIntegerLDT()); responsibleStrategyCache = new ResponsibleStrategyCache(strategies); @@ -161,7 +162,7 @@ private RuleSetDispatchFeature resolveConflicts() { */ private void resolveConflict(RuleSetDispatchFeature d, RuleSet rs) { var folStrat = responsibleStrategyCache.getStrategyByName(JFOLStrategy.NAME); - var intStrat = responsibleStrategyCache.getStrategyByName(IntegerStrategy.NAME); + var intStrat = responsibleStrategyCache.getStrategyByName(JavaIntegerStrategy.NAME); switch (rs.name().toString()) { case "order_terms" -> { bindRuleSet(d, "order_terms", @@ -231,7 +232,7 @@ public Name name() { /// [ComponentStrategy#computeCost(RuleApp, PosInOccurrence, ProofGoal)] /// @param strats the relevant [ComponentStrategy]s for this computation private R reduceTillMax(R init, R max, BiFunction accumulator, - Function mapper, LinkedHashSet strats) { + Function mapper, LinkedHashSet> strats) { for (ComponentStrategy strategy : strats) { init = accumulator.apply(init, mapper.apply(strategy)); if (init == max) { @@ -261,10 +262,10 @@ private class ReduceTillMaxFeature implements Feature { /// [ComponentStrategy#instantiateApp(RuleApp, PosInOccurrence, Goal, MutableState)]). private final StrategyCostFunction mapper; /// A function to get the relevant strategies for a [Rule] - private final Function> ruleToStrategy; + private final Function>> ruleToStrategy; ReduceTillMaxFeature(StrategyCostFunction mapper, - Function> ruleToStrategy) { + Function>> ruleToStrategy) { this.mapper = mapper; this.ruleToStrategy = ruleToStrategy; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/ModularJavaDLStrategyFactory.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/ModularJavaDLStrategyFactory.java index 2f90c2fd3c8..4bde9cf1b4f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/ModularJavaDLStrategyFactory.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/ModularJavaDLStrategyFactory.java @@ -18,6 +18,7 @@ import de.uka.ilkd.key.strategy.definition.StrategySettingsDefinition; import org.key_project.logic.Name; +import org.key_project.prover.strategy.ComponentStrategy; import org.jspecify.annotations.NonNull; @@ -128,9 +129,10 @@ private static OneOfStrategyPropertyDefinition getUserOptions() { } @Override - public Strategy<@NonNull Goal> create(Proof proof, StrategyProperties strategyProperties) { - List componentStrategies = componentFactories.stream() - .map(f -> (ComponentStrategy) f.create(proof, strategyProperties)) + public org.key_project.prover.strategy.Strategy<@NonNull Goal> create(Proof proof, + StrategyProperties strategyProperties) { + List> componentStrategies = componentFactories.stream() + .map(f -> (ComponentStrategy) f.create(proof, strategyProperties)) .collect(Collectors.toList()); return new ModularJavaDLStrategy(proof, componentStrategies, strategyProperties); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/QueueRuleApplicationManager.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/QueueRuleApplicationManager.java index bad91e986e0..9c715903fee 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/QueueRuleApplicationManager.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/QueueRuleApplicationManager.java @@ -38,7 +38,7 @@ * {@link #next()}. This operation will remove the element from the queue. The priority of a given * {@link RuleApp} corresponds to its {@link RuleAppCost}. A {@link RuleApp} can be equipped with a * {@link RuleAppCost} by converting it into a {@link RuleAppContainer}. The cost of a - * {@link RuleApp} is computed according to a given {@link Strategy} (see + * {@link RuleApp} is computed according to a given {@link JavaStrategy} (see * {@link Feature#computeCost(RuleApp, PosInOccurrence, ProofGoal, MutableState)}). * *

    Why the set-aside state of this class belongs to one goal only

    diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/ResponsibleStrategyCache.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/ResponsibleStrategyCache.java index 75dcf6b8e05..b49f5a5e9d4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/ResponsibleStrategyCache.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/ResponsibleStrategyCache.java @@ -7,23 +7,25 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.BuiltInRule; -import de.uka.ilkd.key.strategy.ComponentStrategy.StrategyAspect; import org.key_project.logic.Name; import org.key_project.prover.rules.Rule; import org.key_project.prover.rules.RuleSet; +import org.key_project.prover.strategy.ComponentStrategy; +import org.key_project.prover.strategy.ComponentStrategy.StrategyAspect; /// A cache for the strategies responsible for a given [Rule] and [RuleSet]. public class ResponsibleStrategyCache { // map rulesets to the strategies that participate in their cost computations, instantiation or // approval decisions - private final Map> costResponsibilityMap = - new LinkedHashMap>(); - private final Map> instantiationResponsibilityMap = - new LinkedHashMap>(); - private final Map> approvalResponsibilityMap = - new LinkedHashMap>(); + private final Map>> costResponsibilityMap = + new LinkedHashMap>>(); + private final Map>> instantiationResponsibilityMap = + new LinkedHashMap>>(); + private final Map>> approvalResponsibilityMap = + new LinkedHashMap>>(); // Map rules to the strategies that participate in their cost computations, instantiation or // approval decisions. These are filled lazily on the first query for a rule. One strategy // object is shared by all goals of a proof, so under the multi-core prover several worker @@ -33,16 +35,16 @@ public class ResponsibleStrategyCache { // the result stays reproducible. A plain map here corrupts under concurrent writes and made // the strategy return an inconsistent set between two evaluations of the same feature term, // which broke the BackTrackingManager's determinism check (a worker AssertionError). - private final Map> costRuleToStrategyMap = + private final Map>> costRuleToStrategyMap = new ConcurrentHashMap<>(); - private final Map> instantiationRuleToStrategyMap = + private final Map>> instantiationRuleToStrategyMap = new ConcurrentHashMap<>(); - private final Map> approvalRuleToStrategyMap = + private final Map>> approvalRuleToStrategyMap = new ConcurrentHashMap<>(); - private final Map nameToStrategyMap = - new HashMap(); + private final Map> nameToStrategyMap = + new HashMap<>(); - public ResponsibleStrategyCache(List strategies) { + public ResponsibleStrategyCache(List> strategies) { initialize(StrategyAspect.Cost, strategies); initialize(StrategyAspect.Instantiation, strategies); initialize(StrategyAspect.Approval, strategies); @@ -54,9 +56,9 @@ public ResponsibleStrategyCache(List strategies) { * @param aspect the StrategyAspect for which the cache is created * @param strategies list of all component strategies */ - private void initialize(StrategyAspect aspect, List strategies) { + private void initialize(StrategyAspect aspect, List> strategies) { var map = getResponsibilityMap(aspect); - for (ComponentStrategy strategy : strategies) { + for (ComponentStrategy strategy : strategies) { nameToStrategyMap.put(strategy.name(), strategy); var res = strategy.getResponsibilities(aspect); for (var rs : res) { @@ -66,7 +68,7 @@ private void initialize(StrategyAspect aspect, List strategie } /// Returns the map for the given aspect - private Map> getRuleToStrategyMap( + private Map>> getRuleToStrategyMap( StrategyAspect aspect) { return switch (aspect) { case Cost -> costRuleToStrategyMap; @@ -76,7 +78,8 @@ private Map> getRuleToStrategyMap( } /// Returns the map for the given aspect - private Map> getResponsibilityMap(StrategyAspect aspect) { + private Map>> getResponsibilityMap( + StrategyAspect aspect) { return switch (aspect) { case Cost -> costResponsibilityMap; case Instantiation -> instantiationResponsibilityMap; @@ -85,15 +88,15 @@ private Map> getResponsibilityMap(StrategyAspec } /// Returns the strategies responsible for the given [Rule] under the given [StrategyAspect]. - public LinkedHashSet getResponsibleStrategies(Rule rule, - List strategies, StrategyAspect aspect) { + public LinkedHashSet> getResponsibleStrategies(Rule rule, + List> strategies, StrategyAspect aspect) { var ruleToStrategyMap = getRuleToStrategyMap(aspect); // computeIfAbsent fills the entry atomically: concurrent workers proving different goals // of the same proof never see a half-built map or overwrite each other. The mapping // function only reads the responsibility maps (built once in the constructor, read-only - // afterwards) and the strategies list, so it is a pure function of the rule. + // afterward) and the strategies list, so it is a pure function of the rule. return ruleToStrategyMap.computeIfAbsent(rule, r -> { - LinkedHashSet strats = new LinkedHashSet<>(); + LinkedHashSet> strats = new LinkedHashSet<>(); if (r instanceof BuiltInRule bir) { for (var cs : strategies) { if (cs.isResponsibleFor(bir)) { @@ -102,11 +105,11 @@ public LinkedHashSet getResponsibleStrategies(Rule rule, } } else { var ruleSets = r.ruleSets(); - Map> responsibilityMap = + Map>> responsibilityMap = getResponsibilityMap(aspect); while (ruleSets.hasNext()) { var rs = ruleSets.next(); - List s = responsibilityMap.get(rs); + List> s = responsibilityMap.get(rs); if (s != null) { strats.addAll(s); } @@ -117,7 +120,7 @@ public LinkedHashSet getResponsibleStrategies(Rule rule, } /// Returns the strategy with the given [Name] - public ComponentStrategy getStrategyByName(Name name) { + public ComponentStrategy getStrategyByName(Name name) { return nameToStrategyMap.get(name); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/SetStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/SetStrategy.java index e128eb6eebb..a50fe47f252 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/SetStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/SetStrategy.java @@ -8,22 +8,27 @@ import java.util.Set; import de.uka.ilkd.key.ldt.SetLDT; +import de.uka.ilkd.key.logic.NamespaceSet; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.rule.BuiltInRule; import de.uka.ilkd.key.strategy.feature.MatchedAssumesFeature; -import de.uka.ilkd.key.strategy.feature.RuleSetDispatchFeature; import de.uka.ilkd.key.strategy.feature.SetsSmallerThanFeature; +import de.uka.ilkd.key.strategy.termgenerator.SuperTermGenerator; import org.key_project.logic.Name; +import org.key_project.logic.Namespace; import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.IBuiltInRule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.AbstractFeatureStrategy; +import org.key_project.prover.strategy.ComponentStrategy; import org.key_project.prover.strategy.costbased.CostBand; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; import org.key_project.prover.strategy.costbased.termfeature.TermFeature; import org.jspecify.annotations.NonNull; @@ -34,17 +39,18 @@ /// Strategy for the sort generic theory of sets. /// Do not create directly; use [SetStrategyFactory] instead. -public class SetStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class SetStrategy extends AbstractFeatureStrategy implements ComponentStrategy { public static final Name NAME = new Name("Set Strategy"); private final RuleSetDispatchFeature costComputationDispatcher; private final boolean stopAtFirstNonCloseableGoal; private final SetTermFeatures stf; + private final Proof proof; public SetStrategy(Proof proof, StrategyProperties strategyProperties) { - super(proof); - stf = new SetTermFeatures(getServices().getTypeConverter().getLDT(SetLDT.class)); + this.proof = proof; + stf = new SetTermFeatures(proof.getServices().getTypeConverter().getLDT(SetLDT.class)); costComputationDispatcher = setupCostComputationF(); stopAtFirstNonCloseableGoal = @@ -125,7 +131,27 @@ public Set getResponsibilities(StrategyAspect aspect) { } @Override - public boolean isResponsibleFor(BuiltInRule rule) { + public boolean isResponsibleFor(IBuiltInRule rule) { return false; } + + // TODO: Unify in class? + @Override + protected RuleSet getHeuristic(String p_name) { + final NamespaceSet nss = proof.getNamespaces(); + final Namespace<@NonNull RuleSet> ns = nss.ruleSets(); + final RuleSet h = ns.lookup(new Name(p_name)); + + assert h != null : "Did not find the rule set " + p_name; + + return h; + } + + @Override + protected Feature isBelow(TermFeature t) { + final de.uka.ilkd.key.strategy.termProjection.TermBuffer superTerm = + new de.uka.ilkd.key.strategy.termProjection.TermBuffer(); + return not(sum(superTerm, SuperTermGenerator.upwards(any(), proof.getServices()), + not(applyTF(superTerm, t)))); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/SimpleFilteredStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/SimpleFilteredStrategy.java index f4c0ccdd0ca..0c226a0c1b2 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/SimpleFilteredStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/SimpleFilteredStrategy.java @@ -25,7 +25,7 @@ * Trivial implementation of the Strategy interface that uses only the goal time to determine the * cost of a RuleApp. A TacletFilter is used to filter out RuleApps. */ -public class SimpleFilteredStrategy implements Strategy { +public class SimpleFilteredStrategy implements JavaStrategy { private static final Name NAME = new Name("Simple ruleset"); @@ -93,7 +93,7 @@ public boolean isApprovedApp(RuleApp app, PosInOccurrence pio, @Override public void instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, - RuleAppCostCollector collector) {} + org.key_project.prover.strategy.RuleAppCostCollector collector) {} @Override public boolean isStopAtFirstNonCloseableGoal() { diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/StaticFeatureCollection.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/StaticFeatureCollection.java index a1446fc9309..2886271c3a1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/StaticFeatureCollection.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/StaticFeatureCollection.java @@ -13,6 +13,7 @@ import de.uka.ilkd.key.rule.*; import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.strategy.feature.*; +import de.uka.ilkd.key.strategy.feature.InstantiatedSVFeature; import de.uka.ilkd.key.strategy.quantifierHeuristics.LiteralsSmallerThanFeature; import de.uka.ilkd.key.strategy.termProjection.*; import de.uka.ilkd.key.strategy.termfeature.EqTermFeature; @@ -360,7 +361,8 @@ protected static TermFeature opSub(Operator op, TermFeature sub0, TermFeature su return add(op(op), sub(sub0, sub1)); } - protected static TermFeature eq(TermBuffer t) { + protected static TermFeature eq( + org.key_project.prover.strategy.costbased.termProjection.TermBuffer t) { return EqTermFeature.create(t); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/StrategyFactory.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/StrategyFactory.java index 8fdf6e1d122..0e0e482c5df 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/StrategyFactory.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/StrategyFactory.java @@ -25,11 +25,13 @@ public interface StrategyFactory extends Named { * @param strategyProperties the StrategyProperties to customize the strategy * @return the newly created strategy */ - Strategy<@NonNull Goal> create(Proof proof, StrategyProperties strategyProperties); + org.key_project.prover.strategy.Strategy<@NonNull Goal> create(Proof proof, + StrategyProperties strategyProperties); /** * Returns the {@link StrategySettingsDefinition} which describes how an user interface has to - * look like to edit {@link StrategySettings} supported by created {@link Strategy} instances. + * look like to edit {@link StrategySettings} supported by created {@link JavaStrategy} + * instances. * * @return The {@link StrategySettingsDefinition} which describes the user interface. */ diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/StringStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/StringStrategy.java index f1effcca15e..f29364170b3 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/StringStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/StringStrategy.java @@ -13,18 +13,20 @@ import de.uka.ilkd.key.logic.op.ParametricFunctionInstance; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.rule.BuiltInRule; import de.uka.ilkd.key.strategy.feature.*; import org.key_project.logic.Name; import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.IBuiltInRule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.ComponentStrategy; import org.key_project.prover.strategy.costbased.CostBand; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; import org.key_project.prover.strategy.costbased.feature.SumFeature; import org.key_project.prover.strategy.costbased.termfeature.OperatorClassTF; import org.key_project.prover.strategy.costbased.termfeature.TermFeature; @@ -32,11 +34,12 @@ import org.jspecify.annotations.NonNull; import static de.uka.ilkd.key.strategy.StringCost.*; +import static org.key_project.prover.strategy.StaticFeatureCollection.*; /// Strategy for string related rules. /// /// Do not create directly; use [StringStrategyFactory] instead. -public class StringStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class StringStrategy extends JavaAbstractFeatureStrategy implements ComponentStrategy { public static final Name NAME = new Name("String Strategy"); /// The features defining the three phases: cost computation, approval, @@ -44,14 +47,14 @@ public class StringStrategy extends AbstractFeatureStrategy implements Component private final RuleSetDispatchFeature costComputationDispatcher; /// Useful [TermFeature] collections - private final ArithTermFeatures tf; + private final JavaArithTermFeatures tf; private final FormulaTermFeatures ff; private final boolean stopAtFirstNonCloseableGoal; public StringStrategy(Proof proof, StrategyProperties strategyProperties) { super(proof); - this.tf = new ArithTermFeatures(proof.getServices().getTypeConverter().getIntegerLDT()); + this.tf = new JavaArithTermFeatures(proof.getServices().getTypeConverter().getIntegerLDT()); this.ff = new FormulaTermFeatures(this.tf); costComputationDispatcher = setupCostComputationF(); @@ -143,8 +146,8 @@ private void setUpStringNormalisation(RuleSetDispatchFeature d) { bindRuleSet(d, "stringsConcatNotBothLiterals", ifZero(MatchedAssumesFeature.INSTANCE, ifZero( - add(applyTF(instOf("leftStr"), seqLiteral), - applyTF(instOf("rightStr"), seqLiteral)), + add(applyTF(StaticFeatureCollection.instOf("leftStr"), seqLiteral), + applyTF(StaticFeatureCollection.instOf("rightStr"), seqLiteral)), inftyConst()), inftyConst())); bindRuleSet(d, "stringsReduceConcat", CostBand.DEFER.at(-400)); @@ -214,7 +217,7 @@ public RuleSetDispatchFeature getDispatcher(StrategyAspect aspect) { } @Override - public boolean isResponsibleFor(BuiltInRule rule) { + public boolean isResponsibleFor(IBuiltInRule rule) { return false; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/SymExStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/SymExStrategy.java index e689dcacf7e..3b6da75fe34 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/SymExStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/SymExStrategy.java @@ -19,26 +19,30 @@ import org.key_project.logic.Name; import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.IBuiltInRule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.ComponentStrategy; import org.key_project.prover.strategy.costbased.CostBand; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.feature.Feature; import org.key_project.prover.strategy.costbased.feature.FindDepthFeature; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; import org.key_project.prover.strategy.costbased.feature.ScaleFeature; import org.key_project.prover.strategy.costbased.feature.SumFeature; import org.jspecify.annotations.NonNull; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.*; import static de.uka.ilkd.key.strategy.SymExCost.*; /// Strategy for symbolic execution rules. /// /// Do not create directly. Use [SymExStrategyFactory] instead. -public class SymExStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class SymExStrategy extends JavaAbstractFeatureStrategy implements ComponentStrategy { public static final Name NAME = new Name("SymExStrategy"); private final FormulaTermFeatures ff; @@ -54,7 +58,7 @@ public SymExStrategy(Proof proof, StrategyProperties strategyProperties) { super(proof); this.strategyProperties = strategyProperties; - var tf = new ArithTermFeatures(getServices().getTypeConverter().getIntegerLDT()); + var tf = new JavaArithTermFeatures(getServices().getTypeConverter().getIntegerLDT()); ff = new FormulaTermFeatures(tf); costComputationDispatcher = setupCostComputationF(); @@ -297,7 +301,7 @@ public Name name() { } @Override - public boolean isResponsibleFor(BuiltInRule rule) { + public boolean isResponsibleFor(IBuiltInRule rule) { return rule instanceof WhileInvariantRule || rule instanceof LoopScopeInvariantRule || rule instanceof BlockContractInternalRule || rule instanceof BlockContractExternalRule diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/TacletAppContainer.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/TacletAppContainer.java index 0b53bc2c41c..c3ca60de45a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/TacletAppContainer.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/TacletAppContainer.java @@ -177,7 +177,7 @@ private ImmutableList instantiateApp(NoPosTacletApp app, @SuppressWarnings("unchecked") final ImmutableList[] resA = new ImmutableList[] { targetList }; - final RuleAppCostCollector collector = (newApp, cost) -> { + final org.key_project.prover.strategy.RuleAppCostCollector collector = (newApp, cost) -> { if (cost instanceof TopRuleAppCost) { return; } @@ -315,7 +315,7 @@ protected static ImmutableList createInitialAppContainers( * Create containers for FindTaclets or NoFindTaclets. * * @param p_app if p_pio is null, p_app has to be a - * TacletApp for a NoFindTaclet, otherwise for a + * ITacletApp for a NoFindTaclet, otherwise for a * FindTaclet. * @return list of containers for currently applicable TacletApps, the cost may be an instance * of TopRuleAppCost. diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/definition/IDefaultStrategyPropertiesFactory.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/definition/IDefaultStrategyPropertiesFactory.java index 6c09abc1cc0..48868d7ae22 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/definition/IDefaultStrategyPropertiesFactory.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/definition/IDefaultStrategyPropertiesFactory.java @@ -4,12 +4,12 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package de.uka.ilkd.key.strategy.definition; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import de.uka.ilkd.key.strategy.StrategyProperties; /** * Instances of this factory are used to create default {@link StrategyProperties} used by a - * {@link Strategy} defined via its {@link StrategySettingsDefinition}. + * {@link JavaStrategy} defined via its {@link StrategySettingsDefinition}. * * @author Martin Hentschel */ diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/definition/StrategySettingsDefinition.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/definition/StrategySettingsDefinition.java index c31d0e7ad43..441777a3b2f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/definition/StrategySettingsDefinition.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/definition/StrategySettingsDefinition.java @@ -7,7 +7,7 @@ import java.util.ArrayList; import de.uka.ilkd.key.settings.StrategySettings; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import de.uka.ilkd.key.strategy.StrategyFactory; import de.uka.ilkd.key.strategy.StrategyProperties; @@ -24,7 +24,7 @@ *

    * Each {@link StrategyFactory} should provide an instance of this class to define the user * interface which the user can use to edit supported {@link StrategySettings} in created - * {@link Strategy} instances. If a {@link StrategyFactory} provides no + * {@link JavaStrategy} instances. If a {@link StrategyFactory} provides no * {@link StrategySettingsDefinition} an empty user interface or even bedder an error message should * be shown to the user. *

    diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/AbstractMonomialSmallerThanFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/AbstractMonomialSmallerThanFeature.java index d3c58a67fb8..798b3006091 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/AbstractMonomialSmallerThanFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/AbstractMonomialSmallerThanFeature.java @@ -4,8 +4,9 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package de.uka.ilkd.key.strategy.feature; -import de.uka.ilkd.key.ldt.IntegerLDT; + +import org.key_project.ldt.IIntLdt; import org.key_project.logic.Term; import org.key_project.logic.op.Function; import org.key_project.logic.op.Operator; @@ -15,7 +16,7 @@ public abstract class AbstractMonomialSmallerThanFeature extends SmallerThanFeat private final Function mul; - protected AbstractMonomialSmallerThanFeature(IntegerLDT numbers) { + protected AbstractMonomialSmallerThanFeature(IIntLdt numbers) { this.mul = numbers.getMul(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/AtomsSmallerThanFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/AtomsSmallerThanFeature.java index 469215b175d..33023f090b5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/AtomsSmallerThanFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/AtomsSmallerThanFeature.java @@ -4,10 +4,10 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package de.uka.ilkd.key.strategy.feature; -import de.uka.ilkd.key.ldt.IntegerLDT; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.TacletApp; +import org.key_project.ldt.IIntLdt; import org.key_project.logic.Term; import org.key_project.logic.op.Function; import org.key_project.prover.sequent.PosInOccurrence; @@ -37,7 +37,7 @@ public class AtomsSmallerThanFeature extends AbstractMonomialSmallerThanFeature private final Function Z; private AtomsSmallerThanFeature(ProjectionToTerm left, ProjectionToTerm right, - IntegerLDT numbers) { + IIntLdt numbers) { super(numbers); this.left = left; this.right = right; @@ -46,7 +46,7 @@ private AtomsSmallerThanFeature(ProjectionToTerm left, ProjectionToTerm left, ProjectionToTerm right, - IntegerLDT numbers) { + IIntLdt numbers) { return new AtomsSmallerThanFeature(left, right, numbers); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BinaryTacletAppFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BinaryTacletAppFeature.java index bb7e1075e19..76addebaa33 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BinaryTacletAppFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BinaryTacletAppFeature.java @@ -48,11 +48,11 @@ protected BinaryTacletAppFeature(boolean p_nonTacletValue) { * Compute whether the result of the feature is zero (true) or infinity * (false) * - * @param app the TacletApp + * @param app the ITacletApp * @param pos position where app is to be applied * @param goal the goal on which app is to be applied * @param mState the MutableState used to store modifiable information - * @return true iff the the result of the feature is supposed to be zero. + * @return true iff the result of the feature is supposed to be zero. */ protected abstract boolean filter(TacletApp app, PosInOccurrence pos, Goal goal, MutableState mState); diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BranchMultiplicationCountFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BranchMultiplicationCountFeature.java index 704dd5a2e79..97b646280dc 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BranchMultiplicationCountFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BranchMultiplicationCountFeature.java @@ -7,11 +7,11 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.rule.TacletApp; -import de.uka.ilkd.key.util.properties.Properties.Property; import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.util.Properties; /** * Counts how often a rule has already been applied on the branch leading to a goal, and admits a @@ -39,8 +39,8 @@ public final class BranchMultiplicationCountFeature extends BinaryTacletAppFeatu private record BranchCount(int nodeSerial, int count) { } - private static final Property COUNT_ON_BRANCH = - new Property<>(BranchCount.class, "crossMultiplicationsOnBranch"); + private static final Properties.Property COUNT_ON_BRANCH = + new Properties.Property<>(BranchCount.class, "crossMultiplicationsOnBranch"); private final String rulePrefix; diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/CheckApplyEqFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/CheckApplyEqFeature.java index 0b666aba4ac..8c536c2068b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/CheckApplyEqFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/CheckApplyEqFeature.java @@ -17,6 +17,8 @@ import org.key_project.prover.strategy.costbased.feature.Feature; import org.key_project.prover.strategy.costbased.feature.StableCost; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + /** * This feature checks that an equation is not applied to itself. This means that the focus of the * rule application must not be one side of an equation that is the instantiation of the first @@ -30,7 +32,8 @@ public class CheckApplyEqFeature extends BinaryTacletAppFeature { private CheckApplyEqFeature() {} @Override - protected boolean filter(TacletApp p_app, PosInOccurrence pos, Goal goal, MutableState mState) { + protected boolean filter(@MonotonicNonNull TacletApp p_app, PosInOccurrence pos, Goal goal, + MutableState mState) { assert pos != null : "Need to know the position of " + "the application of the taclet"; AssumesFormulaInstantiation ifInst = p_app.assumesFormulaInstantiations().head(); diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DiffFindAndIfFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DiffFindAndIfFeature.java index 8a85a29f36b..5b7ba13af31 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DiffFindAndIfFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DiffFindAndIfFeature.java @@ -16,6 +16,8 @@ import org.key_project.prover.strategy.costbased.feature.WeakStableCost; import org.key_project.util.collection.ImmutableList; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + /** * Binary feature that returns zero iff the \assumes- and find-formula of a Taclet are * matched to different members of the sequent. If a taclet has more than one formula in its @@ -34,7 +36,8 @@ public class DiffFindAndIfFeature extends BinaryTacletAppFeature { private DiffFindAndIfFeature() {} @Override - protected boolean filter(TacletApp app, PosInOccurrence pos, Goal goal, MutableState mState) { + protected boolean filter(@MonotonicNonNull TacletApp app, PosInOccurrence pos, Goal goal, + MutableState mState) { assert pos != null : "Feature is only applicable to rules with find"; ImmutableList list = app.assumesFormulaInstantiations(); diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DiffFindAndReplacewithFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DiffFindAndReplacewithFeature.java index d575bd88a60..8ee63a8004d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DiffFindAndReplacewithFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DiffFindAndReplacewithFeature.java @@ -16,6 +16,8 @@ import org.key_project.prover.strategy.costbased.feature.Feature; import org.key_project.prover.strategy.costbased.feature.StableCost; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; /** @@ -33,15 +35,18 @@ public class DiffFindAndReplacewithFeature extends BinaryTacletAppFeature { private DiffFindAndReplacewithFeature() {} @Override - protected boolean filter(TacletApp app, PosInOccurrence pos, Goal goal, MutableState mState) { + protected boolean filter(@MonotonicNonNull TacletApp app, PosInOccurrence pos, Goal goal, + MutableState mState) { assert pos != null && app.rule() instanceof RewriteTaclet : "Feature is only applicable to rewrite taclets"; - for (TacletGoalTemplate template : app.rule().goalTemplates()) { - final JTerm replaceWith = ((RewriteTacletGoalTemplate) template).replaceWith(); - if (replaceWith.equalsModProperty(pos.subTerm(), - IRRELEVANT_TERM_LABELS_PROPERTY)) { - return false; + for (TacletGoalTemplate template : app.taclet().goalTemplates()) { + if (template instanceof RewriteTacletGoalTemplate rwTGT) { + final JTerm replaceWith = rwTGT.replaceWith(); + if (replaceWith.equalsModProperty(pos.subTerm(), + IRRELEVANT_TERM_LABELS_PROPERTY)) { + return false; + } } } return true; diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/EqNonDuplicateAppFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/EqNonDuplicateAppFeature.java index f93671cc82c..d6c33f0a62e 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/EqNonDuplicateAppFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/EqNonDuplicateAppFeature.java @@ -11,6 +11,8 @@ import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.feature.Feature; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + /** * Binary feature that returns zero iff a certain Taclet app has not already been performed. @@ -25,7 +27,7 @@ public class EqNonDuplicateAppFeature extends AbstractNonDuplicateAppFeature { private EqNonDuplicateAppFeature() {} @Override - public boolean filter(TacletApp app, PosInOccurrence pos, + public boolean filter(@MonotonicNonNull TacletApp app, PosInOccurrence pos, Goal goal, MutableState mState) { assert pos != null : "Feature is only applicable to rules with find"; diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/FindRightishFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/FindRightishFeature.java index 633e2a3915b..af346abb36e 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/FindRightishFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/FindRightishFeature.java @@ -4,9 +4,9 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package de.uka.ilkd.key.strategy.feature; -import de.uka.ilkd.key.ldt.IntegerLDT; import de.uka.ilkd.key.logic.op.Equality; +import org.key_project.ldt.IIntLdt; import org.key_project.logic.op.Operator; import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.rules.RuleApp; @@ -30,11 +30,11 @@ public class FindRightishFeature implements Feature { private final Operator add; private final static RuleAppCost one = NumberRuleAppCost.create(1); - public static Feature create(IntegerLDT numbers) { + public static Feature create(IIntLdt numbers) { return new FindRightishFeature(numbers); } - private FindRightishFeature(IntegerLDT numbers) { + private FindRightishFeature(IIntLdt numbers) { add = numbers.getAdd(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/IsBoundedByInequationFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/IsBoundedByInequationFeature.java index b76f8efbf71..0306e2c9085 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/IsBoundedByInequationFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/IsBoundedByInequationFeature.java @@ -13,7 +13,6 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.TacletApp; import de.uka.ilkd.key.rule.metaconstruct.arith.Monomial; -import de.uka.ilkd.key.strategy.termgenerator.RelevantSequentFormulasGenerator; import org.key_project.logic.Term; import org.key_project.prover.sequent.PosInOccurrence; @@ -21,6 +20,7 @@ import org.key_project.prover.strategy.costbased.feature.VolatileCost; import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; import org.key_project.prover.strategy.costbased.termfeature.TermFeature; +import org.key_project.prover.strategy.costbased.termgenerator.RelevantSequentFormulasGenerator; import org.key_project.util.ConcurrentLruCache; import org.key_project.util.collection.ImmutableList; diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/JavaFeatureConstants.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/JavaFeatureConstants.java new file mode 100644 index 00000000000..a2cc5be4367 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/JavaFeatureConstants.java @@ -0,0 +1,69 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package de.uka.ilkd.key.strategy.feature; + +import de.uka.ilkd.key.proof.Goal; +import de.uka.ilkd.key.strategy.termProjection.FocusFormulaProjection; +import de.uka.ilkd.key.strategy.termProjection.FocusProjection; + +import org.key_project.ldt.IIntLdt; +import org.key_project.prover.strategy.FeatureConstants; +import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; + +import org.jspecify.annotations.NullMarked; + +@NullMarked +public class JavaFeatureConstants implements FeatureConstants { + @Override + public ProjectionToTerm focusProjection() { + return FocusProjection.INSTANCE; + } + + @Override + public ProjectionToTerm focusProjection(int stepsUpwards) { + return FocusProjection.create(stepsUpwards); + } + + @Override + public ProjectionToTerm focusFormulaProjection() { + return FocusFormulaProjection.INSTANCE; + } + + @Override + public Feature matchedAssumesFeature() { + return MatchedAssumesFeature.INSTANCE; + } + + @Override + public Feature nonDuplicateAppModPositionFeature() { + return NonDuplicateAppModPositionFeature.INSTANCE; + } + + @Override + public Feature notInScopeOfModalityFeature() { + return NotInScopeOfModalityFeature.INSTANCE; + } + + @Override + public Feature diffFindAndIfFeature() { + return DiffFindAndIfFeature.INSTANCE; + } + + @Override + public Feature topLevelFindSucc() { + return TopLevelFindFeature.SUCC; + } + + @Override + public Feature checkApplyEqFeature() { + return CheckApplyEqFeature.INSTANCE; + } + + @Override + public Feature findRightishFeature(IIntLdt numbers) { + return FindRightishFeature.create(numbers); + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/MatchedAssumesFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/MatchedAssumesFeature.java index 644dc2e0532..c31351b6360 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/MatchedAssumesFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/MatchedAssumesFeature.java @@ -12,6 +12,8 @@ import org.key_project.prover.strategy.costbased.feature.Feature; import org.key_project.prover.strategy.costbased.feature.StableCost; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + /** * Binary features that returns zero iff the if-formulas of a Taclet are instantiated or the Taclet * does not have any if-formulas. @@ -24,7 +26,8 @@ public final class MatchedAssumesFeature extends BinaryTacletAppFeature { private MatchedAssumesFeature() {} @Override - protected boolean filter(TacletApp app, PosInOccurrence pos, Goal goal, MutableState mState) { + protected boolean filter(@MonotonicNonNull TacletApp app, PosInOccurrence pos, Goal goal, + MutableState mState) { return app.assumesInstantionsComplete(); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/MonomialsSmallerThanFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/MonomialsSmallerThanFeature.java index b3107a3c6c2..95ad7b89a6f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/MonomialsSmallerThanFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/MonomialsSmallerThanFeature.java @@ -5,10 +5,10 @@ package de.uka.ilkd.key.strategy.feature; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.ldt.IntegerLDT; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.TacletApp; +import org.key_project.ldt.IIntLdt; import org.key_project.logic.Term; import org.key_project.logic.op.Function; import org.key_project.prover.sequent.PosInOccurrence; @@ -48,7 +48,7 @@ public class MonomialsSmallerThanFeature extends AbstractMonomialSmallerThanFeat private MonomialsSmallerThanFeature(ProjectionToTerm left, ProjectionToTerm right, - IntegerLDT numbers) { + IIntLdt numbers) { super(numbers); this.left = left; this.right = right; @@ -59,7 +59,7 @@ private MonomialsSmallerThanFeature(ProjectionToTerm left, ProjectionToTer hasCoeff = createHasCoeffTermFeature(numbers); } - static TermFeature createHasCoeffTermFeature(final IntegerLDT numbers) { + static TermFeature createHasCoeffTermFeature(final IIntLdt numbers) { return BinarySumTermFeature.createSum(OperatorTF.create(numbers.getMul()), SubTermFeature.create( new TermFeature[] { ConstTermFeature.createConst(NumberRuleAppCost.getZeroCost()), @@ -67,7 +67,7 @@ static TermFeature createHasCoeffTermFeature(final IntegerLDT numbers) { } public static Feature create(ProjectionToTerm left, ProjectionToTerm right, - IntegerLDT numbers) { + IIntLdt numbers) { return new MonomialsSmallerThanFeature(left, right, numbers); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/NoSelfApplicationFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/NoSelfApplicationFeature.java index 20acd4560a8..337f3064e07 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/NoSelfApplicationFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/NoSelfApplicationFeature.java @@ -14,6 +14,8 @@ import org.key_project.prover.strategy.costbased.feature.StableCost; import org.key_project.util.collection.ImmutableList; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + /** * This feature checks that the position of application is not contained in the if-formulas. If the * rule application is admissible, zero is returned. @@ -26,7 +28,8 @@ public class NoSelfApplicationFeature extends BinaryTacletAppFeature { private NoSelfApplicationFeature() {} @Override - protected boolean filter(TacletApp p_app, PosInOccurrence pos, Goal goal, MutableState mState) { + protected boolean filter(@MonotonicNonNull TacletApp p_app, PosInOccurrence pos, Goal goal, + MutableState mState) { assert pos != null : "NoSelfApplicationFeature: Need to know the position of the application of the taclet"; diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/NonDuplicateAppFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/NonDuplicateAppFeature.java index 421f80b5f27..ed4e1724fe3 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/NonDuplicateAppFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/NonDuplicateAppFeature.java @@ -11,6 +11,8 @@ import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.feature.Feature; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + /** * Binary feature that returns zero iff a certain Taclet app has not already been performed @@ -20,7 +22,7 @@ public class NonDuplicateAppFeature extends AbstractNonDuplicateAppFeature { public static final Feature INSTANCE = new NonDuplicateAppFeature(); @Override - public boolean filter(TacletApp app, PosInOccurrence pos, + public boolean filter(@MonotonicNonNull TacletApp app, PosInOccurrence pos, Goal goal, MutableState mState) { if (!app.assumesInstantionsComplete()) { return true; @@ -31,8 +33,7 @@ public boolean filter(TacletApp app, PosInOccurrence pos, @Override protected boolean comparePio(TacletApp newApp, TacletApp oldApp, - PosInOccurrence newPio, - PosInOccurrence oldPio) { + PosInOccurrence newPio, PosInOccurrence oldPio) { return oldPio.equals(newPio); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/PolynomialValuesCmpFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/PolynomialValuesCmpFeature.java index 2c69f183e72..0795184460c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/PolynomialValuesCmpFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/PolynomialValuesCmpFeature.java @@ -83,8 +83,9 @@ public static Feature divides(ProjectionToTerm left, ProjectionToTerm, Set> listenerMap = diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/properties/MapProperties.java b/key.core/src/main/java/de/uka/ilkd/key/util/properties/MapProperties.java index 0b4dad08ac1..0ceb9045cb0 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/properties/MapProperties.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/properties/MapProperties.java @@ -6,6 +6,8 @@ import java.util.IdentityHashMap; +import org.key_project.util.Properties; + import org.jspecify.annotations.Nullable; public class MapProperties extends AbstractProperties { diff --git a/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java b/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java index aa8eaf30ea3..dac3b51f435 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java +++ b/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java @@ -356,8 +356,8 @@ public void testNoFindTacletWithoutIf() { * proof=new Proof(); proof.setRoot(new Node(proof, initSeq)); IList * goals=ImmSLList.nil(); Goal goal=new Goal(proof.root(),new RuleAppIndex(index)); * goals=goals.prepend(goal); while (goals.size()!=0) { SequentFormula cfma=null; SequentFormula - * userCfma=null; // in the real system the //user would select this IList - * rapplist=ImmSLList.nil(); out="\n"+out+("Goals: "+goals+"\n"); goal=goals.head(); + * userCfma=null; // in the real system the //user would select this IList + * rapplist=ImmSLList.nil(); out="\n"+out+("Goals: "+goals+"\n"); goal=goals.head(); * Iterator it=goal.node().sequent().antecedent().iterator(); while * (it.hasNext()) { userCfma=it.next(); rapplist=rapplist.prepend(goal.ruleAppIndex(). * getTacletAppAtAndBelow(TacletFilter.TRUE, new PosInOccurrence(userCfma, PosInTerm.TOP_LEVEL, @@ -404,7 +404,7 @@ public void testIncompleteNoFindTacletApp() { public void testIncompleteSuccTacletApp() { TacletApp orright = TacletForTests.lookupTaclet("or_right"); assertFalse(orright.complete(), - "TacletApp should not be complete, as SVs are not instantiated"); + "ITacletApp should not be complete, as SVs are not instantiated"); Services services = TacletForTests.services(); SchemaVariable b = TacletForTests.getSchemaVariables().lookup(new Name("b")); @@ -414,14 +414,14 @@ public void testIncompleteSuccTacletApp() { "b and c should be in the set of not instantiated SVs"); orright = orright.addInstantiation(b, TacletForTests.parseTerm("A"), false, services); assertFalse(orright.complete(), - "TacletApp should not be complete, as B is not instantiated"); + "ITacletApp should not be complete, as B is not instantiated"); orright = orright.addInstantiation(c, TacletForTests.parseTerm("B"), false, services); - assertFalse(orright.complete(), "TacletApp should not be complete, as Position unknown"); + assertFalse(orright.complete(), "ITacletApp should not be complete, as Position unknown"); Sequent seq = proof[0].root().sequent(); orright = orright.setPosInOccurrence( new PosInOccurrence(seq.succedent().get(0), PosInTerm.getTopLevel(), false), services); assertTrue(orright.complete(), - "TacletApp should now be complete with Position set and SVs " + "instantiated"); + "ITacletApp should now be complete with Position set and SVs " + "instantiated"); } diff --git a/key.core/src/test/java/de/uka/ilkd/key/rule/TestCollisionResolving.java b/key.core/src/test/java/de/uka/ilkd/key/rule/TestCollisionResolving.java index 5d102173045..f27c9ec3252 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/rule/TestCollisionResolving.java +++ b/key.core/src/test/java/de/uka/ilkd/key/rule/TestCollisionResolving.java @@ -237,12 +237,12 @@ public void testNameConflict1() { /* * IList sviList=taclet.matchIf (seq, * taclet.match(semiseq.get(0).formula(), taclet.find(), - * MatchConditions.EMPTY_MATCHCONDITIONS, null, Constraint.BOTTOM), null); TacletApp app = + * MatchConditions.EMPTY_MATCHCONDITIONS, null, Constraint.BOTTOM), null); ITacletApp app = * PosTacletApp.createPosTacletApp(taclet, sviList.head(), pos); */ TacletApp app1 = app.prepareUserInstantiation(services); assertNotSame(app, app1, - "A different TacletApp should have been created to resolve" + " name conflicts"); + "A different ITacletApp should have been created to resolve" + " name conflicts"); assertNotEquals(((JTerm) app1.instantiations().getInstantiation(u)).op().name(), ((JTerm) app1.instantiations().getInstantiation(v)).op().name(), @@ -317,10 +317,10 @@ public void testNameConflictAfterInput() throws SVInstantiationException { * Sequent seq=Sequent.createSuccSequent(semiseq); PosInOccurrence pos=new * PosInOccurrence(semiseq.get(1), PosInTerm.TOP_LEVEL.down(0), seq); IList * sviList=taclet.matchIf (seq, taclet.match(semiseq.get(1).formula().sub(0), taclet.find(), - * taclet.createInitialInstantiation())); TacletApp app = - * PosTacletApp.createPosTacletApp(taclet, sviList.head(), pos); TacletApp + * taclet.createInitialInstantiation())); ITacletApp app = + * PosTacletApp.createPosTacletApp(taclet, sviList.head(), pos); ITacletApp * app1=app.prepareUserInstantiation(); - * assertTue("A different TacletApp should have been created to resolve" +" name conflicts", + * assertTue("A different ITacletApp should have been created to resolve" +" name conflicts", * app!=app1); assertTrue("The names of x and the instantiations of v should be different", * !(new Name("x")).equals (((Term)app1.instantiations().getInstantiation(v)).op().name())); * diff --git a/key.core/src/test/resources/de/uka/ilkd/key/prover/mt/shared-feature-state-allowlist.txt b/key.core/src/test/resources/de/uka/ilkd/key/prover/mt/shared-feature-state-allowlist.txt index b197a6bd1aa..127f9972c24 100644 --- a/key.core/src/test/resources/de/uka/ilkd/key/prover/mt/shared-feature-state-allowlist.txt +++ b/key.core/src/test/resources/de/uka/ilkd/key/prover/mt/shared-feature-state-allowlist.txt @@ -4,4 +4,6 @@ # such an object is shared mutable state under the multi-core prover -- fix it (move per-call state # to the MutableState, as ForEachCP does) rather than allowlist, unless it is genuinely safe. -de.uka.ilkd.key.strategy.AbstractFeatureStrategy#instantiateActive # toggled only while the feature tree is built at strategy construction (enableInstantiate/disableInstantiate in the strategy setup); never read or written during proof search +# toggled only while the feature tree is built at strategy construction (enableInstantiate/disableInstantiate in the strategy setup); never read or written during proof search +org.key_project.prover.strategy.AbstractFeatureStrategy#instantiateActive +de.uka.ilkd.key.strategy.JavaAbstractFeatureStrategy#instantiateActive diff --git a/key.core/src/testFixtures/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingStrategy.java b/key.core/src/testFixtures/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingStrategy.java index 7e976d6711a..58cee639849 100644 --- a/key.core/src/testFixtures/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingStrategy.java +++ b/key.core/src/testFixtures/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingStrategy.java @@ -9,11 +9,11 @@ import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.strategy.JavaCardDLStrategy; -import de.uka.ilkd.key.strategy.RuleAppCostCollector; import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.RuleAppCostCollector; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; diff --git a/key.core/src/testFixtures/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingTestFile.java b/key.core/src/testFixtures/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingTestFile.java index 0f2f8491cec..b0181a11cd0 100644 --- a/key.core/src/testFixtures/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingTestFile.java +++ b/key.core/src/testFixtures/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingTestFile.java @@ -16,9 +16,9 @@ import de.uka.ilkd.key.proof.runallproofs.proofcollection.TestFile; import de.uka.ilkd.key.proof.runallproofs.proofcollection.TestProperty; import de.uka.ilkd.key.prover.impl.ApplyStrategy; -import de.uka.ilkd.key.strategy.Strategy; import org.key_project.prover.engine.impl.ApplyStrategyInfo; +import org.key_project.prover.strategy.Strategy; import org.jspecify.annotations.NonNull; diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRule.java b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRule.java new file mode 100644 index 00000000000..fc8da2d8533 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRule.java @@ -0,0 +1,30 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.rules; + +import org.key_project.logic.LogicServices; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.sequent.PosInOccurrence; + +import org.jspecify.annotations.NonNull; + +public interface IBuiltInRule> extends Rule, RuleExecutor { + /** + * returns true iff a rule is applicable at the given position. This does not necessarily mean + * that a rule application will change the goal (this decision is made due to performance + * reasons) + */ + boolean isApplicable(GOAL goal, PosInOccurrence pio); + + boolean isApplicableOnSubTerms(); + + IBuiltInRuleApp createApp(PosInOccurrence pos, LogicServices services); + + @Override + default @NonNull RuleExecutor<@NonNull GOAL> getExecutor() { + return this; + } + +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRuleApp.java b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRuleApp.java new file mode 100644 index 00000000000..7e1099adc41 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRuleApp.java @@ -0,0 +1,37 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.rules; + +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.util.collection.ImmutableList; + +public interface IBuiltInRuleApp> extends RuleApp { + + /** + * Tries to complete the rule application from the available information. + */ + IBuiltInRuleApp tryToInstantiate(Goal goal); + + IBuiltInRuleApp forceInstantiate(Goal goal); + + /** + * returns true if tryToInstantiate is able to complete the app + * + * @return true if tryToInstantiate is able to complete the app + */ + boolean isSufficientlyComplete(); + + ImmutableList assumesInsts(); + + IBuiltInRuleApp setAssumesInsts(ImmutableList ifInsts); + + IBuiltInRuleApp replacePos(PosInOccurrence newPos); + + /** + * returns the built-in rule of this rule application + */ + IBuiltInRule rule(); +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/rules/ITacletApp.java b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/ITacletApp.java new file mode 100644 index 00000000000..60b6aa08a25 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/ITacletApp.java @@ -0,0 +1,51 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.rules; + +import org.key_project.logic.LogicServices; +import org.key_project.logic.Term; +import org.key_project.logic.op.sv.SchemaVariable; +import org.key_project.prover.rules.instantiation.AssumesFormulaInstantiation; +import org.key_project.prover.rules.instantiation.MatchResultInfo; +import org.key_project.prover.rules.instantiation.SVInstantiations; +import org.key_project.util.collection.ImmutableList; +import org.key_project.util.collection.ImmutableSet; + +import org.jspecify.annotations.NonNull; + +public interface ITacletApp extends RuleApp { + + /// returns the taclet associated with this taclet application + Taclet taclet(); + + /** + * returns the instantiations for the application of the Taclet at the specified position. + * + * @return the SVInstantiations needed to instantiate the Taclet + */ + default SVInstantiations instantiations() { + return matchConditions().getInstantiations(); + } + + @NonNull + MatchResultInfo matchConditions(); + + ImmutableList assumesFormulaInstantiations(); + + boolean assumesInstantionsComplete(); + + /** + * returns the variables that have not yet been instantiated and need to be instantiated to + * apply the Taclet. (These are not all SchemaVariables like the one that appear only in the + * addrule sections) + * + * @return ImmutableSet with SchemaVariables that have not been instantiated yet + */ + @NonNull + ImmutableSet uninstantiatedVars(); + + ITacletApp addCheckedInstantiation(SchemaVariable sv, Term term, LogicServices services, + boolean interesting); +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/AbstractFeatureStrategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/AbstractFeatureStrategy.java new file mode 100644 index 00000000000..5ff33a501b1 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/AbstractFeatureStrategy.java @@ -0,0 +1,104 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy; + +import org.key_project.logic.Name; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.rules.RuleSet; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.costbased.MutableState; +import org.key_project.prover.strategy.costbased.RuleAppCost; +import org.key_project.prover.strategy.costbased.TopRuleAppCost; +import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; +import org.key_project.prover.strategy.costbased.feature.instantiator.BackTrackingManager; +import org.key_project.prover.strategy.costbased.feature.instantiator.ForEachCP; +import org.key_project.prover.strategy.costbased.feature.instantiator.OneOfCP; +import org.key_project.prover.strategy.costbased.feature.instantiator.SVInstantiationCP; +import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; +import org.key_project.prover.strategy.costbased.termProjection.TermBuffer; +import org.key_project.prover.strategy.costbased.termfeature.TermFeature; +import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; + +public abstract class AbstractFeatureStrategy> + extends StaticFeatureCollection implements Strategy { + /// It is possible to turn off the method instantiate, + /// which can be useful in order to use the same feature definitions both for + /// cost computation and instantiation. + /// + /// Counts nesting depth of instantiation activation to avoid premature deactivation. + private short instantiateActive = 0; + + protected void enableInstantiate() { + instantiateActive++; + assert instantiateActive >= 0 : "overflow occurred"; + } + + protected void disableInstantiate() { + instantiateActive--; + assert instantiateActive >= 0; + } + + protected void bindRuleSet(RuleSetDispatchFeature d, RuleSet ruleSet, Feature f) { + d.add(ruleSet, f); + } + + protected void bindRuleSet(RuleSetDispatchFeature d, String ruleSet, Feature f) { + bindRuleSet(d, getHeuristic(ruleSet), f); + } + + protected void bindRuleSet(RuleSetDispatchFeature d, String ruleSet, long cost) { + bindRuleSet(d, getHeuristic(ruleSet), longConst(cost)); + } + + protected void clearRuleSetBindings(RuleSetDispatchFeature d, String ruleSet) { + d.clear(getHeuristic(ruleSet)); + } + + protected abstract RuleSet getHeuristic(String p_name); + + protected Feature instantiate(String sv, ProjectionToTerm value) { + return instantiate(new Name(sv), value); + } + + protected Feature instantiate(Name sv, ProjectionToTerm value) { + if (instantiateActive != 0) { + return SVInstantiationCP.create(sv, value); + } else { + return longConst(0); + } + } + + protected Feature forEach(TermBuffer x, TermGenerator gen, Feature body) { + return ForEachCP.create(x, gen, body); + } + + protected Feature oneOf(Feature[] features) { + return OneOfCP.create(features); + } + + protected abstract Feature isBelow(TermFeature t); + + @Override + public void instantiateApp(RuleApp app, PosInOccurrence pio, + G goal, + org.key_project.prover.strategy.RuleAppCostCollector collector) { + final MutableState mState = new MutableState(); + final BackTrackingManager btManager = mState.getBacktrackingManager(); + btManager.setup(app); + do { + final RuleAppCost cost = instantiateApp(app, pio, goal, mState); + if (cost instanceof TopRuleAppCost) { + continue; + } + final RuleApp res = btManager.getResultingapp(); + if (res == app || res == null) { + continue; + } + collector.collect(res, cost); + } while (btManager.backtrack()); + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/ArithTermFeatures.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java similarity index 78% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/ArithTermFeatures.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java index bbd72b39cf4..65c31b6f19f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/ArithTermFeatures.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java @@ -2,30 +2,83 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy; - -import de.uka.ilkd.key.ldt.IntegerLDT; -import de.uka.ilkd.key.logic.op.Equality; +package org.key_project.prover.strategy; +import org.key_project.ldt.IIntLdt; import org.key_project.logic.op.Function; import org.key_project.logic.op.Operator; import org.key_project.logic.sort.Sort; import org.key_project.prover.strategy.costbased.termfeature.TermFeature; -class ArithTermFeatures extends StaticFeatureCollection { +public class ArithTermFeatures extends StaticFeatureCollection { + final Sort intS; + + final Function Z; + final Function add; + final Function mul; + final Function mod; + final Function div; + + final public Operator eq; + final Function leq; + final Function geq; + + final public TermFeature intF; - public ArithTermFeatures(IntegerLDT numbers) { + final TermFeature addF; + final TermFeature mulF; + final protected TermFeature modF; + final protected TermFeature divF; + + final public TermFeature eqF; + final TermFeature leqF; + final TermFeature geqF; + + final TermFeature constant; + final public TermFeature atom; + final TermFeature linearMonomial; + + // left-associatively arranged monomials + final TermFeature monomial; + // left-associatively arranged polynomials + final public TermFeature polynomial; + + final public TermFeature literal; + final TermFeature posLiteral; + final public TermFeature negLiteral; + final public TermFeature nonNegLiteral; + final TermFeature nonPosLiteral; + final TermFeature zeroLiteral; + final TermFeature oneLiteral; + final TermFeature atLeastTwoLiteral; + + final TermFeature nonNegMonomial; + final TermFeature posMonomial; + final TermFeature negMonomial; + final TermFeature nonCoeffMonomial; + final TermFeature nonNegOrNonCoeffMonomial; + final TermFeature atLeastTwoCoeffMonomial; + + final public TermFeature intEquation; + final TermFeature linearEquation; + final TermFeature monomialEquation; + final public TermFeature intInEquation; + final TermFeature linearInEquation; + final TermFeature intRelation; + final TermFeature intRelationOp; + + final public TermFeature notContainsProduct; + public TermFeature notContainsDivMod; + + public ArithTermFeatures(IIntLdt numbers, Operator eq) { Z = numbers.getNumberSymbol(); - C = numbers.getCharSymbol(); add = numbers.getAdd(); mul = numbers.getMul(); mod = numbers.getMod(); div = numbers.getDiv(); - jmod = numbers.getJModulo(); - jdiv = numbers.getJDivision(); - eq = Equality.EQUALS; + this.eq = eq; leq = numbers.getLessOrEquals(); geq = numbers.getGreaterOrEquals(); @@ -37,8 +90,6 @@ public ArithTermFeatures(IntegerLDT numbers) { mulF = op(mul); modF = op(mod); divF = op(div); - jmodF = op(jmod); - jdivF = op(jdiv); eqF = op(eq); geqF = op(geq); @@ -55,8 +106,6 @@ public ArithTermFeatures(IntegerLDT numbers) { posLiteral = add(nonNegLiteral, not(zeroLiteral)); atLeastTwoLiteral = add(posLiteral, not(oneLiteral)); - charLiteral = op(C); - constant = constantTermFeature(); atom = add(not(addF), not(mulF)); @@ -86,73 +135,6 @@ public ArithTermFeatures(IntegerLDT numbers) { intRelation = add(or(leqF, geqF, eqF), sub(add(intF, nonNegMonomial), polynomial)); notContainsProduct = rec(any(), ifZero(mulF, not(sub(not(literal), not(literal))))); - notContainsDivMod = rec(any(), add(add(not(divF), not(modF)), add(not(jdivF), not(jmodF)))); + notContainsDivMod = rec(any(), add(not(divF), not(modF))); } - - final Sort intS; - - final Function Z; - final Function C; - final Function add; - final Function mul; - final Function mod; - final Function div; - final Function jmod; - final Function jdiv; - - final Operator eq; - final Function leq; - final Function geq; - - final TermFeature intF; - - final TermFeature addF; - final TermFeature mulF; - final TermFeature modF; - final TermFeature divF; - final TermFeature jmodF; - final TermFeature jdivF; - - final TermFeature eqF; - final TermFeature leqF; - final TermFeature geqF; - - final TermFeature constant; - final TermFeature atom; - final TermFeature linearMonomial; - - // left-associatively arranged monomials - final TermFeature monomial; - // left-associatively arranged polynomials - final TermFeature polynomial; - - final TermFeature literal; - final TermFeature posLiteral; - final TermFeature negLiteral; - final TermFeature nonNegLiteral; - final TermFeature nonPosLiteral; - final TermFeature zeroLiteral; - final TermFeature oneLiteral; - final TermFeature atLeastTwoLiteral; - - final TermFeature charLiteral; - - final TermFeature nonNegMonomial; - final TermFeature posMonomial; - final TermFeature negMonomial; - final TermFeature nonCoeffMonomial; - final TermFeature nonNegOrNonCoeffMonomial; - final TermFeature atLeastTwoCoeffMonomial; - - final TermFeature intEquation; - final TermFeature linearEquation; - final TermFeature monomialEquation; - final TermFeature intInEquation; - final TermFeature linearInEquation; - final TermFeature intRelationOp; - final TermFeature intRelation; - - final TermFeature notContainsProduct; - final TermFeature notContainsDivMod; - } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/ComponentStrategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ComponentStrategy.java similarity index 59% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/ComponentStrategy.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ComponentStrategy.java index 3aaedfb0580..e2617ffd747 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/ComponentStrategy.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ComponentStrategy.java @@ -2,19 +2,18 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy; +package org.key_project.prover.strategy; import java.util.Set; -import de.uka.ilkd.key.proof.Goal; -import de.uka.ilkd.key.rule.BuiltInRule; -import de.uka.ilkd.key.strategy.feature.RuleSetDispatchFeature; - +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.IBuiltInRule; import org.key_project.prover.rules.RuleSet; +import org.key_project.prover.strategy.costbased.feature.RuleSetDispatchFeature; import org.jspecify.annotations.Nullable; -public interface ComponentStrategy extends Strategy { +public interface ComponentStrategy> extends Strategy { enum StrategyAspect { Cost, Instantiation, Approval; } @@ -26,7 +25,7 @@ enum StrategyAspect { /// The rule sets this strategy is designed to handle. Set getResponsibilities(StrategyAspect aspect); - /// Whether this strategy is responsible for the given [BuiltInRule]. This is necessary as + /// Whether this strategy is responsible for the given [IBuiltInRule]. This is necessary as /// built-in rules have no rule sets. - boolean isResponsibleFor(BuiltInRule rule); + boolean isResponsibleFor(IBuiltInRule rule); } diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FeatureConstants.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FeatureConstants.java new file mode 100644 index 00000000000..bbf80aa95d6 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FeatureConstants.java @@ -0,0 +1,32 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy; + +import org.key_project.ldt.IIntLdt; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; + +public interface FeatureConstants> { + ProjectionToTerm focusProjection(); + + ProjectionToTerm focusProjection(int stepsUpwards); + + ProjectionToTerm focusFormulaProjection(); + + Feature matchedAssumesFeature(); + + Feature nonDuplicateAppModPositionFeature(); + + Feature notInScopeOfModalityFeature(); + + Feature diffFindAndIfFeature(); + + Feature topLevelFindSucc(); + + Feature checkApplyEqFeature(); + + Feature findRightishFeature(IIntLdt numbers); +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IFormulaTermFeatures.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IFormulaTermFeatures.java new file mode 100644 index 00000000000..5ca6c7a8db4 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IFormulaTermFeatures.java @@ -0,0 +1,61 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy; + +import org.key_project.prover.strategy.costbased.termfeature.TermFeature; + +public interface IFormulaTermFeatures { + TermFeature forF(); + + TermFeature orF(); + + TermFeature andF(); + + TermFeature impF(); + + TermFeature notF(); + + TermFeature propJunctor(); + + TermFeature ifThenElse(); + + TermFeature notExecutable(); + + TermFeature notContainsExecutable(); + + TermFeature quantifiedFor(); + + TermFeature quantifiedOr(); + + TermFeature quantifiedAnd(); + + TermFeature atom(); + + TermFeature literal(); + + TermFeature clause(); + + TermFeature clauseSet(); + + TermFeature quantifiedClauseSet(); + + TermFeature pureLitConjDisj(); + + TermFeature quantifiedPureLitConjDisj(); + + TermFeature elemUpdate(); + + TermFeature update(); + + TermFeature program(); + + TermFeature modalOperator(); + + TermFeature cutAllowed(); + + TermFeature cutAllowedBelowQuantifier(); + + TermFeature cutPriority(); +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java similarity index 66% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategy.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java index 503724d5cfd..79cc0e1a9ed 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategy.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java @@ -2,53 +2,41 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy; +package org.key_project.prover.strategy; import java.util.HashSet; import java.util.Set; -import de.uka.ilkd.key.ldt.IntegerLDT; -import de.uka.ilkd.key.logic.JTerm; -import de.uka.ilkd.key.logic.op.Equality; -import de.uka.ilkd.key.logic.op.Junctor; -import de.uka.ilkd.key.proof.Goal; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.rule.BuiltInRule; -import de.uka.ilkd.key.strategy.feature.*; -import de.uka.ilkd.key.strategy.termProjection.*; -import de.uka.ilkd.key.strategy.termgenerator.MultiplesModEquationsGenerator; -import de.uka.ilkd.key.strategy.termgenerator.RelevantSequentFormulasGenerator; -import de.uka.ilkd.key.strategy.termgenerator.RootsGenerator; -import de.uka.ilkd.key.strategy.termgenerator.SuperTermGenerator; - +import org.key_project.ldt.IIntLdt; import org.key_project.logic.Name; import org.key_project.logic.PosInTerm; import org.key_project.logic.Term; +import org.key_project.logic.op.Operator; import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.IBuiltInRule; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; -import org.key_project.prover.strategy.costbased.CostBand; -import org.key_project.prover.strategy.costbased.MutableState; -import org.key_project.prover.strategy.costbased.RuleAppCost; -import org.key_project.prover.strategy.costbased.TopRuleAppCost; -import org.key_project.prover.strategy.costbased.feature.Feature; -import org.key_project.prover.strategy.costbased.feature.FocusInAntecFeature; -import org.key_project.prover.strategy.costbased.feature.ScaleFeature; -import org.key_project.prover.strategy.costbased.feature.SumFeature; +import org.key_project.prover.strategy.costbased.*; +import org.key_project.prover.strategy.costbased.feature.*; +import org.key_project.prover.strategy.costbased.termProjection.AssumptionProjection; +import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; +import org.key_project.prover.strategy.costbased.termProjection.TermBuffer; import org.key_project.prover.strategy.costbased.termfeature.TermFeature; +import org.key_project.prover.strategy.costbased.termgenerator.RelevantSequentFormulasGenerator; import org.key_project.prover.strategy.costbased.termgenerator.SequentFormulasGenerator; import org.key_project.prover.strategy.costbased.termgenerator.SubtermGenerator; +import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; /// This strategy implements reasoning for integer arithmetics. In particular, /// it supports linear integer arithmetics via Gaussian elimination, /// Fourier-Motzkin; and non-linear integer reasoning via cross-multiplication /// and Gröbner basis. -/// -/// Do not create directly, instead use [IntegerStrategyFactory]. -public class IntegerStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public abstract class IntegerStrategy> extends AbstractFeatureStrategy + implements ComponentStrategy { /// Reads better than a bare boolean at the call sites of [#setupMultiplyInequations]. private static final boolean AT_APPROVAL = true; @@ -59,24 +47,20 @@ public class IntegerStrategy extends AbstractFeatureStrategy implements Componen /// Magic constants private static final int IN_EQ_SIMP_NON_LIN_COST = 1000; - /// Caps how often a cross multiplication is applied on a branch. - /// Justified by empirical measurements. Candidate to be exposed in - /// a settings strategy pane (not the strategy pane) - private static final int BRANCH_MULT_CAP = 8; private static final int POLY_DIVISION_COST = -2250; /// The features defining the three phases: cost computation, approval, /// additionalInstanceCreationAndEvaluation - private final RuleSetDispatchFeature costComputationDispatcher; - private final RuleSetDispatchFeature approvalDispatcher; - private final RuleSetDispatchFeature instantiationDispatcher; + private final RuleSetDispatchFeature costComputationDispatcher = new RuleSetDispatchFeature(); + private final RuleSetDispatchFeature approvalDispatcher = new RuleSetDispatchFeature(); + private final RuleSetDispatchFeature instantiationDispatcher = new RuleSetDispatchFeature(); /// Useful [TermFeature] collections - private final ArithTermFeatures tf; - private final FormulaTermFeatures ff; + protected final ArithTermFeatures tf; + protected final IFormulaTermFeatures ff; /// enum for the different arithmetic treatments - private enum ArithTreatment { + protected enum ArithTreatment { /// Non-linear arithmetic switched off. BASIC, /// Inequations are cross-multiplied but only in a bound and capped manner. @@ -88,45 +72,44 @@ private enum ArithTreatment { } /// configuration options extracted from [StrategyProperties] - private final ArithTreatment arith; + protected final ArithTreatment arith; private final boolean stopAtFirstNonCloseableGoal; - public IntegerStrategy(Proof proof, StrategyProperties strategyProperties) { - super(proof); - this.tf = new ArithTermFeatures(proof.getServices().getTypeConverter().getIntegerLDT()); - this.ff = new FormulaTermFeatures(this.tf); + private final IIntLdt numbers; + + final FeatureConstants featureConstants; + public IntegerStrategy(ArithTermFeatures tf, IFormulaTermFeatures ff, + boolean nonLinearArithmeticEnabled, boolean divAndModuloReasoningEnabled, + boolean stopAtFirstNonCloseableGoal, FeatureConstants featureConstants, + IIntLdt numbers) { + this.tf = tf; + this.ff = ff; // determine configuration - final String nonLinArith = - strategyProperties.getProperty(StrategyProperties.NON_LIN_ARITH_OPTIONS_KEY); - if (StrategyProperties.NON_LIN_ARITH_COMPLETION.equals(nonLinArith)) { + if (nonLinearArithmeticEnabled) { arith = ArithTreatment.MODEL_SEARCH; - } else if (StrategyProperties.NON_LIN_ARITH_DEF_OPS.equals(nonLinArith)) { + } else if (divAndModuloReasoningEnabled) { arith = ArithTreatment.DEF_OPS; } else { arith = ArithTreatment.BASIC; } + this.stopAtFirstNonCloseableGoal = stopAtFirstNonCloseableGoal; - stopAtFirstNonCloseableGoal = - strategyProperties.getProperty(StrategyProperties.STOPMODE_OPTIONS_KEY) - .equals(StrategyProperties.STOPMODE_NONCLOSE); - - // setup cost computations - costComputationDispatcher = setupCostComputationF(); - approvalDispatcher = setupApprovalDispatcher(); - instantiationDispatcher = setupInstantiationF(); + this.featureConstants = featureConstants; + this.numbers = numbers; } - @Override - public boolean isResponsibleFor(RuleSet rs) { - return costComputationDispatcher.get(rs) != null || instantiationDispatcher.get(rs) != null; + protected void init() { + // setup cost computations + setupCostComputationF(costComputationDispatcher); + setupApprovalDispatcher(approvalDispatcher); + setupInstantiationF(instantiationDispatcher); } - private RuleSetDispatchFeature setupInstantiationF() { + private void setupInstantiationF(RuleSetDispatchFeature d) { enableInstantiate(); - final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); setupArithPrimaryCategories(d); setupDefOpsPrimaryCategories(d); setupInstantiationWithoutRetry(d); @@ -144,22 +127,17 @@ private RuleSetDispatchFeature setupInstantiationF() { : inftyConst()); disableInstantiate(); - return d; } - private RuleSetDispatchFeature setupApprovalDispatcher() { - final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); - final IntegerLDT numbers = getServices().getTypeConverter().getIntegerLDT(); + protected void setupApprovalDispatcher(RuleSetDispatchFeature d) { if (arith != ArithTreatment.BASIC) { - // Two things keep cross-multiplication from running in circles. The - // InEquationMultFeature bounding admits only products bounded by the left side - // of an inequation already in the sequent, which caps the monomials that are - // derivable at all. In DefOps mode that check is stricter, exact match only, - // and a further limit applies: a branch that already carries BRANCH_MULT_CAP - // multiplications takes no more. Both are enforced here rather than where costs - // are computed, because a candidate's cost is computed when it enters the queue - // while the sequent and the branch keep growing until it is applied. + // The InEquationMultFeature bounding enforced here is what prevents + // cross-multiplication from running in circles: only products that are + // bounded by the left side of an inequation already present in the + // sequent are approved, so the derivable monomials are capped. In + // DefOps mode the check is stricter (exact match only) to avoid the + // saturation blow-up acceptable for Model Search. // baseCost is zero on the approval dispatcher: approval only distinguishes // finite (approved) from infinite (rejected), so the base cost is irrelevant // here and left out to keep the approval decision identical to stock. @@ -180,24 +158,26 @@ private RuleSetDispatchFeature setupApprovalDispatcher() { * * bindRuleSet ( d, "inEqSimp_signCases", isInstantiated ( "signCasesLeft" ) ); */ - setupNewSymApproval(d, numbers); - - bindRuleSet(d, "defOps_div", NonDuplicateAppModPositionFeature.INSTANCE); - bindRuleSet(d, "defOps_jdiv", NonDuplicateAppModPositionFeature.INSTANCE); + bindRuleSet(d, "defOps_div", featureConstants.nonDuplicateAppModPositionFeature()); if (arith == ArithTreatment.MODEL_SEARCH) { setupInEqCaseDistinctionsApproval(d); } + } - return d; + @Override + public boolean isResponsibleFor(RuleSet rs) { + return costComputationDispatcher.get(rs) != null || instantiationDispatcher.get(rs) != null; } - private RuleSetDispatchFeature setupCostComputationF() { - final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); - final IntegerLDT numbers = getServices().getTypeConverter().getIntegerLDT(); + @Override + public boolean isStopAtFirstNonCloseableGoal() { + return stopAtFirstNonCloseableGoal; + } + private void setupCostComputationF(RuleSetDispatchFeature d) { bindRuleSet(d, "simplify_int", inftyConst()); setupArithPrimaryCategories(d); @@ -208,39 +188,40 @@ private RuleSetDispatchFeature setupCostComputationF() { bindRuleSet(d, "order_terms", add(applyTF("commEqRight", tf.monomial), applyTF("commEqLeft", tf.polynomial), - monSmallerThan("commEqLeft", "commEqRight", numbers), + createMonomialSmallerThan("commEqLeft", "commEqRight", numbers), CostBand.NORMALIZE.cost())); - final TermBuffer equation = new TermBuffer(); - final TermBuffer left = new TermBuffer(); - final TermBuffer right = new TermBuffer(); + final TermBuffer equation = new TermBuffer<>(); + final TermBuffer left = new TermBuffer<>(); + final TermBuffer right = new TermBuffer<>(); bindRuleSet(d, "apply_equations", SumFeature.createSum( - add(applyTF(FocusProjection.create(0), tf.monomial), - ScaleFeature.createScaled(FindRightishFeature.create(numbers), 5.0)), - ifZero(MatchedAssumesFeature.INSTANCE, - add(CheckApplyEqFeature.INSTANCE, let(equation, AssumptionProjection.create(0), - add(not(applyTF(equation, ff.update)), - // there might be updates in - // front of the assumption - // formula; in this case we wait - // until the updates have - // been applied - let(left, sub(equation, 0), - let(right, sub(equation, 1), - add(applyTF(left, tf.nonNegOrNonCoeffMonomial), - applyTF(right, tf.polynomial), - MonomialsSmallerThanFeature.create(right, left, - numbers)))))))), + add(applyTF(featureConstants.focusProjection(0), tf.monomial), + ScaleFeature.createScaled(featureConstants.findRightishFeature(numbers), 5.0)), + ifZero(featureConstants.matchedAssumesFeature(), + add(featureConstants.checkApplyEqFeature(), + let(equation, AssumptionProjection.create(0), + add(not(applyTF(equation, ff.update())), + // there might be updates in + // front of the assumption + // formula; in this case we wait + // until the updates have + // been applied + let(left, sub(equation, 0), + let(right, sub(equation, 1), + add(applyTF(left, tf.nonNegOrNonCoeffMonomial), + applyTF(right, tf.polynomial), + createMonomialsSmallerThanFeature(right, left, + numbers)))))))), longConst(CombinationCost.ORDERED_REWRITING))); - final TermBuffer l = new TermBuffer(); - final TermBuffer r = new TermBuffer(); + final TermBuffer l = new TermBuffer<>(); + final TermBuffer r = new TermBuffer<>(); bindRuleSet(d, "apply_equations_andOr", add(let(l, instOf("applyEqLeft"), let(r, instOf("applyEqRight"), add(applyTF(l, tf.nonNegOrNonCoeffMonomial), applyTF(r, tf.polynomial), - MonomialsSmallerThanFeature.create(r, l, numbers)))), + createMonomialsSmallerThanFeature(r, l, numbers)))), longConst(CombinationCost.CNF_CONVERSION))); // For taclets that need instantiation, but where the instantiation is @@ -251,15 +232,84 @@ private RuleSetDispatchFeature setupCostComputationF() { // never be instantiated (so that these applications can be removed from // the queue and do not have to be considered again). setupInstantiationWithoutRetry(d); + } - return d; + @Override + public > RuleAppCost computeCost(RuleApp app, + PosInOccurrence pos, Goal goal, MutableState mState) { + return this.costComputationDispatcher.computeCost(app, pos, goal, mState); } @Override - public boolean isStopAtFirstNonCloseableGoal() { - return stopAtFirstNonCloseableGoal; + public boolean isResponsibleFor(IBuiltInRule rule) { + return false; + } + + @Override + public Set getResponsibilities(StrategyAspect aspect) { + var set = new HashSet(); + set.addAll(getDispatcher(aspect).ruleSets()); + return set; } + @Override + public boolean isApprovedApp(RuleApp app, PosInOccurrence pio, G goal) { + return !(approvalDispatcher.computeCost(app, pio, goal, + new MutableState()) == TopRuleAppCost.INSTANCE); + + } + + @Override + public RuleAppCost instantiateApp(RuleApp app, PosInOccurrence pio, G goal, + MutableState mState) { + return instantiationDispatcher.computeCost(app, pio, goal, mState); + } + + @Override + public Name name() { + return NAME; + } + + @Override + public RuleSetDispatchFeature getDispatcher(StrategyAspect aspect) { + return switch (aspect) { + case StrategyAspect.Cost -> costComputationDispatcher; + case StrategyAspect.Instantiation -> instantiationDispatcher; + case StrategyAspect.Approval -> approvalDispatcher; + }; + } + + private void setupInEqCaseDistinctionsApproval(RuleSetDispatchFeature d) { + final TermBuffer atom = new TermBuffer<>(); + final TermBuffer literal = new TermBuffer<>(); + final TermBuffer intRel = new TermBuffer<>(); + final TermBuffer rootInf = new TermBuffer<>(); + + bindRuleSet(d, "inEqSimp_signCases", add(isInstantiated("signCasesLeft"), + let(atom, instOf("signCasesLeft"), allowPosNegCaseDistinction(atom)))); + + // this is somewhat ugly. we should introduce some concept of "tagging" + // rule application so that they can be recognised again later + bindRuleSet(d, "cut", + add(isInstantiated("cutFormula"), or( + not(sum(intRel, SequentFormulasGenerator.antecedent(), + ifZero(isRootInferenceProducer(intRel), + sum(rootInf, createRootsGenerator(intRel), + not(eq(instOf("cutFormula"), rootInf)))))), + ifZero(applyTF("cutFormula", opSub(tf.eq, tf.atom, tf.literal)), + let(atom, sub(StaticFeatureCollection.instOf("cutFormula"), 0), let(literal, + sub(StaticFeatureCollection.instOf("cutFormula"), 1), + allowInEqStrengthening(atom, literal))))))); + } + + private Feature allowInEqStrengthening(TermBuffer atom, TermBuffer literal) { + final TermBuffer antecFor = new TermBuffer<>(); + + return add(not(succIntEquationExists()), + not(sum(antecFor, SequentFormulasGenerator.antecedent(), + not(applyTF(antecFor, add(or(tf.leqF, tf.geqF), + sub(createEqTermFeature(atom), createEqTermFeature(literal)))))))); + } // ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// @@ -300,8 +350,7 @@ private void setupArithPrimaryCategories(RuleSetDispatchFeature d) { bindRuleSet(d, "polyDivision", DivModCost.POLY_DIVISION); } - private void setupPolySimp(RuleSetDispatchFeature d, IntegerLDT numbers) { - + private void setupPolySimp(RuleSetDispatchFeature d, IIntLdt numbers) { // category "expansion" (normalising polynomial terms) bindRuleSet(d, "polySimp_elimSubNeg", longConst(PolynomialCost.EXPAND)); @@ -309,7 +358,7 @@ private void setupPolySimp(RuleSetDispatchFeature d, IntegerLDT numbers) { bindRuleSet(d, "polySimp_homo", add(applyTF("homoRight", add(not(tf.zeroLiteral), tf.polynomial)), or(applyTF("homoLeft", or(tf.addF, tf.negMonomial)), - not(monSmallerThan("homoRight", "homoLeft", numbers))), + not(createMonomialSmallerThan("homoRight", "homoLeft", numbers))), longConst(PolynomialCost.EXPAND))); bindRuleSet(d, "polySimp_pullOutFactor", add(applyTFNonStrict("pullOutLeft", tf.literal), @@ -321,7 +370,8 @@ private void setupPolySimp(RuleSetDispatchFeature d, IntegerLDT numbers) { bindRuleSet(d, "polySimp_mulOrder", add(applyTF("commRight", tf.monomial), or( applyTF("commLeft", tf.addF), - add(applyTF("commLeft", tf.atom), atomSmallerThan("commLeft", "commRight", numbers))), + add(applyTF("commLeft", tf.atom), + createAtomSmallerThanFeature("commLeft", "commRight", numbers))), longConst(PolynomialCost.MUL_ORDER))); bindRuleSet(d, "polySimp_mulAssoc", @@ -332,7 +382,7 @@ private void setupPolySimp(RuleSetDispatchFeature d, IntegerLDT numbers) { bindRuleSet(d, "polySimp_addOrder", SumFeature.createSum(applyTF("commLeft", tf.monomial), applyTF("commRight", tf.polynomial), - monSmallerThan("commRight", "commLeft", numbers), + createMonomialSmallerThan("commRight", "commLeft", numbers), longConst(PolynomialCost.ADD_ORDER))); bindRuleSet(d, "polySimp_addAssoc", @@ -354,10 +404,10 @@ private void setupPolySimp(RuleSetDispatchFeature d, IntegerLDT numbers) { .createSum(applyTF("sepResidue", tf.polynomial), ifZero(isInstantiated("sepPosMono"), add(applyTF("sepPosMono", tf.nonNegMonomial), - monSmallerThan("sepResidue", "sepPosMono", numbers))), + createMonomialSmallerThan("sepResidue", "sepPosMono", numbers))), ifZero(isInstantiated("sepNegMono"), add(applyTF("sepNegMono", tf.negMonomial), - monSmallerThan("sepResidue", "sepNegMono", numbers))), + createMonomialSmallerThan("sepResidue", "sepNegMono", numbers))), longConst(LinearEquationCost.BALANCE))); bindRuleSet(d, "polySimp_normalise", add(applyTF("invertRight", tf.zeroLiteral), @@ -366,23 +416,26 @@ private void setupPolySimp(RuleSetDispatchFeature d, IntegerLDT numbers) { // application of equations: some specialised rules that handle // monomials and their coefficients properly - final TermBuffer eqLeft = new TermBuffer(); - final TermBuffer focus = new TermBuffer(); + final TermBuffer eqLeft = new TermBuffer<>(); + final TermBuffer focus = new TermBuffer<>(); final TermFeature atLeastTwoLCEquation = - opSub(Equality.EQUALS, opSub(tf.mul, tf.atom, tf.atLeastTwoLiteral), tf.intF); + opSub(tf.eq, opSub(tf.mul, tf.atom, tf.atLeastTwoLiteral), tf.intF); - final Feature validEqApplication = add(not(eq(eqLeft, focus)), + final Feature validEqApplication = add(not(eq(eqLeft, focus, this::createEqTermFeature)), // otherwise, the normal equation rules can and should // be used - ifZero(applyTF(AssumptionProjection.create(0), atLeastTwoLCEquation), + ifZero( + StaticFeatureCollection.applyTF(AssumptionProjection.create(0), + atLeastTwoLCEquation), add(FocusInAntecFeature.getInstance(), - applyTF(FocusFormulaProjection.INSTANCE, atLeastTwoLCEquation))), - ReducibleMonomialsFeature.createReducible(focus, eqLeft)); + applyTF(featureConstants.focusFormulaProjection(), atLeastTwoLCEquation))), + createReducibleMonomialFeature(focus, eqLeft)); final Feature eqMonomialFeature = add(not(directlyBelowSymbolAtIndex(tf.mul, -1)), - ifZero(MatchedAssumesFeature.INSTANCE, let(focus, FocusProjection.create(0), - let(eqLeft, sub(AssumptionProjection.create(0), 0), validEqApplication)))); + ifZero(featureConstants.matchedAssumesFeature(), + let(focus, featureConstants.focusProjection(0), + let(eqLeft, sub(AssumptionProjection.create(0), 0), validEqApplication)))); bindRuleSet(d, "polySimp_applyEq", add(eqMonomialFeature, longConst(LinearEquationCost.APPLY_EQ_MONOMIAL_TIEBREAK))); @@ -392,53 +445,58 @@ private void setupPolySimp(RuleSetDispatchFeature d, IntegerLDT numbers) { // bindRuleSet(d, "defOps_expandModulo", - add(NonDuplicateAppModPositionFeature.INSTANCE, longConst(DivModCost.EXPAND_MODULO))); + add(featureConstants.nonDuplicateAppModPositionFeature(), + longConst(DivModCost.EXPAND_MODULO))); // category "saturate" bindRuleSet(d, "polySimp_critPair", - ifZero(MatchedAssumesFeature.INSTANCE, - add(monSmallerThan("cpLeft1", "cpLeft2", numbers), - not(TrivialMonomialLCRFeature.create(instOf("cpLeft1"), instOf("cpLeft2")))))); + ifZero(featureConstants.matchedAssumesFeature(), + add(createMonomialSmallerThan("cpLeft1", "cpLeft2", numbers), + not(createTrivialMonomialLCRFeature(instOf("cpLeft1"), instOf("cpLeft2")))))); } private void setupDivModDivision(RuleSetDispatchFeature d) { - - final TermBuffer denomLC = new TermBuffer(); - final TermBuffer numTerm = new TermBuffer(); - final TermBuffer divCoeff = new TermBuffer(); + final TermBuffer denomLC = new TermBuffer<>(); + final TermBuffer numTerm = new TermBuffer<>(); + final TermBuffer divCoeff = new TermBuffer<>(); // exact polynomial division final Feature checkNumTerm = ifZero( add(not(applyTF(numTerm, tf.addF)), - ReducibleMonomialsFeature.createReducible(numTerm, denomLC)), - add(instantiate("polyDivCoeff", ReduceMonomialsProjection.create(numTerm, denomLC)), + createReducibleMonomialFeature(numTerm, denomLC)), + add(instantiate("polyDivCoeff", createReduceMonomialsProjection(numTerm, denomLC)), inftyConst())); final Feature isReduciblePoly = - sum(numTerm, SubtermGenerator.rightTraverse(instOf("divNum"), tf.addF), checkNumTerm); + sum(numTerm, SubtermGenerator.rightTraverse(StaticFeatureCollection.instOf("divNum"), + tf.addF), checkNumTerm); // polynomial division modulo equations of the antecedent - final Feature checkCoeffE = ifZero(contains(divCoeff, FocusProjection.create(0)), + final Feature checkCoeffE = ifZero( + contains(divCoeff, featureConstants.focusProjection(0), this::createEqTermFeature), // do not apply if the result contains the original term longConst(0), add(instantiate("polyDivCoeff", divCoeff), inftyConst())); final Feature isReduciblePolyE = - sum(numTerm, SubtermGenerator.rightTraverse(instOf("divNum"), tf.addF), + sum(numTerm, + SubtermGenerator.rightTraverse(StaticFeatureCollection.instOf("divNum"), + tf.addF), ifZero(applyTF(numTerm, tf.addF), longConst(0), sum(divCoeff, - MultiplesModEquationsGenerator.create(numTerm, denomLC), checkCoeffE))); + createMultiplesModEquationsGenerator(numTerm, denomLC), checkCoeffE))); bindRuleSet(d, "defOps_divModPullOut", SumFeature.createSum( not(add(applyTF("divNum", tf.literal), applyTF("divDenom", tf.literal))), applyTF("divNum", tf.polynomial), applyTF("divDenom", tf.polynomial), ifZero(applyTF("divDenom", tf.addF), - let(denomLC, sub(instOf("divDenom"), 1), not(isReduciblePoly)), + let(denomLC, sub(StaticFeatureCollection.instOf("divDenom"), 1), + not(isReduciblePoly)), let(denomLC, instOf("divDenom"), ifZero(isReduciblePoly, // no possible division has been found so far - add(NotInScopeOfModalityFeature.INSTANCE, ifZero(isReduciblePolyE, + add(featureConstants.notInScopeOfModalityFeature(), ifZero(isReduciblePolyE, // try again later longConst(-DivModCost.POLY_DIVISION)))))), CostBand.DEFAULT.at(100))); @@ -454,8 +512,6 @@ private void setupDivModDivision(RuleSetDispatchFeature d) { // never be instantiated (so that these applications can be removed from // the queue and do not have to be considered again). private void setupPolySimpInstantiationWithoutRetry(RuleSetDispatchFeature d) { - final IntegerLDT numbers = getServices().getTypeConverter().getIntegerLDT(); - // category "direct equations" setupPullOutGcd(d, "polySimp_pullOutGcd", false); @@ -471,65 +527,64 @@ private void setupPolySimpInstantiationWithoutRetry(RuleSetDispatchFeature d) { ifZero(not(isInstantiated("newSymDef")), SumFeature.createSum( applyTF("newSymLeft", tf.atom), applyTF("newSymLeftCoeff", tf.atLeastTwoLiteral), applyTF("newSymRight", tf.polynomial), instantiate("newSymDef", - MonomialColumnOp.create(instOf("newSymLeftCoeff"), instOf("newSymRight")))))); + createMonomialColumnOp(instOf("newSymLeftCoeff"), instOf("newSymRight")))))); - final TermBuffer divisor = new TermBuffer(); - final TermBuffer dividend = new TermBuffer(); + final TermBuffer divisor = new TermBuffer<>(); + final TermBuffer dividend = new TermBuffer<>(); bindRuleSet(d, "polySimp_applyEqPseudo", add(applyTF("aePseudoTargetLeft", tf.monomial), applyTF("aePseudoTargetRight", tf.polynomial), - ifZero(MatchedAssumesFeature.INSTANCE, - SumFeature.createSum(DiffFindAndIfFeature.INSTANCE, + ifZero(featureConstants.matchedAssumesFeature(), + SumFeature.createSum(featureConstants.diffFindAndIfFeature(), applyTF("aePseudoLeft", add(tf.nonCoeffMonomial, not(tf.atom))), applyTF("aePseudoLeftCoeff", tf.atLeastTwoLiteral), applyTF("aePseudoRight", tf.polynomial), - MonomialsSmallerThanFeature.create(instOf("aePseudoRight"), + createMonomialsSmallerThanFeature(instOf("aePseudoRight"), instOf("aePseudoLeft"), numbers), - let(divisor, instOf("aePseudoLeft"), - let(dividend, instOf("aePseudoTargetLeft"), - add(ReducibleMonomialsFeature.createReducible(dividend, divisor), + let(divisor, StaticFeatureCollection.instOf("aePseudoLeft"), + let(dividend, StaticFeatureCollection.instOf("aePseudoTargetLeft"), + add(createReducibleMonomialFeature(dividend, divisor), instantiate("aePseudoTargetFactor", - ReduceMonomialsProjection.create(dividend, divisor))))))))); + createReduceMonomialsProjection(dividend, divisor))))))))); } - private void setupNewSymApproval(RuleSetDispatchFeature d, IntegerLDT numbers) { - final TermBuffer antecFor = new TermBuffer(); + private void setupNewSymApproval(RuleSetDispatchFeature d, IIntLdt numbers) { + final TermBuffer antecFor = new TermBuffer<>(); final Feature columnOpEq = applyTF(antecFor, opSub(tf.eq, opSub(tf.mul, tf.atom, tf.atLeastTwoLiteral), tf.polynomial)); final Feature biggerLeftSide = - MonomialsSmallerThanFeature.create(instOf("newSymLeft"), + createMonomialsSmallerThanFeature(instOf("newSymLeft"), subAt(antecFor, PosInTerm.getTopLevel().down(0).down(0)), numbers); bindRuleSet(d, "polySimp_newSym", add(isInstantiated("newSymDef"), sum(antecFor, SequentFormulasGenerator.antecedent(), not(add(columnOpEq, biggerLeftSide))))); } private void setupPullOutGcd(RuleSetDispatchFeature d, String ruleSet, boolean roundingUp) { - final TermBuffer gcd = new TermBuffer(); + final TermBuffer gcd = new TermBuffer<>(); final Feature instantiateDivs; if (roundingUp) { instantiateDivs = add( instantiate("elimGcdLeftDiv", - DividePolynomialsProjection.createRoundingUp(gcd, instOf("elimGcdLeft"))), + createRoundingUpDividePolynomialsProjection(gcd, instOf("elimGcdLeft"))), instantiate("elimGcdRightDiv", - DividePolynomialsProjection.createRoundingUp(gcd, instOf("elimGcdRight")))); + createRoundingUpDividePolynomialsProjection(gcd, instOf("elimGcdRight")))); } else { instantiateDivs = add( instantiate("elimGcdLeftDiv", - DividePolynomialsProjection.createRoundingDown(gcd, instOf("elimGcdLeft"))), + createRoundingDownDividePolynomialsProjection(gcd, instOf("elimGcdLeft"))), instantiate("elimGcdRightDiv", - DividePolynomialsProjection.createRoundingDown(gcd, instOf("elimGcdRight")))); + createRoundingDownDividePolynomialsProjection(gcd, instOf("elimGcdRight")))); } bindRuleSet(d, ruleSet, add(applyTF("elimGcdLeft", tf.nonNegMonomial), applyTF("elimGcdRight", tf.polynomial), - let(gcd, CoeffGcdProjection.create(instOf("elimGcdLeft"), instOf("elimGcdRight")), + let(gcd, createCoeffGcdProjection(instOf("elimGcdLeft"), instOf("elimGcdRight")), add(applyTF(gcd, tf.atLeastTwoLiteral), instantiate("elimGcd", gcd), instantiateDivs)))); } - private void setupInEqSimp(RuleSetDispatchFeature d, IntegerLDT numbers) { - + private void setupInEqSimp(RuleSetDispatchFeature d, IIntLdt numbers) { // category "expansion" (normalising inequations) bindRuleSet(d, "inEqSimp_moveLeft", LinearInequationCost.MOVE_LEFT); @@ -539,14 +594,14 @@ private void setupInEqSimp(RuleSetDispatchFeature d, IntegerLDT numbers) { bindRuleSet(d, "inEqSimp_commute", SumFeature.createSum(applyTF("commRight", tf.monomial), applyTF("commLeft", tf.polynomial), - monSmallerThan("commLeft", "commRight", numbers), + createMonomialSmallerThan("commLeft", "commRight", numbers), longConst(LinearInequationCost.COMMUTE))); // this is copied from "polySimp_homo" bindRuleSet(d, "inEqSimp_homo", add(applyTF("homoRight", add(not(tf.zeroLiteral), tf.polynomial)), or(applyTF("homoLeft", or(tf.addF, tf.negMonomial)), - not(monSmallerThan("homoRight", "homoLeft", numbers))))); + not(createMonomialSmallerThan("homoRight", "homoLeft", numbers))))); // category "direct inequations" @@ -555,9 +610,9 @@ private void setupInEqSimp(RuleSetDispatchFeature d, IntegerLDT numbers) { add(applyTF("sepResidue", tf.polynomial), ifZero(isInstantiated("sepPosMono"), add(applyTF("sepPosMono", tf.nonNegMonomial), - monSmallerThan("sepResidue", "sepPosMono", numbers))), + createMonomialSmallerThan("sepResidue", "sepPosMono", numbers))), ifZero(isInstantiated("sepNegMono"), add(applyTF("sepNegMono", tf.negMonomial), - monSmallerThan("sepResidue", "sepNegMono", numbers))))); + createMonomialSmallerThan("sepResidue", "sepNegMono", numbers))))); // this is copied from "polySimp_normalise" bindRuleSet(d, "inEqSimp_normalise", @@ -570,45 +625,47 @@ private void setupInEqSimp(RuleSetDispatchFeature d, IntegerLDT numbers) { bindRuleSet(d, "inEqSimp_exactShadow", SumFeature.createSum(applyTF("esLeft", tf.nonCoeffMonomial), applyTFNonStrict("esCoeff2", tf.nonNegLiteral), applyTF("esRight2", tf.polynomial), - ifZero(MatchedAssumesFeature.INSTANCE, + ifZero(featureConstants.matchedAssumesFeature(), SumFeature.createSum(applyTFNonStrict("esCoeff1", tf.nonNegLiteral), applyTF("esRight1", tf.polynomial), - not(PolynomialValuesCmpFeature.leq(instOf("esRight2"), instOf("esRight1"), + not(createLeqPolynomialValuesCmpFeature(instOf("esRight2"), + instOf("esRight1"), instOfNonStrict("esCoeff1"), instOfNonStrict("esCoeff2"))))))); // category "propagation" bindRuleSet(d, "inEqSimp_contradInEqs", add(applyTF("contradLeft", tf.monomial), - ifZero(MatchedAssumesFeature.INSTANCE, - SumFeature.createSum(DiffFindAndIfFeature.INSTANCE, + ifZero(featureConstants.matchedAssumesFeature(), + SumFeature.createSum(featureConstants.diffFindAndIfFeature(), applyTF("contradRightSmaller", tf.polynomial), applyTF("contradRightBigger", tf.polynomial), applyTFNonStrict("contradCoeffSmaller", tf.posLiteral), applyTFNonStrict("contradCoeffBigger", tf.posLiteral), - PolynomialValuesCmpFeature.lt(instOf("contradRightSmaller"), + createLtPolynomialValuesCmpFeature(instOf("contradRightSmaller"), instOf("contradRightBigger"), instOfNonStrict("contradCoeffBigger"), instOfNonStrict("contradCoeffSmaller")))))); bindRuleSet(d, "inEqSimp_contradEqs", add(applyTF("contradLeft", tf.monomial), - ifZero(MatchedAssumesFeature.INSTANCE, + ifZero(featureConstants.matchedAssumesFeature(), SumFeature.createSum(applyTF("contradRightSmaller", tf.polynomial), - applyTF("contradRightBigger", tf.polynomial), PolynomialValuesCmpFeature - .lt(instOf("contradRightSmaller"), instOf("contradRightBigger")))), + applyTF("contradRightBigger", tf.polynomial), + createLtPolynomialValuesCmpFeature(instOf("contradRightSmaller"), + instOf("contradRightBigger")))), longConst(LinearInequationCost.CONTRAD))); bindRuleSet(d, "inEqSimp_strengthen", longConst(LinearInequationCost.STRENGTHEN)); bindRuleSet(d, "inEqSimp_subsumption", add(applyTF("subsumLeft", tf.monomial), - ifZero(MatchedAssumesFeature.INSTANCE, - SumFeature.createSum(DiffFindAndIfFeature.INSTANCE, + ifZero(featureConstants.matchedAssumesFeature(), + SumFeature.createSum(featureConstants.diffFindAndIfFeature(), applyTF("subsumRightSmaller", tf.polynomial), applyTF("subsumRightBigger", tf.polynomial), applyTFNonStrict("subsumCoeffSmaller", tf.posLiteral), applyTFNonStrict("subsumCoeffBigger", tf.posLiteral), - PolynomialValuesCmpFeature.leq(instOf("subsumRightSmaller"), + createLeqPolynomialValuesCmpFeature(instOf("subsumRightSmaller"), instOf("subsumRightBigger"), instOfNonStrict("subsumCoeffBigger"), instOfNonStrict("subsumCoeffSmaller")))))); @@ -620,7 +677,8 @@ private void setupInEqSimp(RuleSetDispatchFeature d, IntegerLDT numbers) { AT_COST); bindRuleSet(d, "inEqSimp_split_eq", - add(TopLevelFindFeature.SUCC, longConst(NonlinearArithmeticCost.SPLIT_EQ))); + add(featureConstants.topLevelFindSucc(), + longConst(NonlinearArithmeticCost.SPLIT_EQ))); bindRuleSet(d, "inEqSimp_signCases", not(isInstantiated("signCasesLeft"))); } else if (arith == ArithTreatment.DEF_OPS) { @@ -646,25 +704,25 @@ private void setupInEqSimp(RuleSetDispatchFeature d, IntegerLDT numbers) { bindRuleSet(d, "inEqSimp_and_contradInEqs", SumFeature.createSum(applyTF("contradLeft", tf.monomial), applyTF("contradRightSmaller", tf.polynomial), - applyTF("contradRightBigger", tf.polynomial), PolynomialValuesCmpFeature - .lt(instOf("contradRightSmaller"), instOf("contradRightBigger")))); + applyTF("contradRightBigger", tf.polynomial), createLtPolynomialValuesCmpFeature( + instOf("contradRightSmaller"), instOf("contradRightBigger")))); bindRuleSet(d, "inEqSimp_andOr_subsumption", SumFeature.createSum(applyTF("subsumLeft", tf.monomial), applyTF("subsumRightSmaller", tf.polynomial), - applyTF("subsumRightBigger", tf.polynomial), PolynomialValuesCmpFeature - .leq(instOf("subsumRightSmaller"), instOf("subsumRightBigger")))); + applyTF("subsumRightBigger", tf.polynomial), createLeqPolynomialValuesCmpFeature( + instOf("subsumRightSmaller"), instOf("subsumRightBigger")))); bindRuleSet(d, "inEqSimp_and_subsumptionEq", SumFeature.createSum(applyTF("subsumLeft", tf.monomial), applyTF("subsumRightSmaller", tf.polynomial), - applyTF("subsumRightBigger", tf.polynomial), PolynomialValuesCmpFeature - .lt(instOf("subsumRightSmaller"), instOf("subsumRightBigger")))); + applyTF("subsumRightBigger", tf.polynomial), createLtPolynomialValuesCmpFeature( + instOf("subsumRightSmaller"), instOf("subsumRightBigger")))); - final Term tOne = getServices().getTermBuilder().zTerm("1"); - final TermBuffer one = new TermBuffer() { + final Term tOne = zTerm("1"); + final TermBuffer one = new TermBuffer<>() { @Override - public void setContent(Term term, MutableState mState) {} + public void setContent(@Nullable Term term, MutableState mState) {} @Override public @NonNull Term getContent(MutableState mState) { @@ -673,16 +731,16 @@ public void setContent(Term term, MutableState mState) {} @Override public @NonNull Term toTerm(RuleApp app, PosInOccurrence pos, - Goal goal, MutableState mState) { + G goal, MutableState mState) { return tOne; } }; - final JTerm tTwo = getServices().getTermBuilder().zTerm("2"); - final TermBuffer two = new TermBuffer() { + final Term tTwo = zTerm("2"); + final TermBuffer two = new TermBuffer<>() { @Override - public void setContent(Term term, MutableState mState) {} + public void setContent(@Nullable Term term, MutableState mState) {} @Override public @NonNull Term getContent(MutableState mState) { @@ -691,7 +749,7 @@ public void setContent(Term term, MutableState mState) {} @Override public @NonNull Term toTerm(RuleApp app, PosInOccurrence pos, - Goal goal, MutableState mState) { + G goal, MutableState mState) { return tTwo; } @@ -701,14 +759,14 @@ public void setContent(Term term, MutableState mState) {} SumFeature.createSum(applyTF("tautLeft", tf.monomial), applyTF("tautRightSmaller", tf.polynomial), applyTF("tautRightBigger", tf.polynomial), - PolynomialValuesCmpFeature.leq(instOf("tautRightSmaller"), + createLeqPolynomialValuesCmpFeature(instOf("tautRightSmaller"), opTerm(numbers.getAdd(), one, instOf("tautRightBigger"))))); bindRuleSet(d, "inEqSimp_or_weaken", SumFeature.createSum(applyTF("weakenLeft", tf.monomial), applyTF("weakenRightSmaller", tf.polynomial), applyTF("weakenRightBigger", tf.polynomial), - PolynomialValuesCmpFeature.eq( + createEqPolynomialValuesCmpFeature( opTerm(numbers.getAdd(), one, instOf("weakenRightSmaller")), instOf("weakenRightBigger")))); @@ -716,7 +774,7 @@ public void setContent(Term term, MutableState mState) {} SumFeature.createSum(applyTF("antiSymmLeft", tf.monomial), applyTF("antiSymmRightSmaller", tf.polynomial), applyTF("antiSymmRightBigger", tf.polynomial), - PolynomialValuesCmpFeature.eq( + createEqPolynomialValuesCmpFeature( opTerm(numbers.getAdd(), two, instOf("antiSymmRightSmaller")), instOf("antiSymmRightBigger")))); @@ -754,7 +812,7 @@ private void setupMultiplyInequations(RuleSetDispatchFeature d, Feature baseCost // The branch limit exists to stop DefOps saturating; Model Search is expected to // saturate and keeps its unlimited behaviour. final boolean capBranch = atApproval && arith == ArithTreatment.DEF_OPS; - final TermBuffer intRel = new TermBuffer(); + final TermBuffer intRel = new TermBuffer<>(); /* * final Feature partiallyBounded = not ( sum ( intRel, SequentFormulasGenerator.sequent (), @@ -764,13 +822,14 @@ private void setupMultiplyInequations(RuleSetDispatchFeature d, Feature baseCost final Feature intRelation = applyTF(intRel, tf.intRelation); final var relevantSequentFormulas = - RelevantSequentFormulasGenerator.sequent(tf.intRelationOp); + RelevantSequentFormulasGenerator.sequent(tf.intRelationOp); final Feature totallyBounded = not(sum(intRel, relevantSequentFormulas, - not(add(InEquationMultFeature - .totallyBounded(instOf("multLeft"), instOf("multFacLeft"), sub(intRel, 0)), + not(add( + createTotalyBoundedInEquationMultFeature(instOf("multLeft"), instOf("multFacLeft"), + sub(intRel, 0)), intRelation)))); - final Feature exactlyBounded = new IsBoundedByInequationFeature( + final Feature exactlyBounded = createExactlyBoundedInEquationMultFeature( instOf("multLeft"), instOf("multFacLeft"), tf.intRelation); // this is a bit hackish @@ -788,7 +847,7 @@ private void setupMultiplyInequations(RuleSetDispatchFeature d, Feature baseCost baseCost, applyTF("multLeft", tf.nonNegMonomial), applyTF("multRight", tf.polynomial), - ifZero(MatchedAssumesFeature.INSTANCE, + ifZero(featureConstants.matchedAssumesFeature(), SumFeature.createSum( applyTF("multFacLeft", tf.nonNegMonomial), ifZero(applyTF("multRight", tf.literal), CostBand.DEFAULT.at(-100)), @@ -800,7 +859,7 @@ private void setupMultiplyInequations(RuleSetDispatchFeature d, Feature baseCost * "multRight", tf.polynomial ) ), ifZero ( applyTF ( "multFacRight", tf.literal * ), longConst ( -100 ), applyTF ( "multFacRight", tf.polynomial ) ), */ - not(TermSmallerThanFeature.create(FocusProjection.create(0), + not(createTermSmallerThanFeature(featureConstants.focusProjection(0), AssumptionProjection.create(0))), onlyExactlyBounded ? ifZero(add(applyTF("multLeft", tf.linearMonomial), @@ -809,8 +868,8 @@ private void setupMultiplyInequations(RuleSetDispatchFeature d, Feature baseCost : longConst(0), capBranch - ? ifZero(BranchMultiplicationCountFeature.atMost("multiply_2_inEq", - BRANCH_MULT_CAP), longConst(0), notAllowedF) + ? ifZero(getBranchCountFeatureFor("multiply_2_inEq"), longConst(0), + notAllowedF) : longConst(0), ifZero(exactlyBounded, CostBand.DEFAULT.cost(), onlyExactlyBounded ? notAllowedF @@ -827,6 +886,8 @@ private void setupMultiplyInequations(RuleSetDispatchFeature d, Feature baseCost ), notAllowedF))); } + protected abstract Feature getBranchCountFeatureFor(String prefix); + private void setupInEqSimpInstantiation(RuleSetDispatchFeature d) { // category "handling of non-linear inequations" @@ -856,60 +917,64 @@ private void setupInEqSimpInstantiationWithoutRetry(RuleSetDispatchFeature d) { // category "handling of non-linear inequations" - final TermBuffer divisor = new TermBuffer(); - final TermBuffer dividend = new TermBuffer(); + final TermBuffer divisor = new TermBuffer<>(); + final TermBuffer dividend = new TermBuffer<>(); bindRuleSet(d, "inEqSimp_nonLin_divide", SumFeature.createSum( applyTF("divProd", tf.nonCoeffMonomial), applyTFNonStrict("divProdBoundNonPos", tf.nonPosLiteral), applyTFNonStrict("divProdBoundNonNeg", tf.nonNegLiteral), - ifZero(MatchedAssumesFeature.INSTANCE, + ifZero(featureConstants.matchedAssumesFeature(), let(divisor, instOf("divX"), let(dividend, instOf("divProd"), SumFeature.createSum(applyTF(divisor, tf.nonCoeffMonomial), not(eq(dividend, divisor)), applyTFNonStrict("divXBoundPos", tf.posLiteral), applyTFNonStrict("divXBoundNeg", tf.negLiteral), - ReducibleMonomialsFeature.createReducible(dividend, divisor), instantiate( - "divY", ReduceMonomialsProjection.create(dividend, divisor)))))))); + createReducibleMonomialFeature(dividend, divisor), instantiate( + "divY", createReduceMonomialsProjection(dividend, divisor)))))))); setupNonLinTermIsPosNeg(d, "inEqSimp_nonLin_pos", true); setupNonLinTermIsPosNeg(d, "inEqSimp_nonLin_neg", false); } private void setupNonLinTermIsPosNeg(RuleSetDispatchFeature d, String ruleSet, boolean pos) { - final TermBuffer divisor = new TermBuffer(); - final TermBuffer dividend = new TermBuffer(); - final TermBuffer quotient = new TermBuffer(); - final TermBuffer antecFor = new TermBuffer(); + final TermBuffer divisor = new TermBuffer<>(); + final TermBuffer dividend = new TermBuffer<>(); + final TermBuffer quotient = new TermBuffer<>(); + final TermBuffer antecFor = new TermBuffer<>(); bindRuleSet(d, ruleSet, SumFeature .createSum(applyTF("divProd", tf.nonCoeffMonomial), applyTFNonStrict("divProdBoundPos", tf.posLiteral), applyTFNonStrict("divProdBoundNeg", tf.negLiteral), - ifZero(MatchedAssumesFeature.INSTANCE, + ifZero(featureConstants.matchedAssumesFeature(), let(divisor, instOf("divX"), let(dividend, instOf("divProd"), SumFeature.createSum(applyTF(divisor, tf.nonCoeffMonomial), - not(applyTF(dividend, eq(divisor))), + not(applyTF(dividend, createEqTermFeature(divisor))), applyTFNonStrict("divXBoundNonPos", tf.nonPosLiteral), applyTFNonStrict("divXBoundNonNeg", tf.nonNegLiteral), - ReducibleMonomialsFeature.createReducible(dividend, divisor), + createReducibleMonomialFeature(dividend, divisor), let(quotient, - ReduceMonomialsProjection.create(dividend, divisor), add( + createReduceMonomialsProjection(dividend, divisor), add( sum(antecFor, SequentFormulasGenerator.antecedent(), not(applyTF(antecFor, - pos ? opSub(tf.geq, eq(quotient), tf.posLiteral) - : opSub(tf.leq, eq(quotient), + pos ? opSub(tf.geq, + createEqTermFeature(quotient), + tf.posLiteral) + : opSub(tf.leq, + createEqTermFeature(quotient), tf.negLiteral)))), instantiate("divY", quotient))))))))); } private void setupSquaresAreNonNegative(RuleSetDispatchFeature d) { - final TermBuffer intRel = new TermBuffer(); - final TermBuffer product = new TermBuffer(); - final TermBuffer factor = new TermBuffer(); + final TermBuffer intRel = new TermBuffer<>(); + final TermBuffer product = new TermBuffer<>(); + final TermBuffer factor = new TermBuffer<>(); final Feature productContainsSquare = - applyTF(sub(product, 0), or(eq(factor), opSub(tf.mul, any(), eq(factor)))); + applyTF(sub(product, 0), + or(createEqTermFeature(factor), opSub(tf.mul, any(), createEqTermFeature(factor)))); final Feature productIsProduct = applyTF(product, opSub(tf.mul, any(), not(tf.mulF))); bindRuleSet(d, "inEqSimp_nonNegSquares", @@ -921,9 +986,9 @@ private void setupSquaresAreNonNegative(RuleSetDispatchFeature d) { } private void setupInEqCaseDistinctions(RuleSetDispatchFeature d) { - final TermBuffer intRel = new TermBuffer(); - final TermBuffer atom = new TermBuffer(); - final TermBuffer rootInf = new TermBuffer(); + final TermBuffer intRel = new TermBuffer<>(); + final TermBuffer atom = new TermBuffer<>(); + final TermBuffer rootInf = new TermBuffer<>(); final Feature posNegSplitting = forEach(intRel, SequentFormulasGenerator.antecedent(), add(applyTF(intRel, tf.intRelation), @@ -950,11 +1015,11 @@ private void setupInEqCaseDistinctions(RuleSetDispatchFeature d) { final Feature rootInferences = forEach(intRel, SequentFormulasGenerator.antecedent(), add(isRootInferenceProducer(intRel), - forEach(rootInf, RootsGenerator.create(intRel, getServices()), + forEach(rootInf, createRootsGenerator(intRel), add(instantiate("cutFormula", rootInf), - ifZero(applyTF(rootInf, op(Junctor.OR)), + ifZero(applyTF(rootInf, op(or())), CostBand.DEFAULT.at(50)), - ifZero(applyTF(rootInf, op(Junctor.AND)), + ifZero(applyTF(rootInf, op(and())), CostBand.DEFAULT.at(20)))), longConst(NonlinearArithmeticCost.MULTIPLY))); @@ -962,13 +1027,13 @@ private void setupInEqCaseDistinctions(RuleSetDispatchFeature d) { bindRuleSet(d, "cut", oneOf(new Feature[] { strengthening, rootInferences })); } - private Feature isRootInferenceProducer(TermBuffer intRel) { + private Feature isRootInferenceProducer(TermBuffer intRel) { return applyTF(intRel, add(tf.intRelation, sub(tf.nonCoeffMonomial, tf.literal))); } - private Feature allowPosNegCaseDistinction(TermBuffer atom) { - final TermBuffer antecFor = new TermBuffer(); - final TermFeature eqAtom = eq(atom); + private Feature allowPosNegCaseDistinction(TermBuffer atom) { + final TermBuffer antecFor = new TermBuffer<>(); + final TermFeature eqAtom = createEqTermFeature(atom); return add(not(succIntEquationExists()), sum(antecFor, SequentFormulasGenerator.antecedent(), @@ -976,43 +1041,13 @@ private Feature allowPosNegCaseDistinction(TermBuffer atom) { opSub(tf.leq, eqAtom, tf.negLiteral), opSub(tf.geq, eqAtom, tf.posLiteral)))))); } - private Feature allowInEqStrengthening(TermBuffer atom, TermBuffer literal) { - final TermBuffer antecFor = new TermBuffer(); - - return add(not(succIntEquationExists()), - not(sum(antecFor, SequentFormulasGenerator.antecedent(), - not(applyTF(antecFor, add(or(tf.leqF, tf.geqF), sub(eq(atom), eq(literal)))))))); - } - private Feature succIntEquationExists() { - final TermBuffer succFor = new TermBuffer(); + final TermBuffer succFor = new TermBuffer<>(); return not(sum(succFor, RelevantSequentFormulasGenerator.succedent(tf.intEquation), not(applyTF(succFor, tf.intEquation)))); } - private void setupInEqCaseDistinctionsApproval(RuleSetDispatchFeature d) { - final TermBuffer atom = new TermBuffer(); - final TermBuffer literal = new TermBuffer(); - final TermBuffer intRel = new TermBuffer(); - final TermBuffer rootInf = new TermBuffer(); - - bindRuleSet(d, "inEqSimp_signCases", add(isInstantiated("signCasesLeft"), - let(atom, instOf("signCasesLeft"), allowPosNegCaseDistinction(atom)))); - - // this is somewhat ugly. we should introduce some concept of "tagging" - // rule application so that they can be recognised again later - bindRuleSet(d, "cut", - add(isInstantiated("cutFormula"), or( - not(sum(intRel, SequentFormulasGenerator.antecedent(), - ifZero(isRootInferenceProducer(intRel), - sum(rootInf, RootsGenerator.create(intRel, getServices()), - not(eq(instOf("cutFormula"), rootInf)))))), - ifZero(applyTF("cutFormula", opSub(tf.eq, tf.atom, tf.literal)), - let(atom, sub(instOf("cutFormula"), 0), let(literal, - sub(instOf("cutFormula"), 1), allowInEqStrengthening(atom, literal))))))); - } - // ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// // @@ -1022,27 +1057,16 @@ private void setupInEqCaseDistinctionsApproval(RuleSetDispatchFeature d) { // ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// - private void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { - + protected void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { if (arith != ArithTreatment.BASIC) { // the axiom defining division only has to be inserted once, because // it adds equations to the antecedent bindRuleSet(d, "defOps_div", - SumFeature.createSum(NonDuplicateAppModPositionFeature.INSTANCE, + SumFeature.createSum(featureConstants.nonDuplicateAppModPositionFeature(), applyTF("divNum", tf.polynomial), applyTF("divDenom", tf.polynomial), applyTF("divNum", tf.notContainsDivMod), applyTF("divDenom", tf.notContainsDivMod), - ifZero(isBelow(ff.modalOperator), longConst(DivModCost.BELOW_MODALITY)))); - - bindRuleSet(d, "defOps_jdiv", - SumFeature.createSum(NonDuplicateAppModPositionFeature.INSTANCE, - applyTF("divNum", tf.polynomial), applyTF("divDenom", tf.polynomial), - applyTF("divNum", tf.notContainsDivMod), - applyTF("divDenom", tf.notContainsDivMod), - ifZero(isBelow(ff.modalOperator), longConst(DivModCost.BELOW_MODALITY)))); - - bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), - applyTF("divDenom", tf.polynomial), longConst(DivModCost.INLINE))); + ifZero(isBelow(ff.modalOperator()), longConst(DivModCost.BELOW_MODALITY)))); setupDefOpsExpandMod(d); @@ -1051,10 +1075,6 @@ private void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { bindRuleSet(d, "defOps_modHomoEq", DivModCost.MOD_HOMO_EQ); } else { bindRuleSet(d, "defOps_div", inftyConst()); - bindRuleSet(d, "defOps_jdiv", inftyConst()); - - bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), - applyTF("divDenom", tf.literal), longConst(DivModCost.MOD))); bindRuleSet(d, "defOps_mod", add(applyTF("divNum", tf.literal), applyTF("divDenom", tf.literal), longConst(DivModCost.MOD))); @@ -1063,20 +1083,19 @@ private void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { bindRuleSet(d, "defOps_expandJNumericOp", inftyConst()); bindRuleSet(d, "defOps_modHomoEq", inftyConst()); } - } private void setupDefOpsExpandMod(RuleSetDispatchFeature d) { - final TermBuffer superTerm = new TermBuffer(); + final TermBuffer superTerm = new TermBuffer<>(); final Feature subsumedModulus = add(applyTF(superTerm, sub(opSub(tf.mod, any(), tf.literal), tf.zeroLiteral)), - PolynomialValuesCmpFeature.divides(instOf("divDenom"), sub(sub(superTerm, 0), 1))); + createDividesPolynomialValuesCmpFeature(instOf("divDenom"), + sub(sub(superTerm, 0), 1))); final Feature exSubsumedModulus = add(applyTF("divDenom", tf.literal), not(sum(superTerm, - SuperTermGenerator.upwardsWithIndex(sub(or(tf.addF, tf.mulF), any()), - getServices()), + upwardsWithIndexSuperGenerator(sub(or(tf.addF, tf.mulF), any())), not(subsumedModulus)))); bindRuleSet(d, "defOps_mod", @@ -1084,67 +1103,111 @@ private void setupDefOpsExpandMod(RuleSetDispatchFeature d) { longConst(DivModCost.MOD), SumFeature.createSum(applyTF("divNum", tf.polynomial), applyTF("divDenom", tf.polynomial), - ifZero(isBelow(ff.modalOperator), exSubsumedModulus, + ifZero(isBelow(ff.modalOperator()), exSubsumedModulus, or(add(applyTF("divNum", tf.notContainsDivMod), applyTF("divDenom", tf.notContainsDivMod)), exSubsumedModulus)), longConst(DivModCost.MOD_EXPAND)))); } - /** - * For taclets that need instantiation, but where the instantiation is deterministic and does - * not have to be repeated at a later point, we setup the same feature terms both in the cost - * computation method and in the instantiation method. The definitions in - * setupInstantiationWithoutRetry should give cost infinity to those incomplete - * rule applications that will never be instantiated (so that these applications can be removed - * from the queue and do not have to be considered again). - */ + /// For taclets that need instantiation, but where the instantiation is deterministic and does + /// not have to be repeated at a later point, we set up the same feature terms both in the cost + /// computation method and in the instantiation method. The definitions in + /// `setupInstantiationWithoutRetry` should give cost infinity to those incomplete + /// rule applications that will never be instantiated (so that these applications can be removed + /// from the queue and do not have to be considered again). private void setupInstantiationWithoutRetry(RuleSetDispatchFeature d) { setupPolySimpInstantiationWithoutRetry(d); setupInEqSimpInstantiationWithoutRetry(d); } - @Override - public boolean isApprovedApp(RuleApp app, PosInOccurrence pio, Goal goal) { - return !(approvalDispatcher.computeCost(app, pio, goal, - new MutableState()) == TopRuleAppCost.INSTANCE); + protected abstract Feature createReducibleMonomialFeature(ProjectionToTerm dividend, + ProjectionToTerm divisor); - } + protected abstract Feature createTrivialMonomialLCRFeature(ProjectionToTerm a, + ProjectionToTerm b); - @Override - public RuleAppCost instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, - MutableState mState) { - return instantiationDispatcher.computeCost(app, pio, goal, mState); - } + protected abstract ProjectionToTerm createReduceMonomialsProjection( + ProjectionToTerm dividend, ProjectionToTerm divisor); - @Override - public Name name() { - return NAME; - } + protected abstract ProjectionToTerm createMonomialColumnOp( + ProjectionToTerm leftCoefficient, + ProjectionToTerm polynomial); - @Override - public > RuleAppCost computeCost(RuleApp app, - PosInOccurrence pos, Goal goal, MutableState mState) { - return this.costComputationDispatcher.computeCost(app, pos, goal, mState); - } + protected abstract Feature createMonomialsSmallerThanFeature(ProjectionToTerm left, + ProjectionToTerm right, IIntLdt numbers); - @Override - public Set getResponsibilities(StrategyAspect aspect) { - var set = new HashSet(); - set.addAll(getDispatcher(aspect).ruleSets()); - return set; - } + protected abstract Feature createAtomSmallerThanFeature(String left, String right, + IIntLdt numbers); - @Override - public RuleSetDispatchFeature getDispatcher(StrategyAspect aspect) { - return switch (aspect) { - case StrategyAspect.Cost -> costComputationDispatcher; - case StrategyAspect.Instantiation -> instantiationDispatcher; - case StrategyAspect.Approval -> approvalDispatcher; - }; - } + protected abstract ProjectionToTerm createRoundingUpDividePolynomialsProjection( + ProjectionToTerm leftCoefficient, ProjectionToTerm polynomial); - @Override - public boolean isResponsibleFor(BuiltInRule rule) { - return false; + protected abstract ProjectionToTerm createRoundingDownDividePolynomialsProjection( + ProjectionToTerm leftCoefficient, ProjectionToTerm polynomial); + + protected abstract ProjectionToTerm createCoeffGcdProjection( + ProjectionToTerm monomialLeft, ProjectionToTerm monomialRight); + + protected abstract Feature createExactlyBoundedInEquationMultFeature( + ProjectionToTerm mult1Candidate, ProjectionToTerm mult2Candidate, + TermFeature targetCandidate); + + protected abstract Feature createTotalyBoundedInEquationMultFeature( + ProjectionToTerm mult1Candidate, ProjectionToTerm mult2Candidate, + ProjectionToTerm targetCandidate); + + protected abstract Feature createLtPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right); + + protected abstract Feature createLtPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right, ProjectionToTerm leftCoeff, + ProjectionToTerm rightCoeff); + + protected abstract Feature createLeqPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right); + + protected abstract Feature createLeqPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right, ProjectionToTerm leftCoeff, + ProjectionToTerm rightCoeff); + + protected abstract Feature createEqPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right); + + protected abstract Feature createEqPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right, ProjectionToTerm leftCoeff, + ProjectionToTerm rightCoeff); + + protected abstract Feature createDividesPolynomialValuesCmpFeature(ProjectionToTerm left, + ProjectionToTerm right); + + protected abstract TermFeature createEqTermFeature(TermBuffer t); + + protected abstract Feature directlyBelowSymbolAtIndex(Operator symbol, int index); + + protected abstract TermGenerator createMultiplesModEquationsGenerator( + ProjectionToTerm source, ProjectionToTerm target); + + protected abstract Term zTerm(String num); + + protected abstract ProjectionToTerm opTerm(Operator op, ProjectionToTerm subTerm0, + ProjectionToTerm subTerm1); + + protected abstract Feature createTermSmallerThanFeature(ProjectionToTerm left, + ProjectionToTerm right); + + protected abstract Feature createMonomialSmallerThan(String left, String right, + IIntLdt numbers); + + protected abstract TermGenerator createRootsGenerator(ProjectionToTerm powerRelation); + + protected abstract Operator or(); + + protected abstract Operator and(); + + protected abstract TermGenerator upwardsWithIndexSuperGenerator(TermFeature cond); + + protected Feature eq(ProjectionToTerm t1, ProjectionToTerm t2) { + final TermBuffer buf = new TermBuffer<>(); + return let(buf, t1, applyTF(t2, createEqTermFeature(buf))); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/RuleAppCostCollector.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/RuleAppCostCollector.java similarity index 93% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/RuleAppCostCollector.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/RuleAppCostCollector.java index 626765e14fc..08c83d8a535 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/RuleAppCostCollector.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/RuleAppCostCollector.java @@ -2,7 +2,7 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy; +package org.key_project.prover.strategy; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.strategy.costbased.RuleAppCost; diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/StaticFeatureCollection.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/StaticFeatureCollection.java new file mode 100644 index 00000000000..b64f4ef9bd3 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/StaticFeatureCollection.java @@ -0,0 +1,294 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy; + +import org.key_project.logic.Name; +import org.key_project.logic.PosInTerm; +import org.key_project.logic.op.Function; +import org.key_project.logic.op.Operator; +import org.key_project.logic.sort.Sort; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.strategy.costbased.NumberRuleAppCost; +import org.key_project.prover.strategy.costbased.RuleAppCost; +import org.key_project.prover.strategy.costbased.TopRuleAppCost; +import org.key_project.prover.strategy.costbased.feature.*; +import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; +import org.key_project.prover.strategy.costbased.termProjection.SVInstantiationProjection; +import org.key_project.prover.strategy.costbased.termProjection.SubtermProjection; +import org.key_project.prover.strategy.costbased.termProjection.TermBuffer; +import org.key_project.prover.strategy.costbased.termfeature.*; +import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; + +/// Collection of strategy features that can be accessed statically. This class is essentially a +/// collection of constructors for various features. +/// +/// @author Kai Wallisch \ +public class StaticFeatureCollection { + public static Feature longConst(long a) { + return ConstFeature.createConst(cost(a)); + } + + public static Feature inftyConst() { + return ConstFeature.createConst(infty()); + } + + public static TermFeature any() { + return longTermConst(0); + } + + public static TermFeature longTermConst(long a) { + return ConstTermFeature.createConst(cost(a)); + } + + public static TermFeature inftyTermConst() { + return ConstTermFeature.createConst(infty()); + } + + public static Feature add(Feature a, Feature b) { + return SumFeature.createSum(a, b); + } + + public static Feature add(Feature a, Feature b, Feature c) { + return SumFeature.createSum(a, b, c); + } + + @SafeVarargs + public static Feature add(Feature... features) { + return SumFeature.createSum(features); + } + + public static TermFeature add(TermFeature a, TermFeature b) { + return BinarySumTermFeature.createSum(a, b); + } + + public static > Feature sum(TermBuffer x, TermGenerator gen, + Feature body) { + return ComprehendedSumFeature.create(x, gen, body); + } + + public static TermFeature add(TermFeature a, TermFeature b, TermFeature c) { + // could be done more efficiently + return add(a, add(b, c)); + } + + public static TermFeature or(TermFeature a, TermFeature b) { + return ifZero(a, longTermConst(0), b); + } + + public static TermFeature or(TermFeature a, TermFeature b, TermFeature c) { + return or(a, or(b, c)); + } + + public static TermFeature or(TermFeature... features) { + TermFeature orFeature = inftyTermConst(); + for (var f : features) { + orFeature = or(orFeature, f); + } + return orFeature; + } + + public static Feature or(Feature a, Feature b) { + return ifZero(a, longConst(0), b); + } + + public static Feature or(Feature a, Feature b, Feature c) { + return or(a, or(b, c)); + } + + @SafeVarargs + public static Feature or(Feature... features) { + Feature orFeature = inftyConst(); + for (Feature f : features) { + orFeature = or(orFeature, f); + } + return orFeature; + } + + public static Feature ifZero(Feature cond, Feature thenFeature) { + return ShannonFeature.createConditionalBinary(cond, thenFeature); + } + + public static Feature ifZero(Feature cond, Feature thenFeature, + Feature elseFeature) { + return ShannonFeature.createConditionalBinary(cond, thenFeature, elseFeature); + } + + public static TermFeature ifZero(TermFeature cond, TermFeature thenFeature) { + return ShannonTermFeature.createConditionalBinary(cond, thenFeature); + } + + public static TermFeature ifZero(TermFeature cond, TermFeature thenFeature, + TermFeature elseFeature) { + return ShannonTermFeature.createConditionalBinary(cond, thenFeature, elseFeature); + } + + public static Feature not(Feature f) { + return ifZero(f, inftyConst(), longConst(0)); + } + + public static TermFeature not(TermFeature f) { + return ifZero(f, ConstTermFeature.createConst(TopRuleAppCost.INSTANCE), longTermConst(0)); + } + + public static Feature eq(Feature a, Feature b) { + return CompareCostsFeature.eq(a, b); + } + + public static > Feature eq(ProjectionToTerm t1, + ProjectionToTerm t2, + java.util.function.Function, TermFeature> createEqTermFeature) { + final TermBuffer buf = new TermBuffer<>(); + return let(buf, t1, applyTF(t2, createEqTermFeature.apply(buf))); + } + + public static Feature less(Feature a, Feature b) { + return CompareCostsFeature.less(a, b); + } + + public static Feature leq(Feature a, Feature b) { + return CompareCostsFeature.leq(a, b); + } + + public static RuleAppCost cost(long p) { + return NumberRuleAppCost.create(p); + } + + private static RuleAppCost infty() { + return TopRuleAppCost.INSTANCE; + } + + /// Create a projection of taclet applications to the instantiation of the schema variables + /// `schemaVar`. If `schemaVar` is not instantiated for a particular taclet + /// app, an error will be raised + /// + /// @param schemaVar schema variable + /// @return projection of taclet applications + public static > ProjectionToTerm instOf(String schemaVar) { + return SVInstantiationProjection.create(new Name(schemaVar), true); + } + + /// Create a projection of taclet applications to the instantiation of the schema variables + /// `schemaVar`. The projection will be partial and undefined for those taclet + /// applications that do not instantiate `schemaVar` + /// + /// @param schemaVar schema variable + /// @return projection of taclet applications + public static > ProjectionToTerm instOfNonStrict( + String schemaVar) { + return SVInstantiationProjection.create(new Name(schemaVar), false); + } + + public static TermFeature op(Operator op) { + return OperatorTF.create(op); + } + + public static TermFeature rec(TermFeature cond, TermFeature summand) { + return RecSubTermFeature.create(cond, summand); + } + + public static > ProjectionToTerm subAt(ProjectionToTerm t, + PosInTerm pit) { + return SubtermProjection.create(t, pit); + } + + public static TermFeature sub(TermFeature sub0) { + return SubTermFeature.create(new TermFeature[] { sub0 }); + } + + public static TermFeature sub(TermFeature sub0, TermFeature sub1) { + return SubTermFeature.create(new TermFeature[] { sub0, sub1 }); + } + + public static > ProjectionToTerm sub(ProjectionToTerm t, + int index) { + return SubtermProjection.create(t, PosInTerm.getTopLevel().down(index)); + } + + public static TermFeature opSub(Operator op, TermFeature sub0) { + return add(op(op), sub(sub0)); + } + + public static TermFeature opSub(Operator op, TermFeature sub0, TermFeature sub1) { + return add(op(op), sub(sub0, sub1)); + } + + public static > Feature contains(ProjectionToTerm bigTerm, + ProjectionToTerm searchedTerm, + java.util.function.Function, TermFeature> createEqTermFeature) { + final TermBuffer buf = new TermBuffer<>(); + return let(buf, searchedTerm, + applyTF(bigTerm, not(rec(any(), not(createEqTermFeature.apply(buf)))))); + } + + public static > Feature let(TermBuffer x, + ProjectionToTerm value, + Feature body) { + return LetFeature.create(x, value, body); + } + + public static > Feature println(ProjectionToTerm t) { + return applyTF(t, PrintTermFeature.INSTANCE); + } + + public static TermFeature extendsTrans(Sort s) { + return SortExtendsTransTermFeature.create(s); + } + + /// Invoke the term feature `tf` on the term that instantiation of + /// `schemaVar`. This is the strict/safe version that raises an error of + /// `schemaVar` is not instantiated for a particular taclet app + /// + /// @param schemaVar schema variable + /// @param tf term feature + /// @return feature + public static > Feature applyTF(String schemaVar, TermFeature tf) { + return applyTF(StaticFeatureCollection.instOf(schemaVar), tf); + } + + /// Invoke the term feature `tf` on the term that instantiation of + /// `schemaVar`. This is the non-strict/unsafe version that simply returns zero if + /// `schemaVar` is not instantiated for a particular taclet app + /// + /// @param schemaVar schema variable + /// @param tf term feature + /// @return feature + public static > Feature applyTFNonStrict(String schemaVar, + TermFeature tf) { + return applyTFNonStrict(StaticFeatureCollection.instOfNonStrict(schemaVar), tf); + } + + /// Evaluate the term feature `tf` for the term described by the projection + /// `term`. If `term` is undefined for a particular rule app, an exception + /// is raised + /// + /// @param term term describing the projection + /// @param tf term feature + /// @return feature + public static > Feature applyTF(ProjectionToTerm term, + TermFeature tf) { + return ApplyTFFeature.create(term, tf); + } + + /// Evaluate the term feature `tf` for the term described by the projection + /// `term`. If `term` is undefined for a particular rule app, zero is + /// returned + /// + /// @param term term describing the projection + /// @param tf term feature + /// @return feature + public static > Feature applyTFNonStrict(ProjectionToTerm term, + TermFeature tf) { + return ApplyTFFeature.createNonStrict(term, tf, NumberRuleAppCost.getZeroCost()); + } + + public static TermFeature constantTermFeature() { + return TermPredicateTermFeature + .create(term -> term.op() instanceof Function && term.arity() == 0); + } + + public static Feature isInstantiated(String schemaVar) { + return InstantiatedSVFeature.create(new Name(schemaVar)); + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/Strategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/Strategy.java similarity index 67% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/Strategy.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/Strategy.java index 874c7944673..44573a4ded7 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/Strategy.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/Strategy.java @@ -2,11 +2,7 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy; - -import de.uka.ilkd.key.proof.Goal; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.settings.ProofSettings; +package org.key_project.prover.strategy; import org.key_project.logic.Named; import org.key_project.prover.proof.ProofGoal; @@ -15,15 +11,11 @@ import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; +import org.key_project.prover.strategy.costbased.TopRuleAppCost; import org.key_project.prover.strategy.costbased.feature.Feature; import org.jspecify.annotations.NonNull; - - -/** - * Generic interface for evaluating the cost of a RuleApp with regard to a specific strategy - */ public interface Strategy> extends Named, Feature { /** * Evaluate the cost of a RuleApp. Starts a new independent computation. @@ -65,29 +57,10 @@ default RuleAppCost computeCost(RuleApp app, PosInOccurrence pos, Goal goal) { void instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, RuleAppCostCollector collector); - /** - * Updates the {@link Strategy} for the given {@link Proof} by setting the {@link Strategy}'s - * {@link StrategyProperties} to the given ones. - * - * @param proof The {@link Proof} the strategy of which should be updated. - * @param p The new {@link StrategyProperties} - */ - static void updateStrategySettings(Proof proof, StrategyProperties p) { - final Strategy strategy = proof.getActiveStrategy(); - ProofSettings.DEFAULT_SETTINGS.getStrategySettings().setStrategy(strategy.name()); - ProofSettings.DEFAULT_SETTINGS.getStrategySettings().setActiveStrategyProperties(p); - - proof.getSettings().getStrategySettings().setStrategy(strategy.name()); - proof.getSettings().getStrategySettings().setActiveStrategyProperties(p); - - proof.setActiveStrategy(strategy); - } - - default boolean isResponsibleFor(RuleSet rs) { return false; } + boolean isResponsibleFor(RuleSet rs); default RuleAppCost instantiateApp(RuleApp app, PosInOccurrence pio, - de.uka.ilkd.key.proof.Goal goal, - MutableState mState) { - return null; + Goal goal, MutableState mState) { + return TopRuleAppCost.INSTANCE; } } diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/CombinationCost.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/CombinationCost.java new file mode 100644 index 00000000000..7d2ef4f32c9 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/CombinationCost.java @@ -0,0 +1,44 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased; + +/** + * Costs whose meaning spans more than one component strategy — the theory-combination + * constants, as opposed to the theory-internal holders (like {@link FOLCost} and the integer + * holders). + * + *

    + * A theory-local rule may also reference a constant here when sharing the level is the documented + * intent (e.g. {@code conjNormalForm} at {@link #CNF_CONVERSION}), so that retuning the + * combination level moves the coupled rule with it. + *

    + * + *

    + * Values are byte-identical to the literals they replace; verify changes with a full runAllProofs + * (as for {@link CostBand}). + *

    + */ +final public class CombinationCost { + private CombinationCost() {} + + /** + * Demodulation: use an oriented equation as a rewrite rule, only in the decreasing direction + * of the reduction ordering (see the {@code TermSmallerThanFeature} / + * {@code MonomialsSmallerThanFeature} guards at the call sites; right ≺ left). The FOL half + * instantiates this with the generic term ordering, the Integer half with the monomial + * ordering. The orientation step itself ({@code order_terms}) sits at + * {@code CostBand.NORMALIZE}. Deliberately its own level — not {@code EXECUTE}, which + * is reserved for symbolic execution. + */ + static public final long ORDERED_REWRITING = -4000; + + /** + * Priority at which CNF conversion runs: {@code conjNormalForm} (associativity, commutation, + * distribution, if-then-else expansion — the fine ordering among these comes from the + * {@code cnf_*} co-rule-sets, {@link FOLCost#CNF_RESTRUCTURE}) and ordered rewriting within + * and/or clause contexts ({@code apply_equations_andOr}, conflict-dispatched). + */ + static public final long CNF_CONVERSION = -150; +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/DivModCost.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/DivModCost.java new file mode 100644 index 00000000000..c8dc1e674f1 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/DivModCost.java @@ -0,0 +1,38 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased; + +/* + * Theory-internal cost constants for the integer arithmetic strategy, grouped by the arithmetic + * sub-theory they belong to. The grouping deliberately anticipates a future split of + * IntegerStrategy into separate sub-strategies (polynomial / linear / non-linear / div-mod): each + * holder is meant to move with its sub-strategy. Cross-theory levels stay in + * {@link org.key_project.prover.strategy.costbased.CostBand}; only the arithmetic-internal ordering + * lives here. All values are byte-identical to the literals they replace. + * + * The file is named after the integer-arithmetic *theory*; a plain "IntegerCost(s)" would suggest + * an integer-valued cost type (an implementation of RuleAppCost) rather than a holder of cost + * constants. + */ + + +/** Division / modulo and DefOps expansion ({@code polyDivision}, {@code defOps_*}). */ +final public class DivModCost { + private DivModCost() {} + + static public final long POLY_DIVISION = -2250; + static public final long EXPAND_MODULO = -600; + /** extra cost for defOps_div/jdiv applied below a modality. */ + static public final long BELOW_MODALITY = 200; + static public final long EXPAND_RANGES = -8000; + static public final long MOD_HOMO_EQ = -5000; + static public final long EXPAND_NUMERIC_OP = -500; + /** defOps_jdiv_inline for a literal numerator (eager, concrete division). */ + static public final long INLINE = -5000; + /** literal-only division / modulo (defOps_mod, off-mode jdiv_inline). */ + static public final long MOD = -4000; + /** modulo expansion for a polynomial (non-literal) modulus (defOps_mod). */ + static public final long MOD_EXPAND = -3500; +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/FOLCost.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/FOLCost.java similarity index 79% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/FOLCost.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/FOLCost.java index 6877f5dea8b..9f3a05b40e4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/FOLCost.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/FOLCost.java @@ -2,7 +2,7 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy; +package org.key_project.prover.strategy.costbased; /** * FOL-theory-internal ordering costs, used by {@link FOLStrategy}. These are the fine, within-FOL @@ -12,18 +12,18 @@ * *

    * Values are byte-identical to the literals they replace. They position FOL rules within the shared - * {@link org.key_project.prover.strategy.costbased.CostBand} ladder, so changing one shifts the + * {@link CostBand} ladder, so changing one shifts the * cross-theory search — verify with a full runAllProofs and a Model-Search node-for-node comparison - * (as for {@code CostBand}). + * (as for {@link CostBand}). *

    */ -final class FOLCost { +final public class FOLCost { private FOLCost() {} /** * Distribution / swapping of quantifiers ({@code distrQuantifier}, {@code swapQuantifiers}). */ - static final long QUANTIFIER_DISTRIBUTION = -300; + static public final long QUANTIFIER_DISTRIBUTION = -300; /** * Restructuring of CNF clauses by associativity / distribution ({@code cnf_orAssoc}, @@ -32,7 +32,7 @@ private FOLCost() {} * {@link CombinationCost#CNF_CONVERSION} level via the dual rule-set tags of the * {@code conjNormalForm} taclets. */ - static final long CNF_RESTRUCTURE = -35; + static public final long CNF_RESTRUCTURE = -35; /** * Defer {@code replace_known_right} when its target is in the consequent of an implication or @@ -40,14 +40,14 @@ private FOLCost() {} * available as a known-true fact). Deliberately not applied to * {@code replace_known_left}, whose antecedent-true facts stay valid across the decomposition. */ - static final long REPLACE_KNOWN_UNDER_CONNECTIVE = 100; + static public final long REPLACE_KNOWN_UNDER_CONNECTIVE = 100; /** Standard cost of a direct cut ({@code cut_direct}). */ - static final long CUT_DIRECT_STANDARD = 100; + static public final long CUT_DIRECT_STANDARD = 100; /** Preferred direction of the {@code pullOutQuantifier*} rules. */ - static final long PULL_OUT_QUANTIFIER = -20; + static public final long PULL_OUT_QUANTIFIER = -20; /** Dispreferred direction of the {@code pullOutQuantifier*} rules. */ - static final long PULL_OUT_QUANTIFIER_REVERSE = -40; + static public final long PULL_OUT_QUANTIFIER_REVERSE = -40; } diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/LinearEquationCost.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/LinearEquationCost.java new file mode 100644 index 00000000000..7171acc7b7e --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/LinearEquationCost.java @@ -0,0 +1,34 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased; + +/** + * Polynomial equation solving (Gaussian / Gröbner). These {@code polySimp_*} rule sets + * live + * here rather than in {@link PolynomialCost} on purpose: they do not just canonicalise a term, they + * derive from and apply equations, so they belong to the "linear" (solving) layer next to + * {@link LinearInequationCost}. + */ +final public class LinearEquationCost { + private LinearEquationCost() {} + + // The base costs of apply_equations / apply_equations_andOr are combination-shared with + // FOLStrategy (conflict-dispatched; the Integer halves use the monomial ordering as + // demodulation guard): see CombinationCost.ORDERED_REWRITING and + // CombinationCost.CNF_CONVERSION. + + /** polySimp_balance, polySimp_normalise. */ + static public final long BALANCE = -30; + /** + * polySimp_applyEq — a small tie-break rider on top of the general demodulation cost + * {@link CombinationCost#ORDERED_REWRITING} (the {@code apply_eq_monomials} taclet carries both + * rule sets, so the effective cost is their sum). The rigid variant polySimp_applyEqRigid is + * written {@code APPLY_EQ_MONOMIAL_TIEBREAK + 1} at the call site; that +1 is only an + * (uninteresting) tie-break between the two rules, a step-3 candidate to flatten. Step-3 idea: + * test whether this specialised variant is needed at all, or should just be a small delta + * preferring the original {@code apply_equations} rules. + */ + static public final long APPLY_EQ_MONOMIAL_TIEBREAK = 1; +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/LinearInequationCost.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/LinearInequationCost.java new file mode 100644 index 00000000000..83d562c9ee3 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/LinearInequationCost.java @@ -0,0 +1,28 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased; + +/** Linear inequation solving — the Omega / Fourier-Motzkin machinery ({@code inEqSimp_*}). */ +final public class LinearInequationCost { + private LinearInequationCost() {} + + static public final long PROPAGATION = -2400; + static public final long SATURATE = -1900; + /** General GCD normalisation of inequations — confluent, hence safe to apply eagerly. */ + static public final long PULLOUT_GCD_CONFLUENT = -2150; + static public final long FOR_NORMALISATION = -1100; + static public final long MOVE_LEFT = -90; + static public final long MAKE_NON_STRICT = -80; + static public final long CONTRAD = -60; + static public final long COMMUTE = -40; + static public final long STRENGTHEN = -30; + static public final long ANTISYMM = -20; + /** + * Faster antecedent-specialised GCD pull-out, but not confluent (the result can depend + * on application order), hence pinned near baseline so it fires only opportunistically — in + * contrast to the eager {@link #PULLOUT_GCD_CONFLUENT}. + */ + static public final long PULLOUT_GCD_ANTEC_NONCONFLUENT = -10; +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/MutableState.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/MutableState.java index 8aba79e0811..d74e2deb7f7 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/MutableState.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/MutableState.java @@ -81,7 +81,7 @@ public int getChoicePointIndex(Object choicePoint) { /// returns the backtracking manager to access [ChoicePoint]s /// /// @return the backtracking manager - public @Nullable BackTrackingManager getBacktrackingManager() { + public BackTrackingManager getBacktrackingManager() { if (btManager == null) { btManager = new BackTrackingManager(); } diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/NonlinearArithmeticCost.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/NonlinearArithmeticCost.java new file mode 100644 index 00000000000..5fcfc42a344 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/NonlinearArithmeticCost.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, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased; + +/** Non-linear arithmetic — cross-multiplication, sign cases, root inferences (Model Search). */ +final public class NonlinearArithmeticCost { + private NonlinearArithmeticCost() {} + + /** + * inEqSimp_nonLin (cross-multiplication) base; case-distinction offsets are + * {@code MULTIPLY + n}. + */ + static public final long MULTIPLY = 1000; + /** + * Divide an inequation by a factor of known sign/bound to bound the quotient (the + * {@code divide_inEq*} taclets) — the inverse of cross-multiplication. Kept clearly more eager + * than {@link #MULTIPLY}, since dividing/reducing is safer and more productive than + * multiplying. + */ + static public final long DIVIDE_INEQUATION = -1400; + static public final long SPLIT_EQ = -100; +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/PolynomialCost.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/PolynomialCost.java new file mode 100644 index 00000000000..4ffa491cf34 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/PolynomialCost.java @@ -0,0 +1,20 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased; + +/** Polynomial normal-form canonicalisation (Buchberger normalisation) — the "basic" substrate. */ +final public class PolynomialCost { + private PolynomialCost() {} + + /** elimSubNeg, homo, pullOutFactor, elimOneLeft/Right. */ + static public final long EXPAND = -120; + static public final long MUL_ORDER = -100; + static public final long MUL_ASSOC = -80; + static public final long ADD_ORDER = -60; + static public final long ADD_ASSOC = -10; + /** polySimp_dist base; the distLeft sub-case is {@code DISTRIBUTE + 20}. */ + static public final long DISTRIBUTE = -35; + static public final long PULLOUT_GCD = -2250; +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/BinaryTacletAppFeature.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/BinaryTacletAppFeature.java new file mode 100644 index 00000000000..99668a6fba2 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/BinaryTacletAppFeature.java @@ -0,0 +1,50 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased.feature; + +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.ITacletApp; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.costbased.MutableState; + +import org.jspecify.annotations.NonNull; + +/// Abstract superclass for features of TacletApps that have either zero or top cost. +public abstract class BinaryTacletAppFeature> extends BinaryFeature { + + private final boolean nonTacletValue; + + protected BinaryTacletAppFeature() { + nonTacletValue = true; + } + + /// @param p_nonTacletValue the value that is to be returned should the feature be applied to a + /// rule that is not a taclet + protected BinaryTacletAppFeature(boolean p_nonTacletValue) { + nonTacletValue = p_nonTacletValue; + } + + @Override + final protected > boolean filter(RuleApp app, + PosInOccurrence pos, + PGoal goal, MutableState mState) { + if (app instanceof ITacletApp tacletApp) { + return filter(tacletApp, pos, (G) goal, mState); + } + return nonTacletValue; + } + + /// Compute whether the result of the feature is zero (`true`) or infinity + /// (`false`) + /// + /// @param app the ITacletApp + /// @param pos position where `app` is to be applied + /// @param goal the goal on which `app` is to be applied + /// @param mState the MutableState used to store modifiable information + /// @return true iff the result of the feature is supposed to be zero. + protected abstract boolean filter(ITacletApp app, PosInOccurrence pos, G goal, + MutableState mState); +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/ComprehendedSumFeature.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/ComprehendedSumFeature.java similarity index 94% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/feature/ComprehendedSumFeature.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/ComprehendedSumFeature.java index c40f5f56a96..469af961617 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/ComprehendedSumFeature.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/ComprehendedSumFeature.java @@ -2,7 +2,7 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy.feature; +package org.key_project.prover.strategy.costbased.feature; import org.key_project.logic.Term; import org.key_project.prover.proof.ProofGoal; @@ -12,8 +12,6 @@ import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.TopRuleAppCost; -import org.key_project.prover.strategy.costbased.feature.Feature; -import org.key_project.prover.strategy.costbased.feature.StableCost; import org.key_project.prover.strategy.costbased.termProjection.TermBuffer; import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/CountBranchFeature.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/CountBranchFeature.java similarity index 91% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/feature/CountBranchFeature.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/CountBranchFeature.java index c2e3e686d5c..4214dce3a82 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/CountBranchFeature.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/CountBranchFeature.java @@ -2,17 +2,15 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy.feature; - -import de.uka.ilkd.key.rule.Taclet; +package org.key_project.prover.strategy.costbased.feature; import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.rules.Taclet; import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; -import org.key_project.prover.strategy.costbased.feature.Feature; import org.jspecify.annotations.NonNull; diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/InstantiatedSVFeature.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/InstantiatedSVFeature.java new file mode 100644 index 00000000000..6880d1ab483 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/InstantiatedSVFeature.java @@ -0,0 +1,34 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased.feature; + +import org.key_project.logic.Name; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.ITacletApp; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.costbased.MutableState; +import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; +import org.key_project.prover.strategy.costbased.termProjection.SVInstantiationProjection; + +/// Feature that returns zero iff a certain schema variable is instantiated. If the schemavariable +/// is not instantiated schema variable or does not occur in the taclet infinity costs are returned. +@StableCost +public class InstantiatedSVFeature> extends BinaryTacletAppFeature { + + private final ProjectionToTerm instProj; + + public static > Feature create(Name svName) { + return new InstantiatedSVFeature(svName); + } + + protected InstantiatedSVFeature(Name svName) { + instProj = SVInstantiationProjection.create(svName, false); + } + + @Override + protected boolean filter(ITacletApp app, PosInOccurrence pos, G goal, MutableState mState) { + return instProj.toTerm(app, pos, goal, mState) != null; + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/RuleSetDispatchFeature.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java similarity index 87% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/feature/RuleSetDispatchFeature.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java index f737c505fee..cd21e6bb4ba 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/RuleSetDispatchFeature.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java @@ -2,7 +2,7 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy.feature; +package org.key_project.prover.strategy.costbased.feature; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -11,22 +11,21 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import de.uka.ilkd.key.rule.Taclet; -import de.uka.ilkd.key.rule.TacletApp; - import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.ITacletApp; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.rules.RuleSet; +import org.key_project.prover.rules.Taclet; import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.TopRuleAppCost; -import org.key_project.prover.strategy.costbased.feature.Feature; -import org.key_project.prover.strategy.costbased.feature.SumFeature; import org.key_project.util.collection.ImmutableList; +import org.checkerframework.checker.nullness.qual.KeyFor; import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; /** @@ -39,7 +38,7 @@ public class RuleSetDispatchFeature implements Feature { private static final Feature[] NO_FEATURES = new Feature[0]; - private final Map rulesetToFeature = new LinkedHashMap<>(); + private final Map<@NonNull RuleSet, @NonNull Feature> rulesetToFeature = new LinkedHashMap<>(); /** * For each taclet the features bound to the rule sets the taclet belongs to, in rule @@ -50,7 +49,7 @@ public class RuleSetDispatchFeature implements Feature { */ private final Map featuresByTaclet = new ConcurrentHashMap<>(); - public Set ruleSets() { + public Set<@KeyFor("this.rulesetToFeature") RuleSet> ruleSets() { return rulesetToFeature.keySet(); } @@ -58,12 +57,12 @@ public Set ruleSets() { public > RuleAppCost computeCost(RuleApp app, PosInOccurrence pos, Goal goal, MutableState mState) { - if (!(app instanceof TacletApp)) { + if (!(app instanceof ITacletApp tapp)) { return NumberRuleAppCost.getZeroCost(); } RuleAppCost res = NumberRuleAppCost.getZeroCost(); - for (Feature partialF : featuresFor(((TacletApp) app).taclet())) { + for (Feature partialF : featuresFor(tapp.taclet())) { res = res.add(partialF.computeCost(app, pos, goal, mState)); if (res instanceof TopRuleAppCost) { break; @@ -121,7 +120,7 @@ public void clear(RuleSet ruleSet) { * @return The {@link Feature} used for the given {@link RuleSet} or {@code null} if not * available. */ - public Feature get(RuleSet ruleSet) { + public @Nullable Feature get(@NonNull RuleSet ruleSet) { return rulesetToFeature.get(ruleSet); } @@ -132,7 +131,7 @@ public Feature get(RuleSet ruleSet) { * @return The {@link Feature} used for the given {@link RuleSet} or {@code null} if not * available. */ - public Feature remove(RuleSet ruleSet) { + public @Nullable Feature remove(@NonNull RuleSet ruleSet) { featuresByTaclet.clear(); return rulesetToFeature.remove(ruleSet); } diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/ForEachCP.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/ForEachCP.java new file mode 100644 index 00000000000..bc07a21d3a9 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/ForEachCP.java @@ -0,0 +1,131 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased.feature.instantiator; + +import java.util.Iterator; + +import org.key_project.logic.Term; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.costbased.MutableState; +import org.key_project.prover.strategy.costbased.NumberRuleAppCost; +import org.key_project.prover.strategy.costbased.RuleAppCost; +import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.termProjection.TermBuffer; +import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; + +import org.jspecify.annotations.NonNull; + +/// Feature representing a `ChoicePoint` that iterates over the terms returned by a +/// `TermGenerator`. The terms are stored in a `TermBuffer` one after the other +/// and can subsequently be used to instantiate a rule application +public class ForEachCP> implements Feature { + + private final TermBuffer<@NonNull G> var; + private final TermGenerator<@NonNull G> generator; + private final Feature body; + + /** + * @param var TermBuffer in which the terms are going to be stored + * @param generator the terms that are to be iterated over + * @param body a feature that is supposed to be evaluated repeatedly for the possible values of + * var + */ + public static > Feature create(TermBuffer<@NonNull G> var, + TermGenerator<@NonNull G> generator, + Feature body) { + return new ForEachCP<>(var, generator, body); + } + + private ForEachCP(TermBuffer<@NonNull G> var, TermGenerator<@NonNull G> generator, + Feature body) { + this.var = var; + this.generator = generator; + this.body = body; + } + + @Override + public > RuleAppCost computeCost(final RuleApp app, + final PosInOccurrence pos, final GOAL goal, + MutableState mState) { + final Term outerVarContent = var.getContent(mState); + var.setContent(null, mState); + + final BackTrackingManager manager = mState.getBacktrackingManager(); + manager.passChoicePoint(new CP(app, pos, (G) goal, mState), this); + + final RuleAppCost res; + if (var.getContent(mState) != null) { + res = body.computeCost(app, pos, goal, mState); + } else { + res = NumberRuleAppCost.getZeroCost(); + } + + var.setContent(outerVarContent, mState); + return res; + } + + private final class CP implements ChoicePoint { + private final class BranchIterator implements Iterator { + private final Iterator terms; + private final RuleApp oldApp; + + private final MutableState mState; + + private BranchIterator(Iterator terms, + RuleApp oldApp, MutableState mState) { + this.terms = terms; + this.oldApp = oldApp; + this.mState = mState; + } + + @Override + public boolean hasNext() { + return terms.hasNext(); + } + + @Override + public CPBranch next() { + final Term generatedTerm = terms.next(); + return new CPBranch() { + @Override + public void choose() { + var.setContent(generatedTerm, mState); + } + + @Override + public RuleApp getRuleAppForBranch() { + return oldApp; + } + }; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + + private final PosInOccurrence pos; + private final RuleApp app; + private final @NonNull G goal; + private final MutableState mState; + + private CP(RuleApp app, PosInOccurrence pos, G goal, + MutableState mState) { + this.pos = pos; + this.app = app; + this.goal = goal; + this.mState = mState; + } + + @Override + public Iterator getBranches(RuleApp oldApp) { + return new BranchIterator(generator.generate(app, pos, goal, mState), oldApp, mState); + } + } + +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/OneOfCP.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/OneOfCP.java new file mode 100644 index 00000000000..fdc0d1b5d18 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/OneOfCP.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, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased.feature.instantiator; + +import java.util.Iterator; + +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.costbased.MutableState; +import org.key_project.prover.strategy.costbased.RuleAppCost; +import org.key_project.prover.strategy.costbased.feature.Feature; + +import org.jspecify.annotations.NonNull; + +public class OneOfCP implements Feature { + private final Feature[] features; + + private OneOfCP(Feature[] features) { + this.features = features; + } + + public static Feature create(Feature[] features) { + return new OneOfCP(features); + } + + @Override + public > RuleAppCost computeCost(RuleApp app, + PosInOccurrence pos, + Goal goal, + MutableState mState) { + final BackTrackingManager manager = mState.getBacktrackingManager(); + manager.passChoicePoint(new CP(mState), this); + return features[mState.getChoicePointIndex(this)].computeCost(app, pos, goal, mState); + } + + private final class CP implements ChoicePoint { + private final MutableState mState; + + private CP(MutableState mState) { + this.mState = mState; + } + + private final class BranchIterator implements Iterator { + private int num = 0; + private final RuleApp oldApp; + + public BranchIterator(RuleApp oldApp) { + this.oldApp = oldApp; + } + + @Override + public boolean hasNext() { + return num < features.length; + } + + @Override + public CPBranch next() { + final int chosen = num++; + return new CPBranch() { + @Override + public void choose() { + mState.setChoicePointIndex(OneOfCP.this, chosen); + } + + @Override + public RuleApp getRuleAppForBranch() { + return oldApp; + } + }; + } + + /** + * throws an unsupported operation exception + */ + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + + @Override + public Iterator getBranches(RuleApp oldApp) { + return new BranchIterator(oldApp); + } + } +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/SVInstantiationCP.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/SVInstantiationCP.java new file mode 100644 index 00000000000..87d7ca07ca9 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/SVInstantiationCP.java @@ -0,0 +1,125 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased.feature.instantiator; + +import java.util.Iterator; + +import org.key_project.logic.Name; +import org.key_project.logic.Term; +import org.key_project.logic.op.sv.SchemaVariable; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.ITacletApp; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.rules.Trigger; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.costbased.MutableState; +import org.key_project.prover.strategy.costbased.NumberRuleAppCost; +import org.key_project.prover.strategy.costbased.RuleAppCost; +import org.key_project.prover.strategy.costbased.feature.Feature; +import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; +import org.key_project.util.collection.ImmutableList; +import org.key_project.util.collection.ImmutableSet; + +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +/// Feature representing a `ChoicePoint` for instantiating a schema variable of a taclet +/// with the term that is returned by a `ProjectionToTerm`. This feature is useful in +/// particular combined with `ForEachCP`. Although the feature formally is a choice point, +/// it will always have exactly one branch +public class SVInstantiationCP> implements Feature { + private final @Nullable Name svToInstantiate; + private final ProjectionToTerm value; + + public static > Feature create(Name svToInstantiate, + ProjectionToTerm value) { + return new SVInstantiationCP(svToInstantiate, value); + } + + public static > Feature createTriggeredVarCP(ProjectionToTerm value) { + return new SVInstantiationCP(null, value); + } + + + private SVInstantiationCP(@Nullable Name svToInstantiate, ProjectionToTerm value) { + this.svToInstantiate = svToInstantiate; + this.value = value; + } + + @Override + public > RuleAppCost computeCost(RuleApp app, + PosInOccurrence pos, + Goal goal, MutableState mState) { + final BackTrackingManager manager = mState.getBacktrackingManager(); + manager.passChoicePoint(new CP(app, pos, (G) goal, mState), this); + return NumberRuleAppCost.getZeroCost(); + } + + private SchemaVariable findSVWithName(ITacletApp app) { + if (svToInstantiate == null) { + final Trigger trigger = app.taclet().getTrigger(); + assert trigger != null : "@AssumeAssertion(nullness): Trigger should not be null"; + return trigger.triggerVar(); + } + + final ImmutableSet vars = app.uninstantiatedVars(); + for (SchemaVariable svt : vars) { + if (svt.name().equals(svToInstantiate)) { + return svt; + } + } + + throw new IllegalArgumentException("Did not find schema variable " + svToInstantiate + + " that I was supposed to instantiate\n" + "(taclet " + app.taclet().name() + ")\n" + + "Either the name of the variable is wrong, or the variable\n" + + "has already been instantiated."); + } + + + private class CP implements ChoicePoint { + private final PosInOccurrence pos; + private final RuleApp app; + private final G goal; + private final MutableState mState; + + private CP(RuleApp app, PosInOccurrence pos, G goal, + MutableState mState) { + this.pos = pos; + this.app = app; + this.goal = goal; + this.mState = mState; + } + + @Override + public Iterator getBranches(RuleApp oldApp) { + if (!(oldApp instanceof final ITacletApp tapp)) { + // Debug.fail("Instantiation feature is only applicable to " + "taclet apps, but got + // ", + // oldApp); + throw new IllegalArgumentException( + "Rule application must be a taclet application, but is " + oldApp); + } + + final SchemaVariable sv = findSVWithName(tapp); + final Term instTerm = value.toTerm(app, pos, goal, mState); + assert instTerm != null : "@AssumeAssertion(nullness): Term should not be null"; + + final RuleApp newApp = + tapp.addCheckedInstantiation(sv, instTerm, + goal.proof().getServices(), true); + + final CPBranch branch = new CPBranch() { + @Override + public void choose() {} + + @Override + public RuleApp getRuleAppForBranch() { return newApp; } + }; + + return ImmutableList.singleton(branch).iterator(); + } + + } +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/AssumptionProjection.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/AssumptionProjection.java new file mode 100644 index 00000000000..a847308c5ec --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/AssumptionProjection.java @@ -0,0 +1,43 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased.termProjection; + +import org.key_project.logic.Term; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.ITacletApp; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.costbased.MutableState; +import org.key_project.prover.strategy.costbased.feature.StableCost; + +/// Term projection that delivers the assumptions of a taclet application (the formulas that the +/// \assumes clause of the taclet refers to). +@StableCost +public class AssumptionProjection> implements ProjectionToTerm { + + private final int no; + + private AssumptionProjection(int no) { + this.no = no; + } + + public static > ProjectionToTerm create(int no) { + return new AssumptionProjection(no); + } + + @Override + public Term toTerm(RuleApp app, PosInOccurrence pos, G goal, MutableState mutableState) { + assert app instanceof ITacletApp + : "Projection is only applicable to taclet apps," + " but got " + app; + final var tapp = (ITacletApp) app; + + assert tapp.assumesFormulaInstantiations() != null + : "Projection is only applicable to taclet apps with assumptions," + + " but got " + + app; + + return tapp.assumesFormulaInstantiations().skip(no).head().getSequentFormula().formula(); + } +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/ProjectionToTerm.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/ProjectionToTerm.java index 5aa7f3e58a2..11f1ccf93c4 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/ProjectionToTerm.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/ProjectionToTerm.java @@ -15,7 +15,7 @@ /// Interface for mappings from rule applications to terms. This is used, for instance, for /// determining the instantiation of a schema variable. We also allow projections to be partial, -/// which is signalled by toTerm returning null +/// which is signaled by `toTerm` returning `null` public interface ProjectionToTerm> extends CostClassifiable { @Nullable Term toTerm(RuleApp app, PosInOccurrence pos, Goal goal, MutableState mState); diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SVInstantiationProjection.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SVInstantiationProjection.java new file mode 100644 index 00000000000..c6bcf38d4ee --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SVInstantiationProjection.java @@ -0,0 +1,56 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased.termProjection; + +import org.key_project.logic.Name; +import org.key_project.logic.Term; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.ITacletApp; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.costbased.MutableState; +import org.key_project.prover.strategy.costbased.feature.StableCost; + +import org.jspecify.annotations.Nullable; + +/// Projection of taclet apps to the instantiation of a schema variable. The projection can either +/// be partial and undefined for those apps that do not instantiate the schema variable in +/// question, or it can raise an error for such applications +@StableCost +public class SVInstantiationProjection> implements ProjectionToTerm { + + private final Name svName; + private final boolean demandInst; + + private SVInstantiationProjection(Name svName, boolean demandInst) { + this.svName = svName; + this.demandInst = demandInst; + } + + public static > SVInstantiationProjection create(Name svName, + boolean demandInst) { + return new SVInstantiationProjection<>(svName, demandInst); + } + + @Override + public @Nullable Term toTerm(RuleApp app, PosInOccurrence pos, G goal, + MutableState mutableState) { + if (!(app instanceof final ITacletApp tapp)) { + throw new IllegalArgumentException( + "Projections can only be applied to taclet applications, not to " + app); + } + final Object instObj = tapp.instantiations().lookupValue(svName); + if (!(instObj instanceof Term instantiation)) { + if (demandInst) { + throw new IllegalArgumentException("Did not find schema variable " + svName + + " that I was supposed to examine" + " (taclet " + tapp.taclet().name() + ")"); + } + return null; + } + return instantiation; + } + + +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SubtermProjection.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SubtermProjection.java new file mode 100644 index 00000000000..ec511dff468 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SubtermProjection.java @@ -0,0 +1,39 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.prover.strategy.costbased.termProjection; + +import org.key_project.logic.PosInTerm; +import org.key_project.logic.Term; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.RuleApp; +import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.costbased.MutableState; +import org.key_project.prover.strategy.costbased.feature.StableCost; + +/// Projection for computing a subterm of a given term. The position of the subterm within the +/// complete term is described using a `PosInTerm`. +@StableCost +public class SubtermProjection> implements ProjectionToTerm { + private final PosInTerm pit; + private final ProjectionToTerm completeTerm; + + public static > ProjectionToTerm create( + ProjectionToTerm completeTerm, + PosInTerm pit) { + return new SubtermProjection(completeTerm, pit); + } + + private SubtermProjection(ProjectionToTerm completeTerm, PosInTerm pit) { + this.completeTerm = completeTerm; + this.pit = pit; + } + + @Override + public Term toTerm(RuleApp app, PosInOccurrence pos, G goal, MutableState mState) { + final Term completeTermInst = completeTerm.toTerm(app, pos, goal, mState); + assert completeTermInst != null : "@AssumeAssertion(nullness): Term should not be null"; + return pit.getSubTerm(completeTermInst); + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/termgenerator/RelevantSequentFormulasGenerator.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termgenerator/RelevantSequentFormulasGenerator.java similarity index 78% rename from key.core/src/main/java/de/uka/ilkd/key/strategy/termgenerator/RelevantSequentFormulasGenerator.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termgenerator/RelevantSequentFormulasGenerator.java index 996fc75432e..210f9df46af 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/termgenerator/RelevantSequentFormulasGenerator.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termgenerator/RelevantSequentFormulasGenerator.java @@ -2,16 +2,15 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.strategy.termgenerator; +package org.key_project.prover.strategy.costbased.termgenerator; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; -import de.uka.ilkd.key.proof.Goal; - import org.key_project.logic.Term; +import org.key_project.prover.proof.ProofGoal; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; import org.key_project.prover.sequent.Sequent; @@ -20,7 +19,6 @@ import org.key_project.prover.strategy.costbased.TopRuleAppCost; import org.key_project.prover.strategy.costbased.feature.VolatileCost; import org.key_project.prover.strategy.costbased.termfeature.TermFeature; -import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; import org.key_project.util.ConcurrentLruCache; import org.key_project.util.collection.ImmutableList; @@ -28,7 +26,8 @@ * Enumerates the formulas of the sequent that satisfy a term feature. */ @VolatileCost -public final class RelevantSequentFormulasGenerator implements TermGenerator { +public final class RelevantSequentFormulasGenerator> + implements TermGenerator { /** Specifies whether to iterate over all formulas or only one of those of one semisequent */ private enum SequentScope { @@ -51,7 +50,7 @@ private record Selection(Sequent sequent, ImmutableList formulas) { /** * Caching of selected formulas to be iterated over (second key for cache is in Selection) */ - private final Map selections = new ConcurrentLruCache<>(200); + private final Map selections = new ConcurrentLruCache<>(200); private RelevantSequentFormulasGenerator(SequentScope part, TermFeature accepted) { this.part = part; @@ -62,24 +61,27 @@ private RelevantSequentFormulasGenerator(SequentScope part, TermFeature accepted * @param filter the TermFeature used to filter the formulas of the sequent * @return the formulas of the sequent the feature accepts */ - public static RelevantSequentFormulasGenerator sequent(TermFeature filter) { - return new RelevantSequentFormulasGenerator(SequentScope.SEQUENT, filter); + public static > RelevantSequentFormulasGenerator sequent( + TermFeature filter) { + return new RelevantSequentFormulasGenerator<>(SequentScope.SEQUENT, filter); } /** * @param filter the TermFeature used to filter the formulas of the sequent * @return the formulas of the antecedent the feature accepts */ - public static RelevantSequentFormulasGenerator antecedent(TermFeature filter) { - return new RelevantSequentFormulasGenerator(SequentScope.ANTECEDENT, filter); + public static > RelevantSequentFormulasGenerator antecedent( + TermFeature filter) { + return new RelevantSequentFormulasGenerator<>(SequentScope.ANTECEDENT, filter); } /** * @param filter the TermFeature used to filter the formulas of the sequent * @return the formulas of the succedent the feature accepts */ - public static RelevantSequentFormulasGenerator succedent(TermFeature filter) { - return new RelevantSequentFormulasGenerator(SequentScope.SUCCEDENT, filter); + public static > RelevantSequentFormulasGenerator succedent( + TermFeature filter) { + return new RelevantSequentFormulasGenerator<>(SequentScope.SUCCEDENT, filter); } /** @@ -91,7 +93,7 @@ public static RelevantSequentFormulasGenerator succedent(TermFeature filter) { * @param mState the state the filter is evaluated in * @return the accepted formulas */ - public ImmutableList selection(Goal goal, MutableState mState) { + public ImmutableList selection(G goal, MutableState mState) { final Sequent sequent = goal.sequent(); final Selection cached = selections.get(goal); if (cached != null && cached.sequent() == sequent) { @@ -103,12 +105,12 @@ public ImmutableList selection(Goal goal, MutableState mState) { } @Override - public Iterator generate(RuleApp app, PosInOccurrence pos, Goal goal, + public Iterator generate(RuleApp app, PosInOccurrence pos, G goal, MutableState mState) { return selection(goal, mState).iterator(); } - private List select(Goal goal, MutableState mState) { + private List select(G goal, MutableState mState) { final var services = goal.proof().getServices(); final List formulas = new ArrayList<>(); final Iterable source = switch (part) { diff --git a/key.ncore/src/main/java/org/key_project/ldt/IIntLdt.java b/key.ncore/src/main/java/org/key_project/ldt/IIntLdt.java new file mode 100644 index 00000000000..d2c8a5f20e4 --- /dev/null +++ b/key.ncore/src/main/java/org/key_project/ldt/IIntLdt.java @@ -0,0 +1,29 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2, + * or (at your option) any later version. + * SPDX-License-Identifier: GPL-2.0-or-later */ +package org.key_project.ldt; + +import org.key_project.logic.op.Function; + +public interface IIntLdt { + Function getNumberSymbol(); + + Function getAdd(); + + Function getMul(); + + Function getMod(); + + Function getDiv(); + + Function getLessOrEquals(); + + Function getGreaterOrEquals(); + + Function getNegativeNumberSign(); + + Function getNumberLiteralFor(int i); + + Function getNumberTerminator(); +} diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/StrategySelectionView.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/StrategySelectionView.java index fdd61dd9e79..25ed0e73747 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/StrategySelectionView.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/StrategySelectionView.java @@ -30,7 +30,7 @@ import de.uka.ilkd.key.settings.StrategyPresetsSettings; import de.uka.ilkd.key.settings.StrategyPresetsSettings.StrategyPreset; import de.uka.ilkd.key.strategy.JavaCardDLStrategy; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import de.uka.ilkd.key.strategy.StrategyFactory; import de.uka.ilkd.key.strategy.StrategyProperties; import de.uka.ilkd.key.strategy.definition.AbstractStrategyPropertyDefinition; @@ -38,6 +38,8 @@ import de.uka.ilkd.key.strategy.definition.StrategyPropertyValueDefinition; import de.uka.ilkd.key.strategy.definition.StrategySettingsDefinition; +import org.key_project.prover.strategy.Strategy; + import org.jspecify.annotations.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,7 +58,7 @@ *

    * As future work this class should not show a fixed content defined by {@link #DEFINITION}. Instead * it should update the UI controls based on the currently active proof and its {@link Profile} - * since different {@link Profile}s support different {@link Strategy}s with different + * since different {@link Profile}s support different {@link JavaStrategy}s with different * {@link StrategyProperties}. For more information have a look at: * {@code http://i12www.ira.uka.de/~klebanov/mantis/view.php?id=1359} *

    diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/DefaultTacletMenuItem.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/DefaultTacletMenuItem.java index 45076342adc..579768625d4 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/DefaultTacletMenuItem.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/DefaultTacletMenuItem.java @@ -31,7 +31,7 @@ class DefaultTacletMenuItem extends JMenuItem implements TacletMenuItem { /** * creates TacletMenuItem attached to a Taclet * - * @param connectedTo the TacletApp that is represented by the item + * @param connectedTo the ITacletApp that is represented by the item * @param notationInfo the NotationInfo used to print terms */ public DefaultTacletMenuItem(TacletApp connectedTo, NotationInfo notationInfo, diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/InsertionTacletBrowserMenuItem.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/InsertionTacletBrowserMenuItem.java index e3e0d33ad36..c9ca1328443 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/InsertionTacletBrowserMenuItem.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/nodeviews/InsertionTacletBrowserMenuItem.java @@ -84,7 +84,7 @@ protected Collection createInsertionList() { * Adds a new taclet to be displayed by this component it is assumed that the app has been * tested before by {@link #isResponsible}. * - * @param app the TacletApp to be added + * @param app the ITacletApp to be added */ public void add(TacletApp app) { insertionTaclets.add(createListItem(app)); diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/properties/Properties.java b/key.util/src/main/java/org/key_project/util/Properties.java similarity index 97% rename from key.core/src/main/java/de/uka/ilkd/key/util/properties/Properties.java rename to key.util/src/main/java/org/key_project/util/Properties.java index d861f21e771..16e2dc3f5fd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/properties/Properties.java +++ b/key.util/src/main/java/org/key_project/util/Properties.java @@ -2,7 +2,7 @@ * KeY is licensed under the GNU General Public License Version 2, * or (at your option) any later version. * SPDX-License-Identifier: GPL-2.0-or-later */ -package de.uka.ilkd.key.util.properties; +package org.key_project.util; import java.util.concurrent.atomic.AtomicInteger; diff --git a/keyext.isabelletranslation/src/main/java/org/key_project/isabelletranslation/automation/IsabelleRule.java b/keyext.isabelletranslation/src/main/java/org/key_project/isabelletranslation/automation/IsabelleRule.java index 7ba50737d09..0404c47ebe6 100644 --- a/keyext.isabelletranslation/src/main/java/org/key_project/isabelletranslation/automation/IsabelleRule.java +++ b/keyext.isabelletranslation/src/main/java/org/key_project/isabelletranslation/automation/IsabelleRule.java @@ -4,11 +4,11 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ package org.key_project.isabelletranslation.automation; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.AbstractExternalSolverRuleApp; import de.uka.ilkd.key.rule.ExternalSolverRule; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.prover.rules.RuleApp; import org.key_project.prover.sequent.PosInOccurrence; @@ -46,7 +46,7 @@ public AbstractExternalSolverRuleApp createApp } @Override - public IsabelleRuleApp createApp(PosInOccurrence pos, TermServices services) { + public IsabelleRuleApp createApp(PosInOccurrence pos, LogicServices services) { return new IsabelleRuleApp(this, null, "", ""); } diff --git a/keyext.proofmanagement/src/main/java/org/key_project/proofmanagement/check/KeYFacade.java b/keyext.proofmanagement/src/main/java/org/key_project/proofmanagement/check/KeYFacade.java index 80ebc5e1d6c..c822483c112 100644 --- a/keyext.proofmanagement/src/main/java/org/key_project/proofmanagement/check/KeYFacade.java +++ b/keyext.proofmanagement/src/main/java/org/key_project/proofmanagement/check/KeYFacade.java @@ -30,7 +30,7 @@ import de.uka.ilkd.key.settings.Configuration; import de.uka.ilkd.key.speclang.Contract; import de.uka.ilkd.key.speclang.SLEnvInput; -import de.uka.ilkd.key.strategy.Strategy; +import de.uka.ilkd.key.strategy.JavaStrategy; import de.uka.ilkd.key.strategy.StrategyProperties; import de.uka.ilkd.key.util.ProgressMonitor; @@ -350,7 +350,7 @@ private static ReplayResult replayProof(CheckerData.ProofEntry line, EnvInput en .getActiveStrategyProperties(); newProps.setProperty(StrategyProperties.OSS_OPTIONS_KEY, StrategyProperties.OSS_ON); - Strategy.updateStrategySettings(proof, newProps); + JavaStrategy.updateStrategySettings(proof, newProps); OneStepSimplifier.refreshOSS(proof); // passing null is ok since ProblemLoader is only used for error reporting as origin @@ -386,7 +386,7 @@ private static ReplayResult replayProof(CheckerData.ProofEntry line, EnvInput en StrategyProperties newProps = proof.getSettings().getStrategySettings() .getActiveStrategyProperties(); newProps.setProperty(StrategyProperties.OSS_OPTIONS_KEY, ossStatus); - Strategy.updateStrategySettings(proof, newProps); + JavaStrategy.updateStrategySettings(proof, newProps); OneStepSimplifier.refreshOSS(proof); result = new ReplayResult(status, errors, lastTouchedNode);