From 77abc51ab2ef122f5669d3c6f74b04f734955db8 Mon Sep 17 00:00:00 2001 From: Richard Bubel Date: Thu, 12 Feb 2026 15:27:40 +0100 Subject: [PATCH 1/9] Moved ComponentStrategy to ncore --- ...repareInfFlowContractPreBranchesMacro.java | 2 +- .../SelfcompositionStateExpansionMacro.java | 8 +-- .../UseInformationFlowContractMacro.java | 6 +- .../InfFlowBlockContractInternalRule.java | 4 +- .../rule/InfFlowWhileInvariantRule.java | 5 +- .../rule/ModalitySideProofRule.java | 4 +- .../rule/QuerySideProofRule.java | 7 +- .../strategy/SimplifyTermStrategy.java | 7 +- .../strategy/SymbolicExecutionStrategy.java | 8 ++- .../util/SymbolicExecutionUtil.java | 6 +- .../ilkd/key/testgen/macros/TestGenMacro.java | 2 +- .../key/wd/macro/WellDefinednessMacro.java | 7 +- .../instantiation_model/TacletFindModel.java | 2 +- .../TacletInstantiationModel.java | 2 +- .../de/uka/ilkd/key/logic/VariableNamer.java | 2 +- .../key/macros/AbstractBlastingMacro.java | 7 +- .../AbstractPropositionalExpansionMacro.java | 11 ++-- .../de/uka/ilkd/key/macros/AutoMacro.java | 2 +- .../macros/AutoPilotPrepareProofMacro.java | 8 +-- .../uka/ilkd/key/macros/FilterStrategy.java | 7 +- .../macros/FinishSymbolicExecutionMacro.java | 6 +- ...SymbolicExecutionUntilMergePointMacro.java | 6 +- .../ilkd/key/macros/OneStepProofMacro.java | 7 +- .../ilkd/key/macros/StrategyProofMacro.java | 7 +- .../macros/TranscendentalFloatSMTMacro.java | 2 +- .../main/java/de/uka/ilkd/key/proof/Goal.java | 10 +-- .../java/de/uka/ilkd/key/proof/Proof.java | 2 +- .../de/uka/ilkd/key/proof/TacletAppIndex.java | 2 +- .../proof/delayedcut/DelayedCutProcessor.java | 2 +- .../key/proof/io/AbstractProblemLoader.java | 6 +- .../proof/replay/AbstractProofReplayer.java | 2 +- .../uka/ilkd/key/prover/impl/PerfScope.java | 6 +- .../rule/AbstractExternalSolverRuleApp.java | 1 + .../key/rule/AbstractLoopInvariantRule.java | 5 +- .../key/rule/BlockContractExternalRule.java | 4 +- .../key/rule/BlockContractInternalRule.java | 4 +- .../de/uka/ilkd/key/rule/BuiltInRule.java | 20 +----- .../rule/EqualityModuloProofIrrelevancy.java | 6 +- .../uka/ilkd/key/rule/ExternalSolverRule.java | 4 +- .../de/uka/ilkd/key/rule/IBuiltInRuleApp.java | 24 ++----- .../de/uka/ilkd/key/rule/JmlAssertRule.java | 3 +- .../uka/ilkd/key/rule/LoopApplyHeadRule.java | 4 +- .../key/rule/LoopContractExternalRule.java | 4 +- .../key/rule/LoopContractInternalRule.java | 4 +- .../de/uka/ilkd/key/rule/NoPosTacletApp.java | 10 +-- .../ilkd/key/rule/ObserverToUpdateRule.java | 4 +- .../uka/ilkd/key/rule/OneStepSimplifier.java | 6 +- .../de/uka/ilkd/key/rule/PosTacletApp.java | 8 +-- .../de/uka/ilkd/key/rule/QueryExpand.java | 3 +- .../uka/ilkd/key/rule/SetStatementRule.java | 3 +- .../java/de/uka/ilkd/key/rule/Taclet.java | 4 +- .../java/de/uka/ilkd/key/rule/TacletApp.java | 34 +++++----- .../key/rule/UseDependencyContractRule.java | 3 +- .../key/rule/UseOperationContractRule.java | 3 +- .../uka/ilkd/key/rule/WhileInvariantRule.java | 5 +- .../executor/javadl/AntecTacletExecutor.java | 2 +- .../executor/javadl/FindTacletExecutor.java | 2 +- .../rule/executor/javadl/TacletExecutor.java | 2 +- .../ilkd/key/rule/merge/CloseAfterMerge.java | 4 +- .../de/uka/ilkd/key/rule/merge/MergeRule.java | 4 +- .../de/uka/ilkd/key/scripts/SetCommand.java | 6 +- .../java/de/uka/ilkd/key/smt/SMTRule.java | 4 +- .../key/strategy/AbstractFeatureStrategy.java | 6 +- .../uka/ilkd/key/strategy/FIFOStrategy.java | 10 +-- .../de/uka/ilkd/key/strategy/FOLStrategy.java | 7 +- .../ilkd/key/strategy/IntegerStrategy.java | 8 ++- .../uka/ilkd/key/strategy/JFOLStrategy.java | 2 +- .../key/strategy/JFOLStrategyFactory.java | 3 +- .../ilkd/key/strategy/JavaCardDLStrategy.java | 7 +- .../uka/ilkd/key/strategy/JavaStrategy.java | 66 +++++++++++++++++++ .../key/strategy/ModularJavaDLStrategy.java | 15 +++-- .../ModularJavaDLStrategyFactory.java | 8 ++- .../strategy/QueueRuleApplicationManager.java | 2 +- .../strategy/ResponsibleStrategyCache.java | 53 ++++++++------- .../key/strategy/SimpleFilteredStrategy.java | 4 +- .../ilkd/key/strategy/StrategyFactory.java | 6 +- .../uka/ilkd/key/strategy/StringStrategy.java | 8 ++- .../uka/ilkd/key/strategy/SymExStrategy.java | 7 +- .../ilkd/key/strategy/TacletAppContainer.java | 4 +- .../IDefaultStrategyPropertiesFactory.java | 4 +- .../StrategySettingsDefinition.java | 4 +- .../feature/BinaryTacletAppFeature.java | 2 +- .../ilkd/key/util/HelperClassForTests.java | 4 +- .../de/uka/ilkd/key/util/ProofStarter.java | 2 +- .../performance/DataRecordingStrategy.java | 2 +- .../performance/DataRecordingTestFile.java | 2 +- .../de/uka/ilkd/key/rule/TestApplyTaclet.java | 14 ++-- .../ilkd/key/rule/TestCollisionResolving.java | 10 +-- .../prover/rules/IBuiltInRule.java | 29 ++++++++ .../prover/rules/IBuiltInRuleApp.java | 36 ++++++++++ .../key_project/prover/rules/ITacletApp.java | 31 +++++++++ .../prover}/strategy/ComponentStrategy.java | 15 ++--- .../strategy/RuleAppCostCollector.java | 2 +- .../prover}/strategy/Strategy.java | 42 ++---------- .../feature/RuleSetDispatchFeature.java | 11 ++-- .../uka/ilkd/key/gui/ApplyTacletDialog.java | 2 +- .../ilkd/key/gui/StrategySelectionView.java | 6 +- .../gui/nodeviews/DefaultTacletMenuItem.java | 2 +- .../InsertionTacletBrowserMenuItem.java | 2 +- .../automation/IsabelleRule.java | 4 +- .../proofmanagement/check/KeYFacade.java | 6 +- 101 files changed, 476 insertions(+), 327 deletions(-) create mode 100644 key.core/src/main/java/de/uka/ilkd/key/strategy/JavaStrategy.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRule.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRuleApp.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/rules/ITacletApp.java rename {key.core/src/main/java/de/uka/ilkd/key => key.ncore.calculus/src/main/java/org/key_project/prover}/strategy/ComponentStrategy.java (55%) rename {key.core/src/main/java/de/uka/ilkd/key => key.ncore.calculus/src/main/java/org/key_project/prover}/strategy/RuleAppCostCollector.java (93%) rename {key.core/src/main/java/de/uka/ilkd/key => key.ncore.calculus/src/main/java/org/key_project/prover}/strategy/Strategy.java (60%) rename {key.core/src/main/java/de/uka/ilkd/key/strategy => key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased}/feature/RuleSetDispatchFeature.java (91%) 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 614c72d103b..c8a18c337a8 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,12 +10,12 @@ 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 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; 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 3ba8e6f8571..51cc1b7a38c 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 @@ -62,7 +62,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()); } @@ -110,7 +110,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()); @@ -134,7 +134,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)) { @@ -154,7 +154,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 c29e48d2882..b495ea6e849 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 @@ -14,13 +14,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; @@ -166,7 +166,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/rule/InfFlowBlockContractInternalRule.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/InfFlowBlockContractInternalRule.java index 1fbee05a4d6..9ee7886a1ba 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 @@ -25,7 +25,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; @@ -43,6 +42,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; @@ -101,7 +101,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 cd4645f9955..20d85489797 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 @@ -32,6 +32,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; @@ -58,8 +59,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.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/rule/ModalitySideProofRule.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/rule/ModalitySideProofRule.java index 17ad88fed2f..1fdb515dccf 100644 --- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/rule/ModalitySideProofRule.java +++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/rule/ModalitySideProofRule.java @@ -10,7 +10,6 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.JTerm; import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.mgt.ProofEnvironment; @@ -20,6 +19,7 @@ import de.uka.ilkd.key.symbolic_execution.util.SymbolicExecutionSideProofUtil; import de.uka.ilkd.key.symbolic_execution.util.SymbolicExecutionUtil; +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; @@ -119,7 +119,7 @@ public boolean isApplicable(Goal goal, PosInOccurrence pio) { * {@inheritDoc} */ @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.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/rule/QuerySideProofRule.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/rule/QuerySideProofRule.java index 614dcb995db..ebe67383c14 100644 --- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/rule/QuerySideProofRule.java +++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/rule/QuerySideProofRule.java @@ -8,16 +8,15 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.JTerm; import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.TermServices; import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.mgt.ProofEnvironment; import de.uka.ilkd.key.rule.BuiltInRule; import de.uka.ilkd.key.rule.DefaultBuiltInRuleApp; import de.uka.ilkd.key.rule.IBuiltInRuleApp; -import de.uka.ilkd.key.rule.QueryExpand; import de.uka.ilkd.key.symbolic_execution.util.SymbolicExecutionSideProofUtil; +import org.key_project.logic.LogicServices; import org.key_project.logic.Name; import org.key_project.logic.op.Function; import org.key_project.logic.sort.Sort; @@ -150,7 +149,7 @@ public boolean isApplicable(Goal goal, PosInOccurrence pio) { /** * Checks if the query term is supported. The functionality is identical to - * {@link QueryExpand#isApplicable(Goal, PosInOccurrence)}. + * {@link BuiltInRule#isApplicable(org.key_project.prover.proof.ProofGoal, PosInOccurrence)}. * * @param goal The {@link Goal}. * @param pmTerm The {@link JTerm} to with the query to check. @@ -182,7 +181,7 @@ private boolean isApplicableQuery(Goal goal, JTerm pmTerm, * {@inheritDoc} */ @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.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SimplifyTermStrategy.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SimplifyTermStrategy.java index 5ad174975fd..a4b0b8f8454 100644 --- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SimplifyTermStrategy.java +++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SimplifyTermStrategy.java @@ -26,13 +26,13 @@ import org.jspecify.annotations.NonNull; /** - * {@link Strategy} used to simplify {@link JTerm}s in side proofs. + * {@link JavaStrategy} used to simplify {@link JTerm}s in side proofs. * * @author Martin Hentschel */ public class SimplifyTermStrategy extends JavaCardDLStrategy { /** - * The {@link Name} of the side proof {@link Strategy}. + * The {@link Name} of the side proof {@link JavaStrategy}. */ public static final Name name = new Name("Simplify Term Strategy"); @@ -100,7 +100,8 @@ public static class Factory implements StrategyFactory { * {@inheritDoc} */ @Override - public Strategy create(Proof proof, StrategyProperties sp) { + public org.key_project.prover.strategy.Strategy create(Proof proof, + StrategyProperties sp) { return new SimplifyTermStrategy(proof, sp); } diff --git a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java index 515695c1e7a..52249e74c99 100644 --- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java +++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java @@ -8,7 +8,7 @@ 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.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.IDefaultStrategyPropertiesFactory; @@ -27,23 +27,25 @@ import org.key_project.prover.proof.rulefilter.SetRuleFilter; 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.RuleAppCost; import org.key_project.prover.strategy.costbased.TopRuleAppCost; import org.key_project.prover.strategy.costbased.feature.BinaryFeature; 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.RuleSetDispatchFeature; import org.key_project.prover.strategy.costbased.feature.ScaleFeature; import org.key_project.prover.strategy.costbased.termProjection.TermBuffer; import org.jspecify.annotations.NonNull; /** - * {@link Strategy} to use for symbolic execution. + * {@link JavaStrategy} to use for symbolic execution. */ public class SymbolicExecutionStrategy extends JavaCardDLStrategy { /** - * The {@link Name} of the symbolic execution {@link Strategy}. + * The {@link Name} of the symbolic execution {@link JavaStrategy}. */ public static final Name name = new Name("Symbolic Execution Strategy"); diff --git a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionUtil.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionUtil.java index 724ce2bbe16..348d3e667c5 100644 --- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionUtil.java +++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionUtil.java @@ -46,8 +46,8 @@ import de.uka.ilkd.key.settings.StrategySettings; import de.uka.ilkd.key.speclang.Contract; import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.strategy.JavaStrategy; import de.uka.ilkd.key.strategy.ModularJavaDLStrategyFactory; -import de.uka.ilkd.key.strategy.Strategy; import de.uka.ilkd.key.strategy.StrategyProperties; import de.uka.ilkd.key.symbolic_execution.ExecutionVariableExtractor; import de.uka.ilkd.key.symbolic_execution.SymbolicExecutionTreeBuilder; @@ -2562,7 +2562,7 @@ private static JTerm computeTacletAppBranchCondition(Node parent, Node node, boo boolean improveReadability) throws ProofInputException { if (!(parent.getAppliedRuleApp() instanceof TacletApp app)) { throw new ProofInputException( - "Only TacletApp is allowed in branch computation but rule \"" + "Only ITacletApp is allowed in branch computation but rule \"" + parent.getAppliedRuleApp() + "\" was found."); } Services services = node.proof().getServices(); @@ -4312,7 +4312,7 @@ private static ImmutableArray extractValueFromUpdate( /** * Initializes the {@link Proof} of the given {@link SymbolicExecutionTreeBuilder} so that the - * correct {@link Strategy} is used. + * correct {@link JavaStrategy} is used. * * @param builder The {@link SymbolicExecutionTreeBuilder} to initialize. */ 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 ec31a6f59cb..d531c029cff 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 @@ -11,7 +11,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; @@ -19,6 +18,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 21bdf9cf3d8..e923507303c 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 @@ -9,8 +9,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.*; @@ -18,6 +17,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; @@ -95,7 +96,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 0e4e53a806b..44e24fe93c7 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 @@ -70,7 +70,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 429641df1a6..e7d67514292 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/logic/VariableNamer.java b/key.core/src/main/java/de/uka/ilkd/key/logic/VariableNamer.java index f1c099e78e9..696ffd72ada 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 @@ -432,7 +432,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 ec0be803f4f..4ea22bf24c3 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 @@ -25,8 +25,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; @@ -40,6 +39,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; @@ -203,7 +204,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 90bd501af19..6232da484a5 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 @@ -61,7 +61,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()); @@ -85,14 +85,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; @@ -134,7 +135,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 bad70679ffe..e8bbe7958b2 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 @@ -17,12 +17,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 81fac0efff8..29c3e231e60 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 @@ -71,10 +71,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(); @@ -139,7 +139,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); } @@ -151,7 +151,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 c2f8d7a1794..c88c7beb2a6 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 @@ -4,19 +4,20 @@ package de.uka.ilkd.key.macros; import de.uka.ilkd.key.proof.Goal; -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 c1ed41c7091..8d09c7a3196 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 @@ -6,13 +6,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; @@ -20,7 +21,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 3dd12582e8c..9b2b39a49f9 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 @@ -15,7 +15,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; @@ -26,6 +26,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; @@ -37,7 +38,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 989a4284d38..6f3230fdc49 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 @@ -5,13 +5,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; @@ -57,7 +58,7 @@ public String getDescription() { * */ - 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 2975e0c6344..a19d58f74ad 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 @@ -12,13 +12,14 @@ import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.prover.impl.ApplyStrategy; 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.ProverCore; 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; @@ -31,11 +32,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/TranscendentalFloatSMTMacro.java b/key.core/src/main/java/de/uka/ilkd/key/macros/TranscendentalFloatSMTMacro.java index 95a4bee2b5b..debee133e9b 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 @@ -8,9 +8,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 9a928dffa1b..7481066feae 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 @@ -22,7 +22,6 @@ 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; @@ -40,6 +39,7 @@ import org.key_project.prover.sequent.SequentChangeInfo; import org.key_project.prover.sequent.SequentFormula; import org.key_project.prover.strategy.RuleApplicationManager; +import org.key_project.prover.strategy.Strategy; import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; @@ -442,7 +442,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); @@ -450,11 +450,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 a6f5cab1498..2638d4b08e6 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 @@ -30,7 +30,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; @@ -39,6 +38,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.collection.ImmutableSLList; import org.key_project.util.lookup.Lookup; 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 659999ce94c..0d8bacf4cd8 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 @@ -432,7 +432,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 81d3d85e74a..a0c905aa5e4 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 167aff7270c..bf8591ffdd4 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 @@ -30,7 +30,7 @@ import de.uka.ilkd.key.settings.ProofIndependentSettings; 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 org.key_project.util.collection.Pair; @@ -724,7 +724,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); @@ -758,7 +758,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 b4071100ccf..172977e3129 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 @@ -217,7 +217,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 18cceba4682..9256e076389 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 @@ -45,9 +45,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 d6339059ebb..3875a11096d 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 @@ -3,6 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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 d06a048f02f..548b482c363 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 @@ -23,6 +23,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; @@ -157,8 +158,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 7e7bbd0f524..cf0b2d43de2 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 @@ -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.TermLabelState; import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.proof.Goal; @@ -24,6 +23,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; @@ -181,7 +181,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 e041d235090..6e03088067f 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 @@ -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.TermLabelState; import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.logic.op.ProgramVariable; @@ -21,6 +20,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; @@ -194,7 +194,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 cac17c592b7..c05482cda49 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 @@ -3,13 +3,11 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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; @@ -20,21 +18,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 daaef6ec02c..55501f8b217 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 @@ -457,13 +457,13 @@ public static int hashCodeModProofIrrelevancy(Taclet taclet) { } - // 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 9b7753aea5a..f108d937d54 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 @@ -3,9 +3,9 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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; @@ -27,7 +27,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 e1e9997ee47..3bad4336fd0 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 @@ -8,19 +8,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 @@ -34,18 +28,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 6c82cdcb85c..bbc7b04725b 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 @@ -18,6 +18,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; @@ -102,7 +103,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 903524a8dba..cc3dd304141 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 @@ -9,13 +9,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 f469f6aca9f..7c47bf44c38 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 @@ -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.TermLabelState; import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.logic.op.Transformer; @@ -25,6 +24,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; @@ -182,7 +182,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 213804a89b3..0d8c36d7c3b 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 @@ -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.TermLabelState; import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.proof.Goal; @@ -20,6 +19,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; @@ -254,7 +254,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 a9c311b91e4..3dccd54c40b 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 @@ -89,7 +89,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. @@ -128,7 +128,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}) @@ -137,7 +137,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, @@ -166,7 +166,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 @@ -224,7 +224,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 14c46fdac18..629c9499418 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 @@ -19,7 +19,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; @@ -33,6 +32,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; @@ -108,7 +108,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 c04e03ef185..d56e145be2b 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 @@ -12,7 +12,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; @@ -32,6 +31,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; @@ -268,7 +268,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; } @@ -724,7 +724,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 87b63623f94..60d1a116c38 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 @@ -93,7 +93,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) { @@ -148,11 +148,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, @@ -170,7 +170,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 f13302128c9..a0429d73537 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 @@ -21,6 +21,7 @@ import de.uka.ilkd.key.rule.tacletbuilder.RewriteTacletBuilder; 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; @@ -669,7 +670,7 @@ public Long getTimeOfQuery(JTerm t) { } @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 4dc0db593d0..407bca5aacb 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 @@ -15,6 +15,7 @@ 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; @@ -70,7 +71,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 6c2660bd593..ee791db1b22 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 @@ -53,7 +53,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
*
@@ -75,7 +75,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 2a4a5d389e9..d6311d95e4e 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 @@ -29,7 +29,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.*; @@ -38,7 +38,7 @@ import org.jspecify.annotations.Nullable; /** - * 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
  • @@ -48,7 +48,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(); @@ -82,7 +82,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); @@ -406,7 +406,7 @@ protected ImmutableSet calculateNonInstantiatedSV() { * @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) { @@ -478,7 +478,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); @@ -714,7 +714,7 @@ && uninstantiatedVars().isEmpty() } /** - * 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 @@ -931,18 +931,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) { @@ -961,7 +962,7 @@ public boolean assumesInstantionsComplete() { } /** - * 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 @@ -996,12 +997,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; @@ -1018,7 +1020,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 8c30fb92ed2..fda2166fb49 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 @@ -24,6 +24,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; @@ -594,7 +595,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 5daaa777ad5..d1f82d8cecd 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 @@ -33,6 +33,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; @@ -544,7 +545,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 bae9c49e129..f602a3913f8 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 @@ -29,6 +29,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; @@ -129,8 +130,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 4433601b9d8..3523e83e2f8 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 @@ -70,7 +70,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 5f10ae4312e..85bab724f9f 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 @@ -168,7 +168,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 c01f777c4db..5fb231f091b 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 @@ -178,7 +178,7 @@ protected void applyAddrule(ImmutableList 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/AbstractFeatureStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/AbstractFeatureStrategy.java index 0da58226050..64c77d25502 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/AbstractFeatureStrategy.java @@ -7,7 +7,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; @@ -25,6 +24,7 @@ import org.key_project.prover.strategy.costbased.TopRuleAppCost; 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.RuleSetDispatchFeature; import org.key_project.prover.strategy.costbased.feature.instantiator.BackTrackingManager; import org.key_project.prover.strategy.costbased.termProjection.ProjectionToTerm; import org.key_project.prover.strategy.costbased.termProjection.TermBuffer; @@ -36,7 +36,7 @@ import org.jspecify.annotations.NonNull; public abstract class AbstractFeatureStrategy extends StaticFeatureCollection - implements Strategy { + implements JavaStrategy { private final Proof proof; @@ -117,7 +117,7 @@ protected void clearRuleSetBindings(RuleSetDispatchFeature d, String ruleSet) { @Override public void instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, - RuleAppCostCollector collector) { + org.key_project.prover.strategy.RuleAppCostCollector collector) { final MutableState mState = new MutableState(); final BackTrackingManager btManager = mState.getBacktrackingManager(); btManager.setup(app); 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 9aaac0ef5a5..11e08eff6e0 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 @@ -21,7 +21,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"); @@ -57,14 +57,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 @@ -73,7 +74,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 2d0680f0089..be09c621037 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 @@ -11,7 +11,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.*; @@ -28,9 +27,11 @@ 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.ComponentStrategy; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.TopRuleAppCost; @@ -48,7 +49,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 AbstractFeatureStrategy implements ComponentStrategy { public static final Name NAME = new Name("FOL Strategy"); protected final StrategyProperties strategyProperties; @@ -621,7 +622,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/IntegerStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategy.java index 85da5d6c654..fed278e1022 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategy.java @@ -12,7 +12,6 @@ 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; @@ -23,14 +22,17 @@ 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.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.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.RuleSetDispatchFeature; 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.termfeature.TermFeature; @@ -45,7 +47,7 @@ /// and Gröbner basis. /// /// Do not create directly, instead use [IntegerStrategyFactory]. -public class IntegerStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class IntegerStrategy extends AbstractFeatureStrategy implements ComponentStrategy { public static final Name NAME = new Name("Integer Strategy"); @@ -1034,7 +1036,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/JFOLStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JFOLStrategy.java index fa596fc1f9f..490fba79421 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 @@ -6,12 +6,12 @@ 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; 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 888b9962685..0a30ea974b7 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 @@ -36,7 +36,8 @@ public class JFOLStrategyFactory implements StrategyFactory { + "might cause proof splitting." + ""; @Override - public Strategy<@NonNull Goal> create(Proof proof, StrategyProperties strategyProperties) { + public org.key_project.prover.strategy.Strategy<@NonNull Goal> create(Proof proof, + StrategyProperties strategyProperties) { return new JFOLStrategy(proof, strategyProperties); } 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 afe6e7bdeaa..de8ed39d82a 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 @@ -11,7 +11,6 @@ import de.uka.ilkd.key.ldt.LocSetLDT; 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.*; @@ -22,9 +21,11 @@ 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.ComponentStrategy; import org.key_project.prover.strategy.costbased.MutableState; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.TopRuleAppCost; @@ -38,7 +39,7 @@ /// strategy. /// /// Do not create directly, instead use [JavaCardDLStrategyFactory]. -public class JavaCardDLStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class JavaCardDLStrategy extends AbstractFeatureStrategy 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(); @@ -571,7 +572,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/JavaStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaStrategy.java new file mode 100644 index 00000000000..6d03b495d79 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaStrategy.java @@ -0,0 +1,66 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.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.RuleApp; +import org.key_project.prover.rules.RuleSet; +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.RuleAppCost; + + +/** + * Generic interface for evaluating the cost of a RuleApp with regard to a specific strategy + */ +public interface JavaStrategy extends Strategy { + /** + * Evaluate the cost of a RuleApp. Starts a new independent computation. + * + * @param app the RuleApp + * @param pos position where app is to be applied + * @param goal the goal on which app is to be applied + * @return the cost of the rule application expressed as a + * RuleAppCost object. TopRuleAppCost.INSTANCE + * indicates that the rule shall not be applied at all (it is discarded by + * the strategy). + */ + @Override + default RuleAppCost computeCost(RuleApp app, PosInOccurrence pos, Goal goal) { + return computeCost(app, pos, goal, new MutableState()); + } + + /** + * 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; } + + @Override + default RuleAppCost instantiateApp(RuleApp app, PosInOccurrence pio, + Goal goal, MutableState mState) { + return null; + } +} 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 2bb30c59d34..e05aac3840c 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 @@ -9,11 +9,9 @@ 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.AgeFeature; 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; @@ -46,7 +47,7 @@ public class ModularJavaDLStrategy extends AbstractFeatureStrategy { 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; @@ -55,7 +56,7 @@ public class ModularJavaDLStrategy extends AbstractFeatureStrategy { private final ResponsibleStrategyCache responsibleStrategyCache; - public ModularJavaDLStrategy(Proof proof, List componentStrategies, + public ModularJavaDLStrategy(Proof proof, List> componentStrategies, StrategyProperties properties) { super(proof); strategies.addAll(componentStrategies); @@ -202,7 +203,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) { @@ -232,10 +233,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 a356f1b00e2..f54d4f1f28e 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 @@ -17,6 +17,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; @@ -122,9 +123,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 ff7fbb523af..a18e74d9dfe 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 @@ -32,7 +32,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)}). */ @NullMarked 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 0d09a23b5d7..d0037c8c6cd 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 @@ -5,35 +5,37 @@ import java.util.*; +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 - private final Map> costRuleToStrategyMap = - new LinkedHashMap>(); - private final Map> instantiationRuleToStrategyMap = - new LinkedHashMap>(); - private final Map> approvalRuleToStrategyMap = - new LinkedHashMap>(); - private final Map nameToStrategyMap = - new HashMap(); + private final Map>> costRuleToStrategyMap = + new LinkedHashMap>>(); + private final Map>> instantiationRuleToStrategyMap = + new LinkedHashMap>>(); + private final Map>> approvalRuleToStrategyMap = + new LinkedHashMap>>(); + 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); @@ -45,9 +47,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) { @@ -57,7 +59,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; @@ -67,7 +69,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; @@ -76,10 +79,10 @@ 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); - LinkedHashSet strats = ruleToStrategyMap.get(rule); + LinkedHashSet> strats = ruleToStrategyMap.get(rule); if (strats == null) { strats = new LinkedHashSet<>(); if (rule instanceof BuiltInRule bir) { @@ -90,11 +93,11 @@ public LinkedHashSet getResponsibleStrategies(Rule rule, } } else { var ruleSets = rule.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); } 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 7c20b783df1..97c8c31249b 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 @@ -24,7 +24,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"); @@ -90,7 +90,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/StrategyFactory.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/StrategyFactory.java index fa6196d726a..1b9ce3a3514 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 @@ -24,11 +24,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 06600a5cdbb..904f503d7c8 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 @@ -12,17 +12,19 @@ import de.uka.ilkd.key.logic.op.SortDependingFunction; 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.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,7 +34,7 @@ /// Strategy for string related rules. /// /// Do not create directly; use [StringStrategyFactory] instead. -public class StringStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class StringStrategy extends AbstractFeatureStrategy implements ComponentStrategy { public static final Name NAME = new Name("String Strategy"); /// The features defining the three phases: cost computation, approval, @@ -205,7 +207,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 d4c55df36d5..e2edca94b5b 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 @@ -17,13 +17,16 @@ 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.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.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; @@ -32,7 +35,7 @@ /// Strategy for symbolic execution rules. /// /// Do not create directly. Use [SymExStrategyFactory] instead. -public class SymExStrategy extends AbstractFeatureStrategy implements ComponentStrategy { +public class SymExStrategy extends AbstractFeatureStrategy implements ComponentStrategy { public static final Name NAME = new Name("SymExStrategy"); private final FormulaTermFeatures ff; @@ -267,7 +270,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 22282daa683..865b50bc510 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 @@ -132,7 +132,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; } @@ -214,7 +214,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 c8a7e9899b6..bdceed2be33 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 @@ -3,12 +3,12 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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 af4ca3ab930..ac1f0e150c1 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 @@ -6,7 +6,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; @@ -23,7 +23,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/BinaryTacletAppFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BinaryTacletAppFeature.java index 1aa0f1108db..51631c47470 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 @@ -47,7 +47,7 @@ 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 diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/HelperClassForTests.java b/key.core/src/main/java/de/uka/ilkd/key/util/HelperClassForTests.java index 260b9674042..2c026da04b2 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/HelperClassForTests.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/HelperClassForTests.java @@ -25,7 +25,7 @@ import de.uka.ilkd.key.settings.ChoiceSettings; import de.uka.ilkd.key.settings.ProofSettings; import de.uka.ilkd.key.speclang.Contract; -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.ImmutableList; @@ -138,7 +138,7 @@ public static void setOneStepSimplificationEnabled(Proof proof, boolean enabled) proof.getSettings().getStrategySettings().getActiveStrategyProperties(); newProps.setProperty(StrategyProperties.OSS_OPTIONS_KEY, newVal); - Strategy.updateStrategySettings(proof, newProps); + JavaStrategy.updateStrategySettings(proof, newProps); OneStepSimplifier.refreshOSS(proof); } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/ProofStarter.java b/key.core/src/main/java/de/uka/ilkd/key/util/ProofStarter.java index aa5bcaa2884..70f09ddf693 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/ProofStarter.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/ProofStarter.java @@ -18,7 +18,6 @@ import de.uka.ilkd.key.proof.mgt.ProofEnvironment; import de.uka.ilkd.key.prover.impl.ApplyStrategy; import de.uka.ilkd.key.rule.OneStepSimplifier; -import de.uka.ilkd.key.strategy.Strategy; import de.uka.ilkd.key.strategy.StrategyFactory; import de.uka.ilkd.key.strategy.StrategyProperties; @@ -27,6 +26,7 @@ import org.key_project.prover.engine.ProverTaskListener; 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.collection.ImmutableSLList; diff --git a/key.core/src/test/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingStrategy.java b/key.core/src/test/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingStrategy.java index 9af8750195a..d4723f0fec6 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingStrategy.java +++ b/key.core/src/test/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingStrategy.java @@ -8,11 +8,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/test/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingTestFile.java b/key.core/src/test/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingTestFile.java index 1481b332aee..0122cb5e81a 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingTestFile.java +++ b/key.core/src/test/java/de/uka/ilkd/key/proof/runallproofs/performance/DataRecordingTestFile.java @@ -15,9 +15,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.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 9e0c5b0d422..c0ecdcb5e7a 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 @@ -355,8 +355,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, @@ -393,7 +393,7 @@ public void testNoFindTacletWithoutIf() { @Test public void testIncompleteNoFindTacletApp() { NoPosTacletApp cut = TacletForTests.getRules().lookup("TestApplyTaclet_cut"); - assertFalse(cut.complete(), "TacletApp should not be complete, as b is not instantiated"); + assertFalse(cut.complete(), "ITacletApp should not be complete, as b is not instantiated"); SchemaVariable b = TacletForTests.getSchemaVariables().lookup(new Name("b")); assertTrue(cut.uninstantiatedVars().contains(b), "b should be in the set of not instantiated SVs"); @@ -403,7 +403,7 @@ public void testIncompleteNoFindTacletApp() { public void testIncompleteSuccTacletApp() { TacletApp orright = TacletForTests.getRules().lookup("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")); @@ -413,14 +413,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 381b8b05b8b..a0f0f4aaad0 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 @@ -235,12 +235,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(), @@ -315,10 +315,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.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..90c4c37cffa --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRule.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 + * SPDX-License-Identifier: GPL-2.0-only */ +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..e616659de6c --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/IBuiltInRuleApp.java @@ -0,0 +1,36 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.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..0e9d6951d3c --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/rules/ITacletApp.java @@ -0,0 +1,31 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.prover.rules; + +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.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(); +} 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 55% 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 c68ef3ab5ab..d580e260331 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 @@ -1,17 +1,16 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.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; -public interface ComponentStrategy extends Strategy { +public interface ComponentStrategy> extends Strategy { enum StrategyAspect { Cost, Instantiation, Approval; } @@ -22,7 +21,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.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 a4731236ff7..4173604d0c7 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 @@ -1,7 +1,7 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.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.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 60% 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 6d1c1fd1900..1ff614f9c02 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 @@ -1,11 +1,7 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.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; @@ -18,11 +14,6 @@ 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. @@ -35,9 +26,7 @@ public interface Strategy> extends Named, * indicates that the rule shall not be applied at all (it is discarded by * the strategy). */ - default RuleAppCost computeCost(RuleApp app, PosInOccurrence pos, Goal goal) { - return computeCost(app, pos, goal, new MutableState()); - } + RuleAppCost computeCost(RuleApp app, PosInOccurrence pos, Goal goal); /** * Checks if the {@link Strategy} should stop at the first non-closeable {@link Goal}. @@ -64,29 +53,8 @@ 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; - } + RuleAppCost instantiateApp(RuleApp app, PosInOccurrence pio, + Goal goal, MutableState mState); } 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 91% 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 4b41c75ff2b..e90109c675f 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 @@ -1,15 +1,14 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.strategy.feature; +package org.key_project.prover.strategy.costbased.feature; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; -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.sequent.PosInOccurrence; @@ -17,8 +16,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.SumFeature; import org.key_project.util.collection.ImmutableList; import org.jspecify.annotations.NonNull; @@ -42,12 +39,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(); - ImmutableList ruleSetsOfAppliedTaclet = ((TacletApp) app).taclet().getRuleSets(); + ImmutableList ruleSetsOfAppliedTaclet = tapp.taclet().getRuleSets(); /* * do not use iterator here, as this method is called a lot when proving such that avoiding * object creation helps to reduce the load put on the garbage collector diff --git a/key.ui/src/main/java/de/uka/ilkd/key/gui/ApplyTacletDialog.java b/key.ui/src/main/java/de/uka/ilkd/key/gui/ApplyTacletDialog.java index 5a8728ee6cf..f1744d03986 100644 --- a/key.ui/src/main/java/de/uka/ilkd/key/gui/ApplyTacletDialog.java +++ b/key.ui/src/main/java/de/uka/ilkd/key/gui/ApplyTacletDialog.java @@ -109,7 +109,7 @@ protected JPanel createInfoPanel() { protected JPanel createTacletDisplay() { JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(new TitledBorder("Selected Taclet - " + model[0].taclet().name())); - LOGGER.debug("TacletApp: {}", model[0].taclet()); + LOGGER.debug("ITacletApp: {}", model[0].taclet()); Taclet taclet = model[0].taclet(); StringBuilder tacletSB = new StringBuilder(); 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 37141d6090e..c3dc89ed468 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 @@ -22,11 +22,13 @@ import de.uka.ilkd.key.proof.init.Profile; import de.uka.ilkd.key.settings.ProofSettings; 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.*; +import org.key_project.prover.strategy.Strategy; + import org.jspecify.annotations.NonNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +47,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 0096566ec05..15633e281b0 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 @@ -30,7 +30,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 39e8faaddbf..f3c06bada96 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 @@ -83,7 +83,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/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 dbd67ed6c5e..5656542be38 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 @@ -3,11 +3,11 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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; @@ -45,7 +45,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 6ccf66aed57..cf5d70720ad 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 @@ -29,7 +29,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; @@ -348,7 +348,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 @@ -384,7 +384,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); From fef3051f4fc578d1f566130c26fa92c698bd8a34 Mon Sep 17 00:00:00 2001 From: Richard Bubel Date: Thu, 12 Feb 2026 16:07:27 +0100 Subject: [PATCH 2/9] Fix non-null annotations --- .../costbased/feature/RuleSetDispatchFeature.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java index e90109c675f..d40bcf5e31d 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java @@ -18,7 +18,9 @@ import org.key_project.prover.strategy.costbased.TopRuleAppCost; import org.key_project.util.collection.ImmutableList; +import org.checkerframework.checker.nullness.qual.KeyFor; import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; /** @@ -29,9 +31,9 @@ */ public class RuleSetDispatchFeature implements Feature { - private final Map rulesetToFeature = new LinkedHashMap<>(); + private final Map<@NonNull RuleSet, @NonNull Feature> rulesetToFeature = new LinkedHashMap<>(); - public Set ruleSets() { + public Set<@KeyFor("this.rulesetToFeature") RuleSet> ruleSets() { return rulesetToFeature.keySet(); } @@ -94,7 +96,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); } @@ -105,7 +107,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) { return rulesetToFeature.remove(ruleSet); } } From a0bb49a3b0e0867bdad04ccc59c99bee89d3994a Mon Sep 17 00:00:00 2001 From: Richard Bubel Date: Thu, 12 Feb 2026 16:53:59 +0100 Subject: [PATCH 3/9] Moved up some features and slightly generalized others --- .../strategy/SymbolicExecutionStrategy.java | 2 +- .../java/de/uka/ilkd/key/rule/TacletApp.java | 3 ++- .../ilkd/key/strategy/IntroducedSymbolBy.java | 5 ++++- .../feature/BinaryTacletAppFeature.java | 2 +- .../strategy/feature/CheckApplyEqFeature.java | 5 ++++- .../strategy/feature/DiffFindAndIfFeature.java | 5 ++++- .../feature/DiffFindAndReplacewithFeature.java | 17 +++++++++++------ .../feature/EqNonDuplicateAppFeature.java | 4 +++- .../strategy/feature/MatchedAssumesFeature.java | 5 ++++- .../feature/NoSelfApplicationFeature.java | 5 ++++- .../feature/NonDuplicateAppFeature.java | 7 ++++--- .../feature/PolynomialValuesCmpFeature.java | 5 +++-- .../feature/TriggerVarInstantiatedFeature.java | 5 ++++- .../key_project/prover/rules/ITacletApp.java | 14 ++++++++++++++ .../costbased}/feature/CountBranchFeature.java | 6 ++---- 15 files changed, 65 insertions(+), 25 deletions(-) rename {key.core/src/main/java/de/uka/ilkd/key/strategy => key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased}/feature/CountBranchFeature.java (91%) diff --git a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java index 52249e74c99..b297b3b05da 100644 --- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java +++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java @@ -15,7 +15,6 @@ import de.uka.ilkd.key.strategy.definition.OneOfStrategyPropertyDefinition; import de.uka.ilkd.key.strategy.definition.StrategyPropertyValueDefinition; import de.uka.ilkd.key.strategy.definition.StrategySettingsDefinition; -import de.uka.ilkd.key.strategy.feature.*; import de.uka.ilkd.key.strategy.feature.instantiator.OneOfCP; import de.uka.ilkd.key.strategy.termProjection.FocusProjection; import de.uka.ilkd.key.symbolic_execution.rule.ModalitySideProofRule; @@ -33,6 +32,7 @@ import org.key_project.prover.strategy.costbased.TopRuleAppCost; import org.key_project.prover.strategy.costbased.feature.BinaryFeature; import org.key_project.prover.strategy.costbased.feature.ConditionalFeature; +import org.key_project.prover.strategy.costbased.feature.CountBranchFeature; 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.ScaleFeature; 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 d6311d95e4e..cac58cd8f4a 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 @@ -440,11 +440,11 @@ 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(); } - /** * returns true if the given {@link SchemaVariable} must be explicitly instantiated it does not * check whether sv is already instantiated or not @@ -957,6 +957,7 @@ 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(); } 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 479da221106..d49ba7076ca 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 @@ -17,6 +17,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; @@ -37,7 +39,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/feature/BinaryTacletAppFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/BinaryTacletAppFeature.java index 51631c47470..fe37b23ce61 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 @@ -51,7 +51,7 @@ protected BinaryTacletAppFeature(boolean p_nonTacletValue) { * @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/CheckApplyEqFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/CheckApplyEqFeature.java index 6cf5302230b..9af69d855c2 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 @@ -15,6 +15,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; + /** * 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 @@ -27,7 +29,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 2a212b123a0..a31c09aaf46 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 @@ -14,6 +14,8 @@ import org.key_project.prover.strategy.costbased.feature.Feature; 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 @@ -27,7 +29,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 3a26d98cce0..ec521057ee0 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 @@ -14,6 +14,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; + import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; /** @@ -28,15 +30,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 11226b0a9be..306c97387c6 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 @@ -10,6 +10,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. @@ -24,7 +26,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/MatchedAssumesFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/MatchedAssumesFeature.java index d712c639ec5..7548c1b8304 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 @@ -10,6 +10,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 features that returns zero iff the if-formulas of a Taclet are instantiated or the Taclet * does not have any if-formulas. @@ -21,7 +23,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/NoSelfApplicationFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/NoSelfApplicationFeature.java index 4b9d1c21a48..45d24b20189 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 @@ -12,6 +12,8 @@ import org.key_project.prover.strategy.costbased.feature.Feature; 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. @@ -23,7 +25,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 a3fee055c1c..e7591cfd7ce 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 @@ -10,6 +10,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 @@ -19,7 +21,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; @@ -30,8 +32,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 02fbda9781b..ffbcce586b3 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 @@ -103,8 +103,9 @@ protected boolean compare(Polynomial leftPoly, Polynomial rightPoly) { @Override protected boolean filter(TacletApp app, PosInOccurrence pos, Goal goal, MutableState mState) { - return compare(getPolynomial(left, leftCoeff, app, pos, goal, mState), - getPolynomial(right, rightCoeff, app, pos, goal, mState)); + final TacletApp tacletApp = (TacletApp) app; + return compare(getPolynomial(left, leftCoeff, tacletApp, pos, goal, mState), + getPolynomial(right, rightCoeff, tacletApp, pos, goal, mState)); } protected abstract boolean compare(Polynomial leftPoly, Polynomial rightPoly); diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/TriggerVarInstantiatedFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/TriggerVarInstantiatedFeature.java index 7f0eb989ef4..be363d63fb2 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/TriggerVarInstantiatedFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/TriggerVarInstantiatedFeature.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; + public class TriggerVarInstantiatedFeature extends BinaryTacletAppFeature { public static final Feature INSTANCE = new TriggerVarInstantiatedFeature(); @@ -19,7 +21,8 @@ private TriggerVarInstantiatedFeature() { } @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 app.taclet().hasTrigger(); SVInstantiationProjection instProj = SVInstantiationProjection 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 index 0e9d6951d3c..7f1bfa6d2a9 100644 --- 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 @@ -3,10 +3,12 @@ * SPDX-License-Identifier: GPL-2.0-only */ package org.key_project.prover.rules; +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; @@ -28,4 +30,16 @@ default SVInstantiations instantiations() { 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(); } 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 1a95450ac3d..a15984aea2b 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 @@ -1,17 +1,15 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.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; From 8e8c6c1a2d523863ddccc2b6cbe73e2d1f45d969 Mon Sep 17 00:00:00 2001 From: Drodt Date: Fri, 5 Jun 2026 14:12:04 +0200 Subject: [PATCH 4/9] IntegerStrat in ncore --- .../java/de/uka/ilkd/key/rule/TacletApp.java | 5 + .../key/strategy/StaticFeatureCollection.java | 1 + .../key_project/prover/rules/ITacletApp.java | 5 + .../strategy/AbstractFeatureStrategy.java | 77 ++ .../prover/strategy/ArithTermFeatures.java | 137 ++ .../prover/strategy/ComponentStrategy.java | 2 +- .../prover/strategy/FeatureConstants.java | 30 + .../prover/strategy/FormulaTermFeatures.java | 60 + .../prover/strategy/IntegerStrategy.java | 1121 +++++++++++++++++ .../strategy/StaticFeatureCollection.java | 293 +++++ .../feature/BinaryTacletAppFeature.java | 49 + .../feature/ComprehendedSumFeature.java | 3 +- .../feature/InstantiatedSVFeature.java | 33 + .../feature/instantiator/ForEachCP.java | 130 ++ .../feature/instantiator/OneOfCP.java | 85 ++ .../instantiator/SVInstantiationCP.java | 120 ++ .../termProjection/AssumptionProjection.java | 40 + .../termProjection/ProjectionToTerm.java | 2 +- .../SVInstantiationProjection.java | 48 + .../termProjection/SubtermProjection.java | 34 + .../java/org/key_project/ldt/IIntLdt.java | 28 + 21 files changed, 2299 insertions(+), 4 deletions(-) create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/AbstractFeatureStrategy.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FeatureConstants.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FormulaTermFeatures.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/StaticFeatureCollection.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/BinaryTacletAppFeature.java rename {key.core/src/main/java/de/uka/ilkd/key/strategy => key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased}/feature/ComprehendedSumFeature.java (95%) create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/InstantiatedSVFeature.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/ForEachCP.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/OneOfCP.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/SVInstantiationCP.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/AssumptionProjection.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SVInstantiationProjection.java create mode 100644 key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SubtermProjection.java create mode 100644 key.ncore/src/main/java/org/key_project/ldt/IIntLdt.java 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 d1722a421e2..9212b1a8dc2 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 @@ -416,6 +416,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. 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 2581326631f..f5144f91a34 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 @@ -11,6 +11,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; 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 index 7f1bfa6d2a9..435014a5006 100644 --- 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 @@ -3,6 +3,8 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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; @@ -42,4 +44,7 @@ default SVInstantiations instantiations() { */ @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..ef0d3872f56 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/AbstractFeatureStrategy.java @@ -0,0 +1,77 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.prover.strategy; + +import org.key_project.logic.Name; +import org.key_project.prover.proof.ProofGoal; +import org.key_project.prover.rules.RuleSet; +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.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); +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java new file mode 100644 index 00000000000..28a84a18f67 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java @@ -0,0 +1,137 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.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; + +public class ArithTermFeatures extends StaticFeatureCollection { + final Sort intS; + + final Function Z; + final Function add; + final Function mul; + final Function mod; + final Function div; + + 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 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 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 intRelation; + + final TermFeature notContainsProduct; + final TermFeature notContainsDivMod; + + public ArithTermFeatures(IIntLdt numbers, Operator eq) { + Z = numbers.getNumberSymbol(); + + add = numbers.getAdd(); + mul = numbers.getMul(); + mod = numbers.getMod(); + div = numbers.getDiv(); + + this.eq = eq; + leq = numbers.getLessOrEquals(); + geq = numbers.getGreaterOrEquals(); + + intS = numbers.getNumberSymbol().sort(); + + intF = extendsTrans(intS); + + addF = op(add); + mulF = op(mul); + modF = op(mod); + divF = op(div); + + eqF = op(eq); + geqF = op(geq); + leqF = op(leq); + + literal = op(Z); + negLiteral = opSub(Z, op(numbers.getNegativeNumberSign())); + nonNegLiteral = opSub(Z, not(op(numbers.getNegativeNumberSign()))); + zeroLiteral = + opSub(Z, opSub(numbers.getNumberLiteralFor(0), op(numbers.getNumberTerminator()))); + oneLiteral = + opSub(Z, opSub(numbers.getNumberLiteralFor(1), op(numbers.getNumberTerminator()))); + nonPosLiteral = or(zeroLiteral, negLiteral); + posLiteral = add(nonNegLiteral, not(zeroLiteral)); + atLeastTwoLiteral = add(posLiteral, not(oneLiteral)); + + constant = constantTermFeature(); + + atom = add(not(addF), not(mulF)); + linearMonomial = or(atom, opSub(mul, atom, literal)); + + // left-associatively arranged monomials, literals are only allowed + // as right-most term + monomial = or(atom, opSub(mul, + rec(mulF, or(opSub(mul, any(), not(mulF)), add(not(addF), not(literal)))), atom)); + + // left-associatively arranged polynomials + polynomial = rec(addF, or(opSub(add, any(), not(addF)), monomial)); + + nonNegMonomial = add(monomial, or(not(mulF), sub(any(), not(negLiteral)))); + posMonomial = opSub(mul, monomial, posLiteral); + negMonomial = opSub(mul, monomial, negLiteral); + nonCoeffMonomial = add(monomial, or(not(mulF), sub(any(), not(literal)))); + nonNegOrNonCoeffMonomial = add(monomial, or(not(mulF), sub(any(), not(negLiteral)))); + atLeastTwoCoeffMonomial = opSub(mul, monomial, atLeastTwoLiteral); + + intEquation = opSub(eq, add(intF, nonNegMonomial), add(intF, polynomial)); + linearEquation = opSub(eq, linearMonomial, add(intF, polynomial)); + monomialEquation = opSub(eq, add(intF, nonNegMonomial), add(intF, monomial)); + intInEquation = add(or(leqF, geqF), sub(nonNegMonomial, polynomial)); + linearInEquation = add(or(leqF, geqF), sub(linearMonomial, polynomial)); + 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(not(divF), not(modF))); + } +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ComponentStrategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ComponentStrategy.java index d580e260331..ab345be7fb6 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ComponentStrategy.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ComponentStrategy.java @@ -23,5 +23,5 @@ enum StrategyAspect { /// Whether this strategy is responsible for the given [IBuiltInRule]. This is necessary as /// built-in rules have no rule sets. - boolean isResponsibleFor(IBuiltInRule 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..5a3f84f1a4f --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FeatureConstants.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 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.prover.strategy; + +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(); +} diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FormulaTermFeatures.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FormulaTermFeatures.java new file mode 100644 index 00000000000..26e3318f506 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FormulaTermFeatures.java @@ -0,0 +1,60 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.prover.strategy; + +import org.key_project.prover.strategy.costbased.termfeature.TermFeature; + +public interface FormulaTermFeatures { + 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.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java new file mode 100644 index 00000000000..22433e16ca1 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java @@ -0,0 +1,1121 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.prover.strategy; + +import java.util.HashSet; +import java.util.Set; + +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.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.*; +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.SequentFormulasGenerator; +import org.key_project.prover.strategy.costbased.termgenerator.SubtermGenerator; +import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; + +import org.jspecify.annotations.NonNull; + +public abstract class IntegerStrategy> extends AbstractFeatureStrategy + implements ComponentStrategy { + public static final Name NAME = new Name("Integer Strategy"); + + /// Magic constants + private static final int IN_EQ_SIMP_NON_LIN_COST = 1000; + 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; + + /// Useful [TermFeature] collections + private final ArithTermFeatures tf; + private final FormulaTermFeatures ff; + + /// configuration options extracted from [StrategyProperties] + private final boolean nonLinearArithmeticEnabled; + private final boolean divAndModuloReasoningEnabled; + private final boolean stopAtFirstNonCloseableGoal; + + FeatureConstants featureConstants; + + public IntegerStrategy(ArithTermFeatures tf, FormulaTermFeatures ff, + boolean nonLinearArithmeticEnabled, boolean divAndModuloReasoningEnabled, + boolean stopAtFirstNonCloseableGoal, FeatureConstants featureConstants) { + this.tf = tf; + this.ff = ff; + this.nonLinearArithmeticEnabled = nonLinearArithmeticEnabled; + this.divAndModuloReasoningEnabled = divAndModuloReasoningEnabled; + this.stopAtFirstNonCloseableGoal = stopAtFirstNonCloseableGoal; + + this.featureConstants = featureConstants; + + // setup cost computations + costComputationDispatcher = setupCostComputationF(); + approvalDispatcher = setupApprovalDispatcher(); + instantiationDispatcher = setupInstantiationF(); + } + + private RuleSetDispatchFeature setupInstantiationF() { + enableInstantiate(); + + final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); + setupArithPrimaryCategories(d); + setupDefOpsPrimaryCategories(d); + setupInstantiationWithoutRetry(d); + setupInEqSimpInstantiation(d); + + disableInstantiate(); + return d; + } + + @Override + public boolean isResponsibleFor(RuleSet rs) { + return costComputationDispatcher.get(rs) != null || instantiationDispatcher.get(rs) != null; + } + + protected abstract IIntLdt intLDT(); + + private boolean arithNonLinInferences() { + return nonLinearArithmeticEnabled; + } + + private boolean arithDefOps() { + return divAndModuloReasoningEnabled; + } + + @Override + public boolean isStopAtFirstNonCloseableGoal() { + return stopAtFirstNonCloseableGoal; + } + + private RuleSetDispatchFeature setupCostComputationF() { + final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); + final IIntLdt numbers = intLDT(); + + bindRuleSet(d, "simplify_int", inftyConst()); + + setupArithPrimaryCategories(d); + setupPolySimp(d, numbers); + setupInEqSimp(d, numbers); + + setupDefOpsPrimaryCategories(d); + + bindRuleSet(d, "order_terms", + add(applyTF("commEqRight", tf.monomial), applyTF("commEqLeft", tf.polynomial), + createMonomialSmallerThan("commEqLeft", "commEqRight", numbers), longConst(-5000))); + + final TermBuffer equation = new TermBuffer<>(); + final TermBuffer left = new TermBuffer<>(); + final TermBuffer right = new TermBuffer<>(); + bindRuleSet(d, "apply_equations", + SumFeature.createSum( + add(applyTF(featureConstants.focusProjection(0), tf.monomial), + ScaleFeature.createScaled(featureConstants.findRightishFeature(), 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(-4000))); + + 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), + createMonomialsSmallerThanFeature(r, l, numbers)))), + longConst(-150))); + + // 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 as 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). + setupInstantiationWithoutRetry(d); + + return d; + } + + private RuleSetDispatchFeature setupApprovalDispatcher() { + final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); + final IIntLdt numbers = intLDT(); + + if (arithNonLinInferences()) { + setupMultiplyInequations(d, inftyConst()); + } + // these taclets are not supposed to be applied with metavariable + // instantiations + // I'll keep it here for the moment as documentation, but comment it out + // as meta variables are no longer part of KeY 2.x + /* + * bindRuleSet ( d, "inEqSimp_pullOutGcd", isInstantiated ( "elimGcd" ) ); bindRuleSet ( d, + * "polySimp_pullOutGcd", isInstantiated ( "elimGcd" ) ); + * + * bindRuleSet ( d, "inEqSimp_nonNegSquares", isInstantiated ( "squareFac" ) ); bindRuleSet + * ( d, "inEqSimp_nonLin_divide", isInstantiated ( "divY" ) ); bindRuleSet ( d, + * "inEqSimp_nonLin_pos", isInstantiated ( "divY" ) ); bindRuleSet ( d, + * "inEqSimp_nonLin_neg", isInstantiated ( "divY" ) ); + * + * bindRuleSet ( d, "inEqSimp_signCases", isInstantiated ( "signCasesLeft" ) ); + */ + + setupNewSymApproval(d, numbers); + + + bindRuleSet(d, "defOps_div", featureConstants.nonDuplicateAppModPositionFeature()); + + if (arithNonLinInferences()) { + setupInEqCaseDistinctionsApproval(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 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)))))))); + } + + // ////////////////////////////////////////////////////////////////////////// + // ////////////////////////////////////////////////////////////////////////// + // + // Handling of arithmetic + // + // ////////////////////////////////////////////////////////////////////////// + // ////////////////////////////////////////////////////////////////////////// + + private void setupArithPrimaryCategories(RuleSetDispatchFeature d) { + // Gaussian elimination + Euclidian algorithm for linear equations; + // Buchberger's algorithmus for handling polynomial equations over + // the integers + + bindRuleSet(d, "polySimp_expand", -4500); + bindRuleSet(d, "polySimp_directEquations", -3000); + bindRuleSet(d, "polySimp_pullOutGcd", -2250); + bindRuleSet(d, "polySimp_leftNonUnit", -2000); + bindRuleSet(d, "polySimp_saturate", 0); + + // Omega test for handling linear arithmetic and inequalities over the + // integers; cross-multiplication + case distinctions for nonlinear + // inequalities + + bindRuleSet(d, "inEqSimp_expand", -4400); + bindRuleSet(d, "inEqSimp_directInEquations", -2900); + bindRuleSet(d, "inEqSimp_propagation", -2400); + bindRuleSet(d, "inEqSimp_pullOutGcd", -2150); + bindRuleSet(d, "inEqSimp_saturate", -1900); + bindRuleSet(d, "inEqSimp_forNormalisation", -1100); + bindRuleSet(d, "inEqSimp_special_nonLin", -1400); + + if (arithNonLinInferences()) { + bindRuleSet(d, "inEqSimp_nonLin", IN_EQ_SIMP_NON_LIN_COST); + } else { + bindRuleSet(d, "inEqSimp_nonLin", inftyConst()); + } + // polynomial division, simplification of fractions and mods + bindRuleSet(d, "polyDivision", POLY_DIVISION_COST); + } + + private void setupPolySimp(RuleSetDispatchFeature d, IIntLdt numbers) { + // category "expansion" (normalising polynomial terms) + + bindRuleSet(d, "polySimp_elimSubNeg", longConst(-120)); + + bindRuleSet(d, "polySimp_homo", + add(applyTF("homoRight", add(not(tf.zeroLiteral), tf.polynomial)), + or(applyTF("homoLeft", or(tf.addF, tf.negMonomial)), + not(createMonomialSmallerThan("homoRight", "homoLeft", numbers))), + longConst(-120))); + + bindRuleSet(d, "polySimp_pullOutFactor", add(applyTFNonStrict("pullOutLeft", tf.literal), + applyTFNonStrict("pullOutRight", tf.literal), longConst(-120))); + + bindRuleSet(d, "polySimp_elimOneLeft", -120); + + bindRuleSet(d, "polySimp_elimOneRight", -120); + + bindRuleSet(d, "polySimp_mulOrder", add(applyTF("commRight", tf.monomial), or( + applyTF("commLeft", tf.addF), + add(applyTF("commLeft", tf.atom), + createAtomSmallerThanFeature("commLeft", "commRight", numbers))), + longConst(-100))); + + bindRuleSet(d, "polySimp_mulAssoc", + SumFeature.createSum(applyTF("mulAssocMono0", tf.monomial), + applyTF("mulAssocMono1", tf.monomial), applyTF("mulAssocAtom", tf.atom), + longConst(-80))); + + bindRuleSet(d, "polySimp_addOrder", + SumFeature.createSum(applyTF("commLeft", tf.monomial), + applyTF("commRight", tf.polynomial), + createMonomialSmallerThan("commRight", "commLeft", numbers), longConst(-60))); + + bindRuleSet(d, "polySimp_addAssoc", + SumFeature.createSum(applyTF("addAssocPoly0", tf.polynomial), + applyTF("addAssocPoly1", tf.polynomial), applyTF("addAssocMono", tf.monomial), + longConst(-10))); + + bindRuleSet(d, "polySimp_dist", + SumFeature.createSum(applyTF("distSummand0", tf.polynomial), + applyTF("distSummand1", tf.polynomial), + ifZero(applyTF("distCoeff", tf.monomial), longConst(-15), + applyTF("distCoeff", tf.polynomial)), + applyTF("distSummand0", tf.polynomial), + + applyTF("distSummand1", tf.polynomial), longConst(-35))); + + // category "direct equations" + + bindRuleSet(d, "polySimp_balance", + SumFeature + .createSum(applyTF("sepResidue", tf.polynomial), + ifZero(isInstantiated("sepPosMono"), + add(applyTF("sepPosMono", tf.nonNegMonomial), + createMonomialSmallerThan("sepResidue", "sepPosMono", numbers))), + ifZero(isInstantiated("sepNegMono"), + add(applyTF("sepNegMono", tf.negMonomial), + createMonomialSmallerThan("sepResidue", "sepNegMono", numbers))), + longConst(-30))); + + bindRuleSet(d, "polySimp_normalise", add(applyTF("invertRight", tf.zeroLiteral), + applyTF("invertLeft", tf.negMonomial), longConst(-30))); + + // application of equations: some specialised rules that handle + // monomials and their coefficients properly + + final TermBuffer eqLeft = new TermBuffer<>(); + final TermBuffer focus = new TermBuffer<>(); + + final TermFeature atLeastTwoLCEquation = + opSub(tf.eq, opSub(tf.mul, tf.atom, tf.atLeastTwoLiteral), tf.intF); + + final Feature validEqApplication = add(not(eq(eqLeft, focus, this::createEqTermFeature)), + // otherwise, the normal equation rules can and should + // be used + ifZero( + StaticFeatureCollection.applyTF(AssumptionProjection.create(0), + atLeastTwoLCEquation), + add(FocusInAntecFeature.getInstance(), + applyTF(featureConstants.focusFormulaProjection(), atLeastTwoLCEquation))), + createReducibleMonomialFeature(focus, eqLeft)); + + final Feature eqMonomialFeature = add(not(directlyBelowSymbolAtIndex(tf.mul, -1)), + ifZero(featureConstants.matchedAssumesFeature(), + let(focus, featureConstants.focusProjection(0), + let(eqLeft, sub(AssumptionProjection.create(0), 0), validEqApplication)))); + + bindRuleSet(d, "polySimp_applyEq", add(eqMonomialFeature, longConst(1))); + + bindRuleSet(d, "polySimp_applyEqRigid", add(eqMonomialFeature, longConst(2))); + + // + bindRuleSet(d, "defOps_expandModulo", + add(featureConstants.nonDuplicateAppModPositionFeature(), longConst(-600))); + + // category "saturate" + + bindRuleSet(d, "polySimp_critPair", + 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<>(); + + // exact polynomial division + + final Feature checkNumTerm = ifZero( + add(not(applyTF(numTerm, tf.addF)), + createReducibleMonomialFeature(numTerm, denomLC)), + add(instantiate("polyDivCoeff", createReduceMonomialsProjection(numTerm, denomLC)), + inftyConst())); + + final Feature isReduciblePoly = + sum(numTerm, SubtermGenerator.rightTraverse(StaticFeatureCollection.instOf("divNum"), + tf.addF), checkNumTerm); + + // polynomial division modulo equations of the antecedent + + 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(StaticFeatureCollection.instOf("divNum"), + tf.addF), + ifZero(applyTF(numTerm, tf.addF), longConst(0), sum(divCoeff, + 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(StaticFeatureCollection.instOf("divDenom"), 1), + not(isReduciblePoly)), + let(denomLC, instOf("divDenom"), ifZero(isReduciblePoly, + // no possible division has been found so far + add(featureConstants.notInScopeOfModalityFeature(), ifZero(isReduciblePolyE, + // try again later + longConst(-POLY_DIVISION_COST)))))), + longConst(100))); + + } + + + // 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 as 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 setupPolySimpInstantiationWithoutRetry(RuleSetDispatchFeature d, IIntLdt numbers) { + // category "direct equations" + + setupPullOutGcd(d, "polySimp_pullOutGcd", false); + + // category "polynomial division" + + setupDivModDivision(d); + + // category "handling of equations with non-unit-coefficients on + // left-hand side" + + bindRuleSet(d, "polySimp_newSym", + ifZero(not(isInstantiated("newSymDef")), SumFeature.createSum( + applyTF("newSymLeft", tf.atom), applyTF("newSymLeftCoeff", tf.atLeastTwoLiteral), + applyTF("newSymRight", tf.polynomial), instantiate("newSymDef", + createMonomialColumnOp(instOf("newSymLeftCoeff"), instOf("newSymRight")))))); + + final TermBuffer divisor = new TermBuffer<>(); + final TermBuffer dividend = new TermBuffer<>(); + + bindRuleSet(d, "polySimp_applyEqPseudo", + add(applyTF("aePseudoTargetLeft", tf.monomial), + applyTF("aePseudoTargetRight", tf.polynomial), + ifZero(featureConstants.matchedAssumesFeature(), + SumFeature.createSum(featureConstants.diffFindAndIfFeature(), + applyTF("aePseudoLeft", add(tf.nonCoeffMonomial, not(tf.atom))), + applyTF("aePseudoLeftCoeff", tf.atLeastTwoLiteral), + applyTF("aePseudoRight", tf.polynomial), + createMonomialsSmallerThanFeature(instOf("aePseudoRight"), + instOf("aePseudoLeft"), numbers), + let(divisor, StaticFeatureCollection.instOf("aePseudoLeft"), + let(dividend, StaticFeatureCollection.instOf("aePseudoTargetLeft"), + add(createReducibleMonomialFeature(dividend, divisor), + instantiate("aePseudoTargetFactor", + createReduceMonomialsProjection(dividend, divisor))))))))); + } + + 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 = + 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 Feature instantiateDivs; + if (roundingUp) { + instantiateDivs = add( + instantiate("elimGcdLeftDiv", + createRoundingUpDividePolynomialsProjection(gcd, instOf("elimGcdLeft"))), + instantiate("elimGcdRightDiv", + createRoundingUpDividePolynomialsProjection(gcd, instOf("elimGcdRight")))); + } else { + instantiateDivs = add( + instantiate("elimGcdLeftDiv", + createRoundingDownDividePolynomialsProjection(gcd, instOf("elimGcdLeft"))), + instantiate("elimGcdRightDiv", + createRoundingDownDividePolynomialsProjection(gcd, instOf("elimGcdRight")))); + } + bindRuleSet(d, ruleSet, + add(applyTF("elimGcdLeft", tf.nonNegMonomial), applyTF("elimGcdRight", tf.polynomial), + let(gcd, createCoeffGcdProjection(instOf("elimGcdLeft"), instOf("elimGcdRight")), + add(applyTF(gcd, tf.atLeastTwoLiteral), instantiate("elimGcd", gcd), + instantiateDivs)))); + } + + private void setupInEqSimp(RuleSetDispatchFeature d, IIntLdt numbers) { + // category "expansion" (normalising inequations) + + bindRuleSet(d, "inEqSimp_moveLeft", -90); + + bindRuleSet(d, "inEqSimp_makeNonStrict", -80); + + bindRuleSet(d, "inEqSimp_commute", + SumFeature.createSum(applyTF("commRight", tf.monomial), + applyTF("commLeft", tf.polynomial), + createMonomialSmallerThan("commLeft", "commRight", numbers), longConst(-40))); + + // 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(createMonomialSmallerThan("homoRight", "homoLeft", numbers))))); + + // category "direct inequations" + + // this is copied from "polySimp_balance" + bindRuleSet(d, "inEqSimp_balance", + add(applyTF("sepResidue", tf.polynomial), + ifZero(isInstantiated("sepPosMono"), + add(applyTF("sepPosMono", tf.nonNegMonomial), + createMonomialSmallerThan("sepResidue", "sepPosMono", numbers))), + ifZero(isInstantiated("sepNegMono"), add(applyTF("sepNegMono", tf.negMonomial), + createMonomialSmallerThan("sepResidue", "sepNegMono", numbers))))); + + // this is copied from "polySimp_normalise" + bindRuleSet(d, "inEqSimp_normalise", + add(applyTF("invertRight", tf.zeroLiteral), applyTF("invertLeft", tf.negMonomial))); + + // category "saturate" + + bindRuleSet(d, "inEqSimp_antiSymm", longConst(-20)); + + bindRuleSet(d, "inEqSimp_exactShadow", + SumFeature.createSum(applyTF("esLeft", tf.nonCoeffMonomial), + applyTFNonStrict("esCoeff2", tf.nonNegLiteral), applyTF("esRight2", tf.polynomial), + ifZero(featureConstants.matchedAssumesFeature(), + SumFeature.createSum(applyTFNonStrict("esCoeff1", tf.nonNegLiteral), + applyTF("esRight1", tf.polynomial), + not(createLeqPolynomialValuesCmpFeature(instOf("esRight2"), + instOf("esRight1"), + instOfNonStrict("esCoeff1"), instOfNonStrict("esCoeff2"))))))); + + // category "propagation" + + bindRuleSet(d, "inEqSimp_contradInEqs", + add(applyTF("contradLeft", tf.monomial), + ifZero(featureConstants.matchedAssumesFeature(), + SumFeature.createSum(featureConstants.diffFindAndIfFeature(), + applyTF("contradRightSmaller", tf.polynomial), + applyTF("contradRightBigger", tf.polynomial), + applyTFNonStrict("contradCoeffSmaller", tf.posLiteral), + applyTFNonStrict("contradCoeffBigger", tf.posLiteral), + createLtPolynomialValuesCmpFeature(instOf("contradRightSmaller"), + instOf("contradRightBigger"), instOfNonStrict("contradCoeffBigger"), + instOfNonStrict("contradCoeffSmaller")))))); + + bindRuleSet(d, "inEqSimp_contradEqs", + add(applyTF("contradLeft", tf.monomial), + ifZero(featureConstants.matchedAssumesFeature(), + SumFeature.createSum(applyTF("contradRightSmaller", tf.polynomial), + applyTF("contradRightBigger", tf.polynomial), + createLtPolynomialValuesCmpFeature(instOf("contradRightSmaller"), + instOf("contradRightBigger")))), + longConst(-60))); + + bindRuleSet(d, "inEqSimp_strengthen", longConst(-30)); + + bindRuleSet(d, "inEqSimp_subsumption", + add(applyTF("subsumLeft", tf.monomial), + ifZero(featureConstants.matchedAssumesFeature(), + SumFeature.createSum(featureConstants.diffFindAndIfFeature(), + applyTF("subsumRightSmaller", tf.polynomial), + applyTF("subsumRightBigger", tf.polynomial), + applyTFNonStrict("subsumCoeffSmaller", tf.posLiteral), + applyTFNonStrict("subsumCoeffBigger", tf.posLiteral), + createLeqPolynomialValuesCmpFeature(instOf("subsumRightSmaller"), + instOf("subsumRightBigger"), instOfNonStrict("subsumCoeffBigger"), + instOfNonStrict("subsumCoeffSmaller")))))); + + // category "handling of non-linear inequations" + + if (arithNonLinInferences()) { + setupMultiplyInequations(d, longConst(100)); + + bindRuleSet(d, "inEqSimp_split_eq", + add(featureConstants.topLevelFindSucc(), longConst(-100))); + + bindRuleSet(d, "inEqSimp_signCases", not(isInstantiated("signCasesLeft"))); + } + + // category "normalisation of formulas" + // (e.g., quantified formulas, where the normal sequent calculus + // does not do any normalisation) + + bindRuleSet(d, "inEqSimp_and_contradInEqs", + SumFeature.createSum(applyTF("contradLeft", tf.monomial), + applyTF("contradRightSmaller", tf.polynomial), + 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), createLeqPolynomialValuesCmpFeature( + instOf("subsumRightSmaller"), instOf("subsumRightBigger")))); + + bindRuleSet(d, "inEqSimp_and_subsumptionEq", + SumFeature.createSum(applyTF("subsumLeft", tf.monomial), + applyTF("subsumRightSmaller", tf.polynomial), + applyTF("subsumRightBigger", tf.polynomial), createLtPolynomialValuesCmpFeature( + instOf("subsumRightSmaller"), instOf("subsumRightBigger")))); + + final Term tOne = zTerm("1"); + final TermBuffer one = new TermBuffer<>() { + @Override + public void setContent(Term term, MutableState mState) {} + + @Override + public @NonNull Term getContent(MutableState mState) { + return tOne; + } + + @Override + public @NonNull Term toTerm(RuleApp app, PosInOccurrence pos, + G goal, MutableState mState) { + return tOne; + } + }; + + final Term tTwo = zTerm("2"); + final TermBuffer two = new TermBuffer<>() { + @Override + public void setContent(Term term, MutableState mState) {} + + @Override + public @NonNull Term getContent(MutableState mState) { + return tTwo; + } + + @Override + public @NonNull Term toTerm(RuleApp app, PosInOccurrence pos, + G goal, MutableState mState) { + return tTwo; + } + }; + + bindRuleSet(d, "inEqSimp_or_tautInEqs", + SumFeature.createSum(applyTF("tautLeft", tf.monomial), + applyTF("tautRightSmaller", tf.polynomial), + applyTF("tautRightBigger", tf.polynomial), + 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), + createEqPolynomialValuesCmpFeature( + opTerm(numbers.getAdd(), one, instOf("weakenRightSmaller")), + instOf("weakenRightBigger")))); + + bindRuleSet(d, "inEqSimp_or_antiSymm", + SumFeature.createSum(applyTF("antiSymmLeft", tf.monomial), + applyTF("antiSymmRightSmaller", tf.polynomial), + applyTF("antiSymmRightBigger", tf.polynomial), + createEqPolynomialValuesCmpFeature( + opTerm(numbers.getAdd(), two, instOf("antiSymmRightSmaller")), + instOf("antiSymmRightBigger")))); + + } + + private void setupMultiplyInequations(RuleSetDispatchFeature d, Feature notAllowedF) { + final TermBuffer intRel = new TermBuffer<>(); + + /* + * final Feature partiallyBounded = not ( sum ( intRel, SequentFormulasGenerator.sequent (), + * not ( add ( applyTF ( intRel, tf.intRelation ), InEquationMultFeature .partiallyBounded ( + * instOf ( "multLeft" ), instOf ( "multFacLeft" ), sub ( intRel, 0 ) ) ) ) ) ); + */ + + final Feature totallyBounded = not(sum(intRel, SequentFormulasGenerator.sequent(), + not(add(applyTF(intRel, tf.intRelation), createTotalyBoundedInEquationMultFeature( + instOf("multLeft"), instOf("multFacLeft"), sub(intRel, 0)))))); + + final Feature exactlyBounded = not(sum(intRel, SequentFormulasGenerator.sequent(), + not(add(applyTF(intRel, tf.intRelation), createExactlyBoundedInEquationMultFeature( + instOf("multLeft"), instOf("multFacLeft"), sub(intRel, 0)))))); + + // this is a bit hackish + // + // really, one would need a possibility to express that the cost + // computation for the rule application should be post-poned (and + // repeated at a later point) if the product of the left sides does not + // have any similarity with existing left sides + // (AllowInEquationMultiplication returns false). We + // simulate this by returning non-infinite costs here, but by declining + // the rule application in isApprovedApp). This is not + // perfect, because it is not possible to distinguish between the + // re-cost-computation delay and the normal costs for a rule application + bindRuleSet(d, "inEqSimp_nonLin_multiply", add( + applyTF("multLeft", tf.nonNegMonomial), + applyTF("multRight", tf.polynomial), + ifZero(featureConstants.matchedAssumesFeature(), + SumFeature.createSum( + applyTF("multFacLeft", tf.nonNegMonomial), + ifZero(applyTF("multRight", tf.literal), longConst(-100)), + ifZero(applyTF("multFacRight", tf.literal), longConst(-100), + applyTF("multFacRight", tf.polynomial)), + /* + * ifZero ( applyTF ( "multRight", tf.literal ), longConst ( -100 ), applyTF ( + * "multRight", tf.polynomial ) ), ifZero ( applyTF ( "multFacRight", tf.literal + * ), longConst ( -100 ), applyTF ( "multFacRight", tf.polynomial ) ), + */ + not(createTermSmallerThanFeature(featureConstants.focusProjection(0), + AssumptionProjection.create(0))), + ifZero(exactlyBounded, longConst(0), + ifZero(totallyBounded, longConst(100), notAllowedF)) + /* + * ifZero ( partiallyBounded, longConst ( 400 ), notAllowedF ) ) ), + */ + /* + * applyTF ( "multLeft", rec ( tf.mulF, longTermConst ( 20 ) ) ), applyTF ( + * "multFacLeft", rec ( tf.mulF, longTermConst ( 20 ) ) ), applyTF ( "multRight", + * rec ( tf.addF, longTermConst ( 4 ) ) ), applyTF ( "multFacRight", rec ( tf.addF, + * longTermConst ( 4 ) ) ), + */ + ), notAllowedF))); + } + + private void setupInEqSimpInstantiation(RuleSetDispatchFeature d) { + // category "handling of non-linear inequations" + + setupSquaresAreNonNegative(d); + + if (arithNonLinInferences()) { + setupInEqCaseDistinctions(d); + } + } + + private void setupSquaresAreNonNegative(RuleSetDispatchFeature d) { + final TermBuffer intRel = new TermBuffer<>(); + final TermBuffer product = new TermBuffer<>(); + final TermBuffer factor = new TermBuffer<>(); + + final Feature productContainsSquare = + 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", + forEach(intRel, SequentFormulasGenerator.sequent(), + ifZero(applyTF(intRel, tf.intRelation), + forEach(product, SubtermGenerator.leftTraverse(sub(intRel, 0), tf.mulF), + ifZero(productIsProduct, let(factor, sub(product, 1), + ifZero(productContainsSquare, instantiate("squareFac", factor)))))))); + } + + private void setupInEqCaseDistinctions(RuleSetDispatchFeature d) { + 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), + forEach(atom, SubtermGenerator.leftTraverse(sub(intRel, 0), tf.mulF), + SumFeature.createSum(applyTF(atom, add(tf.atom, not(tf.literal))), + allowPosNegCaseDistinction(atom), instantiate("signCasesLeft", atom), + longConst(IN_EQ_SIMP_NON_LIN_COST + 200) + // , + // applyTF ( atom, rec ( any (), + // longTermConst ( 5 ) ) ) + )))); + + bindRuleSet(d, "inEqSimp_signCases", posNegSplitting); + + final Feature strengthening = forEach(intRel, SequentFormulasGenerator.antecedent(), + SumFeature.createSum( + applyTF(intRel, add(or(tf.geqF, tf.leqF), sub(tf.atom, tf.literal))), + instantiate("cutFormula", opTerm(tf.eq, sub(intRel, 0), sub(intRel, 1))), + longConst(IN_EQ_SIMP_NON_LIN_COST + 300) + // , + // applyTF ( sub ( intRel, 0 ), + // rec ( any (), longTermConst ( 5 ) ) ) + )); + + final Feature rootInferences = forEach(intRel, SequentFormulasGenerator.antecedent(), + add(isRootInferenceProducer(intRel), + forEach(rootInf, createRootsGenerator(intRel), + add(instantiate("cutFormula", rootInf), + ifZero(applyTF(rootInf, op(or())), longConst(50)), + ifZero(applyTF(rootInf, op(and())), longConst(20)))), + longConst(IN_EQ_SIMP_NON_LIN_COST))); + + // noinspection unchecked + bindRuleSet(d, "cut", oneOf(new Feature[] { strengthening, rootInferences })); + } + + 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 = createEqTermFeature(atom); + + return add(not(succIntEquationExists()), + sum(antecFor, SequentFormulasGenerator.antecedent(), + not(applyTF(antecFor, or(opSub(tf.eq, eqAtom, any()), + opSub(tf.leq, eqAtom, tf.negLiteral), opSub(tf.geq, eqAtom, tf.posLiteral)))))); + } + + private Feature succIntEquationExists() { + final TermBuffer succFor = new TermBuffer<>(); + + return not(sum(succFor, SequentFormulasGenerator.succedent(), + not(applyTF(succFor, tf.intEquation)))); + } + + // ////////////////////////////////////////////////////////////////////////// + // ////////////////////////////////////////////////////////////////////////// + // + // Axiomatisation and algorithms for further arithmetic operations: + // division, modulus, modular Java operations + // + // ////////////////////////////////////////////////////////////////////////// + // ////////////////////////////////////////////////////////////////////////// + + private void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { + + if (arithDefOps()) { + // the axiom defining division only has to be inserted once, because + // it adds equations to the antecedent + bindRuleSet(d, "defOps_div", + 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(200)))); + + bindRuleSet(d, "defOps_jdiv", + 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(200)))); + + bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), + applyTF("divDenom", tf.polynomial), longConst(-5000))); + + setupDefOpsExpandMod(d); + + bindRuleSet(d, "defOps_expandRanges", -8000); + bindRuleSet(d, "defOps_expandJNumericOp", -500); + bindRuleSet(d, "defOps_modHomoEq", -5000); + } 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(-4000))); + + bindRuleSet(d, "defOps_mod", add(applyTF("divNum", tf.literal), + applyTF("divDenom", tf.literal), longConst(-4000))); + + bindRuleSet(d, "defOps_expandRanges", inftyConst()); + bindRuleSet(d, "defOps_expandJNumericOp", inftyConst()); + bindRuleSet(d, "defOps_modHomoEq", inftyConst()); + } + } + + private void setupDefOpsExpandMod(RuleSetDispatchFeature d) { + final TermBuffer superTerm = new TermBuffer<>(); + + final Feature subsumedModulus = + add(applyTF(superTerm, sub(opSub(tf.mod, any(), tf.literal), tf.zeroLiteral)), + createDividesPolynomialValuesCmpFeature(instOf("divDenom"), + sub(sub(superTerm, 0), 1))); + + final Feature exSubsumedModulus = add(applyTF("divDenom", tf.literal), + not(sum(superTerm, + upwardsWithIndexSuperGenerator(sub(or(tf.addF, tf.mulF), any())), + not(subsumedModulus)))); + + bindRuleSet(d, "defOps_mod", + ifZero(add(applyTF("divNum", tf.literal), applyTF("divDenom", tf.literal)), + longConst(-4000), + SumFeature.createSum(applyTF("divNum", tf.polynomial), + applyTF("divDenom", tf.polynomial), + ifZero(isBelow(ff.modalOperator()), exSubsumedModulus, + or(add(applyTF("divNum", tf.notContainsDivMod), + applyTF("divDenom", tf.notContainsDivMod)), exSubsumedModulus)), + longConst(-3500)))); + } + + /// 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, intLDT()); + setupInEqSimpInstantiationWithoutRetry(d); + } + + // 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 as 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 setupInEqSimpInstantiationWithoutRetry(RuleSetDispatchFeature d) { + // category "direct inequations" + + setupPullOutGcd(d, "inEqSimp_pullOutGcd_leq", false); + setupPullOutGcd(d, "inEqSimp_pullOutGcd_geq", true); + + // more efficient (but not confluent) versions for the antecedent + bindRuleSet(d, "inEqSimp_pullOutGcd_antec", -10); + + // category "handling of non-linear inequations" + + 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(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), + 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<>(); + + bindRuleSet(d, ruleSet, + SumFeature + .createSum(applyTF("divProd", tf.nonCoeffMonomial), + applyTFNonStrict("divProdBoundPos", tf.posLiteral), + applyTFNonStrict("divProdBoundNeg", tf.negLiteral), + ifZero(featureConstants.matchedAssumesFeature(), + let(divisor, instOf("divX"), let(dividend, instOf("divProd"), + SumFeature.createSum(applyTF(divisor, tf.nonCoeffMonomial), + not(applyTF(dividend, createEqTermFeature(divisor))), + applyTFNonStrict("divXBoundNonPos", tf.nonPosLiteral), + applyTFNonStrict("divXBoundNonNeg", tf.nonNegLiteral), + createReducibleMonomialFeature(dividend, divisor), + let(quotient, + createReduceMonomialsProjection(dividend, divisor), add( + sum(antecFor, SequentFormulasGenerator.antecedent(), + not(applyTF(antecFor, + pos ? opSub(tf.geq, + createEqTermFeature(quotient), + tf.posLiteral) + : opSub(tf.leq, + createEqTermFeature(quotient), + tf.negLiteral)))), + instantiate("divY", quotient))))))))); + } + + protected abstract Feature createReducibleMonomialFeature(ProjectionToTerm dividend, + ProjectionToTerm divisor); + + protected abstract Feature createTrivialMonomialLCRFeature(ProjectionToTerm a, + ProjectionToTerm b); + + protected abstract ProjectionToTerm createReduceMonomialsProjection( + ProjectionToTerm dividend, ProjectionToTerm divisor); + + protected abstract ProjectionToTerm createMonomialColumnOp( + ProjectionToTerm leftCoefficient, + ProjectionToTerm polynomial); + + protected abstract Feature createMonomialsSmallerThanFeature(ProjectionToTerm left, + ProjectionToTerm right, IIntLdt numbers); + + protected abstract Feature createAtomSmallerThanFeature(String left, String right, + IIntLdt numbers); + + protected abstract ProjectionToTerm createRoundingUpDividePolynomialsProjection( + ProjectionToTerm leftCoefficient, ProjectionToTerm polynomial); + + protected abstract ProjectionToTerm createRoundingDownDividePolynomialsProjection( + ProjectionToTerm leftCoefficient, ProjectionToTerm polynomial); + + protected abstract ProjectionToTerm createCoeffGcdProjection( + ProjectionToTerm monomialLeft, ProjectionToTerm monomialRight); + + protected abstract Feature createExactlyBoundedInEquationMultFeature( + ProjectionToTerm mult1Candidate, ProjectionToTerm mult2Candidate, + ProjectionToTerm 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.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..8a1ae2f7cf2 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/StaticFeatureCollection.java @@ -0,0 +1,293 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.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 { + protected static Feature longConst(long a) { + return ConstFeature.createConst(cost(a)); + } + + protected static Feature inftyConst() { + return ConstFeature.createConst(infty()); + } + + protected static TermFeature any() { + return longTermConst(0); + } + + protected static TermFeature longTermConst(long a) { + return ConstTermFeature.createConst(cost(a)); + } + + protected static TermFeature inftyTermConst() { + return ConstTermFeature.createConst(infty()); + } + + protected static Feature add(Feature a, Feature b) { + return SumFeature.createSum(a, b); + } + + protected static Feature add(Feature a, Feature b, Feature c) { + return SumFeature.createSum(a, b, c); + } + + @SafeVarargs + protected static Feature add(Feature... features) { + return SumFeature.createSum(features); + } + + protected static TermFeature add(TermFeature a, TermFeature b) { + return BinarySumTermFeature.createSum(a, b); + } + + protected static > Feature sum(TermBuffer x, TermGenerator gen, + Feature body) { + return ComprehendedSumFeature.create(x, gen, body); + } + + protected static TermFeature add(TermFeature a, TermFeature b, TermFeature c) { + // could be done more efficiently + return add(a, add(b, c)); + } + + protected static TermFeature or(TermFeature a, TermFeature b) { + return ifZero(a, longTermConst(0), b); + } + + protected static TermFeature or(TermFeature a, TermFeature b, TermFeature c) { + return or(a, or(b, c)); + } + + protected static TermFeature or(TermFeature... features) { + TermFeature orFeature = inftyTermConst(); + for (var f : features) { + orFeature = or(orFeature, f); + } + return orFeature; + } + + protected static Feature or(Feature a, Feature b) { + return ifZero(a, longConst(0), b); + } + + protected static Feature or(Feature a, Feature b, Feature c) { + return or(a, or(b, c)); + } + + @SafeVarargs + protected static Feature or(Feature... features) { + Feature orFeature = inftyConst(); + for (Feature f : features) { + orFeature = or(orFeature, f); + } + return orFeature; + } + + protected static Feature ifZero(Feature cond, Feature thenFeature) { + return ShannonFeature.createConditionalBinary(cond, thenFeature); + } + + protected static Feature ifZero(Feature cond, Feature thenFeature, + Feature elseFeature) { + return ShannonFeature.createConditionalBinary(cond, thenFeature, elseFeature); + } + + protected static TermFeature ifZero(TermFeature cond, TermFeature thenFeature) { + return ShannonTermFeature.createConditionalBinary(cond, thenFeature); + } + + protected static TermFeature ifZero(TermFeature cond, TermFeature thenFeature, + TermFeature elseFeature) { + return ShannonTermFeature.createConditionalBinary(cond, thenFeature, elseFeature); + } + + protected static Feature not(Feature f) { + return ifZero(f, inftyConst(), longConst(0)); + } + + protected static TermFeature not(TermFeature f) { + return ifZero(f, ConstTermFeature.createConst(TopRuleAppCost.INSTANCE), longTermConst(0)); + } + + protected static Feature eq(Feature a, Feature b) { + return CompareCostsFeature.eq(a, b); + } + + protected 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))); + } + + protected static Feature less(Feature a, Feature b) { + return CompareCostsFeature.less(a, b); + } + + protected static Feature leq(Feature a, Feature b) { + return CompareCostsFeature.leq(a, b); + } + + protected 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 + protected 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 + protected static > ProjectionToTerm instOfNonStrict( + String schemaVar) { + return SVInstantiationProjection.create(new Name(schemaVar), false); + } + + protected static TermFeature op(Operator op) { + return OperatorTF.create(op); + } + + protected static TermFeature rec(TermFeature cond, TermFeature summand) { + return RecSubTermFeature.create(cond, summand); + } + + protected static > ProjectionToTerm subAt(ProjectionToTerm t, + PosInTerm pit) { + return SubtermProjection.create(t, pit); + } + + protected static TermFeature sub(TermFeature sub0) { + return SubTermFeature.create(new TermFeature[] { sub0 }); + } + + protected static TermFeature sub(TermFeature sub0, TermFeature sub1) { + return SubTermFeature.create(new TermFeature[] { sub0, sub1 }); + } + + protected static > ProjectionToTerm sub(ProjectionToTerm t, + int index) { + return SubtermProjection.create(t, PosInTerm.getTopLevel().down(index)); + } + + protected static TermFeature opSub(Operator op, TermFeature sub0) { + return add(op(op), sub(sub0)); + } + + protected static TermFeature opSub(Operator op, TermFeature sub0, TermFeature sub1) { + return add(op(op), sub(sub0, sub1)); + } + + protected 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)))))); + } + + protected static > Feature let(TermBuffer x, + ProjectionToTerm value, + Feature body) { + return LetFeature.create(x, value, body); + } + + protected static > Feature println(ProjectionToTerm t) { + return applyTF(t, PrintTermFeature.INSTANCE); + } + + protected 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 + protected 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 + protected 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 + protected 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 + protected static > Feature applyTFNonStrict(ProjectionToTerm term, + TermFeature tf) { + return ApplyTFFeature.createNonStrict(term, tf, NumberRuleAppCost.getZeroCost()); + } + + protected static TermFeature constantTermFeature() { + return TermPredicateTermFeature + .create(term -> term.op() instanceof Function && term.arity() == 0); + } + + protected static Feature isInstantiated(String schemaVar) { + return InstantiatedSVFeature.create(new Name(schemaVar)); + } +} 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..d2754766cdc --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/BinaryTacletAppFeature.java @@ -0,0 +1,49 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.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 95% 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 2eabf7ed9ce..1e1f2244a7a 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 @@ -1,7 +1,7 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.strategy.feature; +package org.key_project.prover.strategy.costbased.feature; import org.key_project.logic.Term; import org.key_project.prover.proof.ProofGoal; @@ -11,7 +11,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.termProjection.TermBuffer; import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; 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..fac89dd811f --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/InstantiatedSVFeature.java @@ -0,0 +1,33 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.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. +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.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..b4c33527ae7 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/ForEachCP.java @@ -0,0 +1,130 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.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..605eb45b923 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/OneOfCP.java @@ -0,0 +1,85 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.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 int theChosenOne; + private final ChoicePoint cp = new CP(); + + 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(cp, this); + return features[theChosenOne].computeCost(app, pos, goal, mState); + } + + private final class CP implements ChoicePoint { + 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() { + theChosenOne = 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..60c04735024 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/instantiator/SVInstantiationCP.java @@ -0,0 +1,120 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.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.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.ImmutableSLList; +import org.key_project.util.collection.ImmutableSet; + +import org.jspecify.annotations.NonNull; + +/// 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 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(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) { + return app.taclet().getTrigger().triggerVar(); + } + + final ImmutableSet vars = app.uninstantiatedVars(); + for (SchemaVariable svt : vars) { + if (svt.name().equals(svToInstantiate)) { + return svt; + } + } + + // Debug.fail("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."); + return null; + } + + + 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); + + 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 ImmutableSLList.nil().prepend(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..594830617a6 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/AssumptionProjection.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 + * SPDX-License-Identifier: GPL-2.0-only */ +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; + +/// Term projection that delivers the assumptions of a taclet application (the formulas that the +/// \assumes clause of the taclet refers to). +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().take(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 294edf81436..1a0ef3f168b 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 @@ -13,7 +13,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> { @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..35306441e64 --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SVInstantiationProjection.java @@ -0,0 +1,48 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package org.key_project.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; + +/// 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 +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 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)) { + assert !demandInst; + 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..d3af2c2ca7a --- /dev/null +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/termProjection/SubtermProjection.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 + * SPDX-License-Identifier: GPL-2.0-only */ +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; + +/// Projection for computing a subterm of a given term. The position of the subterm within the +/// complete term is described using a `PosInTerm`. +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) { + return pit.getSubTerm(completeTerm.toTerm(app, pos, goal, mState)); + } +} 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..71b98daca78 --- /dev/null +++ b/key.ncore/src/main/java/org/key_project/ldt/IIntLdt.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 + * SPDX-License-Identifier: GPL-2.0-only */ +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(); +} From 34dd4e704cd1fab4913c295810641b613aa8a9f2 Mon Sep 17 00:00:00 2001 From: Drodt Date: Fri, 5 Jun 2026 16:14:50 +0200 Subject: [PATCH 5/9] (WIP) Integrate IntegerStrat --- .../java/de/uka/ilkd/key/ldt/IntegerLDT.java | 3 +- .../ilkd/key/strategy/ArithTermFeatures.java | 155 --- .../de/uka/ilkd/key/strategy/FOLStrategy.java | 4 +- .../key/strategy/FormulaTermFeatures.java | 135 ++- .../ilkd/key/strategy/IntegerStrategy.java | 1042 ----------------- .../key/strategy/IntegerStrategyFactory.java | 10 +- .../key/strategy/JavaArithTermFeatures.java | 39 + .../ilkd/key/strategy/JavaCardDLStrategy.java | 4 +- .../key/strategy/JavaIntegerStrategy.java | 306 +++++ .../key/strategy/ModularJavaDLStrategy.java | 6 +- .../uka/ilkd/key/strategy/StringStrategy.java | 4 +- .../uka/ilkd/key/strategy/SymExStrategy.java | 2 +- .../AbstractMonomialSmallerThanFeature.java | 4 +- .../feature/AtomsSmallerThanFeature.java | 6 +- .../feature/JavaFeatureConstants.java | 60 + .../feature/MonomialsSmallerThanFeature.java | 8 +- .../prover/strategy/ArithTermFeatures.java | 18 +- ...eatures.java => IFormulaTermFeatures.java} | 2 +- .../prover/strategy/IntegerStrategy.java | 27 +- 19 files changed, 581 insertions(+), 1254 deletions(-) delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/strategy/ArithTermFeatures.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategy.java create mode 100644 key.core/src/main/java/de/uka/ilkd/key/strategy/JavaArithTermFeatures.java create mode 100644 key.core/src/main/java/de/uka/ilkd/key/strategy/JavaIntegerStrategy.java create mode 100644 key.core/src/main/java/de/uka/ilkd/key/strategy/feature/JavaFeatureConstants.java rename key.ncore.calculus/src/main/java/org/key_project/prover/strategy/{FormulaTermFeatures.java => IFormulaTermFeatures.java} (96%) 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 d2101400c23..2d93109e077 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 @@ -18,6 +18,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; @@ -33,7 +34,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/strategy/ArithTermFeatures.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/ArithTermFeatures.java deleted file mode 100644 index 3bf7238141c..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/ArithTermFeatures.java +++ /dev/null @@ -1,155 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.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.logic.op.Operator; -import org.key_project.logic.sort.Sort; -import org.key_project.prover.strategy.costbased.termfeature.TermFeature; - -class ArithTermFeatures extends StaticFeatureCollection { - - public ArithTermFeatures(IntegerLDT numbers) { - 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; - leq = numbers.getLessOrEquals(); - geq = numbers.getGreaterOrEquals(); - - intS = numbers.getNumberSymbol().sort(); - - intF = extendsTrans(intS); - - addF = op(add); - mulF = op(mul); - modF = op(mod); - divF = op(div); - jmodF = op(jmod); - jdivF = op(jdiv); - - eqF = op(eq); - geqF = op(geq); - leqF = op(leq); - - literal = op(Z); - negLiteral = opSub(Z, op(numbers.getNegativeNumberSign())); - nonNegLiteral = opSub(Z, not(op(numbers.getNegativeNumberSign()))); - zeroLiteral = - opSub(Z, opSub(numbers.getNumberLiteralFor(0), op(numbers.getNumberTerminator()))); - oneLiteral = - opSub(Z, opSub(numbers.getNumberLiteralFor(1), op(numbers.getNumberTerminator()))); - nonPosLiteral = or(zeroLiteral, negLiteral); - posLiteral = add(nonNegLiteral, not(zeroLiteral)); - atLeastTwoLiteral = add(posLiteral, not(oneLiteral)); - - charLiteral = op(C); - - constant = constantTermFeature(); - - atom = add(not(addF), not(mulF)); - linearMonomial = or(atom, opSub(mul, atom, literal)); - - // left-associatively arranged monomials, literals are only allowed - // as right-most term - monomial = or(atom, opSub(mul, - rec(mulF, or(opSub(mul, any(), not(mulF)), add(not(addF), not(literal)))), atom)); - - // left-associatively arranged polynomials - polynomial = rec(addF, or(opSub(add, any(), not(addF)), monomial)); - - nonNegMonomial = add(monomial, or(not(mulF), sub(any(), not(negLiteral)))); - posMonomial = opSub(mul, monomial, posLiteral); - negMonomial = opSub(mul, monomial, negLiteral); - nonCoeffMonomial = add(monomial, or(not(mulF), sub(any(), not(literal)))); - nonNegOrNonCoeffMonomial = add(monomial, or(not(mulF), sub(any(), not(negLiteral)))); - atLeastTwoCoeffMonomial = opSub(mul, monomial, atLeastTwoLiteral); - - intEquation = opSub(eq, add(intF, nonNegMonomial), add(intF, polynomial)); - linearEquation = opSub(eq, linearMonomial, add(intF, polynomial)); - monomialEquation = opSub(eq, add(intF, nonNegMonomial), add(intF, monomial)); - intInEquation = add(or(leqF, geqF), sub(nonNegMonomial, polynomial)); - linearInEquation = add(or(leqF, geqF), sub(linearMonomial, polynomial)); - 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)))); - } - - 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 intRelation; - - final TermFeature notContainsProduct; - final TermFeature notContainsDivMod; - -} 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 be09c621037..1964bac2165 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 @@ -61,7 +61,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) { @@ -69,7 +69,7 @@ public FOLStrategy(Proof proof, StrategyProperties strategyProperties) { this.strategyProperties = (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(); 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 f6eb24ac368..37e6cbfde8a 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 @@ -9,12 +9,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); @@ -100,4 +101,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/IntegerStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategy.java deleted file mode 100644 index fed278e1022..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/IntegerStrategy.java +++ /dev/null @@ -1,1042 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.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.strategy.feature.*; -import de.uka.ilkd.key.strategy.termProjection.*; -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.logic.Name; -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.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.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.RuleSetDispatchFeature; -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.termfeature.TermFeature; -import org.key_project.prover.strategy.costbased.termgenerator.SequentFormulasGenerator; -import org.key_project.prover.strategy.costbased.termgenerator.SubtermGenerator; - -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 IntegerStrategy extends AbstractFeatureStrategy implements ComponentStrategy { - - public static final Name NAME = new Name("Integer Strategy"); - - /// Magic constants - private static final int IN_EQ_SIMP_NON_LIN_COST = 1000; - 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; - - /// Useful [TermFeature] collections - private final ArithTermFeatures tf; - private final FormulaTermFeatures ff; - - /// configuration options extracted from [StrategyProperties] - private final boolean nonLinearArithmeticEnabled; - private final boolean divAndModuloReasoningEnabled; - 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); - - // determine configuration - nonLinearArithmeticEnabled = StrategyProperties.NON_LIN_ARITH_COMPLETION.equals( - strategyProperties.getProperty(StrategyProperties.NON_LIN_ARITH_OPTIONS_KEY)); - - divAndModuloReasoningEnabled = - nonLinearArithmeticEnabled || StrategyProperties.NON_LIN_ARITH_DEF_OPS.equals( - strategyProperties.getProperty(StrategyProperties.NON_LIN_ARITH_OPTIONS_KEY)); - - stopAtFirstNonCloseableGoal = - strategyProperties.getProperty(StrategyProperties.STOPMODE_OPTIONS_KEY) - .equals(StrategyProperties.STOPMODE_NONCLOSE); - - // setup cost computations - costComputationDispatcher = setupCostComputationF(); - approvalDispatcher = setupApprovalDispatcher(); - instantiationDispatcher = setupInstantiationF(); - - } - - @Override - public boolean isResponsibleFor(RuleSet rs) { - return costComputationDispatcher.get(rs) != null || instantiationDispatcher.get(rs) != null; - } - - private RuleSetDispatchFeature setupInstantiationF() { - enableInstantiate(); - - final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); - setupArithPrimaryCategories(d); - setupDefOpsPrimaryCategories(d); - setupInstantiationWithoutRetry(d); - setupInEqSimpInstantiation(d); - - disableInstantiate(); - return d; - } - - private RuleSetDispatchFeature setupApprovalDispatcher() { - final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); - final IntegerLDT numbers = getServices().getTypeConverter().getIntegerLDT(); - - if (arithNonLinInferences()) { - setupMultiplyInequations(d, inftyConst()); - } - // these taclets are not supposed to be applied with metavariable - // instantiations - // I'll keep it here for the moment as documentation, but comment it out - // as meta variables are no longer part of KeY 2.x - /* - * bindRuleSet ( d, "inEqSimp_pullOutGcd", isInstantiated ( "elimGcd" ) ); bindRuleSet ( d, - * "polySimp_pullOutGcd", isInstantiated ( "elimGcd" ) ); - * - * bindRuleSet ( d, "inEqSimp_nonNegSquares", isInstantiated ( "squareFac" ) ); bindRuleSet - * ( d, "inEqSimp_nonLin_divide", isInstantiated ( "divY" ) ); bindRuleSet ( d, - * "inEqSimp_nonLin_pos", isInstantiated ( "divY" ) ); bindRuleSet ( d, - * "inEqSimp_nonLin_neg", isInstantiated ( "divY" ) ); - * - * bindRuleSet ( d, "inEqSimp_signCases", isInstantiated ( "signCasesLeft" ) ); - */ - - setupNewSymApproval(d, numbers); - - - bindRuleSet(d, "defOps_div", NonDuplicateAppModPositionFeature.INSTANCE); - bindRuleSet(d, "defOps_jdiv", NonDuplicateAppModPositionFeature.INSTANCE); - - if (arithNonLinInferences()) { - setupInEqCaseDistinctionsApproval(d); - } - - return d; - } - - private RuleSetDispatchFeature setupCostComputationF() { - final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); - final IntegerLDT numbers = getServices().getTypeConverter().getIntegerLDT(); - - bindRuleSet(d, "simplify_int", inftyConst()); - - setupArithPrimaryCategories(d); - setupPolySimp(d, numbers); - setupInEqSimp(d, numbers); - - setupDefOpsPrimaryCategories(d); - - bindRuleSet(d, "order_terms", - add(applyTF("commEqRight", tf.monomial), applyTF("commEqLeft", tf.polynomial), - monSmallerThan("commEqLeft", "commEqRight", numbers), longConst(-5000))); - - 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)))))))), - longConst(-4000))); - - 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)))), - longConst(-150))); - - // 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 as 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). - setupInstantiationWithoutRetry(d); - - return d; - } - - private boolean arithNonLinInferences() { - return nonLinearArithmeticEnabled; - } - - private boolean arithDefOps() { - return divAndModuloReasoningEnabled; - } - - @Override - public boolean isStopAtFirstNonCloseableGoal() { - return stopAtFirstNonCloseableGoal; - } - - - // ////////////////////////////////////////////////////////////////////////// - // ////////////////////////////////////////////////////////////////////////// - // - // Handling of arithmetic - // - // ////////////////////////////////////////////////////////////////////////// - // ////////////////////////////////////////////////////////////////////////// - - private void setupArithPrimaryCategories(RuleSetDispatchFeature d) { - // Gaussian elimination + Euclidian algorithm for linear equations; - // Buchberger's algorithmus for handling polynomial equations over - // the integers - - bindRuleSet(d, "polySimp_expand", -4500); - bindRuleSet(d, "polySimp_directEquations", -3000); - bindRuleSet(d, "polySimp_pullOutGcd", -2250); - bindRuleSet(d, "polySimp_leftNonUnit", -2000); - bindRuleSet(d, "polySimp_saturate", 0); - - // Omega test for handling linear arithmetic and inequalities over the - // integers; cross-multiplication + case distinctions for nonlinear - // inequalities - - bindRuleSet(d, "inEqSimp_expand", -4400); - bindRuleSet(d, "inEqSimp_directInEquations", -2900); - bindRuleSet(d, "inEqSimp_propagation", -2400); - bindRuleSet(d, "inEqSimp_pullOutGcd", -2150); - bindRuleSet(d, "inEqSimp_saturate", -1900); - bindRuleSet(d, "inEqSimp_forNormalisation", -1100); - bindRuleSet(d, "inEqSimp_special_nonLin", -1400); - - if (arithNonLinInferences()) { - bindRuleSet(d, "inEqSimp_nonLin", IN_EQ_SIMP_NON_LIN_COST); - } else { - bindRuleSet(d, "inEqSimp_nonLin", inftyConst()); - } - // polynomial division, simplification of fractions and mods - bindRuleSet(d, "polyDivision", POLY_DIVISION_COST); - - } - - private void setupPolySimp(RuleSetDispatchFeature d, IntegerLDT numbers) { - - // category "expansion" (normalising polynomial terms) - - bindRuleSet(d, "polySimp_elimSubNeg", longConst(-120)); - - 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))), - longConst(-120))); - - bindRuleSet(d, "polySimp_pullOutFactor", add(applyTFNonStrict("pullOutLeft", tf.literal), - applyTFNonStrict("pullOutRight", tf.literal), longConst(-120))); - - bindRuleSet(d, "polySimp_elimOneLeft", -120); - - bindRuleSet(d, "polySimp_elimOneRight", -120); - - bindRuleSet(d, "polySimp_mulOrder", add(applyTF("commRight", tf.monomial), or( - applyTF("commLeft", tf.addF), - add(applyTF("commLeft", tf.atom), atomSmallerThan("commLeft", "commRight", numbers))), - longConst(-100))); - - bindRuleSet(d, "polySimp_mulAssoc", - SumFeature.createSum(applyTF("mulAssocMono0", tf.monomial), - applyTF("mulAssocMono1", tf.monomial), applyTF("mulAssocAtom", tf.atom), - longConst(-80))); - - bindRuleSet(d, "polySimp_addOrder", - SumFeature.createSum(applyTF("commLeft", tf.monomial), - applyTF("commRight", tf.polynomial), - monSmallerThan("commRight", "commLeft", numbers), longConst(-60))); - - bindRuleSet(d, "polySimp_addAssoc", - SumFeature.createSum(applyTF("addAssocPoly0", tf.polynomial), - applyTF("addAssocPoly1", tf.polynomial), applyTF("addAssocMono", tf.monomial), - longConst(-10))); - - bindRuleSet(d, "polySimp_dist", - SumFeature.createSum(applyTF("distSummand0", tf.polynomial), - applyTF("distSummand1", tf.polynomial), - ifZero(applyTF("distCoeff", tf.monomial), longConst(-15), - applyTF("distCoeff", tf.polynomial)), - applyTF("distSummand0", tf.polynomial), - - applyTF("distSummand1", tf.polynomial), longConst(-35))); - - // category "direct equations" - - bindRuleSet(d, "polySimp_balance", - SumFeature - .createSum(applyTF("sepResidue", tf.polynomial), - ifZero(isInstantiated("sepPosMono"), - add(applyTF("sepPosMono", tf.nonNegMonomial), - monSmallerThan("sepResidue", "sepPosMono", numbers))), - ifZero(isInstantiated("sepNegMono"), - add(applyTF("sepNegMono", tf.negMonomial), - monSmallerThan("sepResidue", "sepNegMono", numbers))), - longConst(-30))); - - bindRuleSet(d, "polySimp_normalise", add(applyTF("invertRight", tf.zeroLiteral), - applyTF("invertLeft", tf.negMonomial), longConst(-30))); - - // application of equations: some specialised rules that handle - // monomials and their coefficients properly - - 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); - - final Feature validEqApplication = add(not(eq(eqLeft, focus)), - // otherwise, the normal equation rules can and should - // be used - ifZero(applyTF(AssumptionProjection.create(0), atLeastTwoLCEquation), - add(FocusInAntecFeature.getInstance(), - applyTF(FocusFormulaProjection.INSTANCE, atLeastTwoLCEquation))), - ReducibleMonomialsFeature.createReducible(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)))); - - bindRuleSet(d, "polySimp_applyEq", add(eqMonomialFeature, longConst(1))); - - bindRuleSet(d, "polySimp_applyEqRigid", add(eqMonomialFeature, longConst(2))); - - // - bindRuleSet(d, "defOps_expandModulo", - add(NonDuplicateAppModPositionFeature.INSTANCE, longConst(-600))); - - // category "saturate" - - bindRuleSet(d, "polySimp_critPair", - ifZero(MatchedAssumesFeature.INSTANCE, - add(monSmallerThan("cpLeft1", "cpLeft2", numbers), - not(TrivialMonomialLCRFeature.create(instOf("cpLeft1"), instOf("cpLeft2")))))); - } - - private void setupDivModDivision(RuleSetDispatchFeature d) { - - 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)), - inftyConst())); - - final Feature isReduciblePoly = - sum(numTerm, SubtermGenerator.rightTraverse(instOf("divNum"), tf.addF), checkNumTerm); - - // polynomial division modulo equations of the antecedent - - final Feature checkCoeffE = ifZero(contains(divCoeff, FocusProjection.create(0)), - // 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), - ifZero(applyTF(numTerm, tf.addF), longConst(0), sum(divCoeff, - MultiplesModEquationsGenerator.create(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, instOf("divDenom"), ifZero(isReduciblePoly, - // no possible division has been found so far - add(NotInScopeOfModalityFeature.INSTANCE, ifZero(isReduciblePolyE, - // try again later - longConst(-POLY_DIVISION_COST)))))), - longConst(100))); - - } - - - // 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 as 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 setupPolySimpInstantiationWithoutRetry(RuleSetDispatchFeature d) { - final IntegerLDT numbers = getServices().getTypeConverter().getIntegerLDT(); - - // category "direct equations" - - setupPullOutGcd(d, "polySimp_pullOutGcd", false); - - // category "polynomial division" - - setupDivModDivision(d); - - // category "handling of equations with non-unit-coefficients on - // left-hand side" - - bindRuleSet(d, "polySimp_newSym", - 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")))))); - - 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, - applyTF("aePseudoLeft", add(tf.nonCoeffMonomial, not(tf.atom))), - applyTF("aePseudoLeftCoeff", tf.atLeastTwoLiteral), - applyTF("aePseudoRight", tf.polynomial), - MonomialsSmallerThanFeature.create(instOf("aePseudoRight"), - instOf("aePseudoLeft"), numbers), - let(divisor, instOf("aePseudoLeft"), - let(dividend, instOf("aePseudoTargetLeft"), - add(ReducibleMonomialsFeature.createReducible(dividend, divisor), - instantiate("aePseudoTargetFactor", - ReduceMonomialsProjection.create(dividend, divisor))))))))); - } - - private void setupNewSymApproval(RuleSetDispatchFeature d, IntegerLDT 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"), - 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 Feature instantiateDivs; - if (roundingUp) { - instantiateDivs = add( - instantiate("elimGcdLeftDiv", - DividePolynomialsProjection.createRoundingUp(gcd, instOf("elimGcdLeft"))), - instantiate("elimGcdRightDiv", - DividePolynomialsProjection.createRoundingUp(gcd, instOf("elimGcdRight")))); - } else { - instantiateDivs = add( - instantiate("elimGcdLeftDiv", - DividePolynomialsProjection.createRoundingDown(gcd, instOf("elimGcdLeft"))), - instantiate("elimGcdRightDiv", - DividePolynomialsProjection.createRoundingDown(gcd, instOf("elimGcdRight")))); - } - bindRuleSet(d, ruleSet, - add(applyTF("elimGcdLeft", tf.nonNegMonomial), applyTF("elimGcdRight", tf.polynomial), - let(gcd, CoeffGcdProjection.create(instOf("elimGcdLeft"), instOf("elimGcdRight")), - add(applyTF(gcd, tf.atLeastTwoLiteral), instantiate("elimGcd", gcd), - instantiateDivs)))); - } - - private void setupInEqSimp(RuleSetDispatchFeature d, IntegerLDT numbers) { - - // category "expansion" (normalising inequations) - - bindRuleSet(d, "inEqSimp_moveLeft", -90); - - bindRuleSet(d, "inEqSimp_makeNonStrict", -80); - - bindRuleSet(d, "inEqSimp_commute", - SumFeature.createSum(applyTF("commRight", tf.monomial), - applyTF("commLeft", tf.polynomial), - monSmallerThan("commLeft", "commRight", numbers), longConst(-40))); - - // 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))))); - - // category "direct inequations" - - // this is copied from "polySimp_balance" - bindRuleSet(d, "inEqSimp_balance", - add(applyTF("sepResidue", tf.polynomial), - ifZero(isInstantiated("sepPosMono"), - add(applyTF("sepPosMono", tf.nonNegMonomial), - monSmallerThan("sepResidue", "sepPosMono", numbers))), - ifZero(isInstantiated("sepNegMono"), add(applyTF("sepNegMono", tf.negMonomial), - monSmallerThan("sepResidue", "sepNegMono", numbers))))); - - // this is copied from "polySimp_normalise" - bindRuleSet(d, "inEqSimp_normalise", - add(applyTF("invertRight", tf.zeroLiteral), applyTF("invertLeft", tf.negMonomial))); - - // category "saturate" - - bindRuleSet(d, "inEqSimp_antiSymm", longConst(-20)); - - bindRuleSet(d, "inEqSimp_exactShadow", - SumFeature.createSum(applyTF("esLeft", tf.nonCoeffMonomial), - applyTFNonStrict("esCoeff2", tf.nonNegLiteral), applyTF("esRight2", tf.polynomial), - ifZero(MatchedAssumesFeature.INSTANCE, - SumFeature.createSum(applyTFNonStrict("esCoeff1", tf.nonNegLiteral), - applyTF("esRight1", tf.polynomial), - not(PolynomialValuesCmpFeature.leq(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, - applyTF("contradRightSmaller", tf.polynomial), - applyTF("contradRightBigger", tf.polynomial), - applyTFNonStrict("contradCoeffSmaller", tf.posLiteral), - applyTFNonStrict("contradCoeffBigger", tf.posLiteral), - PolynomialValuesCmpFeature.lt(instOf("contradRightSmaller"), - instOf("contradRightBigger"), instOfNonStrict("contradCoeffBigger"), - instOfNonStrict("contradCoeffSmaller")))))); - - bindRuleSet(d, "inEqSimp_contradEqs", - add(applyTF("contradLeft", tf.monomial), - ifZero(MatchedAssumesFeature.INSTANCE, - SumFeature.createSum(applyTF("contradRightSmaller", tf.polynomial), - applyTF("contradRightBigger", tf.polynomial), PolynomialValuesCmpFeature - .lt(instOf("contradRightSmaller"), instOf("contradRightBigger")))), - longConst(-60))); - - bindRuleSet(d, "inEqSimp_strengthen", longConst(-30)); - - bindRuleSet(d, "inEqSimp_subsumption", - add(applyTF("subsumLeft", tf.monomial), - ifZero(MatchedAssumesFeature.INSTANCE, - SumFeature.createSum(DiffFindAndIfFeature.INSTANCE, - applyTF("subsumRightSmaller", tf.polynomial), - applyTF("subsumRightBigger", tf.polynomial), - applyTFNonStrict("subsumCoeffSmaller", tf.posLiteral), - applyTFNonStrict("subsumCoeffBigger", tf.posLiteral), - PolynomialValuesCmpFeature.leq(instOf("subsumRightSmaller"), - instOf("subsumRightBigger"), instOfNonStrict("subsumCoeffBigger"), - instOfNonStrict("subsumCoeffSmaller")))))); - - // category "handling of non-linear inequations" - - if (arithNonLinInferences()) { - setupMultiplyInequations(d, longConst(100)); - - bindRuleSet(d, "inEqSimp_split_eq", add(TopLevelFindFeature.SUCC, longConst(-100))); - - bindRuleSet(d, "inEqSimp_signCases", not(isInstantiated("signCasesLeft"))); - } - - // category "normalisation of formulas" - // (e.g., quantified formulas, where the normal sequent calculus - // does not do any normalisation) - - 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")))); - - 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")))); - - 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")))); - - final Term tOne = getServices().getTermBuilder().zTerm("1"); - final TermBuffer one = new TermBuffer() { - @Override - public void setContent(Term term, MutableState mState) {} - - @Override - public @NonNull Term getContent(MutableState mState) { - return tOne; - } - - @Override - public @NonNull Term toTerm(RuleApp app, PosInOccurrence pos, - Goal goal, MutableState mState) { - return tOne; - } - }; - - final JTerm tTwo = getServices().getTermBuilder().zTerm("2"); - final TermBuffer two = new TermBuffer() { - @Override - public void setContent(Term term, MutableState mState) {} - - @Override - public @NonNull Term getContent(MutableState mState) { - return tTwo; - } - - @Override - public @NonNull Term toTerm(RuleApp app, PosInOccurrence pos, - Goal goal, MutableState mState) { - return tTwo; - } - }; - - bindRuleSet(d, "inEqSimp_or_tautInEqs", - SumFeature.createSum(applyTF("tautLeft", tf.monomial), - applyTF("tautRightSmaller", tf.polynomial), - applyTF("tautRightBigger", tf.polynomial), - PolynomialValuesCmpFeature.leq(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( - opTerm(numbers.getAdd(), one, instOf("weakenRightSmaller")), - instOf("weakenRightBigger")))); - - bindRuleSet(d, "inEqSimp_or_antiSymm", - SumFeature.createSum(applyTF("antiSymmLeft", tf.monomial), - applyTF("antiSymmRightSmaller", tf.polynomial), - applyTF("antiSymmRightBigger", tf.polynomial), - PolynomialValuesCmpFeature.eq( - opTerm(numbers.getAdd(), two, instOf("antiSymmRightSmaller")), - instOf("antiSymmRightBigger")))); - - } - - private void setupMultiplyInequations(RuleSetDispatchFeature d, Feature notAllowedF) { - final TermBuffer intRel = new TermBuffer(); - - /* - * final Feature partiallyBounded = not ( sum ( intRel, SequentFormulasGenerator.sequent (), - * not ( add ( applyTF ( intRel, tf.intRelation ), InEquationMultFeature .partiallyBounded ( - * instOf ( "multLeft" ), instOf ( "multFacLeft" ), sub ( intRel, 0 ) ) ) ) ) ); - */ - - final Feature totallyBounded = not(sum(intRel, SequentFormulasGenerator.sequent(), - not(add(applyTF(intRel, tf.intRelation), InEquationMultFeature - .totallyBounded(instOf("multLeft"), instOf("multFacLeft"), sub(intRel, 0)))))); - - final Feature exactlyBounded = not(sum(intRel, SequentFormulasGenerator.sequent(), - not(add(applyTF(intRel, tf.intRelation), InEquationMultFeature - .exactlyBounded(instOf("multLeft"), instOf("multFacLeft"), sub(intRel, 0)))))); - - // this is a bit hackish - // - // really, one would need a possibility to express that the cost - // computation for the rule application should be post-poned (and - // repeated at a later point) if the product of the left sides does not - // have any similarity with existing left sides - // (AllowInEquationMultiplication returns false). We - // simulate this by returning non-infinite costs here, but by declining - // the rule application in isApprovedApp). This is not - // perfect, because it is not possible to distinguish between the - // re-cost-computation delay and the normal costs for a rule application - bindRuleSet(d, "inEqSimp_nonLin_multiply", add( - applyTF("multLeft", tf.nonNegMonomial), - applyTF("multRight", tf.polynomial), - ifZero(MatchedAssumesFeature.INSTANCE, - SumFeature.createSum( - applyTF("multFacLeft", tf.nonNegMonomial), - ifZero(applyTF("multRight", tf.literal), longConst(-100)), - ifZero(applyTF("multFacRight", tf.literal), longConst(-100), - applyTF("multFacRight", tf.polynomial)), - /* - * ifZero ( applyTF ( "multRight", tf.literal ), longConst ( -100 ), applyTF ( - * "multRight", tf.polynomial ) ), ifZero ( applyTF ( "multFacRight", tf.literal - * ), longConst ( -100 ), applyTF ( "multFacRight", tf.polynomial ) ), - */ - not(TermSmallerThanFeature.create(FocusProjection.create(0), - AssumptionProjection.create(0))), - ifZero(exactlyBounded, longConst(0), - ifZero(totallyBounded, longConst(100), notAllowedF)) - /* - * ifZero ( partiallyBounded, longConst ( 400 ), notAllowedF ) ) ), - */ - /* - * applyTF ( "multLeft", rec ( tf.mulF, longTermConst ( 20 ) ) ), applyTF ( - * "multFacLeft", rec ( tf.mulF, longTermConst ( 20 ) ) ), applyTF ( "multRight", - * rec ( tf.addF, longTermConst ( 4 ) ) ), applyTF ( "multFacRight", rec ( tf.addF, - * longTermConst ( 4 ) ) ), - */ - ), notAllowedF))); - } - - private void setupInEqSimpInstantiation(RuleSetDispatchFeature d) { - // category "handling of non-linear inequations" - - setupSquaresAreNonNegative(d); - - if (arithNonLinInferences()) { - setupInEqCaseDistinctions(d); - } - } - - // 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 as 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 setupInEqSimpInstantiationWithoutRetry(RuleSetDispatchFeature d) { - // category "direct inequations" - - setupPullOutGcd(d, "inEqSimp_pullOutGcd_leq", false); - setupPullOutGcd(d, "inEqSimp_pullOutGcd_geq", true); - - // more efficient (but not confluent) versions for the antecedent - bindRuleSet(d, "inEqSimp_pullOutGcd_antec", -10); - - // category "handling of non-linear inequations" - - 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, - 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)))))))); - - 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(); - - bindRuleSet(d, ruleSet, - SumFeature - .createSum(applyTF("divProd", tf.nonCoeffMonomial), - applyTFNonStrict("divProdBoundPos", tf.posLiteral), - applyTFNonStrict("divProdBoundNeg", tf.negLiteral), - ifZero(MatchedAssumesFeature.INSTANCE, - let(divisor, instOf("divX"), let(dividend, instOf("divProd"), - SumFeature.createSum(applyTF(divisor, tf.nonCoeffMonomial), - not(applyTF(dividend, eq(divisor))), - applyTFNonStrict("divXBoundNonPos", tf.nonPosLiteral), - applyTFNonStrict("divXBoundNonNeg", tf.nonNegLiteral), - ReducibleMonomialsFeature.createReducible(dividend, divisor), - let(quotient, - ReduceMonomialsProjection.create(dividend, divisor), add( - sum(antecFor, SequentFormulasGenerator.antecedent(), - not(applyTF(antecFor, - pos ? opSub(tf.geq, eq(quotient), tf.posLiteral) - : opSub(tf.leq, eq(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 Feature productContainsSquare = - applyTF(sub(product, 0), or(eq(factor), opSub(tf.mul, any(), eq(factor)))); - final Feature productIsProduct = applyTF(product, opSub(tf.mul, any(), not(tf.mulF))); - - bindRuleSet(d, "inEqSimp_nonNegSquares", - forEach(intRel, SequentFormulasGenerator.sequent(), - ifZero(applyTF(intRel, tf.intRelation), - forEach(product, SubtermGenerator.leftTraverse(sub(intRel, 0), tf.mulF), - ifZero(productIsProduct, let(factor, sub(product, 1), - ifZero(productContainsSquare, instantiate("squareFac", factor)))))))); - } - - private void setupInEqCaseDistinctions(RuleSetDispatchFeature d) { - 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), - forEach(atom, SubtermGenerator.leftTraverse(sub(intRel, 0), tf.mulF), - SumFeature.createSum(applyTF(atom, add(tf.atom, not(tf.literal))), - allowPosNegCaseDistinction(atom), instantiate("signCasesLeft", atom), - longConst(IN_EQ_SIMP_NON_LIN_COST + 200) - // , - // applyTF ( atom, rec ( any (), - // longTermConst ( 5 ) ) ) - )))); - - bindRuleSet(d, "inEqSimp_signCases", posNegSplitting); - - final Feature strengthening = forEach(intRel, SequentFormulasGenerator.antecedent(), - SumFeature.createSum( - applyTF(intRel, add(or(tf.geqF, tf.leqF), sub(tf.atom, tf.literal))), - instantiate("cutFormula", opTerm(tf.eq, sub(intRel, 0), sub(intRel, 1))), - longConst(IN_EQ_SIMP_NON_LIN_COST + 300) - // , - // applyTF ( sub ( intRel, 0 ), - // rec ( any (), longTermConst ( 5 ) ) ) - )); - - final Feature rootInferences = forEach(intRel, SequentFormulasGenerator.antecedent(), - add(isRootInferenceProducer(intRel), - forEach(rootInf, RootsGenerator.create(intRel, getServices()), - add(instantiate("cutFormula", rootInf), - ifZero(applyTF(rootInf, op(Junctor.OR)), longConst(50)), - ifZero(applyTF(rootInf, op(Junctor.AND)), longConst(20)))), - longConst(IN_EQ_SIMP_NON_LIN_COST))); - - // noinspection unchecked - bindRuleSet(d, "cut", oneOf(new Feature[] { strengthening, rootInferences })); - } - - 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); - - return add(not(succIntEquationExists()), - sum(antecFor, SequentFormulasGenerator.antecedent(), - not(applyTF(antecFor, or(opSub(tf.eq, eqAtom, any()), - 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(); - - return not(sum(succFor, SequentFormulasGenerator.succedent(), - 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))))))); - } - - // ////////////////////////////////////////////////////////////////////////// - // ////////////////////////////////////////////////////////////////////////// - // - // Axiomatisation and algorithms for further arithmetic operations: - // division, modulus, modular Java operations - // - // ////////////////////////////////////////////////////////////////////////// - // ////////////////////////////////////////////////////////////////////////// - - private void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { - - if (arithDefOps()) { - // 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, - applyTF("divNum", tf.polynomial), applyTF("divDenom", tf.polynomial), - applyTF("divNum", tf.notContainsDivMod), - applyTF("divDenom", tf.notContainsDivMod), - ifZero(isBelow(ff.modalOperator), longConst(200)))); - - 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(200)))); - - bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), - applyTF("divDenom", tf.polynomial), longConst(-5000))); - - setupDefOpsExpandMod(d); - - bindRuleSet(d, "defOps_expandRanges", -8000); - bindRuleSet(d, "defOps_expandJNumericOp", -500); - bindRuleSet(d, "defOps_modHomoEq", -5000); - } 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(-4000))); - - bindRuleSet(d, "defOps_mod", add(applyTF("divNum", tf.literal), - applyTF("divDenom", tf.literal), longConst(-4000))); - - bindRuleSet(d, "defOps_expandRanges", inftyConst()); - bindRuleSet(d, "defOps_expandJNumericOp", inftyConst()); - bindRuleSet(d, "defOps_modHomoEq", inftyConst()); - } - - } - - private void setupDefOpsExpandMod(RuleSetDispatchFeature d) { - 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))); - - final Feature exSubsumedModulus = add(applyTF("divDenom", tf.literal), - not(sum(superTerm, - SuperTermGenerator.upwardsWithIndex(sub(or(tf.addF, tf.mulF), any()), - getServices()), - not(subsumedModulus)))); - - bindRuleSet(d, "defOps_mod", - ifZero(add(applyTF("divNum", tf.literal), applyTF("divDenom", tf.literal)), - longConst(-4000), - SumFeature.createSum(applyTF("divNum", tf.polynomial), - applyTF("divDenom", tf.polynomial), - ifZero(isBelow(ff.modalOperator), exSubsumedModulus, - or(add(applyTF("divNum", tf.notContainsDivMod), - applyTF("divDenom", tf.notContainsDivMod)), exSubsumedModulus)), - longConst(-3500)))); - } - - /** - * 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). - */ - 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); - - } - - @Override - public RuleAppCost instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, - MutableState mState) { - return instantiationDispatcher.computeCost(app, pio, goal, mState); - } - - @Override - public Name name() { - return NAME; - } - - @Override - public > RuleAppCost computeCost(RuleApp app, - PosInOccurrence pos, Goal goal, MutableState mState) { - return this.costComputationDispatcher.computeCost(app, pos, goal, mState); - } - - @Override - public Set getResponsibilities(StrategyAspect aspect) { - var set = new HashSet(); - set.addAll(getDispatcher(aspect).ruleSets()); - return set; - } - - @Override - public RuleSetDispatchFeature getDispatcher(StrategyAspect aspect) { - return switch (aspect) { - case StrategyAspect.Cost -> costComputationDispatcher; - case StrategyAspect.Instantiation -> instantiationDispatcher; - case StrategyAspect.Approval -> approvalDispatcher; - }; - } - - @Override - public boolean isResponsibleFor(IBuiltInRule rule) { - return false; - } -} 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 3f85df875ae..8dc5746b952 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 @@ -10,7 +10,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 = """ @@ -48,8 +48,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 @@ -60,6 +62,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/JavaArithTermFeatures.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaArithTermFeatures.java new file mode 100644 index 00000000000..dd0a8310468 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaArithTermFeatures.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 + * SPDX-License-Identifier: GPL-2.0-only */ +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/JavaCardDLStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java index de8ed39d82a..530ecabcb38 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 @@ -57,7 +57,7 @@ public class JavaCardDLStrategy extends AbstractFeatureStrategy implements Compo private final HeapLDT heapLDT; - private final ArithTermFeatures tf; + private final JavaArithTermFeatures tf; private final FormulaTermFeatures ff; @@ -67,7 +67,7 @@ protected JavaCardDLStrategy(Proof proof, StrategyProperties strategyProperties) this.strategyProperties = (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(); 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..394d1b365d2 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaIntegerStrategy.java @@ -0,0 +1,306 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.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.RuleSet; +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.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; + + 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()); + this.proof = proof; + } + + @Override + protected IIntLdt intLDT() { + return proof.getServices().getTypeConverter().getIntegerLDT(); + } + + protected RuleSetDispatchFeature setupApprovalDispatcher() { + final RuleSetDispatchFeature d = super.setupApprovalDispatcher(); + + bindRuleSet(d, "defOps_jdiv", NonDuplicateAppModPositionFeature.INSTANCE); + + return d; + } + + // ////////////////////////////////////////////////////////////////////////// + // ////////////////////////////////////////////////////////////////////////// + // + // Axiomatisation and algorithms for further arithmetic operations: + // division, modulus, modular Java operations + // + // ////////////////////////////////////////////////////////////////////////// + // ////////////////////////////////////////////////////////////////////////// + + protected void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { + super.setupDefOpsPrimaryCategories(d); + if (arithDefOps()) { + 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(200)))); + + bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), + applyTF("divDenom", tf.polynomial), longConst(-5000))); + } else { + bindRuleSet(d, "defOps_jdiv", inftyConst()); + + bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), + applyTF("divDenom", tf.literal), longConst(-4000))); + } + + } + + @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, + ProjectionToTerm targetCandidate) { + return InEquationMultFeature.exactlyBounded(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)))); + } +} 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 e05aac3840c..a4d878f0dd2 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 @@ -51,7 +51,7 @@ public class ModularJavaDLStrategy extends AbstractFeatureStrategy { private final StrategyProperties strategyProperties; private final Feature reduceInstTillMaxF; - private final ArithTermFeatures tf; + private final JavaArithTermFeatures tf; private final Feature totalCost; private final ResponsibleStrategyCache responsibleStrategyCache; @@ -61,7 +61,7 @@ public ModularJavaDLStrategy(Proof proof, List> componen 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); @@ -126,7 +126,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", 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 69308225644..e0abb904fa9 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 @@ -42,14 +42,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(); 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 e2edca94b5b..718418badc5 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 @@ -51,7 +51,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(); 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 3c69ff78ab3..98fea1e7ae1 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 @@ -3,11 +3,11 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.strategy.feature; -import de.uka.ilkd.key.ldt.IntegerLDT; import de.uka.ilkd.key.logic.op.SkolemTermSV; 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.Name; import org.key_project.logic.Term; import org.key_project.logic.op.Function; @@ -23,7 +23,7 @@ public abstract class AbstractMonomialSmallerThanFeature extends SmallerThanFeat private final Function add, mul, Z; - protected AbstractMonomialSmallerThanFeature(IntegerLDT numbers) { + protected AbstractMonomialSmallerThanFeature(IIntLdt numbers) { this.add = numbers.getAdd(); this.mul = numbers.getMul(); this.Z = numbers.getNumberSymbol(); 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 e4ec1cc7e02..101227aa273 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 @@ -3,10 +3,10 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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; @@ -25,7 +25,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; @@ -34,7 +34,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/JavaFeatureConstants.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/JavaFeatureConstants.java new file mode 100644 index 00000000000..c9d5d810443 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/JavaFeatureConstants.java @@ -0,0 +1,60 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.strategy.feature; + +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; + +public class JavaFeatureConstants implements FeatureConstants { + @Override + public ProjectionToTerm focusProjection() { + return null; + } + + @Override + public ProjectionToTerm focusProjection(int stepsUpwards) { + return null; + } + + @Override + public ProjectionToTerm focusFormulaProjection() { + return null; + } + + @Override + public Feature matchedAssumesFeature() { + return null; + } + + @Override + public Feature nonDuplicateAppModPositionFeature() { + return null; + } + + @Override + public Feature notInScopeOfModalityFeature() { + return null; + } + + @Override + public Feature diffFindAndIfFeature() { + return null; + } + + @Override + public Feature topLevelFindSucc() { + return null; + } + + @Override + public Feature checkApplyEqFeature() { + return null; + } + + @Override + public Feature findRightishFeature() { + return null; + } +} 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 b9209f7d756..46725088fad 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 @@ -4,10 +4,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; @@ -37,7 +37,7 @@ public class MonomialsSmallerThanFeature extends AbstractMonomialSmallerThanFeat private MonomialsSmallerThanFeature(ProjectionToTerm left, ProjectionToTerm right, - IntegerLDT numbers) { + IIntLdt numbers) { super(numbers); this.left = left; this.right = right; @@ -48,7 +48,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()), @@ -56,7 +56,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.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java index 28a84a18f67..5e770995811 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java @@ -26,10 +26,10 @@ public class ArithTermFeatures extends StaticFeatureCollection { final TermFeature addF; final TermFeature mulF; - final TermFeature modF; - final TermFeature divF; + final protected TermFeature modF; + final protected TermFeature divF; - final TermFeature eqF; + final public TermFeature eqF; final TermFeature leqF; final TermFeature geqF; @@ -40,9 +40,9 @@ public class ArithTermFeatures extends StaticFeatureCollection { // left-associatively arranged monomials final TermFeature monomial; // left-associatively arranged polynomials - final TermFeature polynomial; + final public TermFeature polynomial; - final TermFeature literal; + final public TermFeature literal; final TermFeature posLiteral; final TermFeature negLiteral; final TermFeature nonNegLiteral; @@ -58,15 +58,15 @@ public class ArithTermFeatures extends StaticFeatureCollection { final TermFeature nonNegOrNonCoeffMonomial; final TermFeature atLeastTwoCoeffMonomial; - final TermFeature intEquation; + final public TermFeature intEquation; final TermFeature linearEquation; final TermFeature monomialEquation; - final TermFeature intInEquation; + final public TermFeature intInEquation; final TermFeature linearInEquation; final TermFeature intRelation; - final TermFeature notContainsProduct; - final TermFeature notContainsDivMod; + final public TermFeature notContainsProduct; + public TermFeature notContainsDivMod; public ArithTermFeatures(IIntLdt numbers, Operator eq) { Z = numbers.getNumberSymbol(); diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FormulaTermFeatures.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IFormulaTermFeatures.java similarity index 96% rename from key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FormulaTermFeatures.java rename to key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IFormulaTermFeatures.java index 26e3318f506..f8853b25877 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/FormulaTermFeatures.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IFormulaTermFeatures.java @@ -5,7 +5,7 @@ import org.key_project.prover.strategy.costbased.termfeature.TermFeature; -public interface FormulaTermFeatures { +public interface IFormulaTermFeatures { TermFeature forF(); TermFeature orF(); diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java index 22433e16ca1..2e822eda4c9 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java @@ -45,8 +45,8 @@ public abstract class IntegerStrategy> extends AbstractFe private final RuleSetDispatchFeature instantiationDispatcher; /// Useful [TermFeature] collections - private final ArithTermFeatures tf; - private final FormulaTermFeatures ff; + protected final ArithTermFeatures tf; + protected final IFormulaTermFeatures ff; /// configuration options extracted from [StrategyProperties] private final boolean nonLinearArithmeticEnabled; @@ -55,7 +55,7 @@ public abstract class IntegerStrategy> extends AbstractFe FeatureConstants featureConstants; - public IntegerStrategy(ArithTermFeatures tf, FormulaTermFeatures ff, + public IntegerStrategy(ArithTermFeatures tf, IFormulaTermFeatures ff, boolean nonLinearArithmeticEnabled, boolean divAndModuloReasoningEnabled, boolean stopAtFirstNonCloseableGoal, FeatureConstants featureConstants) { this.tf = tf; @@ -96,7 +96,7 @@ private boolean arithNonLinInferences() { return nonLinearArithmeticEnabled; } - private boolean arithDefOps() { + protected boolean arithDefOps() { return divAndModuloReasoningEnabled; } @@ -166,7 +166,7 @@ private RuleSetDispatchFeature setupCostComputationF() { return d; } - private RuleSetDispatchFeature setupApprovalDispatcher() { + protected RuleSetDispatchFeature setupApprovalDispatcher() { final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); final IIntLdt numbers = intLDT(); @@ -882,8 +882,7 @@ private Feature succIntEquationExists() { // ////////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////// - private void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { - + protected void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { if (arithDefOps()) { // the axiom defining division only has to be inserted once, because // it adds equations to the antecedent @@ -894,16 +893,6 @@ private void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { applyTF("divDenom", tf.notContainsDivMod), ifZero(isBelow(ff.modalOperator()), longConst(200)))); - bindRuleSet(d, "defOps_jdiv", - 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(200)))); - - bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), - applyTF("divDenom", tf.polynomial), longConst(-5000))); - setupDefOpsExpandMod(d); bindRuleSet(d, "defOps_expandRanges", -8000); @@ -911,10 +900,6 @@ private void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { bindRuleSet(d, "defOps_modHomoEq", -5000); } 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(-4000))); bindRuleSet(d, "defOps_mod", add(applyTF("divNum", tf.literal), applyTF("divDenom", tf.literal), longConst(-4000))); From e9dae47718cc6ddfd1a27c336266b1799adea687 Mon Sep 17 00:00:00 2001 From: Drodt Date: Wed, 10 Jun 2026 13:45:35 +0200 Subject: [PATCH 6/9] Solve compiler errors --- ...repareInfFlowContractPreBranchesMacro.java | 6 +- .../strategy/SymbolicExecutionStrategy.java | 2 + .../de/uka/ilkd/key/strategy/FOLStrategy.java | 12 ++- .../uka/ilkd/key/strategy/JFOLStrategy.java | 3 + ....java => JavaAbstractFeatureStrategy.java} | 32 +------ .../ilkd/key/strategy/JavaCardDLStrategy.java | 13 ++- .../key/strategy/JavaIntegerStrategy.java | 8 ++ .../uka/ilkd/key/strategy/JavaStrategy.java | 26 ----- .../key/strategy/ModularJavaDLStrategy.java | 2 +- .../uka/ilkd/key/strategy/StringStrategy.java | 8 +- .../uka/ilkd/key/strategy/SymExStrategy.java | 4 +- .../strategy/AbstractFeatureStrategy.java | 26 +++++ .../prover/strategy/ArithTermFeatures.java | 10 +- .../strategy/StaticFeatureCollection.java | 96 +++++++++---------- .../key_project/prover/strategy/Strategy.java | 10 +- 15 files changed, 133 insertions(+), 125 deletions(-) rename key.core/src/main/java/de/uka/ilkd/key/strategy/{AbstractFeatureStrategy.java => JavaAbstractFeatureStrategy.java} (82%) 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 c8a18c337a8..2a0efdc2a3d 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 @@ -9,7 +9,7 @@ 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.JavaAbstractFeatureStrategy; import org.key_project.logic.Name; import org.key_project.prover.proof.ProofGoal; @@ -23,6 +23,8 @@ import org.jspecify.annotations.NonNull; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.hasLabel; + /** * The macro UseInformationFlowContractMacro applies all applicable information flow contracts. @@ -67,7 +69,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.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java index b297b3b05da..8b6b1f04c7b 100644 --- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java +++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/strategy/SymbolicExecutionStrategy.java @@ -40,6 +40,8 @@ import org.jspecify.annotations.NonNull; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.hasLabel; + /** * {@link JavaStrategy} to use for symbolic execution. */ 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 1964bac2165..63c73fd19e5 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 @@ -43,13 +43,15 @@ import org.jspecify.annotations.NonNull; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.*; + /// Strategy for general FOL rules. This does not consider other /// theories like integers or Java-specific functions. /// /// 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; @@ -118,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, + t -> StaticFeatureCollection.eq((TermBuffer) t))))); bindRuleSet(d, "update_elim", add(longConst(-8000), ScaleFeature.createScaled(findDepthFeature, 10.0))); @@ -414,7 +417,8 @@ private void setupQuantifierInstantiationApproval(RuleSetDispatchFeature d) { final TermBuffer varInst = new TermBuffer(); bindRuleSet(d, "gamma", add(isInstantiated("t"), - not(sum(varInst, HeuristicInstantiation.INSTANCE, not(eq(instOf("t"), varInst)))), + not(sum(varInst, HeuristicInstantiation.INSTANCE, + not(StaticFeatureCollection.eq(instOf("t"), varInst)))), InstantiationCostScalerFeature.create(InstantiationCost.create(instOf("t")), longConst(0)))); @@ -422,7 +426,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()); 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 490fba79421..099ea6c151f 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 @@ -15,6 +15,9 @@ 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/AbstractFeatureStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaAbstractFeatureStrategy.java similarity index 82% 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 64c77d25502..d2e0890357a 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 @@ -16,16 +16,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.RuleSetDispatchFeature; -import org.key_project.prover.strategy.costbased.feature.instantiator.BackTrackingManager; 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 +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, - 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()); - } - /** * 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/JavaCardDLStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java index 530ecabcb38..160731feeed 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 @@ -34,12 +34,15 @@ import org.jspecify.annotations.NonNull; +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(); @@ -77,6 +80,8 @@ protected JavaCardDLStrategy(Proof proof, StrategyProperties strategyProperties) costComputationF = setupGlobalF(costComputationDispatcher); instantiationF = setupGlobalF(instantiationDispatcher); approvalF = add(setupApprovalF(), approvalDispatcher); + + computeCost(null, null, null); } @@ -264,7 +269,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; @@ -437,7 +443,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(), 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 index 394d1b365d2..2e07ca1f694 100644 --- 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 @@ -20,11 +20,14 @@ 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.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; @@ -303,4 +306,9 @@ protected Feature isBelow(TermFeature t) { 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 index 6d03b495d79..8be37316dd4 100644 --- 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 @@ -7,34 +7,14 @@ import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.settings.ProofSettings; -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.key_project.prover.strategy.costbased.MutableState; -import org.key_project.prover.strategy.costbased.RuleAppCost; /** * Generic interface for evaluating the cost of a RuleApp with regard to a specific strategy */ public interface JavaStrategy extends Strategy { - /** - * Evaluate the cost of a RuleApp. Starts a new independent computation. - * - * @param app the RuleApp - * @param pos position where app is to be applied - * @param goal the goal on which app is to be applied - * @return the cost of the rule application expressed as a - * RuleAppCost object. TopRuleAppCost.INSTANCE - * indicates that the rule shall not be applied at all (it is discarded by - * the strategy). - */ - @Override - default RuleAppCost computeCost(RuleApp app, PosInOccurrence pos, Goal goal) { - return computeCost(app, pos, goal, new MutableState()); - } - /** * Updates the {@link JavaStrategy} for the given {@link Proof} by setting the * {@link JavaStrategy}'s @@ -57,10 +37,4 @@ static void updateStrategySettings(Proof proof, StrategyProperties p) { @Override default boolean isResponsibleFor(RuleSet rs) { return false; } - - @Override - default RuleAppCost instantiateApp(RuleApp app, PosInOccurrence pio, - Goal goal, MutableState mState) { - return null; - } } 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 a4d878f0dd2..e513591e3f4 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 @@ -43,7 +43,7 @@ /// 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. 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 e0abb904fa9..701665956cd 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 @@ -31,10 +31,12 @@ import org.jspecify.annotations.NonNull; +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, @@ -138,8 +140,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", longConst(100)); 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 718418badc5..f5d600f11fd 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 @@ -32,10 +32,12 @@ import org.jspecify.annotations.NonNull; +import static de.uka.ilkd.key.strategy.StaticFeatureCollection.*; + /// 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; 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 index ef0d3872f56..df088ab7db1 100644 --- 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 @@ -5,9 +5,15 @@ 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; @@ -74,4 +80,24 @@ protected Feature oneOf(Feature[] 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.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java index 5e770995811..a8c4da2b490 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/ArithTermFeatures.java @@ -18,11 +18,11 @@ public class ArithTermFeatures extends StaticFeatureCollection { final Function mod; final Function div; - final Operator eq; + final public Operator eq; final Function leq; final Function geq; - final TermFeature intF; + final public TermFeature intF; final TermFeature addF; final TermFeature mulF; @@ -34,7 +34,7 @@ public class ArithTermFeatures extends StaticFeatureCollection { final TermFeature geqF; final TermFeature constant; - final TermFeature atom; + final public TermFeature atom; final TermFeature linearMonomial; // left-associatively arranged monomials @@ -44,8 +44,8 @@ public class ArithTermFeatures extends StaticFeatureCollection { final public TermFeature literal; final TermFeature posLiteral; - final TermFeature negLiteral; - final TermFeature nonNegLiteral; + final public TermFeature negLiteral; + final public TermFeature nonNegLiteral; final TermFeature nonPosLiteral; final TermFeature zeroLiteral; final TermFeature oneLiteral; 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 index 8a1ae2f7cf2..00e5cd60179 100644 --- 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 @@ -25,62 +25,62 @@ /// /// @author Kai Wallisch \ public class StaticFeatureCollection { - protected static Feature longConst(long a) { + public static Feature longConst(long a) { return ConstFeature.createConst(cost(a)); } - protected static Feature inftyConst() { + public static Feature inftyConst() { return ConstFeature.createConst(infty()); } - protected static TermFeature any() { + public static TermFeature any() { return longTermConst(0); } - protected static TermFeature longTermConst(long a) { + public static TermFeature longTermConst(long a) { return ConstTermFeature.createConst(cost(a)); } - protected static TermFeature inftyTermConst() { + public static TermFeature inftyTermConst() { return ConstTermFeature.createConst(infty()); } - protected static Feature add(Feature a, Feature b) { + public static Feature add(Feature a, Feature b) { return SumFeature.createSum(a, b); } - protected static Feature add(Feature a, Feature b, Feature c) { + public static Feature add(Feature a, Feature b, Feature c) { return SumFeature.createSum(a, b, c); } @SafeVarargs - protected static Feature add(Feature... features) { + public static Feature add(Feature... features) { return SumFeature.createSum(features); } - protected static TermFeature add(TermFeature a, TermFeature b) { + public static TermFeature add(TermFeature a, TermFeature b) { return BinarySumTermFeature.createSum(a, b); } - protected static > Feature sum(TermBuffer x, TermGenerator gen, + public static > Feature sum(TermBuffer x, TermGenerator gen, Feature body) { return ComprehendedSumFeature.create(x, gen, body); } - protected static TermFeature add(TermFeature a, TermFeature b, TermFeature c) { + public static TermFeature add(TermFeature a, TermFeature b, TermFeature c) { // could be done more efficiently return add(a, add(b, c)); } - protected static TermFeature or(TermFeature a, TermFeature b) { + public static TermFeature or(TermFeature a, TermFeature b) { return ifZero(a, longTermConst(0), b); } - protected static TermFeature or(TermFeature a, TermFeature b, TermFeature c) { + public static TermFeature or(TermFeature a, TermFeature b, TermFeature c) { return or(a, or(b, c)); } - protected static TermFeature or(TermFeature... features) { + public static TermFeature or(TermFeature... features) { TermFeature orFeature = inftyTermConst(); for (var f : features) { orFeature = or(orFeature, f); @@ -88,16 +88,16 @@ protected static TermFeature or(TermFeature... features) { return orFeature; } - protected static Feature or(Feature a, Feature b) { + public static Feature or(Feature a, Feature b) { return ifZero(a, longConst(0), b); } - protected static Feature or(Feature a, Feature b, Feature c) { + public static Feature or(Feature a, Feature b, Feature c) { return or(a, or(b, c)); } @SafeVarargs - protected static Feature or(Feature... features) { + public static Feature or(Feature... features) { Feature orFeature = inftyConst(); for (Feature f : features) { orFeature = or(orFeature, f); @@ -105,52 +105,52 @@ protected static Feature or(Feature... features) { return orFeature; } - protected static Feature ifZero(Feature cond, Feature thenFeature) { + public static Feature ifZero(Feature cond, Feature thenFeature) { return ShannonFeature.createConditionalBinary(cond, thenFeature); } - protected static Feature ifZero(Feature cond, Feature thenFeature, + public static Feature ifZero(Feature cond, Feature thenFeature, Feature elseFeature) { return ShannonFeature.createConditionalBinary(cond, thenFeature, elseFeature); } - protected static TermFeature ifZero(TermFeature cond, TermFeature thenFeature) { + public static TermFeature ifZero(TermFeature cond, TermFeature thenFeature) { return ShannonTermFeature.createConditionalBinary(cond, thenFeature); } - protected static TermFeature ifZero(TermFeature cond, TermFeature thenFeature, + public static TermFeature ifZero(TermFeature cond, TermFeature thenFeature, TermFeature elseFeature) { return ShannonTermFeature.createConditionalBinary(cond, thenFeature, elseFeature); } - protected static Feature not(Feature f) { + public static Feature not(Feature f) { return ifZero(f, inftyConst(), longConst(0)); } - protected static TermFeature not(TermFeature f) { + public static TermFeature not(TermFeature f) { return ifZero(f, ConstTermFeature.createConst(TopRuleAppCost.INSTANCE), longTermConst(0)); } - protected static Feature eq(Feature a, Feature b) { + public static Feature eq(Feature a, Feature b) { return CompareCostsFeature.eq(a, b); } - protected static > Feature eq(ProjectionToTerm t1, + 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))); } - protected static Feature less(Feature a, Feature b) { + public static Feature less(Feature a, Feature b) { return CompareCostsFeature.less(a, b); } - protected static Feature leq(Feature a, Feature b) { + public static Feature leq(Feature a, Feature b) { return CompareCostsFeature.leq(a, b); } - protected static RuleAppCost cost(long p) { + public static RuleAppCost cost(long p) { return NumberRuleAppCost.create(p); } @@ -164,7 +164,7 @@ private static RuleAppCost infty() { /// /// @param schemaVar schema variable /// @return projection of taclet applications - protected static > ProjectionToTerm instOf(String schemaVar) { + public static > ProjectionToTerm instOf(String schemaVar) { return SVInstantiationProjection.create(new Name(schemaVar), true); } @@ -174,46 +174,46 @@ protected static > ProjectionToTerm instOf(String sche /// /// @param schemaVar schema variable /// @return projection of taclet applications - protected static > ProjectionToTerm instOfNonStrict( + public static > ProjectionToTerm instOfNonStrict( String schemaVar) { return SVInstantiationProjection.create(new Name(schemaVar), false); } - protected static TermFeature op(Operator op) { + public static TermFeature op(Operator op) { return OperatorTF.create(op); } - protected static TermFeature rec(TermFeature cond, TermFeature summand) { + public static TermFeature rec(TermFeature cond, TermFeature summand) { return RecSubTermFeature.create(cond, summand); } - protected static > ProjectionToTerm subAt(ProjectionToTerm t, + public static > ProjectionToTerm subAt(ProjectionToTerm t, PosInTerm pit) { return SubtermProjection.create(t, pit); } - protected static TermFeature sub(TermFeature sub0) { + public static TermFeature sub(TermFeature sub0) { return SubTermFeature.create(new TermFeature[] { sub0 }); } - protected static TermFeature sub(TermFeature sub0, TermFeature sub1) { + public static TermFeature sub(TermFeature sub0, TermFeature sub1) { return SubTermFeature.create(new TermFeature[] { sub0, sub1 }); } - protected static > ProjectionToTerm sub(ProjectionToTerm t, + public static > ProjectionToTerm sub(ProjectionToTerm t, int index) { return SubtermProjection.create(t, PosInTerm.getTopLevel().down(index)); } - protected static TermFeature opSub(Operator op, TermFeature sub0) { + public static TermFeature opSub(Operator op, TermFeature sub0) { return add(op(op), sub(sub0)); } - protected static TermFeature opSub(Operator op, TermFeature sub0, TermFeature sub1) { + public static TermFeature opSub(Operator op, TermFeature sub0, TermFeature sub1) { return add(op(op), sub(sub0, sub1)); } - protected static > Feature contains(ProjectionToTerm bigTerm, + public static > Feature contains(ProjectionToTerm bigTerm, ProjectionToTerm searchedTerm, java.util.function.Function, TermFeature> createEqTermFeature) { final TermBuffer buf = new TermBuffer<>(); @@ -221,17 +221,17 @@ protected static > Feature contains(ProjectionToTerm b applyTF(bigTerm, not(rec(any(), not(createEqTermFeature.apply(buf)))))); } - protected static > Feature let(TermBuffer x, + public static > Feature let(TermBuffer x, ProjectionToTerm value, Feature body) { return LetFeature.create(x, value, body); } - protected static > Feature println(ProjectionToTerm t) { + public static > Feature println(ProjectionToTerm t) { return applyTF(t, PrintTermFeature.INSTANCE); } - protected static TermFeature extendsTrans(Sort s) { + public static TermFeature extendsTrans(Sort s) { return SortExtendsTransTermFeature.create(s); } @@ -242,7 +242,7 @@ protected static TermFeature extendsTrans(Sort s) { /// @param schemaVar schema variable /// @param tf term feature /// @return feature - protected static > Feature applyTF(String schemaVar, TermFeature tf) { + public static > Feature applyTF(String schemaVar, TermFeature tf) { return applyTF(StaticFeatureCollection.instOf(schemaVar), tf); } @@ -253,7 +253,7 @@ protected static > Feature applyTF(String schemaVar, Term /// @param schemaVar schema variable /// @param tf term feature /// @return feature - protected static > Feature applyTFNonStrict(String schemaVar, + public static > Feature applyTFNonStrict(String schemaVar, TermFeature tf) { return applyTFNonStrict(StaticFeatureCollection.instOfNonStrict(schemaVar), tf); } @@ -265,7 +265,7 @@ protected static > Feature applyTFNonStrict(String schema /// @param term term describing the projection /// @param tf term feature /// @return feature - protected static > Feature applyTF(ProjectionToTerm term, + public static > Feature applyTF(ProjectionToTerm term, TermFeature tf) { return ApplyTFFeature.create(term, tf); } @@ -277,17 +277,17 @@ protected static > Feature applyTF(ProjectionToTerm te /// @param term term describing the projection /// @param tf term feature /// @return feature - protected static > Feature applyTFNonStrict(ProjectionToTerm term, + public static > Feature applyTFNonStrict(ProjectionToTerm term, TermFeature tf) { return ApplyTFFeature.createNonStrict(term, tf, NumberRuleAppCost.getZeroCost()); } - protected static TermFeature constantTermFeature() { + public static TermFeature constantTermFeature() { return TermPredicateTermFeature .create(term -> term.op() instanceof Function && term.arity() == 0); } - protected static Feature isInstantiated(String schemaVar) { + public static Feature isInstantiated(String schemaVar) { return InstantiatedSVFeature.create(new Name(schemaVar)); } } diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/Strategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/Strategy.java index 1ff614f9c02..9ca074d4021 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/Strategy.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/Strategy.java @@ -26,7 +26,9 @@ public interface Strategy> extends Named, * indicates that the rule shall not be applied at all (it is discarded by * the strategy). */ - RuleAppCost computeCost(RuleApp app, PosInOccurrence pos, Goal goal); + default RuleAppCost computeCost(RuleApp app, PosInOccurrence pos, Goal goal) { + return computeCost(app, pos, goal, new MutableState()); + } /** * Checks if the {@link Strategy} should stop at the first non-closeable {@link Goal}. @@ -55,6 +57,8 @@ void instantiateApp(RuleApp app, PosInOccurrence pio, Goal goal, boolean isResponsibleFor(RuleSet rs); - RuleAppCost instantiateApp(RuleApp app, PosInOccurrence pio, - Goal goal, MutableState mState); + default RuleAppCost instantiateApp(RuleApp app, PosInOccurrence pio, + Goal goal, MutableState mState) { + return null; + } } From c6b5187f29bc7ee35104e1800176b6d117caa9d6 Mon Sep 17 00:00:00 2001 From: Drodt Date: Thu, 18 Jun 2026 13:38:56 +0200 Subject: [PATCH 7/9] Implement FeatureConstants --- .../strategy/feature/FindRightishFeature.java | 6 +-- .../feature/JavaFeatureConstants.java | 38 +++++++++++-------- .../prover/strategy/FeatureConstants.java | 3 +- .../prover/strategy/IntegerStrategy.java | 2 +- 4 files changed, 29 insertions(+), 20 deletions(-) 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 a3ddddddbb5..7a1fe7e70dc 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 @@ -3,9 +3,9 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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; @@ -27,11 +27,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/JavaFeatureConstants.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/JavaFeatureConstants.java index c9d5d810443..ff7ef9f477e 100644 --- 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 @@ -3,58 +3,66 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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; -public class JavaFeatureConstants implements FeatureConstants { +import org.jspecify.annotations.NullMarked; + +@NullMarked +public class JavaFeatureConstants implements FeatureConstants { @Override - public ProjectionToTerm focusProjection() { - return null; + public ProjectionToTerm focusProjection() { + return FocusProjection.INSTANCE; } @Override - public ProjectionToTerm focusProjection(int stepsUpwards) { - return null; + public ProjectionToTerm focusProjection(int stepsUpwards) { + return FocusProjection.create(stepsUpwards); } @Override - public ProjectionToTerm focusFormulaProjection() { - return null; + public ProjectionToTerm focusFormulaProjection() { + return FocusFormulaProjection.INSTANCE; } @Override public Feature matchedAssumesFeature() { - return null; + return MatchedAssumesFeature.INSTANCE; } @Override public Feature nonDuplicateAppModPositionFeature() { - return null; + return NonDuplicateAppModPositionFeature.INSTANCE; } @Override public Feature notInScopeOfModalityFeature() { - return null; + return NotInScopeOfModalityFeature.INSTANCE; } @Override public Feature diffFindAndIfFeature() { - return null; + return DiffFindAndIfFeature.INSTANCE; } @Override public Feature topLevelFindSucc() { - return null; + return TopLevelFindFeature.SUCC; } @Override public Feature checkApplyEqFeature() { - return null; + return CheckApplyEqFeature.INSTANCE; } @Override - public Feature findRightishFeature() { - return null; + public Feature findRightishFeature(IIntLdt numbers) { + return FindRightishFeature.create(numbers); } } 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 index 5a3f84f1a4f..8a723d6c6f2 100644 --- 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 @@ -3,6 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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; @@ -26,5 +27,5 @@ public interface FeatureConstants> { Feature checkApplyEqFeature(); - Feature findRightishFeature(); + Feature findRightishFeature(IIntLdt numbers); } diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java index 2e822eda4c9..134da9106fd 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java @@ -127,7 +127,7 @@ private RuleSetDispatchFeature setupCostComputationF() { bindRuleSet(d, "apply_equations", SumFeature.createSum( add(applyTF(featureConstants.focusProjection(0), tf.monomial), - ScaleFeature.createScaled(featureConstants.findRightishFeature(), 5.0)), + ScaleFeature.createScaled(featureConstants.findRightishFeature(numbers), 5.0)), ifZero(featureConstants.matchedAssumesFeature(), add(featureConstants.checkApplyEqFeature(), let(equation, AssumptionProjection.create(0), From ad888ddb0189cb7a7ac6e5ed8f73bd5a4294a87c Mon Sep 17 00:00:00 2001 From: Drodt Date: Thu, 23 Jul 2026 14:30:51 +0200 Subject: [PATCH 8/9] Fix merge --- .../macros/SymbolicExecutionOnlyMacro.java | 2 +- .../key/scripts/AdditionalRulesStrategy.java | 5 +- .../de/uka/ilkd/key/scripts/AutoCommand.java | 4 +- .../de/uka/ilkd/key/scripts/SetCommand.java | 1 - .../de/uka/ilkd/key/strategy/CostReuse.java | 7 +- .../de/uka/ilkd/key/strategy/FOLStrategy.java | 2 +- .../ilkd/key/strategy/JavaCardDLStrategy.java | 8 +- .../key/strategy/JavaIntegerStrategy.java | 7 +- .../key/strategy/ModularJavaDLStrategy.java | 1 - .../strategy/ResponsibleStrategyCache.java | 20 ++--- .../key/strategy/StaticFeatureCollection.java | 3 +- .../AbstractMonomialSmallerThanFeature.java | 1 - .../prover/strategy/IntegerStrategy.java | 84 +++++++------------ .../feature/ComprehendedSumFeature.java | 2 - .../feature/RuleSetDispatchFeature.java | 6 +- .../instantiator/SVInstantiationCP.java | 4 +- .../termProjection/AssumptionProjection.java | 2 +- 17 files changed, 58 insertions(+), 101 deletions(-) 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 fbbb6162c3d..fa42acb5fce 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 @@ -14,7 +14,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; @@ -25,6 +24,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/scripts/AdditionalRulesStrategy.java b/key.core/src/main/java/de/uka/ilkd/key/scripts/AdditionalRulesStrategy.java index b1378a9b0b0..1f5f5558861 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/scripts/AdditionalRulesStrategy.java +++ b/key.core/src/main/java/de/uka/ilkd/key/scripts/AdditionalRulesStrategy.java @@ -11,13 +11,13 @@ import de.uka.ilkd.key.macros.FilterStrategy; import de.uka.ilkd.key.proof.Goal; 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.rules.RuleSet; import org.key_project.prover.sequent.PosInOccurrence; +import org.key_project.prover.strategy.Strategy; import org.key_project.prover.strategy.costbased.NumberRuleAppCost; import org.key_project.prover.strategy.costbased.RuleAppCost; import org.key_project.prover.strategy.costbased.TopRuleAppCost; @@ -42,7 +42,8 @@ class AdditionalRulesStrategy extends FilterStrategy { private final List> 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 1b276a3bbf7..5b48c36da25 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 @@ -14,11 +14,11 @@ import de.uka.ilkd.key.prover.impl.AutoProvers; import de.uka.ilkd.key.scripts.meta.*; 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.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; @@ -94,7 +94,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 b650a6b6e78..e326997f54c 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 @@ -21,7 +21,6 @@ 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; 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 5e8df723d2a..f73ba87e7e1 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 @@ -12,15 +12,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.Feature; -import org.key_project.prover.strategy.costbased.feature.StableCost; -import org.key_project.prover.strategy.costbased.feature.VolatileCost; -import org.key_project.prover.strategy.costbased.feature.WeakStableCost; +import org.key_project.prover.strategy.costbased.feature.*; import org.jspecify.annotations.Nullable; 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 63c73fd19e5..dcefd7af088 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 @@ -121,7 +121,7 @@ private RuleSetDispatchFeature setupCostComputationF() { bindRuleSet(d, "find_term_not_in_assumes", ifZero(MatchedAssumesFeature.INSTANCE, not(contains(AssumptionProjection.create(0), FocusProjection.INSTANCE, - t -> StaticFeatureCollection.eq((TermBuffer) t))))); + StaticFeatureCollection::eq)))); bindRuleSet(d, "update_elim", add(longConst(-8000), ScaleFeature.createScaled(findDepthFeature, 10.0))); 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 160731feeed..4fcd2b81389 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 @@ -68,7 +68,7 @@ protected JavaCardDLStrategy(Proof proof, StrategyProperties strategyProperties) super(proof); heapLDT = getServices().getTypeConverter().getHeapLDT(); - this.strategyProperties = (StrategyProperties) strategyProperties.clone(); + this.strategyProperties = strategyProperties.clone(); this.tf = new JavaArithTermFeatures(getServices().getTypeConverter().getIntegerLDT()); this.ff = new FormulaTermFeatures(this.tf); @@ -80,8 +80,6 @@ protected JavaCardDLStrategy(Proof proof, StrategyProperties strategyProperties) costComputationF = setupGlobalF(costComputationDispatcher); instantiationF = setupGlobalF(instantiationDispatcher); approvalF = add(setupApprovalF(), approvalDispatcher); - - computeCost(null, null, null); } @@ -91,9 +89,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 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 index 2e07ca1f694..59735f94058 100644 --- 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 @@ -59,15 +59,12 @@ public JavaIntegerStrategy(ArithTermFeatures tf, IFormulaTermFeatures ff, Proof .getProperty(StrategyProperties.NON_LIN_ARITH_OPTIONS_KEY)), strategyProperties.getProperty(StrategyProperties.STOPMODE_OPTIONS_KEY) .equals(StrategyProperties.STOPMODE_NONCLOSE), - new JavaFeatureConstants()); + new JavaFeatureConstants(), proof.getServices().getTypeConverter().getIntegerLDT()); this.proof = proof; + init(); } @Override - protected IIntLdt intLDT() { - return proof.getServices().getTypeConverter().getIntegerLDT(); - } - protected RuleSetDispatchFeature setupApprovalDispatcher() { final RuleSetDispatchFeature d = super.setupApprovalDispatcher(); 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 6a5f5e3639f..d50fbde970a 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 @@ -9,7 +9,6 @@ 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.termProjection.FocusProjection; 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 fbebaf1453e..46fa51b2a28 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 @@ -34,14 +34,14 @@ 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 = - new ConcurrentHashMap<>(); - private final Map> instantiationRuleToStrategyMap = - new ConcurrentHashMap<>(); - private final Map> approvalRuleToStrategyMap = - new ConcurrentHashMap<>(); - private final Map nameToStrategyMap = - new HashMap(); + private final Map>> costRuleToStrategyMap = + new ConcurrentHashMap<>(); + private final Map>> instantiationRuleToStrategyMap = + new ConcurrentHashMap<>(); + private final Map>> approvalRuleToStrategyMap = + new ConcurrentHashMap<>(); + private final Map> nameToStrategyMap = + new HashMap<>(); public ResponsibleStrategyCache(List> strategies) { initialize(StrategyAspect.Cost, strategies); @@ -95,7 +95,7 @@ public LinkedHashSet> getResponsibleStrategies(Rule rule // function only reads the responsibility maps (built once in the constructor, read-only // 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)) { @@ -119,7 +119,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/StaticFeatureCollection.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/StaticFeatureCollection.java index f5144f91a34..9ecef3c9e43 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 @@ -359,7 +359,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/feature/AbstractMonomialSmallerThanFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/AbstractMonomialSmallerThanFeature.java index a2006e3ae34..03876c9d908 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 @@ -5,7 +5,6 @@ import java.util.Map; -import de.uka.ilkd.key.ldt.IntegerLDT; import de.uka.ilkd.key.logic.op.SkolemTermSV; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.rule.TacletApp; diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java index e46591cb187..f65991d558c 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java @@ -28,6 +28,7 @@ import org.key_project.prover.strategy.costbased.termgenerator.SubtermGenerator; import org.key_project.prover.strategy.costbased.termgenerator.TermGenerator; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.jspecify.annotations.NonNull; public abstract class IntegerStrategy> extends AbstractFeatureStrategy @@ -40,9 +41,9 @@ public abstract class IntegerStrategy> extends AbstractFe /// The features defining the three phases: cost computation, approval, /// additionalInstanceCreationAndEvaluation - private final RuleSetDispatchFeature costComputationDispatcher; - private final RuleSetDispatchFeature approvalDispatcher; - private final RuleSetDispatchFeature instantiationDispatcher; + private @MonotonicNonNull RuleSetDispatchFeature costComputationDispatcher; + private @MonotonicNonNull RuleSetDispatchFeature approvalDispatcher; + private @MonotonicNonNull RuleSetDispatchFeature instantiationDispatcher; /// Useful [TermFeature] collections protected final ArithTermFeatures tf; @@ -53,11 +54,14 @@ public abstract class IntegerStrategy> extends AbstractFe private final boolean divAndModuloReasoningEnabled; private final boolean stopAtFirstNonCloseableGoal; + private final IIntLdt numbers; + FeatureConstants featureConstants; public IntegerStrategy(ArithTermFeatures tf, IFormulaTermFeatures ff, boolean nonLinearArithmeticEnabled, boolean divAndModuloReasoningEnabled, - boolean stopAtFirstNonCloseableGoal, FeatureConstants featureConstants) { + boolean stopAtFirstNonCloseableGoal, FeatureConstants featureConstants, + IIntLdt numbers) { this.tf = tf; this.ff = ff; this.nonLinearArithmeticEnabled = nonLinearArithmeticEnabled; @@ -66,6 +70,10 @@ public IntegerStrategy(ArithTermFeatures tf, IFormulaTermFeatures ff, this.featureConstants = featureConstants; + this.numbers = numbers; + } + + protected void init() { // setup cost computations costComputationDispatcher = setupCostComputationF(); approvalDispatcher = setupApprovalDispatcher(); @@ -96,52 +104,11 @@ private RuleSetDispatchFeature setupInstantiationF() { return d; } - private RuleSetDispatchFeature setupApprovalDispatcher() { - final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); - final IntegerLDT numbers = getServices().getTypeConverter().getIntegerLDT(); - - if (arithNonLinInferences() || arithDefOps()) { - // 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. - setupMultiplyInequations(d, longConst(0), inftyConst(), !arithNonLinInferences()); - } - // these taclets are not supposed to be applied with metavariable - // instantiations - // I'll keep it here for the moment as documentation, but comment it out - // as meta variables are no longer part of KeY 2.x - /* - * bindRuleSet ( d, "inEqSimp_pullOutGcd", isInstantiated ( "elimGcd" ) ); bindRuleSet ( d, - * "polySimp_pullOutGcd", isInstantiated ( "elimGcd" ) ); - * - * bindRuleSet ( d, "inEqSimp_nonNegSquares", isInstantiated ( "squareFac" ) ); bindRuleSet - * ( d, "inEqSimp_nonLin_divide", isInstantiated ( "divY" ) ); bindRuleSet ( d, - * "inEqSimp_nonLin_pos", isInstantiated ( "divY" ) ); bindRuleSet ( d, - * "inEqSimp_nonLin_neg", isInstantiated ( "divY" ) ); - * - * bindRuleSet ( d, "inEqSimp_signCases", isInstantiated ( "signCasesLeft" ) ); - */ - setupNewSymApproval(d, numbers); - - - bindRuleSet(d, "defOps_div", NonDuplicateAppModPositionFeature.INSTANCE); - bindRuleSet(d, "defOps_jdiv", NonDuplicateAppModPositionFeature.INSTANCE); - - if (arithNonLinInferences()) { - setupInEqCaseDistinctionsApproval(d); - } - - return d; + @Override + public boolean isResponsibleFor(RuleSet rs) { + return costComputationDispatcher.get(rs) != null || instantiationDispatcher.get(rs) != null; } - protected abstract IIntLdt intLDT(); - private boolean arithNonLinInferences() { return nonLinearArithmeticEnabled; } @@ -157,7 +124,6 @@ public boolean isStopAtFirstNonCloseableGoal() { private RuleSetDispatchFeature setupCostComputationF() { final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); - final IIntLdt numbers = intLDT(); bindRuleSet(d, "simplify_int", inftyConst()); @@ -218,10 +184,18 @@ private RuleSetDispatchFeature setupCostComputationF() { protected RuleSetDispatchFeature setupApprovalDispatcher() { final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); - final IIntLdt numbers = intLDT(); - if (arithNonLinInferences()) { - setupMultiplyInequations(d, inftyConst()); + if (arithNonLinInferences() || arithDefOps()) { + // 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. + setupMultiplyInequations(d, longConst(0), inftyConst(), !arithNonLinInferences()); } // these taclets are not supposed to be applied with metavariable // instantiations @@ -238,10 +212,8 @@ protected RuleSetDispatchFeature setupApprovalDispatcher() { * * bindRuleSet ( d, "inEqSimp_signCases", isInstantiated ( "signCasesLeft" ) ); */ - setupNewSymApproval(d, numbers); - bindRuleSet(d, "defOps_div", featureConstants.nonDuplicateAppModPositionFeature()); if (arithNonLinInferences()) { @@ -532,7 +504,7 @@ private void setupDivModDivision(RuleSetDispatchFeature d) { // 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 setupPolySimpInstantiationWithoutRetry(RuleSetDispatchFeature d, IIntLdt numbers) { + private void setupPolySimpInstantiationWithoutRetry(RuleSetDispatchFeature d) { // category "direct equations" setupPullOutGcd(d, "polySimp_pullOutGcd", false); @@ -1050,7 +1022,7 @@ private void setupDefOpsExpandMod(RuleSetDispatchFeature d) { /// 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, intLDT()); + setupPolySimpInstantiationWithoutRetry(d); setupInEqSimpInstantiationWithoutRetry(d); } diff --git a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/ComprehendedSumFeature.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/ComprehendedSumFeature.java index 279b80e9a1e..4985722daab 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/ComprehendedSumFeature.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/ComprehendedSumFeature.java @@ -11,8 +11,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.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java index f56204e56ba..a7ab3455d78 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/costbased/feature/RuleSetDispatchFeature.java @@ -10,13 +10,11 @@ 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; @@ -63,7 +61,7 @@ public class RuleSetDispatchFeature implements Feature { } 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; 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 index 60c04735024..da4f4a0f2ca 100644 --- 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 @@ -17,7 +17,7 @@ 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.ImmutableSLList; +import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSet; import org.jspecify.annotations.NonNull; @@ -113,7 +113,7 @@ public void choose() {} public RuleApp getRuleAppForBranch() { return newApp; } }; - return ImmutableSLList.nil().prepend(branch).iterator(); + 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 index 594830617a6..d35bdd86949 100644 --- 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 @@ -35,6 +35,6 @@ public Term toTerm(RuleApp app, PosInOccurrence pos, G goal, MutableState mutabl + " but got " + app; - return tapp.assumesFormulaInstantiations().take(no).head().getSequentFormula().formula(); + return tapp.assumesFormulaInstantiations().skip(no).head().getSequentFormula().formula(); } } From 832eb1556b2ddea7821d58e404fd85f382ab7f69 Mon Sep 17 00:00:00 2001 From: Drodt Date: Thu, 23 Jul 2026 14:59:43 +0200 Subject: [PATCH 9/9] Fix merge --- .../proof/InfFlowCheckInfo.java | 5 +- .../InfFlowContractAppTacletExecutor.java | 2 +- .../main/java/de/uka/ilkd/key/proof/Goal.java | 4 +- .../key/proof/StrategyInfoUndoMethod.java | 2 +- .../de/uka/ilkd/key/rule/QueryExpand.java | 2 +- .../key/strategy/JavaIntegerStrategy.java | 11 ++- .../BranchMultiplicationCountFeature.java | 6 +- .../util/properties/AbstractProperties.java | 2 + .../key/util/properties/MapProperties.java | 2 + .../prover/strategy/IntegerStrategy.java | 74 ++++++++++++++----- .../org/key_project/util}/Properties.java | 2 +- 11 files changed, 82 insertions(+), 30 deletions(-) rename {key.core/src/main/java/de/uka/ilkd/key/util/properties => key.util/src/main/java/org/key_project/util}/Properties.java (97%) 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 ee82899ad1b..9bcd2fd73cb 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 @@ -6,8 +6,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/executor/InfFlowContractAppTacletExecutor.java b/key.core.infflow/src/main/java/de/uka/ilkd/key/informationflow/rule/executor/InfFlowContractAppTacletExecutor.java index 45c7015825c..6caa01e196c 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 @@ -11,7 +11,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; @@ -19,6 +18,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/src/main/java/de/uka/ilkd/key/proof/Goal.java b/key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java index 034465594ca..3c5cb1db168 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,8 +24,6 @@ import de.uka.ilkd.key.rule.merge.MergeRule; import de.uka.ilkd.key.strategy.QueueRuleApplicationManager; 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; @@ -42,6 +40,8 @@ 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; 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 ab354a8f7bd..220b06bbdb0 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 @@ -3,7 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ 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/rule/QueryExpand.java b/key.core/src/main/java/de/uka/ilkd/key/rule/QueryExpand.java index de2acb77098..be85b9b508e 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 @@ -23,7 +23,6 @@ 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; @@ -38,6 +37,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; 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 index 59735f94058..543e7abb0f8 100644 --- 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 @@ -48,6 +48,11 @@ 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( @@ -84,7 +89,7 @@ protected RuleSetDispatchFeature setupApprovalDispatcher() { protected void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { super.setupDefOpsPrimaryCategories(d); - if (arithDefOps()) { + if (arith == ArithTreatment.DEF_OPS) { bindRuleSet(d, "defOps_jdiv", SumFeature.createSum(NonDuplicateAppModPositionFeature.INSTANCE, applyTF("divNum", tf.polynomial), applyTF("divDenom", tf.polynomial), @@ -100,7 +105,11 @@ protected void setupDefOpsPrimaryCategories(RuleSetDispatchFeature d) { bindRuleSet(d, "defOps_jdiv_inline", add(applyTF("divNum", tf.literal), applyTF("divDenom", tf.literal), longConst(-4000))); } + } + @Override + protected Feature getBranchCountFeatureFor(String prefix) { + return BranchMultiplicationCountFeature.atMost(prefix, BRANCH_MULT_CAP); } @Override 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 56ff1c59679..d3ce98f75fb 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 @@ -6,11 +6,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 @@ -38,8 +38,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/util/properties/AbstractProperties.java b/key.core/src/main/java/de/uka/ilkd/key/util/properties/AbstractProperties.java index 33b7315be86..b962a077c6a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/properties/AbstractProperties.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/properties/AbstractProperties.java @@ -9,6 +9,8 @@ import java.util.Map; import java.util.Set; +import org.key_project.util.Properties; + public abstract class AbstractProperties implements Properties { private final Map, 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 5bae2aca8b3..01a4ed6f152 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 @@ -5,6 +5,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.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java index c2a3a338926..0be5856bdd3 100644 --- a/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java +++ b/key.ncore.calculus/src/main/java/org/key_project/prover/strategy/IntegerStrategy.java @@ -47,10 +47,6 @@ public abstract class IntegerStrategy> extends AbstractFe /// 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, @@ -64,7 +60,7 @@ public abstract class IntegerStrategy> extends AbstractFe 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. @@ -76,7 +72,7 @@ private enum ArithTreatment { } /// configuration options extracted from [StrategyProperties] - private final ArithTreatment arith; + protected final ArithTreatment arith; private final boolean stopAtFirstNonCloseableGoal; private final IIntLdt numbers; @@ -89,8 +85,14 @@ public IntegerStrategy(ArithTermFeatures tf, IFormulaTermFeatures ff, IIntLdt numbers) { this.tf = tf; this.ff = ff; - this.nonLinearArithmeticEnabled = nonLinearArithmeticEnabled; - this.divAndModuloReasoningEnabled = divAndModuloReasoningEnabled; + // determine configuration + if (nonLinearArithmeticEnabled) { + arith = ArithTreatment.MODEL_SEARCH; + } else if (divAndModuloReasoningEnabled) { + arith = ArithTreatment.DEF_OPS; + } else { + arith = ArithTreatment.BASIC; + } this.stopAtFirstNonCloseableGoal = stopAtFirstNonCloseableGoal; this.featureConstants = featureConstants; @@ -129,17 +131,51 @@ private RuleSetDispatchFeature setupInstantiationF() { return d; } - @Override - public boolean isResponsibleFor(RuleSet rs) { - return costComputationDispatcher.get(rs) != null || instantiationDispatcher.get(rs) != null; - } - private boolean arithNonLinInferences() { - return nonLinearArithmeticEnabled; + protected RuleSetDispatchFeature setupApprovalDispatcher() { + final RuleSetDispatchFeature d = new RuleSetDispatchFeature(); + + if (arith != ArithTreatment.BASIC) { + // 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. + setupMultiplyInequations(d, longConst(0), inftyConst(), AT_APPROVAL); + } + // these taclets are not supposed to be applied with metavariable + // instantiations + // I'll keep it here for the moment as documentation, but comment it out + // as meta variables are no longer part of KeY 2.x + /* + * bindRuleSet ( d, "inEqSimp_pullOutGcd", isInstantiated ( "elimGcd" ) ); bindRuleSet ( d, + * "polySimp_pullOutGcd", isInstantiated ( "elimGcd" ) ); + * + * bindRuleSet ( d, "inEqSimp_nonNegSquares", isInstantiated ( "squareFac" ) ); bindRuleSet + * ( d, "inEqSimp_nonLin_divide", isInstantiated ( "divY" ) ); bindRuleSet ( d, + * "inEqSimp_nonLin_pos", isInstantiated ( "divY" ) ); bindRuleSet ( d, + * "inEqSimp_nonLin_neg", isInstantiated ( "divY" ) ); + * + * bindRuleSet ( d, "inEqSimp_signCases", isInstantiated ( "signCasesLeft" ) ); + */ + setupNewSymApproval(d, numbers); + + bindRuleSet(d, "defOps_div", featureConstants.nonDuplicateAppModPositionFeature()); + + if (arith == ArithTreatment.MODEL_SEARCH) { + setupInEqCaseDistinctionsApproval(d); + } + + return d; } - protected boolean arithDefOps() { - return divAndModuloReasoningEnabled; + @Override + public boolean isResponsibleFor(RuleSet rs) { + return costComputationDispatcher.get(rs) != null || instantiationDispatcher.get(rs) != null; } @Override @@ -831,8 +867,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, longConst(0), onlyExactlyBounded ? notAllowedF @@ -849,6 +885,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" 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 b2cf2ce6318..03b3f69901f 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 @@ -1,7 +1,7 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.util.properties; +package org.key_project.util; import java.util.concurrent.atomic.AtomicInteger;