From 6684638895f377c28e4c971418373a6aa138df4b Mon Sep 17 00:00:00 2001 From: Benjamin Weiss Date: Tue, 15 Jan 2008 10:59:37 +0100 Subject: [PATCH] jmlRewrite details see accompanying e-mail --- eclipse/.project | 8 +- examples/_testcase/speclang/testFile.key | 3 + .../speclang/testPackage/TestClass.java | 25 + .../Java Card Allocation.dfSequence | 0 examples/java_dl/for_demo/For.java | 117 + .../payCardOCL/paycard/CardException.java | 5 + .../java_dl/payCardOCL/paycard/ChargeUI.java | 95 + .../payCardOCL/paycard/IssueCardUI.java | 127 + .../java_dl/payCardOCL/paycard/PayCard.java | 41 + .../payCardOCL/paycard/PayCardJunior.java | 70 + .../java_dl/payCardOCL/paycard/Start.java | 11 + .../smtlib/Func_imp_add_overflow.key.proof | 0 examples/smtlib/Func_imp_dist.key.proof | 0 .../smtlib/Func_imp_dist2_unclosed.key.proof | 0 examples/smtlib/Pred-imp_and.key.proof | 0 examples/smtlib/Pred-imp_dist.key.proof | 0 examples/smtlib/Pred-imp_dist2.key.proof | 0 examples/smtlib/Pred-imp_or.key.proof | 0 examples/smtlib/imp_false_false.key.proof | 0 examples/smtlib/imp_false_true.key.proof | 0 .../smtlib/imp_true_false_unclosed.key.proof | 0 examples/smtlib/imp_true_true.key.proof | 0 system/Makefile | 105 +- system/TestKey.java | 18 +- .../key/casetool/FunctionalityOnModel.java | 739 ----- .../de/uka/ilkd/key/casetool/ModelClass.java | 13 - .../de/uka/ilkd/key/casetool/ModelMethod.java | 5 +- .../uka/ilkd/key/casetool/Multiplicity.java | 6 +- .../together/FunctionalityOnModel.java | 773 +++++ .../casetool/together/TogetherEnvInput.java | 145 +- .../casetool/together/TogetherModelClass.java | 33 +- .../together/TogetherModelMethod.java | 54 +- .../together/TogetherOCLSimplInterface.java | 7 +- .../scripts/menuextension/ClassMenu.java | 13 +- .../menuextension/ClassMenuPoint1.java | 13 +- .../menuextension/ClassMenuPoint2.java | 59 +- .../menuextension/ClassMenuPoint3.java | 56 +- .../menuextension/ClassMenuPoint4.java | 69 +- .../menuextension/ClassMenuPoint5.java | 46 +- .../menuextension/ClassMenuPoint6.java | 13 +- .../menuextension/ClassMenuPoint7.java | 24 - .../menuextension/GlobalMenuPoint1_1.java | 7 +- .../scripts/menuextension/OpMenu.java | 16 +- .../scripts/menuextension/OpMenuPoint1.java | 13 +- .../scripts/menuextension/OpMenuPoint10.java | 14 +- .../scripts/menuextension/OpMenuPoint11.java | 13 +- .../scripts/menuextension/OpMenuPoint12.java | 29 - .../scripts/menuextension/OpMenuPoint2.java | 3 +- .../scripts/menuextension/OpMenuPoint3.java | 11 +- .../scripts/menuextension/OpMenuPoint4.java | 12 +- .../scripts/menuextension/OpMenuPoint5.java | 11 +- .../scripts/menuextension/OpMenuPoint6.java | 11 +- .../scripts/menuextension/OpMenuPoint7.java | 11 +- .../scripts/menuextension/OpMenuPoint8.java | 11 +- .../scripts/menuextension/OpMenuPoint9.java | 13 +- .../ilkd/key/cspec/ComputeSpecification.java | 6 +- .../ComputeSpecificationPO.java} | 73 +- .../gui/ClassInvariantSelectionDialog.java | 92 +- .../key/gui/ClassInvariantSelectionPanel.java | 488 ++- .../ilkd/key/gui/ClassSelectionDialog.java | 79 +- system/de/uka/ilkd/key/gui/ClassTree.java | 287 ++ .../key/gui/ComputeSpecificationView.java | 4 +- .../ilkd/key/gui/ContractConfigurator.java | 234 ++ .../ilkd/key/gui/ContractSelectionPanel.java | 166 - .../key/gui/DefaultContractConfigurator.java | 229 -- .../de/uka/ilkd/key/gui/ExceptionDialog.java | 20 +- system/de/uka/ilkd/key/gui/IconFactory.java | 10 + .../uka/ilkd/key/gui/JMLEclipseAdapter.java | 8 +- .../ilkd/key/gui/JMLPOAndSpecProvider.java | 36 - .../de/uka/ilkd/key/gui/JMLSpecBrowser.java | 580 ---- system/de/uka/ilkd/key/gui/KeYMediator.java | 37 +- system/de/uka/ilkd/key/gui/Main.java | 220 +- .../uka/ilkd/key/gui/MethodContractList.java | 222 -- .../gui/OperationContractSelectionPanel.java | 175 + system/de/uka/ilkd/key/gui/POBrowser.java | 532 +++ system/de/uka/ilkd/key/gui/RuleView.java | 8 - .../key/gui/SuperclassSelectionDialog.java | 56 - system/de/uka/ilkd/key/gui/TacletView.java | 3 - system/de/uka/ilkd/key/gui/TaskTree.java | 5 +- .../key/gui/UseMethodContractRuleItem.java | 85 - .../ilkd/key/gui/UsedMethodContractsList.java | 211 -- .../key/gui/UsedSpecificationsDialog.java | 365 +++ .../gui/configuration/GeneralSettings.java | 69 +- .../InsertSystemInvariantTacletMenuItem.java | 2 +- .../ilkd/key/gui/nodeviews/TacletMenu.java | 16 +- system/de/uka/ilkd/key/java/Comment.java | 36 +- .../de/uka/ilkd/key/java/CompilationUnit.java | 1 - system/de/uka/ilkd/key/java/JavaInfo.java | 2 +- .../uka/ilkd/key/java/JavaProgramElement.java | 11 - .../uka/ilkd/key/java/KeYProgModelInfo.java | 17 +- system/de/uka/ilkd/key/java/Position.java | 4 +- system/de/uka/ilkd/key/java/PositionInfo.java | 6 +- .../de/uka/ilkd/key/java/PrettyPrinter.java | 33 +- .../de/uka/ilkd/key/java/ProgramElement.java | 7 - system/de/uka/ilkd/key/java/Recoder2KeY.java | 78 +- .../uka/ilkd/key/java/SchemaRecoder2KeY.java | 7 +- system/de/uka/ilkd/key/java/Services.java | 90 +- .../de/uka/ilkd/key/java/TypeConverter.java | 28 +- .../ilkd/key/java/annotation/Annotation.java | 19 - .../annotation/LoopInvariantAnnotation.java | 122 - .../java/declaration/ClassDeclaration.java | 38 - .../java/declaration/FieldDeclaration.java | 18 + .../declaration/InterfaceDeclaration.java | 32 - .../key/java/declaration/JavaDeclaration.java | 8 + .../java/declaration/MethodDeclaration.java | 33 - .../declaration/ParameterDeclaration.java | 2 +- .../key/java/declaration/TypeDeclaration.java | 31 +- .../declaration/modifier/Ghost.java} | 28 +- .../key/java/declaration/modifier/Model.java | 23 +- .../expression/operator/SetAssignment.java | 79 + .../uka/ilkd/key/java/recoderext/Ghost.java | 37 + .../java/recoderext/ImplicitFieldAdder.java | 48 +- .../key/java/recoderext/JMLTransformer.java | 543 ++++ .../uka/ilkd/key/java/recoderext/Model.java | 37 + .../recoderext/ProofJavaProgramFactory.java | 18 +- .../recoderext/RecoderModelTransformer.java | 13 +- .../key/java/recoderext/SetAssignment.java | 68 + .../key/java/reference/MethodReference.java | 4 - system/de/uka/ilkd/key/java/statement/Do.java | 6 +- .../key/java/statement/LoopStatement.java | 38 +- .../de/uka/ilkd/key/java/statement/While.java | 18 +- .../key/java/visitor/CreatingASTVisitor.java | 53 +- .../DeclarationProgramVariableCollector.java | 13 +- .../key/java/visitor/FieldReplaceVisitor.java | 5 +- .../key/java/visitor/IndexReplaceVisitor.java | 6 +- .../ilkd/key/java/visitor/JavaASTVisitor.java | 43 +- .../ilkd/key/java/visitor/JavaASTWalker.java | 12 +- .../ilkd/key/java/visitor/LabelCollector.java | 7 +- .../java/visitor/ProgVarReplaceVisitor.java | 173 +- .../java/visitor/ProgramReplaceVisitor.java | 4 +- .../key/java/visitor/ProgramSVCollector.java | 38 +- .../java/visitor/ProgramTypeCollector.java | 11 +- .../visitor/ProgramVariableCollector.java | 99 +- ...stDeclarationProgramVariableCollector.java | 3 +- .../de/uka/ilkd/key/java/visitor/Visitor.java | 8 +- .../jml/AmbigiousModelElementException.java | 31 - .../de/uka/ilkd/key/jml/AssignableSpec.java | 31 - .../ilkd/key/jml/Implementation2SpecMap.java | 518 --- system/de/uka/ilkd/key/jml/JMLClassSpec.java | 824 ----- .../key/jml/JMLExceptionalMethodSpec.java | 82 - .../uka/ilkd/key/jml/JMLLemmaMethodSpec.java | 58 - system/de/uka/ilkd/key/jml/JMLMethodSpec.java | 1271 -------- .../uka/ilkd/key/jml/JMLNormalMethodSpec.java | 124 - system/de/uka/ilkd/key/jml/JMLPuritySpec.java | 46 - system/de/uka/ilkd/key/jml/JMLSpec.java | 49 - system/de/uka/ilkd/key/jml/LoopInvariant.java | 122 - system/de/uka/ilkd/key/jml/Signals.java | 49 - system/de/uka/ilkd/key/jml/UsefulTools.java | 545 ---- .../key/jml/WrongIntSemanticsException.java | 26 - system/de/uka/ilkd/key/jmltest/JMLExport.java | 100 + .../uka/ilkd/key/jmltest/JMLLogicPrinter.java | 163 + .../uka/ilkd/key/jmltest/JMLNotationInfo.java | 105 + .../ilkd/key/jmltest/JMLTestFileCreator.java | 176 + .../ilkd/key/jmltest/WrapperConstructor.java | 624 ++++ .../key/logic/AnonymisingUpdateFactory.java | 2 +- .../key/logic/BasicLocationDescriptor.java | 12 +- .../logic/EverythingLocationDescriptor.java | 3 + .../ilkd/key/logic/InnerVariableNamer.java | 4 +- .../ilkd/key/logic/ProgramElementName.java | 12 - system/de/uka/ilkd/key/logic/TermBuilder.java | 30 +- .../ilkd/key/logic/TermCreationException.java | 1 + system/de/uka/ilkd/key/logic/TermFactory.java | 4 +- .../de/uka/ilkd/key/logic/UpdateFactory.java | 10 + .../de/uka/ilkd/key/logic/VariableNamer.java | 15 +- system/de/uka/ilkd/key/logic/ldt/ADT.java | 1 - .../key/logic/ldt/AbstractIntegerLDT.java | 799 +++-- system/de/uka/ilkd/key/logic/ldt/ByteLDT.java | 98 +- system/de/uka/ilkd/key/logic/ldt/CharLDT.java | 98 +- system/de/uka/ilkd/key/logic/ldt/IntLDT.java | 98 +- .../ilkd/key/logic/ldt/IntegerDomainLDT.java | 97 +- .../de/uka/ilkd/key/logic/ldt/IntegerLDT.java | 98 +- system/de/uka/ilkd/key/logic/ldt/LDT.java | 6 +- system/de/uka/ilkd/key/logic/ldt/LongLDT.java | 98 +- .../de/uka/ilkd/key/logic/ldt/ShortLDT.java | 100 +- .../key/logic/op/AbstractMetaOperator.java | 2 + .../ilkd/key/logic/op/AnonymousUpdate.java | 2 +- .../logic/op/NonRigidFunctionLocation.java | 1 + system/de/uka/ilkd/key/logic/op/Op.java | 2 +- .../uka/ilkd/key/logic/op/ProgramMethod.java | 21 +- .../de/uka/ilkd/key/logic/op/ProgramSV.java | 12 - .../ilkd/key/logic/op/ProgramVariable.java | 12 - .../uka/ilkd/key/logic/op/RigidFunction.java | 2 +- .../ilkd/key/logic/sort/ArraySortImpl.java | 10 +- .../ilkd/key/logic/sort/ProgramSVSort.java | 18 +- .../de/uka/ilkd/key/ocl/gf/GFinterface.java | 7 +- .../key/{logic => parser}/AtPreNamespace.java | 8 +- .../ilkd/key/parser/jml/ArithOpProvider.java | 66 - .../parser/jml/DefaultArithOpProvider.java | 145 - .../ilkd/key/parser/jml/JMLSpecBuilder.java | 549 ---- .../ilkd/key/parser/jml/JMLTranslator.java | 458 --- .../jml/NotSupportedExpressionException.java | 47 - system/de/uka/ilkd/key/parser/jml/jml.g | 2840 ----------------- system/de/uka/ilkd/key/parser/keyparser.g | 81 +- .../key/parser/ocl/AttributeResolver.java | 87 - .../ilkd/key/parser/ocl/MethodResolver.java | 113 - .../de/uka/ilkd/key/parser/ocl/OCLEntity.java | 124 - .../key/parser/ocl/OCLTranslationError.java | 29 - .../ilkd/key/parser/ocl/PropertyManager.java | 216 -- .../ilkd/key/parser/ocl/PropertyResolver.java | 36 - .../key/parser/schemajava/SchemaJavaParser.jj | 51 +- system/de/uka/ilkd/key/pp/LogicPrinter.java | 30 +- system/de/uka/ilkd/key/pp/Notation.java | 41 +- system/de/uka/ilkd/key/pp/NotationInfo.java | 10 +- system/de/uka/ilkd/key/pp/ProgramPrinter.java | 47 +- .../de/uka/ilkd/key/proof/AtPreFactory.java | 255 ++ .../ilkd/key/proof/BuiltInRuleAppIndex.java | 10 +- system/de/uka/ilkd/key/proof/Goal.java | 16 +- .../ilkd/key/proof/LoopInvariantProposer.java | 335 +- system/de/uka/ilkd/key/proof/OpReplacer.java | 81 +- .../de/uka/ilkd/key/proof/ProblemLoader.java | 71 +- .../uka/ilkd/key/proof/ProgVarReplacer.java | 19 +- system/de/uka/ilkd/key/proof/Proof.java | 34 +- system/de/uka/ilkd/key/proof/ProofSaver.java | 14 +- .../de/uka/ilkd/key/proof/RuleTreeModel.java | 67 +- .../de/uka/ilkd/key/proof/SymbolReplacer.java | 53 - .../proof/TacletInstantiationsTableModel.java | 3 +- .../de/uka/ilkd/key/proof/TermSVReplacer.java | 150 - .../proof/UseMethodContractRuleFilter.java | 17 - .../proof/UseOperationContractRuleFilter.java | 27 + .../ilkd/key/proof/VariableNameProposer.java | 5 +- .../DecisionProcedureDummyTranslation.java | 0 .../decproc/DecisionProcedureSmtAuflia.java | 0 .../proof/decproc/DecisionProcedureYices.java | 0 ...ultEnvInput.java => AbstractEnvInput.java} | 17 +- .../uka/ilkd/key/proof/init/AbstractPO.java | 373 +-- .../init/AssignableCheckProofOblInput.java | 174 - .../proof/init/BehaviouralSubtypingInvPO.java | 78 +- .../proof/init/BehaviouralSubtypingOpPO.java | 42 +- .../init/BehaviouralSubtypingOpPairPO.java | 116 +- .../uka/ilkd/key/proof/init/CasetoolDLPO.java | 2 +- .../ilkd/key/proof/init/CorrectDependsPO.java | 84 +- .../init/CreatedAttributeTermFactory.java | 29 +- .../ilkd/key/proof/init/DebuggerProfile.java | 8 +- .../de/uka/ilkd/key/proof/init/EnsuresPO.java | 330 +- .../ilkd/key/proof/init/EnsuresPostPO.java | 73 +- .../de/uka/ilkd/key/proof/init/EnvInput.java | 17 +- .../de/uka/ilkd/key/proof/init/Includes.java | 3 +- .../uka/ilkd/key/proof/init/InitConfig.java | 19 +- .../init/InvariantSelectionStrategy.java | 96 - .../de/uka/ilkd/key/proof/init/JMLInvPO.java | 72 - .../ilkd/key/proof/init/JMLPostAndInvPO.java | 95 - .../de/uka/ilkd/key/proof/init/JMLPostPO.java | 63 - .../ilkd/key/proof/init/JMLProofOblInput.java | 36 - .../key/proof/init/JMLProofOblInputImpl.java | 155 - .../ilkd/key/proof/init/JUnitTestProfile.java | 6 +- .../de/uka/ilkd/key/proof/init/JavaInput.java | 160 - .../init/JavaInputWithJMLSpecBrowser.java | 79 - .../uka/ilkd/key/proof/init/JavaProfile.java | 6 +- .../proof/init/JavaTestGenerationProfile.java | 8 +- .../de/uka/ilkd/key/proof/init/KeYFile.java | 553 ++-- .../ilkd/key/proof/init/KeYFileForTests.java | 4 +- .../uka/ilkd/key/proof/init/KeYJMLInput.java | 78 - .../key/proof/init/KeYUserProblemFile.java | 539 +--- .../de/uka/ilkd/key/proof/init/LDTInput.java | 6 + .../init/ModifiesCheckProofOblInput.java | 701 ---- .../key/proof/init/NonInterferencePO.java | 19 +- .../ilkd/key/proof/init/OCLInvSimplPO.java | 9 - .../ilkd/key/proof/init/PreservesGuardPO.java | 145 +- .../ilkd/key/proof/init/PreservesInvPO.java | 52 +- .../key/proof/init/PreservesOwnInvPO.java | 19 +- .../key/proof/init/PreservesThroughoutPO.java | 41 +- .../key/proof/init/ProblemInitializer.java | 61 +- .../key/proof/init/ProofInputException.java | 13 +- .../ilkd/key/proof/init/ProofOblInput.java | 27 +- .../key/proof/init/RespectsModifiesPO.java | 65 +- .../de/uka/ilkd/key/proof/init/SpecExtPO.java | 116 + .../proof/init/StrongOperationContractPO.java | 119 +- .../key/proof/init/TacletSoundnessPO.java | 46 +- .../proof/init/TacletSoundnessPOLoader.java | 1 + .../ilkd/key/proof/mgt/AbstractContract.java | 60 - .../key/proof/mgt/AxiomJustification.java | 27 +- .../de/uka/ilkd/key/proof/mgt/BasicTask.java | 58 +- .../proof/mgt/ComplexRuleJustification.java | 12 +- .../mgt/ComplexRuleJustificationBySpec.java | 61 +- .../de/uka/ilkd/key/proof/mgt/Contract.java | 46 - .../uka/ilkd/key/proof/mgt/ContractSet.java | 81 - .../uka/ilkd/key/proof/mgt/ContractUtil.java | 85 - .../ilkd/key/proof/mgt/ContractWithInvs.java | 155 + .../uka/ilkd/key/proof/mgt/Contractable.java | 15 - .../ilkd/key/proof/mgt/DLHoareTriplePO.java | 190 -- .../ilkd/key/proof/mgt/DLMethodContract.java | 552 ---- .../proof/mgt/DefaultOperationContract.java | 122 - .../proof/mgt/DefaultProofCorrectnessMgt.java | 297 +- .../uka/ilkd/key/proof/mgt/DepAnalysis.java | 68 - .../proof/mgt/InstantiatedMethodContract.java | 117 - .../ilkd/key/proof/mgt/JMLMethodContract.java | 285 -- .../ilkd/key/proof/mgt/JavaModelClass.java | 208 -- .../ilkd/key/proof/mgt/JavaModelMethod.java | 264 -- .../key/proof/mgt/LemmaRuleJustification.java | 76 - .../de/uka/ilkd/key/proof/mgt/LemmaSpec.java | 56 - .../mgt/MethodContractInstantiation.java | 42 - .../key/proof/mgt/OldOperationContract.java | 40 - .../key/proof/mgt/ProofCorrectnessMgt.java | 19 +- .../ilkd/key/proof/mgt/ProofEnvironment.java | 107 +- .../uka/ilkd/key/proof/mgt/ProofStatus.java | 2 - .../ilkd/key/proof/mgt/RuleJustification.java | 17 +- .../mgt/RuleJustificationByAddRules.java | 19 +- .../proof/mgt/RuleJustificationBySpec.java | 30 +- .../key/proof/mgt/RuleJustificationInfo.java | 29 +- .../uka/ilkd/key/proof/mgt/SpecExtractor.java | 19 - .../proof/mgt/SpecificationRepository.java | 339 +- .../reuse/ReuseUpdateSimplificationRule.java | 3 - .../rule/AutomatedContractConfigurator.java | 80 - .../de/uka/ilkd/key/rule/BuiltInRuleApp.java | 2 +- .../key/rule/CheckPrgTransfSoundness.java | 2 - .../ilkd/key/rule/ContractConfigurator.java | 30 - .../ilkd/key/rule/MethodContractRuleApp.java | 24 - .../de/uka/ilkd/key/rule/NoPosTacletApp.java | 9 +- system/de/uka/ilkd/key/rule/Taclet.java | 6 +- system/de/uka/ilkd/key/rule/TacletApp.java | 2 +- .../ilkd/key/rule/UseMethodContractRule.java | 626 ---- .../key/rule/UseOperationContractRule.java | 503 +++ .../key/rule/UseOperationContractRuleApp.java | 38 + .../conditions/NewJumpLabelCondition.java | 8 +- .../FreeProgramVariableDetector.java | 10 +- .../TypeSchemeConstraintExtractor.java | 10 +- .../rule/encapsulation/UniverseAnalyser.java | 3 +- .../ilkd/key/rule/export/TacletLoader.java | 4 +- .../ilkd/key/rule/export/html/HTMLFile.java | 2 - .../rule/metaconstruct/AtPreEquations.java | 81 +- .../rule/metaconstruct/ExpandMethodBody.java | 2 +- .../key/rule/metaconstruct/ForToWhile.java | 118 + .../ForToWhileTransformation.java | 122 + .../rule/metaconstruct/IntroAtPreDefsOp.java | 85 + .../LocationDependentFunction.java | 40 +- .../metaconstruct/MetaConstructWithSV.java | 35 + .../key/rule/metaconstruct/MethodCall.java | 4 - .../rule/metaconstruct/ReplaceWhileLoop.java | 11 +- .../TestProgramMetaConstructs.java | 3 +- .../key/rule/metaconstruct/UnwindLoop.java | 29 +- .../key/rule/metaconstruct/WhileInvRule.java | 10 +- .../metaconstruct/WhileInvRuleWrapper.java | 13 +- .../WhileInvariantTransformation.java | 16 +- .../WhileLoopTransformation.java | 49 +- .../rule/metaconstruct/arith/Monomial.java | 8 +- .../rule/metaconstruct/arith/Polynomial.java | 4 +- .../key/rule/soundness/ProgramSVProxy.java | 13 - .../key/rule/soundness/ProgramSVSkolem.java | 13 - .../key/rule/soundness/SVPrefixCollector.java | 13 +- .../rule/soundness/StaticProgramChecker.java | 16 +- .../ilkd/key/rule/soundness/TacletPORule.java | 3 +- .../TermProgramVariableCollector.java | 12 +- .../ApplyOnAttributeAccess.java | 3 +- .../ApplyOnLocalVariableOrStaticField.java | 8 +- .../updatesimplifier/ApplyOnModality.java | 17 +- .../rule/updatesimplifier/ApplyOnUpdate.java | 9 +- .../UpdateSimplifierTermFactory.java | 2 +- .../key/speclang/AbstractClassInvariant.java | 38 - .../speclang/AbstractOperationContract.java | 65 - .../uka/ilkd/key/speclang/ClassInvariant.java | 40 +- .../ilkd/key/speclang/ClassInvariantImpl.java | 136 + .../key/speclang/DLOperationContract.java | 151 - .../ilkd/key/speclang/FormulaWithAxioms.java | 110 +- .../uka/ilkd/key/speclang/LoopInvariant.java | 105 + .../ilkd/key/speclang/LoopInvariantImpl.java | 266 ++ .../ilkd/key/speclang/OperationContract.java | 55 +- .../key/speclang/OperationContractImpl.java | 313 ++ .../ilkd/key/speclang/PositionedString.java | 66 + .../de/uka/ilkd/key/speclang/SLEnvInput.java | 140 + .../ilkd/key/speclang/SLTranslationError.java | 41 - .../speclang/SignatureVariablesFactory.java | 143 + .../uka/ilkd/key/speclang/SpecExtractor.java | 41 + .../speclang/TranslatedClassInvariant.java | 58 - .../dl/translation/DLSpecFactory.java | 279 ++ .../key/speclang/jml/JMLClassInvariant.java | 69 - .../key/speclang/jml/JMLInfoExtractor.java | 235 ++ .../speclang/jml/JMLOperationContract.java | 124 - .../key/speclang/jml/JMLSpecExtractor.java | 380 +++ .../ilkd/key/speclang/jml/JMLTranslator.java | 75 - .../speclang/jml/pretranslation/Behavior.java | 40 + .../pretranslation/TestJMLPreTranslator.java | 134 + .../pretranslation/TextualJMLClassInv.java | 51 + .../pretranslation/TextualJMLConstruct.java | 34 + .../pretranslation/TextualJMLFieldDecl.java | 51 + .../pretranslation/TextualJMLLoopSpec.java | 141 + .../pretranslation/TextualJMLMethodDecl.java | 62 + .../TextualJMLSetStatement.java | 52 + .../pretranslation/TextualJMLSpecCase.java | 175 + .../speclang/jml/pretranslation/jmlprelexer.g | 296 ++ .../jml/pretranslation/jmlpreparser.g | 992 ++++++ .../jml/translation/JMLExpression.java} | 26 +- .../jml/translation/JMLResolverManager.java | 42 + .../jml/translation/JMLSpecFactory.java | 674 ++++ .../jml/translation/JMLTranslator.java | 217 ++ .../jml/translation/TestJMLTranslator.java | 324 ++ .../jml/translation/jmllexer.g} | 26 +- .../key/speclang/jml/translation/jmlparser.g | 1683 ++++++++++ .../key/speclang/ocl/OCLClassInvariant.java | 76 - .../speclang/ocl/OCLOperationContract.java | 71 - .../key/speclang/ocl/OCLSpecExtractor.java | 165 + .../ilkd/key/speclang/ocl/OCLTranslator.java | 169 - .../ocl/translation}/AssociationResolver.java | 83 +- .../translation}/BuiltInPropertyResolver.java | 282 +- .../translation}/FormulaBoolConverter.java | 2 +- .../ocl/translation}/FunctionFactory.java | 60 +- .../ocl/translation/OCLAttributeResolver.java | 82 + .../ocl/translation}/OCLCollection.java | 53 +- .../speclang/ocl/translation/OCLEntity.java | 67 + .../translation}/OCLFunctionalCollection.java | 52 +- .../ocl/translation/OCLMethodResolver.java | 106 + .../ocl/translation}/OCLParameters.java | 21 +- .../OCLPredicativeCollection.java | 6 +- .../ocl/translation/OCLSpecFactory.java | 212 ++ .../ocl/translation/OCLTranslator.java | 152 + .../ocl/translation/PropertyManager.java | 52 + .../ocl/translation/TestOCLTranslator.java | 319 ++ .../ocl/translation/ocllexer.g} | 16 +- .../ocl/translation/oclparser.g} | 365 ++- .../translation}/AxiomCollector.java | 6 +- .../JavaIntegerSemanticsHelper.java | 353 ++ .../translation/SLAttributeResolver.java | 78 + .../speclang/translation/SLCollection.java | 30 + .../translation/SLCollectionType.java | 35 + .../speclang/translation/SLExpression.java | 123 + .../translation/SLExpressionResolver.java | 45 + .../translation/SLMethodResolver.java | 76 + .../speclang/translation/SLParameters.java | 46 + .../translation/SLResolverManager.java | 243 ++ .../translation/SLTranslationException.java | 74 + .../SLTranslationExceptionManager.java | 124 + .../speclang/translation/SLTypeResolver.java | 32 + .../key/strategy/FindTacletAppContainer.java | 3 - .../ilkd/key/strategy/JavaCardDLStrategy.java | 18 +- .../strategy/NoFindTacletAppContainer.java | 3 - .../AbstractMonomialSmallerThanFeature.java | 4 +- .../strategy/feature/FindRightishFeature.java | 2 +- .../feature/MonomialsSmallerThanFeature.java | 6 +- .../quantifierHeuristics/HandleArith.java | 6 +- .../LiteralsSmallerThanFeature.java | 2 +- .../AbstractDividePolynomialsProjection.java | 2 +- .../ilkd/key/unittest/EquivalenceClass.java | 6 +- .../uka/ilkd/key/unittest/TestGenerator.java | 12 +- .../UseMethodContractRuleForTestGen.java | 57 - system/de/uka/ilkd/key/util/Debug.java | 16 + .../ilkd/key/visualdebugger/DebuggerPO.java | 31 - .../ilkd/key/visualdebugger/ProofStarter.java | 20 +- .../key/visualdebugger/VisualDebugger.java | 2 +- .../visualdebugger/executiontree/ITNode.java | 2 +- .../SymbolicObjectDiagram.java | 2 +- .../SimpleVisualizationStrategy.java | 4 +- .../menuextension/KeyMenuExtension.properties | 4 +- .../uka/ilkd/key/gui/images/toolbar/jml.png | Bin 0 -> 1374 bytes .../uka/ilkd/key/gui/images/toolbar/uml.png | Bin 0 -> 993 bytes .../de/uka/ilkd/key/proof/rules/javaRules.key | 57 +- 444 files changed, 21704 insertions(+), 22533 deletions(-) create mode 100644 examples/_testcase/speclang/testFile.key create mode 100644 examples/_testcase/speclang/testPackage/TestClass.java mode change 100644 => 100755 examples/java_dl/cassisdemo/Java Card Allocation.dfSequence create mode 100644 examples/java_dl/for_demo/For.java create mode 100644 examples/java_dl/payCardOCL/paycard/CardException.java create mode 100644 examples/java_dl/payCardOCL/paycard/ChargeUI.java create mode 100644 examples/java_dl/payCardOCL/paycard/IssueCardUI.java create mode 100644 examples/java_dl/payCardOCL/paycard/PayCard.java create mode 100644 examples/java_dl/payCardOCL/paycard/PayCardJunior.java create mode 100644 examples/java_dl/payCardOCL/paycard/Start.java mode change 100644 => 100755 examples/smtlib/Func_imp_add_overflow.key.proof mode change 100644 => 100755 examples/smtlib/Func_imp_dist.key.proof mode change 100644 => 100755 examples/smtlib/Func_imp_dist2_unclosed.key.proof mode change 100644 => 100755 examples/smtlib/Pred-imp_and.key.proof mode change 100644 => 100755 examples/smtlib/Pred-imp_dist.key.proof mode change 100644 => 100755 examples/smtlib/Pred-imp_dist2.key.proof mode change 100644 => 100755 examples/smtlib/Pred-imp_or.key.proof mode change 100644 => 100755 examples/smtlib/imp_false_false.key.proof mode change 100644 => 100755 examples/smtlib/imp_false_true.key.proof mode change 100644 => 100755 examples/smtlib/imp_true_false_unclosed.key.proof mode change 100644 => 100755 examples/smtlib/imp_true_true.key.proof delete mode 100644 system/de/uka/ilkd/key/casetool/FunctionalityOnModel.java create mode 100644 system/de/uka/ilkd/key/casetool/together/FunctionalityOnModel.java mode change 100644 => 100755 system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint3.java mode change 100755 => 100644 system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint5.java delete mode 100644 system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint7.java delete mode 100644 system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint12.java rename system/de/uka/ilkd/key/{proof/init/ComputeSpecificationPONew.java => cspec/ComputeSpecificationPO.java} (67%) create mode 100644 system/de/uka/ilkd/key/gui/ClassTree.java create mode 100644 system/de/uka/ilkd/key/gui/ContractConfigurator.java delete mode 100644 system/de/uka/ilkd/key/gui/ContractSelectionPanel.java delete mode 100644 system/de/uka/ilkd/key/gui/DefaultContractConfigurator.java delete mode 100644 system/de/uka/ilkd/key/gui/JMLPOAndSpecProvider.java delete mode 100644 system/de/uka/ilkd/key/gui/JMLSpecBrowser.java delete mode 100644 system/de/uka/ilkd/key/gui/MethodContractList.java create mode 100644 system/de/uka/ilkd/key/gui/OperationContractSelectionPanel.java create mode 100644 system/de/uka/ilkd/key/gui/POBrowser.java delete mode 100644 system/de/uka/ilkd/key/gui/SuperclassSelectionDialog.java delete mode 100644 system/de/uka/ilkd/key/gui/UseMethodContractRuleItem.java delete mode 100644 system/de/uka/ilkd/key/gui/UsedMethodContractsList.java create mode 100644 system/de/uka/ilkd/key/gui/UsedSpecificationsDialog.java delete mode 100644 system/de/uka/ilkd/key/java/annotation/Annotation.java delete mode 100644 system/de/uka/ilkd/key/java/annotation/LoopInvariantAnnotation.java rename system/de/uka/ilkd/key/{proof/mgt/PrePostPair.java => java/declaration/modifier/Ghost.java} (52%) create mode 100644 system/de/uka/ilkd/key/java/expression/operator/SetAssignment.java create mode 100644 system/de/uka/ilkd/key/java/recoderext/Ghost.java create mode 100644 system/de/uka/ilkd/key/java/recoderext/JMLTransformer.java create mode 100644 system/de/uka/ilkd/key/java/recoderext/Model.java create mode 100644 system/de/uka/ilkd/key/java/recoderext/SetAssignment.java delete mode 100644 system/de/uka/ilkd/key/jml/AmbigiousModelElementException.java delete mode 100644 system/de/uka/ilkd/key/jml/AssignableSpec.java delete mode 100644 system/de/uka/ilkd/key/jml/Implementation2SpecMap.java delete mode 100644 system/de/uka/ilkd/key/jml/JMLClassSpec.java delete mode 100644 system/de/uka/ilkd/key/jml/JMLExceptionalMethodSpec.java delete mode 100644 system/de/uka/ilkd/key/jml/JMLLemmaMethodSpec.java delete mode 100644 system/de/uka/ilkd/key/jml/JMLMethodSpec.java delete mode 100644 system/de/uka/ilkd/key/jml/JMLNormalMethodSpec.java delete mode 100644 system/de/uka/ilkd/key/jml/JMLPuritySpec.java delete mode 100644 system/de/uka/ilkd/key/jml/JMLSpec.java delete mode 100644 system/de/uka/ilkd/key/jml/LoopInvariant.java delete mode 100644 system/de/uka/ilkd/key/jml/Signals.java delete mode 100644 system/de/uka/ilkd/key/jml/UsefulTools.java delete mode 100644 system/de/uka/ilkd/key/jml/WrongIntSemanticsException.java create mode 100755 system/de/uka/ilkd/key/jmltest/JMLExport.java create mode 100755 system/de/uka/ilkd/key/jmltest/JMLLogicPrinter.java create mode 100755 system/de/uka/ilkd/key/jmltest/JMLNotationInfo.java create mode 100755 system/de/uka/ilkd/key/jmltest/JMLTestFileCreator.java create mode 100644 system/de/uka/ilkd/key/jmltest/WrapperConstructor.java rename system/de/uka/ilkd/key/{logic => parser}/AtPreNamespace.java (92%) delete mode 100644 system/de/uka/ilkd/key/parser/jml/ArithOpProvider.java delete mode 100644 system/de/uka/ilkd/key/parser/jml/DefaultArithOpProvider.java delete mode 100644 system/de/uka/ilkd/key/parser/jml/JMLSpecBuilder.java delete mode 100644 system/de/uka/ilkd/key/parser/jml/JMLTranslator.java delete mode 100644 system/de/uka/ilkd/key/parser/jml/NotSupportedExpressionException.java delete mode 100644 system/de/uka/ilkd/key/parser/jml/jml.g delete mode 100644 system/de/uka/ilkd/key/parser/ocl/AttributeResolver.java delete mode 100644 system/de/uka/ilkd/key/parser/ocl/MethodResolver.java delete mode 100644 system/de/uka/ilkd/key/parser/ocl/OCLEntity.java delete mode 100644 system/de/uka/ilkd/key/parser/ocl/OCLTranslationError.java delete mode 100644 system/de/uka/ilkd/key/parser/ocl/PropertyManager.java delete mode 100644 system/de/uka/ilkd/key/parser/ocl/PropertyResolver.java create mode 100644 system/de/uka/ilkd/key/proof/AtPreFactory.java delete mode 100644 system/de/uka/ilkd/key/proof/SymbolReplacer.java delete mode 100644 system/de/uka/ilkd/key/proof/TermSVReplacer.java delete mode 100644 system/de/uka/ilkd/key/proof/UseMethodContractRuleFilter.java create mode 100644 system/de/uka/ilkd/key/proof/UseOperationContractRuleFilter.java mode change 100644 => 100755 system/de/uka/ilkd/key/proof/decproc/DecisionProcedureDummyTranslation.java mode change 100644 => 100755 system/de/uka/ilkd/key/proof/decproc/DecisionProcedureSmtAuflia.java mode change 100644 => 100755 system/de/uka/ilkd/key/proof/decproc/DecisionProcedureYices.java rename system/de/uka/ilkd/key/proof/init/{DefaultEnvInput.java => AbstractEnvInput.java} (87%) delete mode 100644 system/de/uka/ilkd/key/proof/init/AssignableCheckProofOblInput.java delete mode 100644 system/de/uka/ilkd/key/proof/init/InvariantSelectionStrategy.java delete mode 100644 system/de/uka/ilkd/key/proof/init/JMLInvPO.java delete mode 100644 system/de/uka/ilkd/key/proof/init/JMLPostAndInvPO.java delete mode 100644 system/de/uka/ilkd/key/proof/init/JMLPostPO.java delete mode 100644 system/de/uka/ilkd/key/proof/init/JMLProofOblInput.java delete mode 100644 system/de/uka/ilkd/key/proof/init/JMLProofOblInputImpl.java delete mode 100644 system/de/uka/ilkd/key/proof/init/JavaInput.java delete mode 100644 system/de/uka/ilkd/key/proof/init/JavaInputWithJMLSpecBrowser.java delete mode 100644 system/de/uka/ilkd/key/proof/init/KeYJMLInput.java delete mode 100644 system/de/uka/ilkd/key/proof/init/ModifiesCheckProofOblInput.java create mode 100755 system/de/uka/ilkd/key/proof/init/SpecExtPO.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/AbstractContract.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/Contract.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/ContractSet.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/ContractUtil.java create mode 100644 system/de/uka/ilkd/key/proof/mgt/ContractWithInvs.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/Contractable.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/DLHoareTriplePO.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/DLMethodContract.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/DefaultOperationContract.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/DepAnalysis.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/InstantiatedMethodContract.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/JMLMethodContract.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/JavaModelClass.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/JavaModelMethod.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/LemmaRuleJustification.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/LemmaSpec.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/MethodContractInstantiation.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/OldOperationContract.java delete mode 100644 system/de/uka/ilkd/key/proof/mgt/SpecExtractor.java delete mode 100644 system/de/uka/ilkd/key/rule/AutomatedContractConfigurator.java delete mode 100644 system/de/uka/ilkd/key/rule/ContractConfigurator.java delete mode 100644 system/de/uka/ilkd/key/rule/MethodContractRuleApp.java delete mode 100644 system/de/uka/ilkd/key/rule/UseMethodContractRule.java create mode 100644 system/de/uka/ilkd/key/rule/UseOperationContractRule.java create mode 100644 system/de/uka/ilkd/key/rule/UseOperationContractRuleApp.java create mode 100644 system/de/uka/ilkd/key/rule/metaconstruct/ForToWhile.java create mode 100644 system/de/uka/ilkd/key/rule/metaconstruct/ForToWhileTransformation.java create mode 100644 system/de/uka/ilkd/key/rule/metaconstruct/IntroAtPreDefsOp.java create mode 100644 system/de/uka/ilkd/key/rule/metaconstruct/MetaConstructWithSV.java delete mode 100644 system/de/uka/ilkd/key/speclang/AbstractClassInvariant.java delete mode 100644 system/de/uka/ilkd/key/speclang/AbstractOperationContract.java create mode 100644 system/de/uka/ilkd/key/speclang/ClassInvariantImpl.java delete mode 100644 system/de/uka/ilkd/key/speclang/DLOperationContract.java create mode 100644 system/de/uka/ilkd/key/speclang/LoopInvariant.java create mode 100644 system/de/uka/ilkd/key/speclang/LoopInvariantImpl.java create mode 100644 system/de/uka/ilkd/key/speclang/OperationContractImpl.java create mode 100644 system/de/uka/ilkd/key/speclang/PositionedString.java create mode 100644 system/de/uka/ilkd/key/speclang/SLEnvInput.java delete mode 100644 system/de/uka/ilkd/key/speclang/SLTranslationError.java create mode 100644 system/de/uka/ilkd/key/speclang/SignatureVariablesFactory.java create mode 100644 system/de/uka/ilkd/key/speclang/SpecExtractor.java delete mode 100644 system/de/uka/ilkd/key/speclang/TranslatedClassInvariant.java create mode 100644 system/de/uka/ilkd/key/speclang/dl/translation/DLSpecFactory.java delete mode 100644 system/de/uka/ilkd/key/speclang/jml/JMLClassInvariant.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/JMLInfoExtractor.java delete mode 100644 system/de/uka/ilkd/key/speclang/jml/JMLOperationContract.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/JMLSpecExtractor.java delete mode 100644 system/de/uka/ilkd/key/speclang/jml/JMLTranslator.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/Behavior.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/TestJMLPreTranslator.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLClassInv.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLConstruct.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLFieldDecl.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLLoopSpec.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLMethodDecl.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLSetStatement.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLSpecCase.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/jmlprelexer.g create mode 100644 system/de/uka/ilkd/key/speclang/jml/pretranslation/jmlpreparser.g rename system/de/uka/ilkd/key/{proof/mgt/HoareTripleContract.java => speclang/jml/translation/JMLExpression.java} (50%) create mode 100644 system/de/uka/ilkd/key/speclang/jml/translation/JMLResolverManager.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/translation/JMLSpecFactory.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/translation/JMLTranslator.java create mode 100644 system/de/uka/ilkd/key/speclang/jml/translation/TestJMLTranslator.java rename system/de/uka/ilkd/key/{parser/jml/lexer.g => speclang/jml/translation/jmllexer.g} (89%) mode change 100755 => 100644 create mode 100644 system/de/uka/ilkd/key/speclang/jml/translation/jmlparser.g delete mode 100644 system/de/uka/ilkd/key/speclang/ocl/OCLClassInvariant.java delete mode 100644 system/de/uka/ilkd/key/speclang/ocl/OCLOperationContract.java create mode 100644 system/de/uka/ilkd/key/speclang/ocl/OCLSpecExtractor.java delete mode 100644 system/de/uka/ilkd/key/speclang/ocl/OCLTranslator.java rename system/de/uka/ilkd/key/{parser/ocl => speclang/ocl/translation}/AssociationResolver.java (53%) rename system/de/uka/ilkd/key/{parser/ocl => speclang/ocl/translation}/BuiltInPropertyResolver.java (59%) rename system/de/uka/ilkd/key/{parser/ocl => speclang/ocl/translation}/FormulaBoolConverter.java (99%) rename system/de/uka/ilkd/key/{parser/ocl => speclang/ocl/translation}/FunctionFactory.java (94%) create mode 100644 system/de/uka/ilkd/key/speclang/ocl/translation/OCLAttributeResolver.java rename system/de/uka/ilkd/key/{parser/ocl => speclang/ocl/translation}/OCLCollection.java (87%) create mode 100644 system/de/uka/ilkd/key/speclang/ocl/translation/OCLEntity.java rename system/de/uka/ilkd/key/{parser/ocl => speclang/ocl/translation}/OCLFunctionalCollection.java (82%) create mode 100644 system/de/uka/ilkd/key/speclang/ocl/translation/OCLMethodResolver.java rename system/de/uka/ilkd/key/{parser/ocl => speclang/ocl/translation}/OCLParameters.java (71%) rename system/de/uka/ilkd/key/{parser/ocl => speclang/ocl/translation}/OCLPredicativeCollection.java (98%) create mode 100644 system/de/uka/ilkd/key/speclang/ocl/translation/OCLSpecFactory.java create mode 100644 system/de/uka/ilkd/key/speclang/ocl/translation/OCLTranslator.java create mode 100644 system/de/uka/ilkd/key/speclang/ocl/translation/PropertyManager.java create mode 100644 system/de/uka/ilkd/key/speclang/ocl/translation/TestOCLTranslator.java rename system/de/uka/ilkd/key/{parser/ocl/lexer.g => speclang/ocl/translation/ocllexer.g} (93%) rename system/de/uka/ilkd/key/{parser/ocl/ocl.g => speclang/ocl/translation/oclparser.g} (69%) rename system/de/uka/ilkd/key/{parser/ocl => speclang/translation}/AxiomCollector.java (82%) create mode 100644 system/de/uka/ilkd/key/speclang/translation/JavaIntegerSemanticsHelper.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLAttributeResolver.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLCollection.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLCollectionType.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLExpression.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLExpressionResolver.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLMethodResolver.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLParameters.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLResolverManager.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLTranslationException.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLTranslationExceptionManager.java create mode 100644 system/de/uka/ilkd/key/speclang/translation/SLTypeResolver.java delete mode 100644 system/de/uka/ilkd/key/unittest/UseMethodContractRuleForTestGen.java create mode 100644 system/resources/de/uka/ilkd/key/gui/images/toolbar/jml.png create mode 100644 system/resources/de/uka/ilkd/key/gui/images/toolbar/uml.png diff --git a/eclipse/.project b/eclipse/.project index 2137f220a51..ba18d85dc01 100644 --- a/eclipse/.project +++ b/eclipse/.project @@ -18,14 +18,14 @@ - tcc_modules + key_lib 2 - tcc_modules + key_lib - key_lib + tcc_modules 2 - key_lib + tcc_modules diff --git a/examples/_testcase/speclang/testFile.key b/examples/_testcase/speclang/testFile.key new file mode 100644 index 00000000000..c18b07613bf --- /dev/null +++ b/examples/_testcase/speclang/testFile.key @@ -0,0 +1,3 @@ +\javaSource "testPackage"; + +\problem { true } diff --git a/examples/_testcase/speclang/testPackage/TestClass.java b/examples/_testcase/speclang/testPackage/TestClass.java new file mode 100644 index 00000000000..fc6765b7875 --- /dev/null +++ b/examples/_testcase/speclang/testPackage/TestClass.java @@ -0,0 +1,25 @@ +package testPackage; + +public class TestClass { + + int i; + long l; + + public int getOne() { + return 1; + } + + public int m(int a) { + return 2; + } + + public int m(long a) { + return 3; + } + + public static int staticMethod() { + return 4; + } + +} + diff --git a/examples/java_dl/cassisdemo/Java Card Allocation.dfSequence b/examples/java_dl/cassisdemo/Java Card Allocation.dfSequence old mode 100644 new mode 100755 diff --git a/examples/java_dl/for_demo/For.java b/examples/java_dl/for_demo/For.java new file mode 100644 index 00000000000..0b3e26f2b5a --- /dev/null +++ b/examples/java_dl/for_demo/For.java @@ -0,0 +1,117 @@ +class For { + + /* This method should be proven automatically since the contract + * of the for loop is transferred to the generated while loop + */ + + /*@ requires length > 0; + @ ensures \result == length; + @*/ + public int annotations(int length) { + int count = 0; + + /*@ loop_invariant i >= 0 & i <= length & count == i; + @ decreasing length - i; + @ assignable count, i; + @*/ + for(int i = 0; i < length; i++) { + count = count + 1; + } + + return count; + } + + + /* + * This method should be proven automatically since the contract + * of the for loop is transferred to the generated while loop + */ + + /*@ requires array != null && array.length > 0; + @ ensures (\forall int i; i >= 0 && i < \old(array).length; \result <= \old(array)[i]); + @ ensures (\forall int i; i >= 0 && i < \old(array).length; array[i] == \old(array)[i]); + */ + public int array_min(int[] array) { + + int min = array[0]; + + /*@ loop_invariant (\forall int j; j >= 0 && j < i; min <= array[j]); + @ assignable i, min; + @ decreasing array.length - i; + */ + for(int i = 1; i < array.length; i++) { + if(min > array[i]) + min = array[i]; + } + + return min; + } + + + /* + * This method is used to show that loops are treated correctly + * even if parts are left out. + */ + + /*@ requires true; + @ ensures true; + */ + public void leave_out() { + + for(int i = 0; i < 100;) { break; } + for(int i = 0; ;i++) { break; } + for(;;) { break; } + + } + + + /* + * This method checks whether breaks and continues are handled + * correctly. + */ + + /*@ requires true; + @ ensures \result; + */ + public boolean checkBreakContinue() { + int dummy; + boolean ret = true; + + outerlabel: { + dummy = 0; // some statement + for(;dummy == 0;dummy++) { + break outerlabel; + } + } + + // dummy must be 0 here + ret &= (dummy == 0); + + dummy = 0; + for(; dummy == 0; dummy++) { + break; + } + // dummy must be 0 here + ret &= (dummy == 0); + + dummy = 0; + for(; dummy == 0; dummy++) { + continue; + } + // dummy must be 1 here + ret &= (dummy == 1); + + dummy = 0; + outer: while(dummy == 0) { + dummy = 1; + for(; true; dummy++) { + continue outer; + } + } + // dummy must be 1 here + ret &= (dummy == 1); + + return ret; + + } +} diff --git a/examples/java_dl/payCardOCL/paycard/CardException.java b/examples/java_dl/payCardOCL/paycard/CardException.java new file mode 100644 index 00000000000..313d8d5aa0d --- /dev/null +++ b/examples/java_dl/payCardOCL/paycard/CardException.java @@ -0,0 +1,5 @@ +public class CardException extends java.lang.Exception{ + + public CardException(){ + } +} diff --git a/examples/java_dl/payCardOCL/paycard/ChargeUI.java b/examples/java_dl/payCardOCL/paycard/ChargeUI.java new file mode 100644 index 00000000000..d2aa3913daf --- /dev/null +++ b/examples/java_dl/payCardOCL/paycard/ChargeUI.java @@ -0,0 +1,95 @@ +/* Generated by Together */ + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.*; + +public class ChargeUI { + + ChargeUI(int desiredCardType, int limit){ + frame = new JFrame("Charge Paycard"); + jTextArea1.setFont(new Font("",Font.PLAIN, 18)); + if (desiredCardType==IssueCardUI.STANDARD){ + this.limit=1000; + paycard = new PayCard(); + } else if (desiredCardType==IssueCardUI.JUNIOR){ + this.limit=100; + paycard = PayCardJunior.createCard(); + } else if (desiredCardType==IssueCardUI.USER_DEFINED){ + this.limit=limit; + paycard = new PayCard(limit); + } + } + + public void initGUI() { + jButton2.setText("Quit"); + jButton2.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){jButton2ActionPerformed(e);}}); + jButton1.setText("charge"); + jButton1.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){jButton1ActionPerformed(e);}}); + frame.setBounds(100,100,550,350); + frame.setResizable(true); + frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); + jTextField1.setText("jTextField1"); + frame.getContentPane().setLayout(new BorderLayout()); + frame.getContentPane().add(new JPanel(),BorderLayout.WEST); + frame.getContentPane().add(new JPanel(),BorderLayout.EAST); + frame.getContentPane().add(jPanel1,BorderLayout.CENTER); + frame.getContentPane().add(jPanel2,BorderLayout.SOUTH); + jPanel2.setLayout(new GridLayout(1,2)); + jPanel2.add(jButton1); + jPanel2.add(jButton2); + jPanel1.setLayout(new BorderLayout()); + jPanel3.setLayout(new GridLayout(1,2)); + jPanel3.add(jLabel1); + jPanel3.add(jTextField1); + jPanel1.add(jPanel3,BorderLayout.SOUTH); + jPanel1.add(jTextArea1); + jPanel1.add(jLabel2,BorderLayout.NORTH); + jLabel1.setText("Amount to charge:"); + jTextField1.setText(""); + jTextArea1.setText(""); + jTextArea1.setBorder(javax.swing.BorderFactory.createEtchedBorder()); + jTextArea1.setEditable(false); + JScrollPane jScrollPane1 = new JScrollPane(jTextArea1); + jScrollPane1.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + jPanel1.add(jScrollPane1, null); + jLabel2.setText("Limit of paycard is "+limit+"."); + jLabel2.setFont(new java.awt.Font("SansSerif", java.awt.Font.BOLD, 14)); + frame.show(); + } + + public void jButton2ActionPerformed(ActionEvent e) { + frame.dispose(); + System.exit(0); + } + + public void jButton1ActionPerformed(ActionEvent e) { + // read textfield + int charge; + try{ + charge=Integer.parseInt(jTextField1.getText()); + } + catch (NumberFormatException ex){ + JOptionPane.showMessageDialog( + frame, "Amount to charge has to be a number!", "Error", + JOptionPane.ERROR_MESSAGE); + return; + } + paycard.charge(charge); + jTextArea1.append(paycard.infoCardMsg()+"\n"); + } + + private JFrame frame; + private int limit; + private JPanel jPanel1 = new JPanel(); + private JPanel jPanel2 = new JPanel(); + private JPanel jPanel3 = new JPanel(); + private JLabel jLabel1 = new JLabel(); + private JTextField jTextField1 = new JTextField(); + private JButton jButton2 = new JButton(); + private PayCard paycard; + private JButton jButton1 = new JButton(); + private JTextArea jTextArea1 = new JTextArea(); + private JLabel jLabel2 = new JLabel(); +} diff --git a/examples/java_dl/payCardOCL/paycard/IssueCardUI.java b/examples/java_dl/payCardOCL/paycard/IssueCardUI.java new file mode 100644 index 00000000000..075099712f9 --- /dev/null +++ b/examples/java_dl/payCardOCL/paycard/IssueCardUI.java @@ -0,0 +1,127 @@ +import javax.swing.JPanel; +import javax.swing.JRadioButtonMenuItem; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class IssueCardUI{ + + public IssueCardUI(){ + frame = new JFrame("Issue Paycard"); + desiredCardType=STANDARD; + } + + public void initGUI() { + frame.setBounds(100,100,550,230); + frame.setResizable(true); + frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); + frame.getContentPane().setLayout(new BorderLayout()); + frame.getContentPane().add(new JPanel(),BorderLayout.WEST); + frame.getContentPane().add(new JPanel(),BorderLayout.EAST); + frame.getContentPane().add(jPanel1,BorderLayout.CENTER); + frame.getContentPane().add(jPanel2,BorderLayout.SOUTH); + GridLayout layout = new GridLayout(3,1); + jPanel1.setLayout(layout); + jPanel2.setLayout(new GridLayout(1,3)); + jPanel3.setLayout(new GridLayout(1,3)); + jPanel5.setLayout(new BorderLayout()); + jPanel1.add(jRadioButton1); + jPanel1.add(jRadioButton2); + jPanel1.add(jPanel3,BorderLayout.SOUTH); + jPanel3.add(jRadioButton3); + jPanel2.add(jButton1); + jPanel2.add(jButton2); + jPanel4.setLayout(new BorderLayout()); + jPanel4.add(jLabel1,BorderLayout.EAST); + jPanel3.add(jPanel4); + jPanel5.add(new JPanel(),BorderLayout.NORTH); + jPanel5.add(new JPanel(),BorderLayout.SOUTH); + jPanel5.add(jTextField1,BorderLayout.CENTER); + jPanel3.add(jPanel5); + jRadioButton1.setText("jRadioButton1"); + jRadioButton1.setLabel("Standard Paycard"); + jRadioButton1.setSelected(true); + jRadioButton2.setText("jRadioButton2"); + jRadioButton2.setLabel("Junior Paycard"); + jRadioButton3.setText("jRadioButton3"); + jRadioButton3.setLabel("User Defined Paycard"); + jButton1.setText("jButton1"); + jButton1.setLabel("Issue Paycard"); + jButton2.setText("jButton2"); + jButton2.setLabel("Quit"); + jTextField1.setText("1000"); + jTextField1.setMaximumSize(new Dimension(200,10)); + jTextField1.setMinimumSize(new Dimension(200,10)); + jTextField1.setPreferredSize(new Dimension(200,10)); + jLabel1.setText("Limit: "); + jLabel1.setToolTipText("Limit of the paycard"); + ButtonGroup group = new ButtonGroup(); + group.add(jRadioButton1); + group.add(jRadioButton2); + group.add(jRadioButton3); + RadioListener listener = new RadioListener(); + jRadioButton1.addActionListener(listener); + jRadioButton2.addActionListener(listener); + jRadioButton3.addActionListener(listener); + frame.show(); + jButton2.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){jButton2ActionPerformed(e);}}); + jButton1.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){jButton1ActionPerformed(e);}}); + } + + public void jButton2ActionPerformed(ActionEvent e) { + frame.dispose(); + System.exit(0); + } + + public void jButton1ActionPerformed(ActionEvent e) { + // read textfield + int limit=0; + if (desiredCardType==USER_DEFINED){ + try{ + limit=Integer.parseInt(jTextField1.getText()); + } + catch (NumberFormatException ex){ + JOptionPane.showMessageDialog( + frame, "Limit has to be a number!", "Error", + JOptionPane.ERROR_MESSAGE); + return; + } + } + frame.dispose(); + ChargeUI chargeUI = new ChargeUI(desiredCardType, limit); + chargeUI.initGUI(); + } + + class RadioListener implements ActionListener{ + public void actionPerformed(ActionEvent e){ + if (e.getActionCommand().equals("Standard Paycard")){ + desiredCardType=STANDARD; + } else if (e.getActionCommand().equals("Junior Paycard")){ + desiredCardType=JUNIOR; + } else if (e.getActionCommand().equals("User Defined Paycard")){ + desiredCardType=USER_DEFINED; + } + } + } + + + private JFrame frame; + private JPanel jPanel1 = new JPanel(); + private JPanel jPanel2 = new JPanel(); + private JPanel jPanel3 = new JPanel(); + private JPanel jPanel4 = new JPanel(); + private JPanel jPanel5 = new JPanel(); + private JRadioButton jRadioButton1 = new JRadioButton(); + private JRadioButton jRadioButton2 = new JRadioButton(); + private JRadioButton jRadioButton3 = new JRadioButton(); + private JButton jButton1 = new JButton(); + private JButton jButton2 = new JButton(); + private JTextField jTextField1 = new JTextField(); + private JLabel jLabel1 = new JLabel(); + protected final static int STANDARD=1; + protected final static int JUNIOR=2; + protected final static int USER_DEFINED=3; + private int desiredCardType; +} diff --git a/examples/java_dl/payCardOCL/paycard/PayCard.java b/examples/java_dl/payCardOCL/paycard/PayCard.java new file mode 100644 index 00000000000..2ff57ee5eb4 --- /dev/null +++ b/examples/java_dl/payCardOCL/paycard/PayCard.java @@ -0,0 +1,41 @@ +public class PayCard { + int limit=1000; + int unsuccessfulOperations; + int id; + int balance=0; + + public PayCard(int limit) { + balance = 0; + unsuccessfulOperations=0; + this.limit=limit; + } + + public PayCard() { + balance=0; + unsuccessfulOperations=0; + } + + /* @preconditions amount>0 + * @postconditions balance>=balance@pre + */ + public void charge(int amount) { + if (this.balance+amount>=this.limit) { + this.unsuccessfulOperations++; + } else { + this.balance=this.balance+amount; + } + } + + // @postconditions result=balance or unsuccessfulOperations>3 + public int available() { + if (unsuccessfulOperations<=3) { + return this.balance; + } + return 0; + } + + + public String infoCardMsg() { + return (" Current balance on card is " + balance); + } +} diff --git a/examples/java_dl/payCardOCL/paycard/PayCardJunior.java b/examples/java_dl/payCardOCL/paycard/PayCardJunior.java new file mode 100644 index 00000000000..5c634bb6ba6 --- /dev/null +++ b/examples/java_dl/payCardOCL/paycard/PayCardJunior.java @@ -0,0 +1,70 @@ +public class PayCardJunior extends PayCard { + + /* @invariants (self.balance >= 0) + * and (self.balance < juniorLimit) + * and (juniorLimit0 + * @postconditions if (balance@pre+amount=juniorLimit) endif + */ + private int checkSum(int sum) { + if (sum >= this.juniorLimit) { + return 0; + } else { + return 1; + } + } + + /* @preconditions amount>0 + * @postconditions if (balance@pre+amountaMethRepr. - * @param modelMethod the method whose specification to compute. - * @return any error messages to pass to the user. - * @see de.uka.ilkd.key.cspec.ComputeSpecification - * @see de.uka.ilkd.key.proof.init.ComputeSpecificationPONew - */ - public static String computeSpecification(ModelMethod modelMethod) { - - ProofOblInput po = new ComputeSpecificationPONew("ComputeSpecification", - modelMethod); - - return startProver(modelMethod.getContainingClass(), po); - } - - - public static String transformXMIFile(ReprModel aReprModel){ - return ""; - } - - - public static String proveDLFormula(ModelClass modelClass, - File file) { - - CasetoolDLPO dlPOFromCasetool = new CasetoolDLPO(modelClass, file); - return startProver(modelClass, dlPOFromCasetool); - } - - - /** - * Used for OCL Simplification. - * @param modelClass the ModelClass whose invariant needs to be simplified. - */ - public static String simplifyInvariant(ModelClass modelClass) { - ProofOblInput po = new OCLInvSimplPO(modelClass); - return startProver(modelClass, po); - } - - - - //------------------------------------------------------------------------- - //New proof obligations - //------------------------------------------------------------------------- - - /** - * Asks the user to choose a supertype and then starts the prover with a - * corresponding "BehaviouralSubtypingInv" proof obligation. - * @param subtype the UMLModelClass with subtype for which behavioural - * subtyping with respect to the invariant has to be shown - * @return error message to the user - */ - public static String proveBehaviouralSubtypingInv(UMLModelClass subtype) { - //let the user select a supertype - SuperclassSelectionDialog dlg = new SuperclassSelectionDialog(subtype); - if(!dlg.wasSuccessful()) { - return ""; - } - ModelClass supertype = dlg.getSuperclass(); - if(supertype == null) { - return "No supertype has been selected."; - } - if(supertype.getMyClassInvariants().isEmpty()) { - return "Supertype does not have any invariants."; - } - - //create and start the PO - final ProofOblInput po = new BehaviouralSubtypingInvPO(subtype, - supertype); - return startProver(subtype, po); - } - - - /** - * Starts the prover with a "BehaviouralSubtypingOpPair" proof obligation. - * @param subMethod the ModelMethod representing the overwriting method to reason about; the proof - * obligation will be about its *first* operation contract - * @return error message to the user - */ - public static String proveBehaviouralSubtypingOpPair( - ModelMethod subMethod){ - //get the relevant contract of the subtype method - ListOfOperationContract subContracts - = subMethod.getMyOperationContracts(); - if(subContracts.isEmpty()) { - return "No contracts are available for the selected method."; - } - OperationContract subContract = subContracts.head(); - - //let the user select a supertype - //(eventually, the user should be allowed to choose a specific contract - //here instead of just a class) - SuperclassSelectionDialog dlg - = new SuperclassSelectionDialog(subMethod.getContainingClass()); - if(!dlg.wasSuccessful()) { - return ""; - } - ModelClass supertype = dlg.getSuperclass(); - if(supertype == null) { - return "No supertype has been selected"; - } - - //determine the method in the chosen supertype which is overriden - //by the subtype method - ModelMethod overriddenMethod = getOverriddenMethod(subMethod, - supertype); - if(overriddenMethod == null) { - return "No overridden method \"" + subMethod.getName() - + "\" could be found in the selected supertype."; - } - - //get the relevant contract of the overridden method - ListOfOperationContract overriddenContracts = - overriddenMethod.getMyOperationContracts(); - if(overriddenContracts.isEmpty()) { - return "No contracts are available for the overridden method."; - } - OperationContract overriddenContract = overriddenContracts.head(); - - //create and start the PO - ProofOblInput po = new BehaviouralSubtypingOpPairPO(subContract, - overriddenContract); - return startProver(supertype, po); - } - - - - /** - * Starts the prover with a "BehaviouralSubtypingOp" proof obligation. - * @param subtype the UMLModelClass with the subtype for whose method - * behavioural subtyping has to be proven - * @return error message to the user - */ - public static String proveBehaviouralSubtypingOp(UMLModelClass subtype){ - //let the user select a supertype - SuperclassSelectionDialog dlg = new SuperclassSelectionDialog(subtype); - if(!dlg.wasSuccessful()) { - return ""; - } - ModelClass supertype = dlg.getSuperclass(); - if(supertype == null) { - return "No supertype has been selected"; - } - - //get all pairs of overriding and overridden operation contracts - //(if there are multiple contracts for one method in either - //the sub- or the supertype, this currently just pairs them in the order - //in which they appear; eventually, the user should be asked instead) - Map contractPairs = new HashMap(); - Vector subOps = subtype.getOps(); - Iterator it = subOps.iterator(); - while(it.hasNext()) { - ModelMethod subMethod = (ModelMethod)(it.next()); - - ModelMethod superMethod = getOverriddenMethod(subMethod, supertype); - if(superMethod != null) { - ListOfOperationContract subContracts - = subMethod.getMyOperationContracts(); - ListOfOperationContract superContracts - = superMethod.getMyOperationContracts(); - IteratorOfOperationContract subIt = subContracts.iterator(); - IteratorOfOperationContract superIt = superContracts.iterator(); - while(subIt.hasNext() && superIt.hasNext()) { - contractPairs.put(subIt.next(), superIt.next()); - } - } - } - if(contractPairs.isEmpty()) { - return "No overridden contracts could be found " - + "in the selected supertype."; - } - - //create and start the PO - ProofOblInput po = new BehaviouralSubtypingOpPO(subtype, - supertype, - contractPairs); - return startProver(subtype, po); - } - - - - /** - * Starts the prover with a "StrongOperationContract" proof obligation. - * @param modelMethod the ModelMethod to reason about; the proof - * obligation will be about its *first* operation - * contract - * @return error message to the user - */ - public static String proveStrongOperationContract(ModelMethod modelMethod) { - //get the relevant contract - ListOfOperationContract contracts - = modelMethod.getMyOperationContracts(); - if(contracts.isEmpty()) { - return "No contracts are available for the selected method."; - } - OperationContract contract = contracts.head(); - - //let the user select the set of assumed invariants - ModelClass containingClass = modelMethod.getContainingClass(); - Set modelClasses = containingClass.getAllClasses(); - - ClassInvariantSelectionDialog dlg = new ClassInvariantSelectionDialog( - "Please select the assumed invariants", - modelClasses, - false, - containingClass); - if(!dlg.wasSuccessful()) { - return ""; - } - ListOfClassInvariant assumedInvs = dlg.getClassInvariants(); - if(assumedInvs.isEmpty()) { - return "No assumed invariants have been selected."; - } - - //let the user select the set of ensured invariants - dlg = new ClassInvariantSelectionDialog("Select ensured invariants", - modelClasses, - false, - containingClass); - if(!dlg.wasSuccessful()) { - return ""; - } - ListOfClassInvariant ensuredInvs = dlg.getClassInvariants(); - if(ensuredInvs.isEmpty()) { - return "No ensured invariants have been selected."; - } - - //create and start the PO - ProofOblInput po = new StrongOperationContractPO(contract, - assumedInvs, - ensuredInvs); - return startProver(containingClass, po); - } - - - - /** - * Asks the user to choose a set of invariants and then starts the prover - * with a corresponding "PreservesInv" proof obligation. - * @param modelMethod the ModelMethod to reason about - * @return error message to the user - */ - public static String provePreservesInv(ModelMethod modelMethod) { - ModelClass containingClass = modelMethod.getContainingClass(); - Set modelClasses = modelMethod.getContainingClass().getAllClasses(); - - //let the user select the set of ensured invariants - ClassInvariantSelectionDialog dlg = new ClassInvariantSelectionDialog( - "Please select the ensured invariants", - modelClasses, - false, - containingClass); - if(!dlg.wasSuccessful()) { - return ""; - } - ListOfClassInvariant ensuredInvs = dlg.getClassInvariants(); - if(ensuredInvs.isEmpty()) { - return "No ensured invariants have been selected."; - } - - //create and start the PO - ProofOblInput po = new PreservesInvPO(modelMethod, - invStrategy, - ensuredInvs); - return startProver(containingClass, po); - } - - - /** - * Starts the prover with a "PreservesOwnInv" proof obligation. - * @param modelMethod the ModelMethod to reason about - * @return error message to the user - */ - public static String provePreservesOwnInv(ModelMethod modelMethod) { - if(modelMethod.getContainingClass() - .getMyClassInvariants().isEmpty()) { - return "No own invariants are available."; - } - - ProofOblInput po = new PreservesOwnInvPO(modelMethod, invStrategy); - return startProver(modelMethod.getContainingClass(), po); - } - - - public static String provePreservesThroughout(ModelMethod modelMethod) { - ModelClass containingClass = modelMethod.getContainingClass(); - Set modelClasses = modelMethod.getContainingClass().getAllClasses(); - - //let the user select the set of throughout invariants - ClassInvariantSelectionDialog dlg = new ClassInvariantSelectionDialog( - "Please select the desired throughout invariants", - modelClasses, - true, - containingClass); - if(!dlg.wasSuccessful()) { - return ""; - } - ListOfClassInvariant invariants = dlg.getClassInvariants(); - if(invariants.isEmpty()) { - return "No throughout invariants have been selected."; - } - - //create and start the PO - ProofOblInput po = new PreservesThroughoutPO(modelMethod, - invariants, - invStrategy); - return startProver(containingClass, po); - } - - - /** - * Starts the prover with an "EnsuresPost" proof obligation. - * @param modelMethod the ModelMethod to reason about; the proof obligation - * will be about its *first* OperationContract - * @param modality the desired modality - * @return error message to the user - */ - public static String proveEnsuresPost(ModelMethod modelMethod, - Modality modality) { - //get the relevant contract - ListOfOperationContract contracts - = modelMethod.getMyOperationContracts(); - if(contracts.isEmpty()) { - return "No contracts are available for the selected method."; - } - OperationContract contract = contracts.head(); - - //create and start the PO - ProofOblInput po = new EnsuresPostPO(contract, - modality, - invStrategy); - return startProver(modelMethod.getContainingClass(), po); - } - - - /** - * Starts the prover with a "RespectsModifies" proof obligation. - * @param modelMethod the ModelMethod to reason about; the proof obligation - * will be about its *first* OperationContract - * @return error message to the user - */ - public static String proveRespectsModifies(ModelMethod modelMethod) { - //get the relevant contract - ListOfOperationContract contracts - = modelMethod.getMyOperationContracts(); - if(contracts.isEmpty()) { - return "No contracts are available for the selected method."; - } - OperationContract contract = contracts.head(); - - //create and start the PO - ProofOblInput po = new RespectsModifiesPO(contract, invStrategy); - return startProver(modelMethod.getContainingClass(), po); - } - - - /** - * Starts the prover with an "IsGuard" proof obligation. - * @param modelMethod the ModelMethod to reason about - * @return error message to the user - */ - public static String provePreservesGuard(ModelMethod modelMethod) { - ModelClass containingClass = modelMethod.getContainingClass(); - Set modelClasses = containingClass.getAllClasses(); - - //let the user select the guarded invariants - ClassInvariantSelectionDialog dlg = new ClassInvariantSelectionDialog( - "Please select the guarded invariants", - modelClasses, - false, - containingClass); - if(!dlg.wasSuccessful()) { - return ""; - } - ListOfClassInvariant guardedInvs = dlg.getClassInvariants(); - if(guardedInvs.isEmpty()) { - return "No guarded invariants have been selected."; - } - - //let the user select the guard classes - ListOfModelClass allClasses = SLListOfModelClass.EMPTY_LIST; - Iterator it = modelClasses.iterator(); - while(it.hasNext()) { - allClasses = allClasses.prepend((UMLModelClass) it.next()); - } - ClassSelectionDialog dlg2 - = new ClassSelectionDialog("Please select the guard", - "Available classes", - allClasses, - containingClass, - true); - if(!dlg2.wasSuccessful()) { - return ""; - } - ListOfModelClass guard = dlg2.getSelection(); - if(guard.isEmpty()) { - return "No guard classes have been selected."; - } - - //create the PO - ProofOblInput po = new PreservesGuardPO(modelMethod, - guardedInvs, - guard, - invStrategy); - return startProver(containingClass, po); - } -} diff --git a/system/de/uka/ilkd/key/casetool/ModelClass.java b/system/de/uka/ilkd/key/casetool/ModelClass.java index 6d5799101dc..b0c917cd863 100644 --- a/system/de/uka/ilkd/key/casetool/ModelClass.java +++ b/system/de/uka/ilkd/key/casetool/ModelClass.java @@ -3,8 +3,6 @@ import java.util.Set; import java.util.Vector; -import de.uka.ilkd.key.speclang.ListOfClassInvariant; - public interface ModelClass { @@ -38,15 +36,4 @@ public interface ModelClass { Vector getOps(); public abstract Set getAllClasses(); - - /** - * Returns the invariants of the class. - */ - public abstract ListOfClassInvariant getMyClassInvariants(); - - /** - * Returns the throughout invariants of the class. - */ - public abstract ListOfClassInvariant getMyThroughoutClassInvariants(); - } diff --git a/system/de/uka/ilkd/key/casetool/ModelMethod.java b/system/de/uka/ilkd/key/casetool/ModelMethod.java index d925c787a6c..6fabd2ff031 100644 --- a/system/de/uka/ilkd/key/casetool/ModelMethod.java +++ b/system/de/uka/ilkd/key/casetool/ModelMethod.java @@ -12,10 +12,9 @@ package de.uka.ilkd.key.casetool; -import de.uka.ilkd.key.proof.mgt.Contractable; import de.uka.ilkd.key.speclang.ListOfOperationContract; -public interface ModelMethod extends ReprModel, Contractable { +public interface ModelMethod extends ReprModel { ModelClass getContainingClass(); @@ -75,6 +74,4 @@ public interface ModelMethod extends ReprModel, Contractable { void setMyGFAbs(String abs); boolean hasOrigParent(); - - ListOfOperationContract getMyOperationContracts(); } diff --git a/system/de/uka/ilkd/key/casetool/Multiplicity.java b/system/de/uka/ilkd/key/casetool/Multiplicity.java index f2577eff2f6..1d070ac998a 100644 --- a/system/de/uka/ilkd/key/casetool/Multiplicity.java +++ b/system/de/uka/ilkd/key/casetool/Multiplicity.java @@ -74,9 +74,9 @@ public static Multiplicity getMultiplicityFromString(String s) { boundaries[count]=nr; count++; } - final int min = boundaries[0]; - final int max = count > 1 ? boundaries[1] : boundaries[0]; - return new Multiplicity(min, max); + final int min1 = boundaries[0]; + final int max1 = count > 1 ? boundaries[1] : boundaries[0]; + return new Multiplicity(min1, max1); } } return null; diff --git a/system/de/uka/ilkd/key/casetool/together/FunctionalityOnModel.java b/system/de/uka/ilkd/key/casetool/together/FunctionalityOnModel.java new file mode 100644 index 00000000000..12654dba496 --- /dev/null +++ b/system/de/uka/ilkd/key/casetool/together/FunctionalityOnModel.java @@ -0,0 +1,773 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.casetool.together; + +import java.io.File; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import de.uka.ilkd.key.casetool.ModelClass; +import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.cspec.ComputeSpecificationPO; +import de.uka.ilkd.key.gui.ClassInvariantSelectionDialog; +import de.uka.ilkd.key.gui.ClassSelectionDialog; +import de.uka.ilkd.key.gui.ContractConfigurator; +import de.uka.ilkd.key.gui.Main; +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.abstraction.*; +import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.logic.op.*; +import de.uka.ilkd.key.proof.init.*; +import de.uka.ilkd.key.proof.mgt.SpecificationRepository; +import de.uka.ilkd.key.speclang.ClassInvariant; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; +import de.uka.ilkd.key.speclang.SetOfOperationContract; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; +import de.uka.ilkd.key.util.KeYExceptionHandler; + + +public class FunctionalityOnModel { + + private FunctionalityOnModel() {} + + + + //------------------------------------------------------------------------- + //Internal methods + //------------------------------------------------------------------------- + + /** + * Tells whether the passed model class has a class invariant. + */ + private static boolean hasAnInvariant(ModelClass modelClass) { + return modelClass.getMyInv() != null + && !modelClass.getMyInv().equals(""); + } + + + /** + * Tells whether the passed model class has a throughout invariant. + */ + private static boolean hasAThroughoutInvariant(ModelClass modelClass) { + return modelClass.getMyThroughout() != null + && !modelClass.getMyThroughout().equals(""); + } + + + /** + * Tells whether the passed model method has an operation contract. + */ + private static boolean hasAContract(ModelMethod modelMethod) { + return modelMethod.getMyPreCond() != null + && !modelMethod.getMyPreCond().equals("") + || modelMethod.getMyPostCond() != null + && !modelMethod.getMyPostCond().equals("") + || modelMethod.getMyModifClause() != null + && !modelMethod.getMyModifClause().equals(""); + } + + + /** + * Returns the method overridden by subMethod in the passed supertype, + * or null if no such method exists. + */ + private static ProgramMethod getOverriddenMethod( + ProgramMethod subMethod, + KeYJavaType superKJT, + JavaInfo javaInfo) { + String name = subMethod.getName(); + int numParameters = subMethod.getParameterDeclarationCount(); + + IteratorOfProgramMethod it + = javaInfo.getAllProgramMethods(superKJT).iterator(); + while(it.hasNext()) { + ProgramMethod superMethod = it.next(); + if(name.equals(superMethod.getName()) + && numParameters == superMethod.getParameterDeclarationCount()) { + boolean parametersEqual = true; + for(int i = 0; i < numParameters; i++) { + if(!subMethod.getParameterType(i) + .equals(superMethod.getParameterType(i))) { + parametersEqual = false; + break; + } + } + + if(parametersEqual) { + return superMethod; + } + } + } + + return null; + } + + + /** + * Finds the KJT corresponding to a ModelClass. + */ + private static KeYJavaType getKJT(ModelClass modelClass, + JavaInfo javaInfo) { + assert modelClass != null; + KeYJavaType result + = javaInfo.getTypeByClassName(modelClass.getFullClassName()); + assert result != null : "KJT not found : \"" + + modelClass.getFullClassName() + "\""; + return result; + } + + + /** + * Finds the ProgramMethod corresponding to a ModelMethod. + */ + private static ProgramMethod getProgramMethod(ModelMethod modelMethod, + JavaInfo javaInfo) { + assert modelMethod != null; + KeYJavaType containingClass = getKJT(modelMethod.getContainingClass(), + javaInfo); + + //collect signature KJTs + ListOfKeYJavaType signature = SLListOfKeYJavaType.EMPTY_LIST; + for(int i = 0; i < modelMethod.getNumParameters(); i++) { + String parTypeName = modelMethod.getParameterTypeAt(i); + KeYJavaType kjt = javaInfo.getTypeByClassName(parTypeName); + assert kjt != null : "KJT not found: \"" + parTypeName + "\""; + signature = signature.append(kjt); + } + + //determine name ("" for constructors) + String operationName + = modelMethod.getName().equals(containingClass.getName()) + ? "" + : modelMethod.getName(); + + //ask javaInfo + ProgramMethod result + = javaInfo.getProgramMethod(containingClass, + operationName, + signature, + containingClass); + assert result != null : "ProgramMethod not found: \"" + + operationName + "\"" + + "\nsignature: " + signature + + "\ncontainer: " + containingClass; + return result; + } + + + /** + * Lets the user select a supertype of subKJT in a dialog window. + */ + private static KeYJavaType askUserForSupertype(KeYJavaType subKJT, + JavaInfo javaInfo) { + //collect supertypes + SetOfKeYJavaType superKJTs = SetAsListOfKeYJavaType.EMPTY_SET; + IteratorOfKeYJavaType it = javaInfo.getAllSupertypes(subKJT).iterator(); + while(it.hasNext()) { + superKJTs = superKJTs.add(it.next()); + } + + //ask user + ClassSelectionDialog dlg = new ClassSelectionDialog( + "Please select a supertype", + "Supertypes of " + subKJT.getName(), + superKJTs, + false); + if(!dlg.wasSuccessful()) { + return null; + } + + //return selection + SetOfKeYJavaType selectedKJTs = dlg.getSelection(); + if(selectedKJTs.size() == 0) { + return null; + } else { + return selectedKJTs.iterator().next(); + } + } + + + /** + * Reads a TogetherEnvInput, i.e. the Java model, standard rules, + * and OCL specifications. + */ + private static InitConfig prepare(ModelClass anyModelClass) + throws ProofInputException { + ProblemInitializer pi = new ProblemInitializer(Main.getInstance()); + EnvInput envInput + = new TogetherEnvInput((TogetherModelClass) anyModelClass); + return pi.prepare(envInput); + } + + + /** + * Same as prepare(), except: + * (1) no specifications are translated, and + * (2) the prover window is not shown + * (though probably we *should* give the user *some* feedback, because + * at least on the first time, when the standard rules have to be loaded, + * this takes rather long). + */ + private static InitConfig prepareSilent(ModelClass anyModelClass) + throws ProofInputException { + Profile profile = Main.getInstance(false).mediator().getProfile(); + ProblemInitializer pi = new ProblemInitializer(profile); + EnvInput envInput + = new TogetherEnvInput((TogetherModelClass) anyModelClass, + false); + return pi.prepare(envInput); + } + + + /** + * Starts the prover with the given PO. + */ + private static void startProver(InitConfig initConfig, ProofOblInput po) + throws ProofInputException { + ProblemInitializer pi = new ProblemInitializer(Main.getInstance()); + pi.startProver(initConfig, po); + } + + + + //------------------------------------------------------------------------- + //Class menu + //------------------------------------------------------------------------- + + /** + * Checks a class invariant for syntactic correctness. + */ + public static void parseClassSpec(TogetherModelClass modelClass) + throws ProofInputException { + assert false; //TODO + } + + + /** + * Starts OCL Simplification. + */ + public static void simplifyInvariant(TogetherModelClass modelClass) + throws ProofInputException { + ProofOblInput po = new OCLInvSimplPO(modelClass); + startProver(prepare(modelClass), po); + } + + + /** + * Starts the prover with a proof obligation specified in a .key file. + */ + public static void proveDLFormula(TogetherModelClass modelClass, + File file) + throws ProofInputException { + CasetoolDLPO dlPOFromCasetool = new CasetoolDLPO(modelClass, file); + startProver(prepare(modelClass), dlPOFromCasetool); + } + + + /** + * Asks the user to choose a supertype and then starts the prover with a + * corresponding "BehaviouralSubtypingInv" proof obligation. + * @param subtype the UMLModelClass with subtype for which behavioural + * subtyping with respect to the invariant has to be shown + * @return error message to the user + */ + public static void proveBehaviouralSubtypingInv(TogetherModelClass subType) + throws ProofInputException { + //no invariant in subtype? + if(!hasAnInvariant(subType)) { + throw new ProofInputException("The selected subtype does not have " + + "an invariant."); + } + + //prepare + InitConfig initConfig = prepare(subType); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + + //let the user select a supertype + KeYJavaType subKJT = getKJT(subType, javaInfo); + KeYJavaType superKJT = askUserForSupertype(subKJT, javaInfo); + if(superKJT == null) { + return; + } + + //create and start the PO + ProofOblInput po = new BehaviouralSubtypingInvPO(initConfig, + subKJT, + superKJT); + startProver(initConfig, po); + } + + + /** + * Starts the prover with a "BehaviouralSubtypingOp" proof obligation. + * @param subtype the {@link UMLModelClass} with the subtype for whose method + * behavioural subtyping has to be proven + + */ + public static void proveBehaviouralSubtypingOp(TogetherModelClass subType) + throws ProofInputException { + //prepare + InitConfig initConfig = prepare(subType); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + SpecificationRepository specRepos + = initConfig.getServices().getSpecificationRepository(); + + //let the user select a supertype + KeYJavaType subKJT = getKJT(subType, javaInfo); + KeYJavaType superKJT = askUserForSupertype(subKJT, javaInfo); + if(superKJT == null) { + return; + } + + //get all pairs of overriding and overridden operation contracts + //(only works correctly if there cannot be more than one contract per + // operation, as it is currently the case in Together) + Map contractPairs = new HashMap(); + IteratorOfProgramMethod subIt + = javaInfo.getAllProgramMethods(subKJT).iterator(); + while(subIt.hasNext()) { + ProgramMethod subPM = subIt.next(); + ProgramMethod superPM = getOverriddenMethod(subPM, + superKJT, + javaInfo); + + if(superPM != null) { + SetOfOperationContract subContracts + = specRepos.getOperationContracts(subPM, + Modality.BOX); + SetOfOperationContract superContracts + = specRepos.getOperationContracts(superPM, + Modality.BOX); + if(subContracts.size() > 0 && superContracts.size() > 0) { + contractPairs.put(subContracts.iterator().next(), + superContracts.iterator().next()); + } + } + } + if(contractPairs.isEmpty()) { + throw new ProofInputException("No overridden contracts could be " + + "found in the selected supertype."); + } + + //create and start the PO + ProofOblInput po = new BehaviouralSubtypingOpPO(initConfig, + subKJT, + superKJT, + contractPairs); + startProver(initConfig, po); + } + + + + //------------------------------------------------------------------------- + //Operation menu + //------------------------------------------------------------------------- + + /** + * Checks an operation contract for syntactic correctness. + * @param modelMethod the ModelMethod to reason about + */ + public static void parseMethodSpec(TogetherModelMethod modelMethod) + throws ProofInputException { + assert false; //TODO + } + + + /** + * Computes and displays the specification of the method. + * Tries to compute the strongest specification (pre and postcondition) + * of aMethRepr. + * @param modelMethod the method whose specification to compute. + */ + public static void computeSpecification(ModelMethod modelMethod) + throws ProofInputException { + //prepare + InitConfig initConfig = prepare(modelMethod.getContainingClass()); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + + //get program method + ProgramMethod pm = getProgramMethod(modelMethod, javaInfo); + + //create and start the PO + ProofOblInput po = new ComputeSpecificationPO(initConfig, pm); + startProver(prepare(modelMethod.getContainingClass()), po); + } + + + /** + * Starts the prover with a "BehaviouralSubtypingOpPair" proof obligation. + * @param subMethod the overwriting method to reason about + */ + public static void proveBehaviouralSubtypingOpPair( + TogetherModelMethod subMethod) + throws ProofInputException { + //no contract for subMethod? + if(!hasAContract(subMethod)) { + throw new ProofInputException("The selected operation " + + "does not have a contract."); + } + + //prepare + InitConfig initConfig = prepare(subMethod.getContainingClass()); + SpecificationRepository specRepos + = initConfig.getServices().getSpecificationRepository(); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + + //let the user select a supertype + KeYJavaType subKJT = getKJT(subMethod.getContainingClass(), javaInfo); + KeYJavaType superKJT = askUserForSupertype(subKJT, javaInfo); + if(superKJT == null) { + return; + } + + //determine the method in the chosen supertype which is overriden + //by the sub type method + ProgramMethod subPM = getProgramMethod(subMethod, javaInfo); + ProgramMethod superPM = getOverriddenMethod(subPM, superKJT, javaInfo); + if(superPM == null) { + throw new ProofInputException( + "No overridden method \"" + subMethod.getName() + + "\" could be found in the selected supertype."); + } + + //get contracts + SetOfOperationContract subContracts + = specRepos.getOperationContracts(subPM, Modality.BOX); + assert subContracts.size() > 0; + SetOfOperationContract superContracts + = specRepos.getOperationContracts(superPM, Modality.BOX); + if(superContracts.size() == 0) { + throw new ProofInputException("The overridden method " + + " does not have a contract."); + } + OperationContract subContract = subContracts.iterator().next(); + OperationContract superContract = superContracts.iterator().next(); + + //create and start the PO + ProofOblInput po = new BehaviouralSubtypingOpPairPO(initConfig, + subContract, + superContract); + startProver(initConfig, po); + } + + + /** + * Starts the prover with a "StrongOperationContract" proof obligation. + * @param modelMethod the ModelMethod to reason about + */ + public static void proveStrongOperationContract( + TogetherModelMethod modelMethod) + throws ProofInputException { + TogetherModelClass containingClass + = (TogetherModelClass) modelMethod.getContainingClass(); + + //no contract? + if(!hasAContract(modelMethod)) { + throw new ProofInputException("The selected operation " + + " does not have a contract."); + } + + //prepare + InitConfig initConfig = prepare(containingClass); + SpecificationRepository specRepos + = initConfig.getServices().getSpecificationRepository(); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + + //let the user select the set of assumed invariants + KeYJavaType kjt = getKJT(containingClass, javaInfo); + ProgramMethod pm = getProgramMethod(modelMethod, javaInfo); + ClassInvariantSelectionDialog dlg = new ClassInvariantSelectionDialog( + "Please select the assumed invariants", + initConfig.getServices(), + false, + kjt); + if(!dlg.wasSuccessful()) { + return; + } + SetOfClassInvariant assumedInvs = dlg.getSelection(); + if(assumedInvs.size() == 0) { + throw new ProofInputException("No assumed invariants " + + "have been selected."); + } + + //let the user select the set of ensured invariants + dlg = new ClassInvariantSelectionDialog( + "Please select the ensured invariants", + initConfig.getServices(), + false, + kjt); + if(!dlg.wasSuccessful()) { + return; + } + SetOfClassInvariant ensuredInvs = dlg.getSelection(); + if(ensuredInvs.size() == 0) { + throw new ProofInputException("No ensured invariants " + + " have been selected."); + } + + //get contract + SetOfOperationContract contracts + = specRepos.getOperationContracts(pm, Modality.BOX); + assert contracts.size() > 0; + OperationContract contract = contracts.iterator().next(); + + //create and start the PO + ProofOblInput po = new StrongOperationContractPO(initConfig, + contract, + assumedInvs, + ensuredInvs); + startProver(initConfig, po); + } + + + /** + * Asks the user to choose a set of invariants and then starts the prover + * with a corresponding "PreservesInv" proof obligation. + * @param modelMethod the ModelMethod to reason about + */ + public static void provePreservesInv(TogetherModelMethod modelMethod) + throws ProofInputException { + TogetherModelClass containingClass + = (TogetherModelClass) modelMethod.getContainingClass(); + + //prepare + InitConfig initConfig = prepare(containingClass); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + + //let the user select the set of ensured invariants + KeYJavaType kjt = getKJT(containingClass, javaInfo); + ProgramMethod pm = getProgramMethod(modelMethod, javaInfo); + ContractConfigurator cc + = new ContractConfigurator(Main.getInstance(), + initConfig.getServices(), + pm, + null, + false, + true, + true); + if(!cc.wasSuccessful()) { + return; + } + if(cc.getEnsuredInvs().size() == 0) { + throw new ProofInputException("No ensured invariants " + + "have been selected."); + } + + //create and start the PO + ProofOblInput po = new PreservesInvPO(initConfig, + pm, + cc.getAssumedInvs(), + cc.getEnsuredInvs()); + startProver(initConfig, po); + } + + + /** + * Starts the prover with a "PreservesOwnInv" proof obligation. + * @param modelMethod the ModelMethod to reason about + */ + public static void provePreservesOwnInv(TogetherModelMethod modelMethod) + throws ProofInputException { + TogetherModelClass containingClass + = (TogetherModelClass) modelMethod.getContainingClass(); + + //no invariant? + if(!hasAnInvariant(containingClass)) { + throw new ProofInputException("No own invariants are available."); + } + + //prepare + InitConfig initConfig = prepare(containingClass); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + + //create and start the PO + ProgramMethod pm = getProgramMethod(modelMethod, javaInfo); + ProofOblInput po = new PreservesOwnInvPO(initConfig, pm); + startProver(initConfig, po); + } + + + /** + * Starts the prover with a "PreservesThroughout" proof obligation. + * @param modelMethod the ModelMethod to reason about + */ + public static void provePreservesThroughout(TogetherModelMethod modelMethod) + throws ProofInputException { + TogetherModelClass containingClass + = (TogetherModelClass) modelMethod.getContainingClass(); + + //prepare + InitConfig initConfig = prepare(containingClass); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + + //let the user select the set of throughout invariants + KeYJavaType kjt = getKJT(containingClass, javaInfo); + ProgramMethod pm = getProgramMethod(modelMethod, javaInfo); + ClassInvariantSelectionDialog dlg = new ClassInvariantSelectionDialog( + "Please select the desired throughout invariants", + initConfig.getServices(), + true, + kjt); + if(!dlg.wasSuccessful()) { + return; + } + SetOfClassInvariant invariants = dlg.getSelection(); + if(invariants.size() == 0) { + throw new ProofInputException("No throughout invariants " + + "have been selected."); + } + + //create and start the PO + ProofOblInput po = new PreservesThroughoutPO(initConfig, + pm, + invariants); + startProver(initConfig, po); + } + + + /** + * Starts the prover with an "EnsuresPost" proof obligation. + * @param modelMethod the ModelMethod to reason about + */ + public static void proveEnsuresPost(TogetherModelMethod modelMethod) + throws ProofInputException { + //no contract? + if(!hasAContract(modelMethod)) { + throw new ProofInputException("The selected operation " + + "does not have a contract."); + } + + //prepare + InitConfig initConfig = prepare(modelMethod.getContainingClass()); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + + //let the user select the contract and the assumed invariants + ProgramMethod pm = getProgramMethod(modelMethod, javaInfo); + ContractConfigurator cc + = new ContractConfigurator(Main.getInstance(), + initConfig.getServices(), + pm, + null, + true, + true, + false); + if(!cc.wasSuccessful()) { + return; + } + + //create and start the PO + ProofOblInput po = new EnsuresPostPO(initConfig, + cc.getContract(), + cc.getAssumedInvs()); + startProver(initConfig, po); + } + + + /** + * Starts the prover with a "RespectsModifies" proof obligation. + * @param modelMethod the ModelMethod to reason about; the proof obligation + * will be about a random one of its OperationContracts + */ + public static void proveRespectsModifies(TogetherModelMethod modelMethod) + throws ProofInputException { + //no contract? + if(!hasAContract(modelMethod)) { + throw new ProofInputException("The selected operation " + + "does not have a contract."); + } + + //prepare + InitConfig initConfig = prepare(modelMethod.getContainingClass()); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + SpecificationRepository specRepos + = initConfig.getServices().getSpecificationRepository(); + + //let the user select the contract and the assumed invariants + ProgramMethod pm = getProgramMethod(modelMethod, javaInfo); + ContractConfigurator cc + = new ContractConfigurator(Main.getInstance(), + initConfig.getServices(), + pm, + null, + true, + true, + false); + if(!cc.wasSuccessful()) { + return; + } + + //create and start the PO + ProofOblInput po = new RespectsModifiesPO(initConfig, + cc.getContract(), + cc.getAssumedInvs()); + startProver(initConfig, po); + } + + + /** + * Starts the prover with an "IsGuard" proof obligation. + * @param modelMethod the ModelMethod to reason about + */ + public static void provePreservesGuard(TogetherModelMethod modelMethod) + throws ProofInputException { + //prepare + InitConfig initConfig = prepare(modelMethod.getContainingClass()); + JavaInfo javaInfo = initConfig.getServices().getJavaInfo(); + + + //let the user select the guarded invariants + KeYJavaType kjt = getKJT(modelMethod.getContainingClass(), javaInfo); + ProgramMethod pm = getProgramMethod(modelMethod, javaInfo); + ClassInvariantSelectionDialog dlg = new ClassInvariantSelectionDialog( + "Please select the guarded invariants", + initConfig.getServices(), + false, + kjt); + if(!dlg.wasSuccessful()) { + return; + } + SetOfClassInvariant guardedInvs = dlg.getSelection(); + if(guardedInvs.size() == 0) { + throw new ProofInputException("No guarded invariants " + + "have been selected."); + } + + //let the user select the guard classes + SetOfKeYJavaType allKJTs = SetAsListOfKeYJavaType.EMPTY_SET; + Iterator it = javaInfo.getAllKeYJavaTypes().iterator(); + while(it.hasNext()) { + allKJTs = allKJTs.add((KeYJavaType)it.next()); + } + ClassSelectionDialog dlg2 + = new ClassSelectionDialog("Please select the guard", + "Available classes", + allKJTs, + kjt, + true); + if(!dlg2.wasSuccessful()) { + return; + } + SetOfKeYJavaType guard = dlg2.getSelection(); + if(guard.size() == 0) { + throw new ProofInputException("No guard classes " + + "have been selected."); + } + + //create and start the PO + ProofOblInput po = new PreservesGuardPO(initConfig, + pm, + guardedInvs, + guard); + startProver(initConfig, po); + } +} diff --git a/system/de/uka/ilkd/key/casetool/together/TogetherEnvInput.java b/system/de/uka/ilkd/key/casetool/together/TogetherEnvInput.java index eec03208f5b..6bf70605fc9 100644 --- a/system/de/uka/ilkd/key/casetool/together/TogetherEnvInput.java +++ b/system/de/uka/ilkd/key/casetool/together/TogetherEnvInput.java @@ -9,43 +9,168 @@ // package de.uka.ilkd.key.casetool.together; +import java.util.Iterator; +import java.util.Vector; + +import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.proof.init.DefaultEnvInput; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; +import de.uka.ilkd.key.java.abstraction.SLListOfKeYJavaType; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.proof.init.AbstractEnvInput; import de.uka.ilkd.key.proof.init.ModStrategy; import de.uka.ilkd.key.proof.init.ProofInputException; +import de.uka.ilkd.key.proof.mgt.SpecificationRepository; +import de.uka.ilkd.key.speclang.ClassInvariant; +import de.uka.ilkd.key.speclang.SetOfOperationContract; +import de.uka.ilkd.key.speclang.ocl.translation.OCLSpecFactory; /** * EnvInput for Together. */ -public class TogetherEnvInput extends DefaultEnvInput { +public class TogetherEnvInput extends AbstractEnvInput { - private final TogetherModelClass modelClass; + private final TogetherModelClass anyTogetherModelClass; + private final boolean createSpecs; //------------------------------------------------------------------------- //constructors //------------------------------------------------------------------------- - public TogetherEnvInput(TogetherModelClass modelClass) { - super("Together input", modelClass.getRootDirectory()); - this.modelClass = modelClass; + public TogetherEnvInput(TogetherModelClass anyTogetherModelClass, + boolean createSpecs) { + super("Together input", anyTogetherModelClass.getRootDirectory()); + this.anyTogetherModelClass = anyTogetherModelClass; + this.createSpecs = createSpecs; } + - + public TogetherEnvInput(TogetherModelClass anyTogetherModelClass) { + this(anyTogetherModelClass, true); + } + + //------------------------------------------------------------------------- - //public interface - //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private KeYJavaType getKJT(TogetherModelClass modelClass, + JavaInfo javaInfo) { + assert modelClass != null; + + KeYJavaType result + = javaInfo.getTypeByClassName(modelClass.getFullClassName()); + assert result != null : "KJT not found : \"" + + modelClass.getFullClassName() + "\""; + return result; + } + + + private ProgramMethod getProgramMethod(TogetherModelMethod modelMethod, + KeYJavaType containingClass, + JavaInfo javaInfo) { + assert modelMethod != null; + + //collect signature KJTs + ListOfKeYJavaType signature = SLListOfKeYJavaType.EMPTY_LIST; + for(int i = 0; i < modelMethod.getNumParameters(); i++) { + String parTypeName = modelMethod.getParameterTypeAt(i); + KeYJavaType kjt = javaInfo.getTypeByClassName(parTypeName); + assert kjt != null : "KJT not found: \"" + parTypeName + "\""; + signature = signature.append(kjt); + } + + //determine name ("" for constructors) + String operationName + = modelMethod.getName().equals(containingClass.getName()) + ? "" + : modelMethod.getName(); + //ask javaInfo + ProgramMethod result + = javaInfo.getProgramMethod(containingClass, + operationName, + signature, + containingClass); + assert result != null : "ProgramMethod not found: \"" + + operationName + "\"" + + "\nsignature: " + signature + + "\ncontainer: " + containingClass; + return result; + } + + + private void createSpecs() + throws ProofInputException { + Services services = initConfig.getServices(); + JavaInfo javaInfo + = services.getJavaInfo(); + SpecificationRepository specRepos + = services.getSpecificationRepository(); + OCLSpecFactory osf = new OCLSpecFactory(services); + + Iterator it = anyTogetherModelClass.getAllClasses().iterator(); + while(it.hasNext()) { + TogetherModelClass mc = (TogetherModelClass) it.next(); + KeYJavaType kjt = getKJT(mc, javaInfo); + + //class invariants + String invString = mc.getMyInv(); + if(invString != null && !invString.equals("")) { + ClassInvariant inv = osf.createOCLClassInvariant(kjt, + invString); + specRepos.addClassInvariant(inv); + } + + //operation contracts + Vector ops = mc.getOps(); + Iterator it2 = ops.iterator(); + while(it2.hasNext()) { + TogetherModelMethod mm = (TogetherModelMethod) it2.next(); + ProgramMethod programMethod = getProgramMethod(mm, + kjt, + javaInfo); + + String preString = mm.getMyPreCond(); + String postString = mm.getMyPostCond(); + String modifiesString = mm.getMyModifClause(); + if(preString != null && !preString.equals("") + || postString != null && !postString.equals("") + || modifiesString != null && !modifiesString.equals("")) { + SetOfOperationContract contracts + = osf.createOCLOperationContracts(programMethod, + preString, + postString, + modifiesString); + specRepos.addOperationContracts(contracts); + } + } + } + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + public void read(ModStrategy mod) throws ProofInputException { if(initConfig == null) { throw new IllegalStateException("InitConfig not set."); } + //create OCL specifications + if(createSpecs) { + createSpecs(); + } + //create UML info Services services = initConfig.getServices(); - services.setUMLInfo(modelClass.createUMLInfo(services)); + services.setUMLInfo(anyTogetherModelClass.createUMLInfo(services)); } } diff --git a/system/de/uka/ilkd/key/casetool/together/TogetherModelClass.java b/system/de/uka/ilkd/key/casetool/together/TogetherModelClass.java index 510d0c7f630..67b221520f4 100644 --- a/system/de/uka/ilkd/key/casetool/together/TogetherModelClass.java +++ b/system/de/uka/ilkd/key/casetool/together/TogetherModelClass.java @@ -26,8 +26,6 @@ import de.uka.ilkd.key.collection.ListOfString; import de.uka.ilkd.key.collection.SLListOfString; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.speclang.*; -import de.uka.ilkd.key.speclang.ocl.OCLClassInvariant; import de.uka.ilkd.key.util.Debug; /** @@ -204,8 +202,8 @@ public void setMyInv(String inv) { this.inv = inv; orig.setProperty("invariants", inv); } - + /** relies on a valid backing RWI model element, i.e. the together * project is still valid (opened) * @author Kristofer Johannisson @@ -434,7 +432,7 @@ private HashSet getAllJavaFiles(RwiPackage pac, HashSet v) { * project is still valid (opened) */ public String[] getClassesInPackage() { - HashSet v = new HashSet(); + HashSet v = new LinkedHashSet(); RwiPackage rootPac=orig.getContainingPackage(); while (rootPac.getContainingPackage()!=null) { rootPac=rootPac.getContainingPackage(); @@ -477,7 +475,7 @@ public Set getAllClasses() { && rootPackage.getContainingPackage().nodes().hasMoreElements()){ rootPackage=rootPackage.getContainingPackage(); } - Set result = new HashSet(); + Set result = new LinkedHashSet(); rwiRecurse(rootPackage.nodes(), result); return result; } @@ -504,32 +502,7 @@ private void rwiRecurse(Enumeration nodeEnum, Set result) { } } - - public ListOfClassInvariant getMyClassInvariants() { - ListOfClassInvariant result = SLListOfClassInvariant.EMPTY_LIST; - - String myInv = getMyInv(); - if(!myInv.equals("")) { - ClassInvariant invariant = new OCLClassInvariant(this, myInv); - result = result.append(invariant); - } - - return result; - } - - - public ListOfClassInvariant getMyThroughoutClassInvariants() { - ListOfClassInvariant result = SLListOfClassInvariant.EMPTY_LIST; - - String myThroughout = getMyThroughout(); - if(!myThroughout.equals("")) { - ClassInvariant invariant = new OCLClassInvariant(this, myThroughout); - result = result.append(invariant); - } - return result; - } - public String toString() { return getClassName(); diff --git a/system/de/uka/ilkd/key/casetool/together/TogetherModelMethod.java b/system/de/uka/ilkd/key/casetool/together/TogetherModelMethod.java index f492f301f6d..4f114456c9b 100644 --- a/system/de/uka/ilkd/key/casetool/together/TogetherModelMethod.java +++ b/system/de/uka/ilkd/key/casetool/together/TogetherModelMethod.java @@ -19,11 +19,6 @@ import de.uka.ilkd.key.casetool.ModelClass; import de.uka.ilkd.key.casetool.ModelMethod; import de.uka.ilkd.key.casetool.UMLModelClass; -import de.uka.ilkd.key.logic.op.Op; -import de.uka.ilkd.key.proof.mgt.Contractable; -import de.uka.ilkd.key.proof.mgt.JavaModelMethod; -import de.uka.ilkd.key.speclang.*; -import de.uka.ilkd.key.speclang.ocl.OCLOperationContract; /** represents a method of the Together model. It is backed by the * corresponding Together RWI model element, but it is independent in @@ -386,7 +381,23 @@ private String shuffleForParser(String argString, } public static String transformTypeJava2OCL(String aJavaType){ - return JavaModelMethod.transformTypeJava2OCL(aJavaType); + if ("int".equals(aJavaType) || + "byte".equals(aJavaType) || + "char".equals(aJavaType) || + "short".equals(aJavaType) || + "long".equals(aJavaType)){ + return "Integer"; + } + else if ("boolean".equals(aJavaType)) {return "Boolean";} + else if (aJavaType.endsWith("[]")) { + String base = transformTypeJava2OCL(aJavaType.substring + (0,aJavaType.length()-2)); + return "KeYArrayOf"+base; + + } + else { + return aJavaType; + } } @@ -583,34 +594,5 @@ public boolean equals(Object cmp) { public int hashCode() { return hash==0 ? (hash=toString().hashCode()) : hash; - } - - public ListOfOperationContract getMyOperationContracts() { - ListOfOperationContract result = SLListOfOperationContract.EMPTY_LIST; - - String myPre = getMyPreCond(); - String myPost = getMyPostCond(); - String myModifies = getMyModifClause(); - if(!myPre.equals("") || !myPost.equals("") || !myModifies.equals("")) { - OperationContract contract = new OCLOperationContract(this, - true, - myPre, - myPost, - myModifies); - result = result.append(contract); - } else { - OperationContract defaultContract = new OCLOperationContract(this, - true, - "true", - "true", - ""); - result = result.append(defaultContract); - } - - return result; - } - - public boolean equalContractable(Contractable c) { - return equals(c); - } + } } diff --git a/system/de/uka/ilkd/key/casetool/together/TogetherOCLSimplInterface.java b/system/de/uka/ilkd/key/casetool/together/TogetherOCLSimplInterface.java index 9ee57f14ec1..1b99d59aaa2 100644 --- a/system/de/uka/ilkd/key/casetool/together/TogetherOCLSimplInterface.java +++ b/system/de/uka/ilkd/key/casetool/together/TogetherOCLSimplInterface.java @@ -20,7 +20,6 @@ import com.togethersoft.openapi.ide.IdeAccess; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; import de.uka.ilkd.key.casetool.HashMapOfClassifier; import de.uka.ilkd.key.casetool.UMLOCLClassifier; import de.uka.ilkd.key.gui.Main; @@ -38,6 +37,7 @@ import de.uka.ilkd.key.pp.ProgramPrinter; import de.uka.ilkd.key.proof.Node; import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.init.ProofInputException; import de.uka.ilkd.key.util.pp.StringBackend; /** @@ -129,7 +129,10 @@ private void createModelInfoFile() { */ private void simplifyInvariant(TogetherModelClass togetherClass, LinkedList newClasses) { - String res = FunctionalityOnModel.simplifyInvariant(togetherClass); + try { + FunctionalityOnModel.simplifyInvariant(togetherClass); + } catch(ProofInputException e) { + } main = Main.getInstance(); //Do not continue until the prover exits (different threads). diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenu.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenu.java index aeeec074f13..5be3acc3539 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenu.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenu.java @@ -20,7 +20,6 @@ import com.togethersoft.openapi.ide.window.IdeWindowManager; import com.togethersoft.openapi.rwi.*; -import de.uka.ilkd.key.casetool.UMLModelClass; import de.uka.ilkd.key.casetool.together.TogetherModelClass; import javax.swing.ProgressMonitor; @@ -45,13 +44,19 @@ public void run(IdeWindowManager winMan, IdeContext context, TogetherModelClass modelClass = new TogetherModelClass(selectedNode, rwiModel, rwiDiagram); - String result = runCore(modelClass); - + String result = ""; + try { + result = runCore(modelClass); + } catch(Exception e) { + e.printStackTrace(System.out); + result = e.toString(); + } if (!result.equals("")){ if (pm!=null) pm.close(); winMan.showMessageDialog("Result", IdeDialogType.INFORMATION, result); } } - protected abstract String runCore(UMLModelClass aReprModelClass); + protected abstract String runCore(TogetherModelClass aReprModelClass) + throws Exception; } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint1.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint1.java index 61f7dc3efa0..0f7605c4544 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint1.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint1.java @@ -12,15 +12,18 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.UMLModelClass; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelClass; +import de.uka.ilkd.key.proof.init.ProofInputException; public class ClassMenuPoint1 extends ClassMenu { public String getMenuEntry(){ - return "Parse Invariant"; + return "Parse Class Spec"; } - protected String runCore(UMLModelClass modelClass){ - return FunctionalityOnModel.parseOneInvariant(modelClass); + protected String runCore(TogetherModelClass modelClass) + throws ProofInputException { + FunctionalityOnModel.parseClassSpec(modelClass); + return "No errors were found."; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint2.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint2.java index 964cec22cf1..8359429fd60 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint2.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint2.java @@ -12,15 +12,64 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.UMLModelClass; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; + +import com.togethersoft.openapi.ide.project.IdeProjectManagerAccess; + +import de.uka.ilkd.key.casetool.together.TogetherModelClass; +import de.uka.ilkd.key.ocl.OCLExport; public class ClassMenuPoint2 extends ClassMenu { + + static File lastDirectory=null; + + private File directory; + public String getMenuEntry(){ - return "Parse Throughout"; + return "Export OCL spec of class"; } - protected String runCore(UMLModelClass modelClass){ - return FunctionalityOnModel.parseOneThroughout(modelClass); + protected String runCore(TogetherModelClass modelClass) { + + if (lastDirectory==null) { + String tprFile = IdeProjectManagerAccess + .getProjectManager().getActiveProject().getFileName(); + String projectRoot = tprFile.substring + (0, tprFile.lastIndexOf(File.separator)); + directory=new File(projectRoot); + } + else + directory=lastDirectory; + JFileChooser jFC = new JFileChooser(directory); + int saved = jFC.showSaveDialog(new JFrame()); + if (saved == JFileChooser.APPROVE_OPTION) { + String filename = jFC.getSelectedFile().getName(); + filename = jFC.getCurrentDirectory()+File.separator+ + (filename.endsWith(".ocl") ? filename : + filename+".ocl"); + + try{ + File file = new File(filename); + FileWriter output = new FileWriter(file); + OCLExport oclExporter = + new OCLExport(modelClass, output); + oclExporter.export(); + output.close(); + lastDirectory = jFC.getCurrentDirectory(); + } catch (IOException ioe) { + String errorMsg = "Could not save \n"+filename+".\n"; + errorMsg += ioe.toString(); + JOptionPane.showMessageDialog(new JFrame(), errorMsg, "Oops...", + JOptionPane.ERROR_MESSAGE); + } + + } + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint3.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint3.java old mode 100644 new mode 100755 index 43058022c6f..33ce998fb43 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint3.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint3.java @@ -13,17 +13,15 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; import java.io.File; -import java.io.FileWriter; -import java.io.IOException; import javax.swing.JFileChooser; import javax.swing.JFrame; -import javax.swing.JOptionPane; import com.togethersoft.openapi.ide.project.IdeProjectManagerAccess; -import de.uka.ilkd.key.casetool.UMLModelClass; -import de.uka.ilkd.key.ocl.OCLExport; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelClass; +import de.uka.ilkd.key.proof.init.ProofInputException; public class ClassMenuPoint3 extends ClassMenu { @@ -31,12 +29,14 @@ public class ClassMenuPoint3 extends ClassMenu { private File directory; + public String getMenuEntry(){ - return "Export OCL spec of class"; + return "DL Proof Obligation"; } - protected String runCore(UMLModelClass modelClass){ - + protected String runCore(TogetherModelClass modelClass) + throws ProofInputException { + if (lastDirectory==null) { String tprFile = IdeProjectManagerAccess .getProjectManager().getActiveProject().getFileName(); @@ -44,33 +44,21 @@ protected String runCore(UMLModelClass modelClass){ (0, tprFile.lastIndexOf(File.separator)); directory=new File(projectRoot); } - else + else { directory=lastDirectory; + } JFileChooser jFC = new JFileChooser(directory); - int saved = jFC.showSaveDialog(new JFrame()); - if (saved == JFileChooser.APPROVE_OPTION) { - String filename = jFC.getSelectedFile().getName(); - filename = jFC.getCurrentDirectory()+File.separator+ - (filename.endsWith(".ocl") ? filename : - filename+".ocl"); - - try{ - File file = new File(filename); - FileWriter output = new FileWriter(file); - OCLExport oclExporter = - new OCLExport(modelClass, output); - oclExporter.export(); - output.close(); - lastDirectory = jFC.getCurrentDirectory(); - } catch (IOException ioe) { - String errorMsg = "Could not save \n"+filename+".\n"; - errorMsg += ioe.toString(); - JOptionPane.showMessageDialog(new JFrame(), errorMsg, "Oops...", - JOptionPane.ERROR_MESSAGE); - } - - } - - return ""; + File sugg=new File(jFC.getCurrentDirectory()+File.separator+"DL_PO.key"); + if (sugg.exists()) { + jFC.setSelectedFile(sugg); + } + jFC.setDialogTitle("Load a .key file with the current model"); + int load = jFC.showOpenDialog(new JFrame()); + if (load == JFileChooser.APPROVE_OPTION) { + File file = jFC.getSelectedFile(); + FunctionalityOnModel.proveDLFormula(modelClass, file); + } + return ""; } } + diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint4.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint4.java index 0c357198293..c2f55f7a005 100755 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint4.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint4.java @@ -8,55 +8,50 @@ // // -/* Generated by Together */ -package de.uka.ilkd.key.casetool.together.scripts.menuextension; +/** @author Kristofer Johannisson */ -import java.io.File; -import javax.swing.JFileChooser; -import javax.swing.JFrame; +package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import com.togethersoft.openapi.ide.project.IdeProjectManagerAccess; +import javax.swing.ProgressMonitor; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.UMLModelClass; +import org.apache.log4j.Logger; -public class ClassMenuPoint4 extends ClassMenu { - - static File lastDirectory=null; - - private File directory; +import de.uka.ilkd.key.casetool.together.TogetherGFInterface; +import de.uka.ilkd.key.casetool.together.TogetherModelClass; +import de.uka.ilkd.key.ocl.gf.CallbackClassInv; +import de.uka.ilkd.key.ocl.gf.Utils; +public class ClassMenuPoint4 extends ClassMenu { + protected static Logger timelogger = Logger.getLogger("de.uka.ilkd.key.ocl.gf.Timer"); + protected static Logger logger = Logger.getLogger("key.ocl.gf"); public String getMenuEntry(){ - return "DL Proof Obligation"; + return "Edit Invariant [GF]"; } - protected String runCore(UMLModelClass modelClass){ - - if (lastDirectory==null) { - String tprFile = IdeProjectManagerAccess - .getProjectManager().getActiveProject().getFileName(); - String projectRoot = tprFile.substring - (0, tprFile.lastIndexOf(File.separator)); - directory=new File(projectRoot); - } - else { - directory=lastDirectory; + protected String runCore(TogetherModelClass modelClass) { + if (timelogger.isDebugEnabled()) { + timelogger.debug(System.currentTimeMillis() + " ObMenuPoint6 runCore"); } - JFileChooser jFC = new JFileChooser(directory); - File sugg=new File(jFC.getCurrentDirectory()+File.separator+"DL_PO.key"); - if (sugg.exists()) { - jFC.setSelectedFile(sugg); + if (logger.isDebugEnabled()) { + logger.debug("Class: " + modelClass.getFullClassName()); } - jFC.setDialogTitle("Load a .key file with the current model"); - int load = jFC.showOpenDialog(new JFrame()); - if (load == JFileChooser.APPROVE_OPTION) { - File file = jFC.getSelectedFile(); - return FunctionalityOnModel.proveDLFormula(modelClass, file); - } - return ""; + pm = new ProgressMonitor(null, "Loading the GF editor for OCL", + "", 0, 9700); + Utils.tickProgress(pm, 1, "Initializing TogetherGFInterface"); + + CallbackClassInv cci = new CallbackClassInv(modelClass); + String name = modelClass.getClassName(); + String pack = modelClass.getContainingPackage(); + String inv = modelClass.getMyInv(); + String abs = modelClass.getMyInvGFAbs(); + + // aReprModelClass.setMyInvGFAbs("just testing..."); + + // return (new GFinterface()).editClassInvariant(aReprModelClass.getClassName(), + // aReprModelClass.getMyInv()); + return (new TogetherGFInterface()).editClassInvariant(name, pack, inv, cci, pm, abs); } } - diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint5.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint5.java old mode 100755 new mode 100644 index 3926d449479..c0287974e65 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint5.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint5.java @@ -8,50 +8,22 @@ // // - -/** @author Kristofer Johannisson */ - - package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import javax.swing.ProgressMonitor; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelClass; +import de.uka.ilkd.key.proof.init.ProofInputException; -import org.apache.log4j.Logger; - -import de.uka.ilkd.key.casetool.UMLModelClass; -import de.uka.ilkd.key.casetool.together.TogetherGFInterface; -import de.uka.ilkd.key.ocl.gf.CallbackClassInv; -import de.uka.ilkd.key.ocl.gf.Utils; public class ClassMenuPoint5 extends ClassMenu { - protected static Logger timelogger = Logger.getLogger("de.uka.ilkd.key.ocl.gf.Timer"); - protected static Logger logger = Logger.getLogger("key.ocl.gf"); - public String getMenuEntry(){ - return "Edit Invariant [GF]"; + return "BehaviouralSubtypingInv"; } - protected String runCore(UMLModelClass modelClass) { - if (timelogger.isDebugEnabled()) { - timelogger.debug(System.currentTimeMillis() + " ObMenuPoint6 runCore"); - } - if (logger.isDebugEnabled()) { - logger.debug("Class: " + modelClass.getFullClassName()); - } - pm = new ProgressMonitor(null, "Loading the GF editor for OCL", - "", 0, 9700); - Utils.tickProgress(pm, 1, "Initializing TogetherGFInterface"); - - CallbackClassInv cci = new CallbackClassInv(modelClass); - String name = modelClass.getClassName(); - String pack = modelClass.getContainingPackage(); - String inv = modelClass.getMyInv(); - String abs = modelClass.getMyInvGFAbs(); - - // aReprModelClass.setMyInvGFAbs("just testing..."); - - // return (new GFinterface()).editClassInvariant(aReprModelClass.getClassName(), - // aReprModelClass.getMyInv()); - return (new TogetherGFInterface()).editClassInvariant(name, pack, inv, cci, pm, abs); + + protected String runCore(TogetherModelClass modelClass) + throws ProofInputException { + FunctionalityOnModel.proveBehaviouralSubtypingInv(modelClass); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint6.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint6.java index 8e4a4395b58..65d1d653c46 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint6.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint6.java @@ -10,15 +10,18 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.UMLModelClass; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelClass; +import de.uka.ilkd.key.proof.init.ProofInputException; public class ClassMenuPoint6 extends ClassMenu { public String getMenuEntry(){ - return "BehaviouralSubtypingInv"; + return "BehaviouralSubtypingOp"; } - protected String runCore(UMLModelClass modelClass){ - return FunctionalityOnModel.proveBehaviouralSubtypingInv(modelClass); + protected String runCore(TogetherModelClass modelClass) + throws ProofInputException { + FunctionalityOnModel.proveBehaviouralSubtypingOp(modelClass); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint7.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint7.java deleted file mode 100644 index fddca934296..00000000000 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/ClassMenuPoint7.java +++ /dev/null @@ -1,24 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.casetool.together.scripts.menuextension; - -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.UMLModelClass; - -public class ClassMenuPoint7 extends ClassMenu { - public String getMenuEntry(){ - return "BehaviouralSubtypingOp"; - } - - protected String runCore(UMLModelClass modelClass){ - return FunctionalityOnModel.proveBehaviouralSubtypingOp(modelClass); - } -} diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/GlobalMenuPoint1_1.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/GlobalMenuPoint1_1.java index 8dd38b6c451..d04b965afaf 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/GlobalMenuPoint1_1.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/GlobalMenuPoint1_1.java @@ -15,7 +15,7 @@ import com.togethersoft.openapi.ide.window.IdeDialogType; import com.togethersoft.openapi.ide.window.IdeWindowManager; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; import de.uka.ilkd.key.casetool.together.TogetherReprModel; public class GlobalMenuPoint1_1 implements GlobalMenu { @@ -23,9 +23,10 @@ public String getMenuEntry(){ return "TransformXMI"; } public void run(IdeWindowManager winMan){ - String result = FunctionalityOnModel.transformXMIFile(new TogetherReprModel()); + assert false; + /*String result = FunctionalityOnModel.transformXMIFile(new TogetherReprModel()); if (!result.equals("")){ winMan.showMessageDialog("Results", IdeDialogType.INFORMATION, result); - } + }*/ } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenu.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenu.java index 694099fc69e..4bcf230e989 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenu.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenu.java @@ -8,8 +8,6 @@ // // -/* Generated by Together */ - // All implementing classes should have a name of // "OpMenu" + ... @@ -22,6 +20,7 @@ import de.uka.ilkd.key.casetool.ModelMethod; import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; import javax.swing.ProgressMonitor; @@ -49,13 +48,20 @@ public void run(IdeWindowManager winMan, TogetherModelMethod modelMethod = new TogetherModelMethod(selectedMember, rwiModel, rwiDiagram); - String result = runCore(modelMethod); - + String result = ""; + try { + result = runCore(modelMethod); + } catch(Exception e) { + e.printStackTrace(System.out); + result = e.toString(); + } + if (!result.equals("")){ if (pm!=null) pm.close(); winMan.showMessageDialog("Result", IdeDialogType.INFORMATION, result); } } - protected abstract String runCore(ModelMethod aReprModelMethod); + protected abstract String runCore(TogetherModelMethod modelMethod) + throws ProofInputException; } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint1.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint1.java index 39007cd4132..ec9d3766bf6 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint1.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint1.java @@ -12,21 +12,24 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; public class OpMenuPoint1 extends OpMenu { public String getMenuEntry(){ - return "ParseMethodSpec"; + return "Parse Method Spec"; } public String getSubMenuName(){ return null; } - protected String runCore(ModelMethod modelMethod){ - return FunctionalityOnModel.parseMethodSpec(modelMethod); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.parseMethodSpec(modelMethod); + return "No errors were found."; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint10.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint10.java index 3461881b480..e7737f4c651 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint10.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint10.java @@ -10,21 +10,23 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; public class OpMenuPoint10 extends OpMenu { public String getMenuEntry() { - return "EnsuresPost (total)"; + return "RespectsModifies"; } public String getSubMenuName() { return "vertical"; } - protected String runCore(ModelMethod modelMethod) { - return FunctionalityOnModel.proveEnsuresPost(modelMethod, Op.DIA); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.proveRespectsModifies(modelMethod); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint11.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint11.java index 3cb83039fe7..ad3afab94f9 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint11.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint11.java @@ -10,20 +10,23 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; public class OpMenuPoint11 extends OpMenu { public String getMenuEntry() { - return "RespectsModifies"; + return "PreservesGuard"; } public String getSubMenuName() { return "vertical"; } - protected String runCore(ModelMethod modelMethod) { - return FunctionalityOnModel.proveRespectsModifies(modelMethod); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.provePreservesGuard(modelMethod); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint12.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint12.java deleted file mode 100644 index 010d1b3e8bf..00000000000 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint12.java +++ /dev/null @@ -1,29 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.casetool.together.scripts.menuextension; - -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; - - -public class OpMenuPoint12 extends OpMenu { - public String getMenuEntry() { - return "PreservesGuard"; - } - - public String getSubMenuName() { - return "vertical"; - } - - protected String runCore(ModelMethod modelMethod) { - return FunctionalityOnModel.provePreservesGuard(modelMethod); - } -} diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint2.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint2.java index a4c69b46e28..c014517ea6b 100755 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint2.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint2.java @@ -16,7 +16,6 @@ import org.apache.log4j.Logger; -import de.uka.ilkd.key.casetool.ModelMethod; import de.uka.ilkd.key.casetool.together.TogetherGFInterface; import de.uka.ilkd.key.casetool.together.TogetherModelMethod; import de.uka.ilkd.key.ocl.gf.CallbackPrePost; @@ -34,7 +33,7 @@ public String getSubMenuName(){ return null; } - protected String runCore(ModelMethod modelMethod){ + protected String runCore(TogetherModelMethod modelMethod){ if (timelogger.isDebugEnabled()) { timelogger.debug(System.currentTimeMillis() + " ObMenuPoint6 runCore"); } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint3.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint3.java index 255c67257ae..8ad293af953 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint3.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint3.java @@ -10,8 +10,9 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; /** @@ -31,7 +32,9 @@ public String getSubMenuName(){ return null; } - protected String runCore(ModelMethod modelMethod){ - return FunctionalityOnModel.computeSpecification(modelMethod); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.computeSpecification(modelMethod); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint4.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint4.java index 9bf98903dc7..afe43142843 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint4.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint4.java @@ -10,8 +10,9 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; @@ -24,8 +25,9 @@ public String getSubMenuName(){ return "horizontal"; } - protected String runCore(ModelMethod modelMethod){ - return FunctionalityOnModel.proveBehaviouralSubtypingOpPair( - modelMethod); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.proveBehaviouralSubtypingOpPair(modelMethod); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint5.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint5.java index 2b39e0a272e..41c1a95c9a0 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint5.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint5.java @@ -10,8 +10,9 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; public class OpMenuPoint5 extends OpMenu { @@ -23,7 +24,9 @@ public String getSubMenuName() { return "horizontal"; } - protected String runCore(ModelMethod modelMethod) { - return FunctionalityOnModel.proveStrongOperationContract(modelMethod); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.proveStrongOperationContract(modelMethod); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint6.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint6.java index 37a72d99567..f6f5cffdae8 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint6.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint6.java @@ -10,8 +10,9 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; public class OpMenuPoint6 extends OpMenu { @@ -23,7 +24,9 @@ public String getSubMenuName() { return "vertical"; } - protected String runCore(ModelMethod modelMethod) { - return FunctionalityOnModel.provePreservesInv(modelMethod); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.provePreservesInv(modelMethod); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint7.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint7.java index 3cf210a347e..5ea469ca349 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint7.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint7.java @@ -10,8 +10,9 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; public class OpMenuPoint7 extends OpMenu { @@ -23,7 +24,9 @@ public String getSubMenuName() { return "vertical"; } - protected String runCore(ModelMethod modelMethod) { - return FunctionalityOnModel.provePreservesOwnInv(modelMethod); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.provePreservesOwnInv(modelMethod); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint8.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint8.java index e697cf09cfa..e9da12f9374 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint8.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint8.java @@ -10,8 +10,9 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; +import de.uka.ilkd.key.proof.init.ProofInputException; public class OpMenuPoint8 extends OpMenu { @@ -23,7 +24,9 @@ public String getSubMenuName() { return "vertical"; } - protected String runCore(ModelMethod modelMethod) { - return FunctionalityOnModel.provePreservesThroughout(modelMethod); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.provePreservesThroughout(modelMethod); + return ""; } } diff --git a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint9.java b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint9.java index 258f6c52167..a9abd035989 100644 --- a/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint9.java +++ b/system/de/uka/ilkd/key/casetool/together/scripts/menuextension/OpMenuPoint9.java @@ -10,21 +10,24 @@ package de.uka.ilkd.key.casetool.together.scripts.menuextension; -import de.uka.ilkd.key.casetool.FunctionalityOnModel; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.casetool.together.FunctionalityOnModel; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.proof.init.ProofInputException; public class OpMenuPoint9 extends OpMenu { public String getMenuEntry() { - return "EnsuresPost (partial)"; + return "EnsuresPost"; } public String getSubMenuName() { return "vertical"; } - protected String runCore(ModelMethod modelMethod) { - return FunctionalityOnModel.proveEnsuresPost(modelMethod, Op.BOX); + protected String runCore(TogetherModelMethod modelMethod) + throws ProofInputException { + FunctionalityOnModel.proveEnsuresPost(modelMethod); + return ""; } } diff --git a/system/de/uka/ilkd/key/cspec/ComputeSpecification.java b/system/de/uka/ilkd/key/cspec/ComputeSpecification.java index 6a9c87a0b0f..948c722b19d 100644 --- a/system/de/uka/ilkd/key/cspec/ComputeSpecification.java +++ b/system/de/uka/ilkd/key/cspec/ComputeSpecification.java @@ -31,7 +31,7 @@ * program. It contains algorithms for and controls the computation of specifications. *

Internals

* Usually, the method {@link - * de.uka.ilkd.key.casetool.FunctionalityOnModel#computeSpecification(ReprModelMethod)} + * de.uka.ilkd.key.casetool.together.FunctionalityOnModel#computeSpecification(ReprModelMethod)} * is triggered by the user interface, and will start the * specification construction process and thereby invoke {@link * de.uka.ilkd.key.proof.init.ComputeSpecificationPO} to construct the @@ -44,9 +44,9 @@ * * @author André Platzer * @version 0.1, 2003-01-28 - * @version-revision $Revision: 1.16.3.1.2.1.3.1.1.3.2.1 $, $Date: Wed, 17 Jan 2007 20:17:31 +0100 $ + * @version-revision $Revision: 1.16.3.1.2.1.3.1.1.3.2.2 $, $Date: Mon, 22 Jan 2007 15:50:58 +0100 $ * @see de.uka.ilkd.key.gui.ComputeSpecificationView - * @see de.uka.ilkd.key.casetool.FunctionalityOnModel#computeSpecification(ReprModelMethod) + * @see de.uka.ilkd.key.casetool.together.FunctionalityOnModel#computeSpecification(ReprModelMethod) */ public class ComputeSpecification { /** diff --git a/system/de/uka/ilkd/key/proof/init/ComputeSpecificationPONew.java b/system/de/uka/ilkd/key/cspec/ComputeSpecificationPO.java similarity index 67% rename from system/de/uka/ilkd/key/proof/init/ComputeSpecificationPONew.java rename to system/de/uka/ilkd/key/cspec/ComputeSpecificationPO.java index 4740f9b5300..3436bbcfee6 100644 --- a/system/de/uka/ilkd/key/proof/init/ComputeSpecificationPONew.java +++ b/system/de/uka/ilkd/key/cspec/ComputeSpecificationPO.java @@ -1,7 +1,5 @@ -package de.uka.ilkd.key.proof.init; +package de.uka.ilkd.key.cspec; -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.cspec.ComputeSpecification; import de.uka.ilkd.key.java.ArrayOfExpression; import de.uka.ilkd.key.java.Statement; import de.uka.ilkd.key.java.StatementBlock; @@ -21,23 +19,27 @@ import de.uka.ilkd.key.logic.ProgramElementName; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.proof.init.AbstractPO; +import de.uka.ilkd.key.proof.init.InitConfig; +import de.uka.ilkd.key.proof.init.ModStrategy; +import de.uka.ilkd.key.proof.init.ProofInputException; import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; -import de.uka.ilkd.key.proof.mgt.OldOperationContract; -import de.uka.ilkd.key.util.Debug; -public class ComputeSpecificationPONew extends AbstractPO { + +public class ComputeSpecificationPO extends AbstractPO { private static final TermBuilder tb = TermBuilder.DF; - private ModelMethod modelMethod; + private ProgramMethod programMethod; private Modality modality; - public ComputeSpecificationPONew(String name, ModelMethod modelMethod) { - super(name, modelMethod.getContainingClass()); + public ComputeSpecificationPO(InitConfig initConfig, + ProgramMethod programMethod) { + super(initConfig, + "ComputeSpecification", + programMethod.getContainerType()); - this.modelMethod = modelMethod; + this.programMethod = programMethod; this.modality = Op.DIA; } @@ -90,46 +92,30 @@ private JavaBlock buildJavaBlock(ProgramVariable[] formalParVars, return result; } - /** - * Returns the program method associated with this proof obligation. - */ - private ProgramMethod getProgramMethod(ListOfProgramVariable paramVars) { - //get class type - String className = modelClass.getFullClassName(); - KeYJavaType classType = javaInfo.getTypeByClassName(className); - Debug.assertTrue(classType != null); - - //get program method - return javaInfo.getProgramMethod(classType, - modelMethod.getName(), - paramVars.toArray(), - classType); - } - public void readProblem(ModStrategy mod) throws ProofInputException { + public void readProblem(ModStrategy mod) throws ProofInputException { //make sure initConfig has been set if(initConfig == null) { throw new IllegalStateException("InitConfig not set."); } //prepare variables, program method and container for @pre-functions - ListOfProgramVariable paramVars = buildParamVars(modelMethod); - ProgramMethod programMethod = getProgramMethod(paramVars); + ListOfProgramVariable paramVars = buildParamVars(programMethod); ProgramVariable selfVar = null; if(programMethod != null && !programMethod.isStatic()) { selfVar = buildSelfVarAsProgVar(); } - ProgramVariable resultVar = buildResultVar(modelMethod); + ProgramVariable resultVar = buildResultVar(programMethod); ProgramVariable exceptionVar = buildExcVar(); //create formal parameters ProgramVariable[] parVars = paramVars.toArray(); ProgramVariable[] formalParVars = new ProgramVariable[parVars.length]; for(int i = 0; i < parVars.length; i++) { - ProgramElementName name + ProgramElementName pen = new ProgramElementName("_" + parVars[i].name()); formalParVars[i] - = new LocationVariable(name, parVars[i].getKeYJavaType()); + = new LocationVariable(pen, parVars[i].getKeYJavaType()); registerInNamespaces(formalParVars[i]); } @@ -155,25 +141,4 @@ public void readProblem(ModStrategy mod) throws ProofInputException { poTerms[0] = resultTerm; } - - public Contractable[] getObjectOfContract() { - return new Contractable[] { modelMethod }; - } - - public boolean initContract(Contract ct) { - if(!(ct instanceof OldOperationContract)) { - return false; - } - - OldOperationContract mct = (OldOperationContract)ct; - - if(! (mct.getModelMethod().equals(modelMethod) - && mct.getModality().equals(modality))) { - return false; - } - - ct.addCompoundProof(getPO()); - return true; - } - } diff --git a/system/de/uka/ilkd/key/gui/ClassInvariantSelectionDialog.java b/system/de/uka/ilkd/key/gui/ClassInvariantSelectionDialog.java index 38647dc1896..5c19b3b67dc 100644 --- a/system/de/uka/ilkd/key/gui/ClassInvariantSelectionDialog.java +++ b/system/de/uka/ilkd/key/gui/ClassInvariantSelectionDialog.java @@ -1,45 +1,64 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + package de.uka.ilkd.key.gui; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.Set; +import java.awt.event.KeyEvent; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; -import javax.swing.JPanel; +import javax.swing.KeyStroke; -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.speclang.ListOfClassInvariant; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; -public class ClassInvariantSelectionDialog extends JDialog { +public class ClassInvariantSelectionDialog extends JDialog { + private final ClassInvariantSelectionPanel panel; + private final JButton okButton; + private final JButton cancelButton; + private boolean successful = false; - private ClassInvariantSelectionPanel panel; - + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + /** * Creates and displays a dialog box asking the user to select a set of - * invariants. - * @param modelClasses the classes to choose invariants from + * class invariants. */ public ClassInvariantSelectionDialog(String title, - Set modelClasses, + Services services, boolean useThroughoutInvs, - ModelClass defaultClass) { + KeYJavaType defaultClass) { super(new JFrame(), title, true); - panel - = new ClassInvariantSelectionPanel(modelClasses, - useThroughoutInvs, - defaultClass, - true); - JPanel rightButtonPanel = panel.getButtonPanel(); - - Dimension buttonDim = new Dimension(95, 25); + + //create invariant selection panel + panel = new ClassInvariantSelectionPanel(services, + useThroughoutInvs, + defaultClass, + true); + panel.setPreferredSize(new Dimension(800, 500)); + getContentPane().add(panel); + Dimension buttonDim = new Dimension(100, 27); - // create "ok" button - JButton okButton = new JButton("OK"); + //create "ok" button + okButton = new JButton("OK"); okButton.setPreferredSize(buttonDim); okButton.setMinimumSize(buttonDim); okButton.addActionListener(new ActionListener() { @@ -48,11 +67,11 @@ public void actionPerformed(ActionEvent e) { setVisible(false); } }); - rightButtonPanel.add(okButton); + panel.getButtonPanel().add(okButton); getRootPane().setDefaultButton(okButton); //create "cancel" button - JButton cancelButton = new JButton("Cancel"); + cancelButton = new JButton("Cancel"); cancelButton.setPreferredSize(buttonDim); cancelButton.setMinimumSize(buttonDim); cancelButton.addActionListener(new ActionListener() { @@ -60,15 +79,31 @@ public void actionPerformed(ActionEvent e) { setVisible(false); } }); - rightButtonPanel.add(cancelButton); - + panel.getButtonPanel().add(cancelButton); + ActionListener escapeListener = new ActionListener() { + public void actionPerformed(ActionEvent event) { + if(event.getActionCommand().equals("ESC")) { + cancelButton.doClick(); + } + } + }; + cancelButton.registerKeyboardAction( + escapeListener, + "ESC", + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JButton.WHEN_IN_FOCUSED_WINDOW); - getContentPane().add(panel); pack(); setLocation(70, 70); setVisible(true); } - + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + /** * Tells whether the user clicked "ok". */ @@ -76,10 +111,11 @@ public boolean wasSuccessful() { return successful; } + /** * Returns the selected set of invariants. */ - public ListOfClassInvariant getClassInvariants() { + public SetOfClassInvariant getSelection() { return panel.getClassInvariants(); } } diff --git a/system/de/uka/ilkd/key/gui/ClassInvariantSelectionPanel.java b/system/de/uka/ilkd/key/gui/ClassInvariantSelectionPanel.java index 3d370646350..33c9a5401c7 100644 --- a/system/de/uka/ilkd/key/gui/ClassInvariantSelectionPanel.java +++ b/system/de/uka/ilkd/key/gui/ClassInvariantSelectionPanel.java @@ -11,12 +11,28 @@ package de.uka.ilkd.key.gui; -import java.awt.*; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.*; +import java.util.Iterator; +import java.util.Set; -import javax.swing.*; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.DefaultListCellRenderer; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTree; +import javax.swing.ListModel; +import javax.swing.ListSelectionModel; +import javax.swing.SwingConstants; import javax.swing.border.TitledBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; @@ -24,61 +40,78 @@ import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.speclang.*; -import de.uka.ilkd.key.util.Debug; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.proof.mgt.SpecificationRepository; +import de.uka.ilkd.key.speclang.ClassInvariant; +import de.uka.ilkd.key.speclang.IteratorOfClassInvariant; +import de.uka.ilkd.key.speclang.SetAsListOfClassInvariant; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; /** - * A dialog for selecting class invariants. + * A panel for selecting class invariants. */ -public class ClassInvariantSelectionPanel extends JPanel { - - private Set modelClasses; - private boolean useThroughoutInvs; +class ClassInvariantSelectionPanel extends JPanel { + + private final Services services; + private final SpecificationRepository specRepos; + private final boolean useThroughoutInvs; + + private final ClassTree classTree; + private final JList invList; + private final JPanel leftButtonPanel; + private final JPanel rightButtonPanel; + + private SetOfClassInvariant selectedInvs + = SetAsListOfClassInvariant.EMPTY_SET; - private ListOfClassInvariant selectedInvs - = SLListOfClassInvariant.EMPTY_LIST; - private JTree classTree; - private JList invList; - private ModelClass selectedClass = null; - private JPanel rightButtonPanel; - private java.util.List selectionListeners = new LinkedList(); + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- - /** - * Creates and displays a dialog box asking the user to select a set of - * invariants. - * @param modelClasses the classes to choose invariants from - */ - public ClassInvariantSelectionPanel( Set modelClasses, - boolean useThroughoutInvs, - ModelClass defaultClass, - boolean selectDefaultInvs) { - - this.modelClasses = modelClasses; + public ClassInvariantSelectionPanel(Services services, + boolean useThroughoutInvs, + KeYJavaType defaultClass, + boolean selectDefaultInvs) { + this.services = services; + this.specRepos = services.getSpecificationRepository(); this.useThroughoutInvs = useThroughoutInvs; + + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + //create list panel + JPanel listPanel = new JPanel(); + listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.X_AXIS)); + listPanel.setPreferredSize(new Dimension(660, 435)); + add(listPanel); + + //create class scroll pane + JScrollPane classScrollPane = new JScrollPane(); + classScrollPane.setBorder(new TitledBorder("Classes")); + Dimension classScrollPaneDim = new Dimension(220, 435); + classScrollPane.setPreferredSize(classScrollPaneDim); + classScrollPane.setMinimumSize(classScrollPaneDim); + listPanel.add(classScrollPane); //create class tree - classTree = buildClassTree(modelClasses); + classTree = new ClassTree(false, defaultClass, services); + setInvCounters(classTree.getRootNode()); classTree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { - DefaultMutableTreeNode selectedNode = - (DefaultMutableTreeNode)(e.getPath().getLastPathComponent()); - TreeEntry te = (TreeEntry)(selectedNode.getUserObject()); - Debug.assertTrue(!selectedNode.isLeaf() - || te.modelClass != null); - selectedClass = te.modelClass; updateInvList(); } }); classTree.setCellRenderer(new DefaultTreeCellRenderer() { private final Color MEDIUMGREEN = new Color(80, 150, 0); private final Color DARKGREEN = new Color(0, 120, 90); - private final Font BOLDFONT = ClassInvariantSelectionPanel.this.getFont().deriveFont(Font.BOLD, 10); + private final Font BOLDFONT + = ClassInvariantSelectionPanel.this + .getFont() + .deriveFont(Font.BOLD, 10); + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, @@ -86,18 +119,21 @@ public Component getTreeCellRendererComponent(JTree tree, boolean leaf, int row, boolean hasFocus) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; - TreeEntry te = (TreeEntry)(node.getUserObject()); - if(te.numSelectedInvs == te.numInvs) { + ClassTree.Entry te = (ClassTree.Entry) node.getUserObject(); + if(te.numSelectedMembers == te.numMembers + && te.numMembers > 0) { setTextNonSelectionColor(MEDIUMGREEN); setTextSelectionColor(MEDIUMGREEN); - } else if(te.numSelectedInvs > 0) { + } else if(te.numSelectedMembers > 0) { setTextNonSelectionColor(DARKGREEN); setTextSelectionColor(DARKGREEN); } else { setTextNonSelectionColor(Color.BLACK); setTextSelectionColor(Color.BLACK); } + setFont(BOLDFONT); return super.getTreeCellRendererComponent(tree, value, @@ -108,11 +144,23 @@ public Component getTreeCellRendererComponent(JTree tree, hasFocus); } }); + classScrollPane.setViewportView(classTree); + + //create invariant scroll pane + JScrollPane invScrollPane = new JScrollPane(); + invScrollPane.setBorder(new TitledBorder((useThroughoutInvs + ? "Throughout invariants" + : "Invariants"))); + Dimension invScrollPaneDim = new Dimension(440, 435); + invScrollPane.setPreferredSize(invScrollPaneDim); + invScrollPane.setMinimumSize(invScrollPaneDim); + listPanel.add(invScrollPane); //create inv list invList = new JList(); invList.setSelectionMode(ListSelectionModel .MULTIPLE_INTERVAL_SELECTION); + final Services finalServices = services; invList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if(e.getValueIsAdjusting()) { @@ -131,49 +179,63 @@ public void valueChanged(ListSelectionEvent e) { removeFromSelection(inv); } } - fireSelectionChanged(e); } }); - - //create list panel - JPanel listPanel = new JPanel(); - listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.X_AXIS)); - add(listPanel); - - //create class scroll pane - JScrollPane classScrollPane = new JScrollPane(classTree); - classScrollPane.setBorder(new TitledBorder("Classes")); - Dimension classScrollPaneDim = new Dimension(220, 400); - classScrollPane.setPreferredSize(classScrollPaneDim); - classScrollPane.setMinimumSize(classScrollPaneDim); - listPanel.add(classScrollPane); - - //create invariant scroll pane - JScrollPane invScrollPane = new JScrollPane(invList); - invScrollPane.setBorder(new TitledBorder((useThroughoutInvs - ? "Throughout invariants" - : "Invariants"))); - Dimension invScrollPaneDim = new Dimension(440, 400); - invScrollPane.setPreferredSize(invScrollPaneDim); - invScrollPane.setMinimumSize(invScrollPaneDim); - listPanel.add(invScrollPane); + invList.setCellRenderer(new DefaultListCellRenderer() { + private final Font PLAINFONT = getFont().deriveFont(Font.PLAIN); + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + ClassInvariant inv = (ClassInvariant) value; + Component supComp + = super.getListCellRendererComponent(list, + value, + index, + isSelected, + cellHasFocus); + + //create label and enclosing panel + JLabel label = new JLabel(); + label.setText(inv.getHTMLText(finalServices)); + label.setFont(PLAINFONT); + FlowLayout lay = new FlowLayout(); + lay.setAlignment(FlowLayout.LEFT); + JPanel result = new JPanel(lay); + result.add(label); + label.setVerticalAlignment(SwingConstants.TOP); + + //set background color + result.setBackground(supComp.getBackground()); + + //set border + TitledBorder border = new TitledBorder( + BorderFactory.createEtchedBorder(), + inv.getName()); + border.setTitleFont(border.getTitleFont() + .deriveFont(Font.BOLD)); + result.setBorder(border); + + return result; + } + }); + invScrollPane.setViewportView(invList); //create button panel JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS)); + buttonPanel.setPreferredSize(new Dimension(660, 27)); + Dimension buttonDim = new Dimension(110, 27); add(buttonPanel); - Dimension buttonDim = new Dimension(95, 25); //create left button panel - JPanel leftButtonPanel = new JPanel(); + leftButtonPanel = new JPanel(); leftButtonPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5)); buttonPanel.add(leftButtonPanel); - - //create right button panel - rightButtonPanel = new JPanel(); - rightButtonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5)); - buttonPanel.add(rightButtonPanel); - + //create "select all" button JButton selectButton = new JButton("Select all"); selectButton.setPreferredSize(buttonDim); @@ -197,173 +259,81 @@ public void actionPerformed(ActionEvent e) { } }); leftButtonPanel.add(unselectButton); - + //create right button panel + rightButtonPanel = new JPanel(); + rightButtonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5)); + buttonPanel.add(rightButtonPanel); + //set default selection if(selectDefaultInvs) { selectAllForClass(defaultClass); } - openClassInTree(defaultClass); - - //show dialog - setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - } - - public JPanel getButtonPanel() { - return rightButtonPanel; - } - - public void addInvariantSelectionListener(ListSelectionListener listener) { - selectionListeners.add(listener); + updateInvList(); } - private void fireSelectionChanged(ListSelectionEvent e) { - Iterator it = selectionListeners.iterator(); - while (it.hasNext()) { - ((ListSelectionListener)it.next()).valueChanged(e); - } - } + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- - private ListOfClassInvariant getRelevantInvs(ModelClass modelClass) { + private SetOfClassInvariant getRelevantInvs(KeYJavaType kjt) { if(useThroughoutInvs) { - return modelClass.getMyThroughoutClassInvariants(); + return specRepos.getThroughoutClassInvariants(kjt); } else { - return modelClass.getMyClassInvariants(); + return specRepos.getClassInvariants(kjt); } } - private DefaultMutableTreeNode getChildByString( - DefaultMutableTreeNode parentNode, - String childString) { - int numChildren = parentNode.getChildCount(); - for(int i = 0; i < numChildren; i++) { - DefaultMutableTreeNode childNode - = (DefaultMutableTreeNode)(parentNode.getChildAt(i)); - - TreeEntry te = (TreeEntry)(childNode.getUserObject()); - if(childString.equals(te.string)) { - return childNode; - } - } - return null; - } - - - private void insertIntoClassTree(DefaultMutableTreeNode rootNode, - ModelClass modelClass) { - String fullClassName = modelClass.getFullClassName(); - int length = fullClassName.length(); - int index = -1; - DefaultMutableTreeNode node = rootNode; - - do { - //get next part of the name - int lastIndex = index; - index = fullClassName.indexOf(".", ++index); - if(index == -1) { - index = length; - } - String namePart = fullClassName.substring(lastIndex + 1, index); - - //try to get child node; otherwise, create and insert it - DefaultMutableTreeNode childNode = - getChildByString(node, namePart); - if(childNode == null) { - TreeEntry te = new TreeEntry(namePart); - childNode = new DefaultMutableTreeNode(te); - node.add(childNode); - } - - //go down to child node - node = childNode; - } while(index != length); - - //save model class in leaf - TreeEntry te = (TreeEntry)(node.getUserObject()); - te.modelClass = modelClass; - } - - private void setInvCounters(DefaultMutableTreeNode node) { - int numInvs = 0; + int numMembers = 0; int numChildren = node.getChildCount(); for(int i = 0; i < numChildren; i++) { DefaultMutableTreeNode childNode - = (DefaultMutableTreeNode)(node.getChildAt(i)); + = (DefaultMutableTreeNode) node.getChildAt(i); setInvCounters(childNode); - TreeEntry te = (TreeEntry)(childNode.getUserObject()); - numInvs += te.numInvs; + ClassTree.Entry te = (ClassTree.Entry)(childNode.getUserObject()); + numMembers += te.numMembers; } - - TreeEntry te = (TreeEntry)(node.getUserObject()); - if(te.modelClass != null) { - numInvs += getRelevantInvs(te.modelClass).size(); + + ClassTree.Entry te = (ClassTree.Entry) node.getUserObject(); + if(te.kjt != null) { + numMembers += getRelevantInvs(te.kjt).size(); } - te.numInvs = numInvs; + te.numMembers = numMembers; } private void setSelectedInvCounters(DefaultMutableTreeNode node) { - int numSelectedInvs = 0; + int numSelectedMembers = 0; int numChildren = node.getChildCount(); for(int i = 0; i < numChildren; i++) { DefaultMutableTreeNode childNode - = (DefaultMutableTreeNode)(node.getChildAt(i)); + = (DefaultMutableTreeNode) node.getChildAt(i); setSelectedInvCounters(childNode); - TreeEntry te = (TreeEntry)(childNode.getUserObject()); - numSelectedInvs += te.numSelectedInvs; + ClassTree.Entry te = (ClassTree.Entry) childNode.getUserObject(); + numSelectedMembers += te.numSelectedMembers; } - TreeEntry te = (TreeEntry)(node.getUserObject()); - if(te.modelClass != null) { - ListOfClassInvariant invs = getRelevantInvs(te.modelClass); + ClassTree.Entry te = (ClassTree.Entry) node.getUserObject(); + if(te.kjt != null) { + SetOfClassInvariant invs = getRelevantInvs(te.kjt); IteratorOfClassInvariant it = invs.iterator(); while(it.hasNext()) { if(selectedInvs.contains(it.next())) { - numSelectedInvs++; + numSelectedMembers++; } } } - te.numSelectedInvs = numSelectedInvs; + te.numSelectedMembers = numSelectedMembers; } - - - private JTree buildClassTree(Set modelClasses) { - //sort classes alphabetically - Object[] mca = modelClasses.toArray(); - Arrays.sort(mca, new Comparator() { - public int compare(Object o1, Object o2) { - ModelClass mc1 = (ModelClass)o1; - ModelClass mc2 = (ModelClass)o2; - return mc1.getFullClassName().compareTo(mc2.getFullClassName()); - } - }); - - //build tree - TreeEntry rootEntry = new TreeEntry(""); - DefaultMutableTreeNode rootNode = - new DefaultMutableTreeNode(rootEntry); - for(int i = 0; i < mca.length; i++) { - ModelClass modelClass = (ModelClass)(mca[i]); - if(getRelevantInvs(modelClass).size() > 0){ - insertIntoClassTree(rootNode, modelClass); - } - } - //set inv counters - setInvCounters(rootNode); - - JTree result = new JTree(new DefaultTreeModel(rootNode)); - //result.setRootVisible(false); - return result; - } - private void addToSelection(ClassInvariant inv) { //make sure inv is not selected already @@ -372,16 +342,16 @@ private void addToSelection(ClassInvariant inv) { } //add it to the selection - selectedInvs = selectedInvs.prepend(inv); + selectedInvs = selectedInvs.add(inv); //update selection counters in tree Object[] nodes = classTree.getSelectionPath().getPath(); for(int i = 0; i < nodes.length; i++) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)(nodes[i]); - TreeEntry te = (TreeEntry)(node.getUserObject()); - te.numSelectedInvs++; - Debug.assertTrue(te.numSelectedInvs > 0 - && te.numSelectedInvs <= te.numInvs); + ClassTree.Entry te = (ClassTree.Entry) node.getUserObject(); + te.numSelectedMembers++; + assert te.numSelectedMembers > 0 + && te.numSelectedMembers <= te.numMembers; } classTree.repaint(); @@ -395,28 +365,28 @@ private void removeFromSelection(ClassInvariant inv) { } //remove it from the selection - selectedInvs = selectedInvs.removeFirst(inv); + selectedInvs = selectedInvs.remove(inv); //update selection counters in tree Object[] nodes = classTree.getSelectionPath().getPath(); for(int i = 0; i < nodes.length; i++) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)(nodes[i]); - TreeEntry te = (TreeEntry)(node.getUserObject()); - te.numSelectedInvs--; - Debug.assertTrue(te.numSelectedInvs >= 0 - && te.numSelectedInvs < te.numInvs); + ClassTree.Entry te = (ClassTree.Entry) node.getUserObject(); + te.numSelectedMembers--; + assert te.numSelectedMembers >= 0 + && te.numSelectedMembers < te.numMembers; } classTree.repaint(); } - private void selectAllForClass(ModelClass modelClass) { + private void selectAllForClass(KeYJavaType kjt) { //select invariants of this class - selectedInvs = getRelevantInvs(modelClass); + selectedInvs = getRelevantInvs(kjt); //update selection counters in tree DefaultMutableTreeNode rootNode - = (DefaultMutableTreeNode)(classTree.getModel().getRoot()); + = (DefaultMutableTreeNode) classTree.getModel().getRoot(); setSelectedInvCounters(rootNode); classTree.repaint(); } @@ -424,16 +394,17 @@ private void selectAllForClass(ModelClass modelClass) { private void selectAll() { //select all - selectedInvs = SLListOfClassInvariant.EMPTY_LIST; - Iterator it = modelClasses.iterator(); + selectedInvs = SetAsListOfClassInvariant.EMPTY_SET; + Set kjts = services.getJavaInfo().getAllKeYJavaTypes(); + Iterator it = kjts.iterator(); while(it.hasNext()) { - ModelClass modelClass = (ModelClass)(it.next()); - selectedInvs = selectedInvs.append(getRelevantInvs(modelClass)); + KeYJavaType kjt = (KeYJavaType)(it.next()); + selectedInvs = selectedInvs.union(getRelevantInvs(kjt)); } //update selection counters in tree DefaultMutableTreeNode rootNode - = (DefaultMutableTreeNode)(classTree.getModel().getRoot()); + = (DefaultMutableTreeNode) classTree.getModel().getRoot(); setSelectedInvCounters(rootNode); classTree.repaint(); } @@ -441,11 +412,11 @@ private void selectAll() { private void unselectAll() { //unselect all - selectedInvs = SLListOfClassInvariant.EMPTY_LIST; + selectedInvs = SetAsListOfClassInvariant.EMPTY_SET; //update selection counters in tree DefaultMutableTreeNode rootNode - = (DefaultMutableTreeNode)(classTree.getModel().getRoot()); + = (DefaultMutableTreeNode) classTree.getModel().getRoot(); setSelectedInvCounters(rootNode); classTree.repaint(); } @@ -454,15 +425,19 @@ private void unselectAll() { private void updateInvList() { invList.setValueIsAdjusting(true); - if(selectedClass == null) { + ClassTree.Entry selectedEntry = classTree.getSelectedEntry(); + + if(selectedEntry == null || selectedEntry.kjt == null) { invList.setListData(new Object[0]); } else { - ListOfClassInvariant invariants = getRelevantInvs(selectedClass); - invList.setListData(invariants.toArray()); + SetOfClassInvariant invariants = getRelevantInvs(selectedEntry.kjt); + ClassInvariant[] listData = invariants.toArray(); + invList.setListData(listData); - IteratorOfClassInvariant it = selectedInvs.iterator(); - while(it.hasNext()) { - invList.setSelectedValue(it.next(), false); + for(int i = 0; i < listData.length; i++) { + if(selectedInvs.contains(listData[i])) { + invList.addSelectionInterval(i, i); + } } } @@ -470,69 +445,20 @@ private void updateInvList() { } - private boolean openClassInTree(ModelClass modelClass) { - //get tree path - Vector pathVector = new Vector(); - - String fullClassName = modelClass.getFullClassName(); - int length = fullClassName.length(); - int index = -1; - DefaultMutableTreeNode node - = (DefaultMutableTreeNode)(classTree.getModel().getRoot()); - Debug.assertTrue(node!=null); - do { - //save current node - pathVector.add(node); - - //get next part of the name - int lastIndex = index; - index = fullClassName.indexOf(".", ++index); - if(index == -1) { - index = length; - } - String namePart = fullClassName.substring(lastIndex + 1, index); - - //get child node, go down to it - DefaultMutableTreeNode childNode = - getChildByString(node, namePart); - if (childNode == null) { - return false; - } - node = childNode; - } while(index != length); - TreePath incompletePath = new TreePath(pathVector.toArray()); - - TreePath path = incompletePath.pathByAddingChild(node); - - classTree.expandPath(incompletePath); - classTree.setSelectionRow(classTree.getRowForPath(path)); - return true; + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public JPanel getButtonPanel() { + return rightButtonPanel; } + /** * Returns the selected set of invariants. */ - public ListOfClassInvariant getClassInvariants() { + public SetOfClassInvariant getClassInvariants() { return selectedInvs; } - - public JList getInvList() { - return invList; - } - - - private static class TreeEntry { - public String string; - public ModelClass modelClass = null; - public int numInvs = 0; - public int numSelectedInvs = 0; - - public TreeEntry(String string) { - this.string = string; - } - - public String toString() { - return string; - } - } } diff --git a/system/de/uka/ilkd/key/gui/ClassSelectionDialog.java b/system/de/uka/ilkd/key/gui/ClassSelectionDialog.java index 49040cf674c..5be3adeaab7 100644 --- a/system/de/uka/ilkd/key/gui/ClassSelectionDialog.java +++ b/system/de/uka/ilkd/key/gui/ClassSelectionDialog.java @@ -16,11 +16,16 @@ import java.awt.event.ActionListener; import java.util.Arrays; import java.util.Comparator; +import java.util.Vector; import javax.swing.*; import javax.swing.border.TitledBorder; -import de.uka.ilkd.key.casetool.*; +import de.uka.ilkd.key.java.abstraction.ClassType; +import de.uka.ilkd.key.java.abstraction.IteratorOfKeYJavaType; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.abstraction.SetAsListOfKeYJavaType; +import de.uka.ilkd.key.java.abstraction.SetOfKeYJavaType; /** @@ -35,16 +40,17 @@ public class ClassSelectionDialog extends JDialog { /** * Creates and displays a dialog box asking the user to make a choice from * a set of classes. - * @param windowTitle Title for the dialog window. + * @param dialogTitle Title for the dialog window. * @param classesTitle Title for the list of available classes. - * @param modelClasses The available classes. + * @param kjts The available types. + * @param defaultClass Default selection. * @param allowMultipleSelection Whether multiple classes or a single class * are to be selected */ public ClassSelectionDialog(String dialogTitle, String classesTitle, - ListOfModelClass modelClasses, - ModelClass defaultClass, + SetOfKeYJavaType kjts, + KeYJavaType defaultClass, boolean allowMultipleSelection) { super(new JFrame(), dialogTitle, true); @@ -56,27 +62,27 @@ public ClassSelectionDialog(String dialogTitle, } else { classList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); } - ModelClass[] classesArray = modelClasses.toArray(); - Arrays.sort(classesArray, new Comparator() { + IteratorOfKeYJavaType it = kjts.iterator(); + Vector v = new Vector(); + while(it.hasNext()) { + KeYJavaType kjt = (KeYJavaType) it.next(); + if(kjt.getJavaType() instanceof ClassType) { + v.add(new WrappedKJT(kjt)); + } + } + Object[] listData = v.toArray(); + Arrays.sort(listData, new Comparator() { public int compare(Object o1, Object o2) { - ModelClass mc1 = (ModelClass)o1; - ModelClass mc2 = (ModelClass)o2; - return mc1.getClassName().compareTo(mc2.getClassName()); + KeYJavaType kjt1 = ((WrappedKJT)o1).kjt; + KeYJavaType kjt2 = ((WrappedKJT)o2).kjt; + return kjt1.getName().compareTo(kjt2.getName()); } }); - classList.setListData(classesArray); - + classList.setListData(listData); + //select default class if(defaultClass != null) { - String defaultName = defaultClass.getFullClassName(); - IteratorOfModelClass it = modelClasses.iterator(); - while(it.hasNext()) { - ModelClass modelClass = it.next(); - if(modelClass.getFullClassName().equals(defaultName)) { - classList.setSelectedValue(modelClass, true); - break; - } - } + classList.setSelectedValue(defaultClass, true); } //create type scroll pane @@ -90,8 +96,8 @@ public int compare(Object o1, Object o2) { //create button panel JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5)); + Dimension buttonDim = new Dimension(100, 27); getContentPane().add(buttonPanel); - Dimension buttonDim = new Dimension(80, 25); //create "ok" button JButton okButton = new JButton("OK"); @@ -117,6 +123,7 @@ public void actionPerformed(ActionEvent e) { }); buttonPanel.add(cancelButton); + //show getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); pack(); @@ -127,11 +134,11 @@ public void actionPerformed(ActionEvent e) { public ClassSelectionDialog(String dialogTitle, String classesTitle, - ListOfModelClass modelClasses, + SetOfKeYJavaType kjts, boolean allowMultipleSelection) { this(dialogTitle, classesTitle, - modelClasses, + kjts, null, allowMultipleSelection); } @@ -148,14 +155,28 @@ public boolean wasSuccessful() { /** * Returns the selected classes. */ - public ListOfModelClass getSelection() { - Object[] selectedClasses = classList.getSelectedValues(); + public SetOfKeYJavaType getSelection() { + Object[] selection = classList.getSelectedValues(); - ListOfModelClass result = SLListOfModelClass.EMPTY_LIST; - for(int i = selectedClasses.length - 1; i >= 0; i--) { - result = result.prepend((UMLModelClass) selectedClasses[i]); + SetOfKeYJavaType result = SetAsListOfKeYJavaType.EMPTY_SET; + for(int i = selection.length - 1; i >= 0; i--) { + result = result.add(((WrappedKJT) selection[i]).kjt); } return result; } + + + + private static class WrappedKJT { + public final KeYJavaType kjt; + + public WrappedKJT(KeYJavaType kjt) { + this.kjt = kjt; + } + + public String toString() { + return kjt.getFullName(); + } + } } diff --git a/system/de/uka/ilkd/key/gui/ClassTree.java b/system/de/uka/ilkd/key/gui/ClassTree.java new file mode 100644 index 00000000000..8b33cf0df52 --- /dev/null +++ b/system/de/uka/ilkd/key/gui/ClassTree.java @@ -0,0 +1,287 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.gui; + +import java.awt.Component; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Iterator; +import java.util.Set; +import java.util.Vector; + +import javax.swing.JLabel; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.declaration.ClassDeclaration; +import de.uka.ilkd.key.java.declaration.InterfaceDeclaration; +import de.uka.ilkd.key.logic.op.IteratorOfProgramMethod; +import de.uka.ilkd.key.logic.op.ListOfProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramMethod; + + +class ClassTree extends JTree { + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public ClassTree(boolean addOperations, + KeYJavaType defaultClass, + Services services) { + super(new DefaultTreeModel(createTree(addOperations, services))); + if(defaultClass != null) { + open(defaultClass); + } + getSelectionModel().setSelectionMode( + TreeSelectionModel.SINGLE_TREE_SELECTION); + setCellRenderer(new DefaultTreeCellRenderer() { + public Component getTreeCellRendererComponent(JTree tree, + Object value, + boolean sel, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Entry entry = (Entry) node.getUserObject(); + + Component result; + if(entry.kjt != null) { + result = super.getTreeCellRendererComponent(tree, + value, + sel, + expanded, + true, + row, + hasFocus); + } else { + result = super.getTreeCellRendererComponent(tree, + value, + sel, + expanded, + leaf, + row, + hasFocus); + + if(entry.pm != null && result instanceof JLabel) { + ((JLabel) result).setIcon(null); + } + } + + return result; + } + }); + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private static DefaultMutableTreeNode getChildByString( + DefaultMutableTreeNode parentNode, + String childString) { + int numChildren = parentNode.getChildCount(); + for(int i = 0; i < numChildren; i++) { + DefaultMutableTreeNode childNode + = (DefaultMutableTreeNode)(parentNode.getChildAt(i)); + + Entry te = (Entry)(childNode.getUserObject()); + if(childString.equals(te.string)) { + return childNode; + } + } + return null; + } + + + private static void insertIntoTree(DefaultMutableTreeNode rootNode, + KeYJavaType kjt, + boolean addOperations, + Services services) { + String fullClassName = kjt.getFullName(); + int length = fullClassName.length(); + int index = -1; + DefaultMutableTreeNode node = rootNode; + do { + //get next part of the name + int lastIndex = index; + index = fullClassName.indexOf(".", ++index); + if(index == -1) { + index = length; + } + String namePart = fullClassName.substring(lastIndex + 1, index); + + //try to get child node; otherwise, create and insert it + DefaultMutableTreeNode childNode = getChildByString(node, namePart); + if(childNode == null) { + Entry te = new Entry(namePart); + childNode = new DefaultMutableTreeNode(te); + node.add(childNode); + } + + //go down to child node + node = childNode; + } while(index != length); + + //save kjt in leaf + ((Entry) node.getUserObject()).kjt = kjt; + + //add all operations of kjt + if(addOperations) { + ListOfProgramMethod pms + = services.getJavaInfo() + .getAllProgramMethodsLocallyDeclared(kjt); + IteratorOfProgramMethod it = pms.iterator(); + while(it.hasNext()) { + ProgramMethod pm = it.next(); + if (!(pm.isImplicit()) + && pm.getMethodDeclaration().getBody() != null) { + StringBuffer sb = new StringBuffer(pm.getName()); + sb.append("("); + for(int i = 0; i < pm.getParameterDeclarationCount(); i++) { + sb.append(pm.getParameterDeclarationAt(i)); + } + sb.append(")"); + Entry te = new Entry(sb.toString()); + DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(te); + te.pm = pm; + node.add(childNode); + } + } + } + } + + + private static DefaultMutableTreeNode createTree(boolean addOperations, + Services services) { + //get all classes + Set kjts = services.getJavaInfo().getAllKeYJavaTypes(); + Iterator it = kjts.iterator(); + while(it.hasNext()) { + KeYJavaType kjt = (KeYJavaType) it.next(); + if(!(kjt.getJavaType() instanceof ClassDeclaration + || kjt.getJavaType() instanceof InterfaceDeclaration)) { + it.remove(); + } + } + + //sort classes alphabetically + Object[] kjtsarr = kjts.toArray(); + Arrays.sort(kjtsarr, new Comparator() { + public int compare(Object o1, Object o2) { + KeYJavaType kjt1 = (KeYJavaType)o1; + KeYJavaType kjt2 = (KeYJavaType)o2; + return kjt1.getFullName().compareTo(kjt2.getFullName()); + } + }); + + //build tree + DefaultMutableTreeNode rootNode + = new DefaultMutableTreeNode(new Entry("")); + for(int i = 0; i < kjtsarr.length; i++) { + KeYJavaType kjt = (KeYJavaType)(kjtsarr[i]); + insertIntoTree(rootNode, kjt, addOperations, services); + } + + return rootNode; + } + + + private void open(KeYJavaType kjt) { + //get tree path + Vector pathVector = new Vector(); + + String fullClassName = kjt.getFullName(); + int length = fullClassName.length(); + int index = -1; + DefaultMutableTreeNode node + = (DefaultMutableTreeNode) getModel().getRoot(); + assert node != null; + do { + //save current node + pathVector.add(node); + + //get next part of the name + int lastIndex = index; + index = fullClassName.indexOf(".", ++index); + if(index == -1) { + index = length; + } + String namePart = fullClassName.substring(lastIndex + 1, index); + + //get child node, go down to it + DefaultMutableTreeNode childNode = getChildByString(node, namePart); + assert childNode != null; + node = childNode; + } while(index != length); + + TreePath incompletePath = new TreePath(pathVector.toArray()); + TreePath path = incompletePath.pathByAddingChild(node); + + expandPath(incompletePath); + setSelectionRow(getRowForPath(path)); + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public DefaultMutableTreeNode getRootNode() { + return (DefaultMutableTreeNode) getModel().getRoot(); + } + + + public DefaultMutableTreeNode getSelectedNode() { + TreePath path = getSelectionPath(); + return path != null + ? (DefaultMutableTreeNode) path.getLastPathComponent() + : null; + } + + + public Entry getSelectedEntry() { + DefaultMutableTreeNode node = getSelectedNode(); + return node != null ? (Entry) node.getUserObject() : null; + } + + + + //------------------------------------------------------------------------- + //inner classes + //------------------------------------------------------------------------- + + static class Entry { + public final String string; + public KeYJavaType kjt = null; + public ProgramMethod pm = null; + public int numMembers = 0; + public int numSelectedMembers = 0; + + public Entry(String string) { + this.string = string; + } + + public String toString() { + return string; + } + } +} diff --git a/system/de/uka/ilkd/key/gui/ComputeSpecificationView.java b/system/de/uka/ilkd/key/gui/ComputeSpecificationView.java index 56e50aec15d..de3b68c326f 100644 --- a/system/de/uka/ilkd/key/gui/ComputeSpecificationView.java +++ b/system/de/uka/ilkd/key/gui/ComputeSpecificationView.java @@ -32,7 +32,7 @@ * * @author André Platzer * @version 1.1, 2003-02-01 - * @version-revision $Revision: 1.14.1.1.2.1.2.4.1.1 $, $Date: Tue, 26 Jun 2007 14:56:17 +0200 $ + * @version-revision $Revision: 1.14.1.1.2.1.2.4.1.2 $, $Date: Fri, 20 Jul 2007 10:11:30 +0200 $ * @see de.uka.ilkd.key.cspec.ComputeSpecification */ public class ComputeSpecificationView { @@ -102,7 +102,7 @@ public static JMenuItem createOptionMenuItems() { * A facade for the user-interface, displaying the computed * specification of a program. * @param mediator the KeY-mediator containing the specification construction proof. - * @see de.uka.ilkd.key.casetool.FunctionalityOnModel#computeSpecification(ReprModelMethod) + * @see de.uka.ilkd.key.casetool.together.FunctionalityOnModel#computeSpecification(ReprModelMethod) */ public static final void show(KeYMediator mediator) { try{ diff --git a/system/de/uka/ilkd/key/gui/ContractConfigurator.java b/system/de/uka/ilkd/key/gui/ContractConfigurator.java new file mode 100644 index 00000000000..52ae39d8958 --- /dev/null +++ b/system/de/uka/ilkd/key/gui/ContractConfigurator.java @@ -0,0 +1,234 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.gui; + +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.KeyStroke; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.logic.op.Modality; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.proof.mgt.ContractWithInvs; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; + + +public class ContractConfigurator extends JDialog { + + private OperationContractSelectionPanel contractPanel; + private ClassInvariantSelectionPanel assumedInvPanel; + private ClassInvariantSelectionPanel ensuredInvPanel; + private JButton okButton; + private JButton cancelButton; + + private boolean successful = false; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + /** + * Helper for constructors. + */ + private void init(Services services, + ProgramMethod pm, + Modality modality, + boolean allowContract, + boolean allowAssumedInvs, + boolean allowEnsuredInvs) { + assert allowContract || allowAssumedInvs || allowEnsuredInvs; + + JTabbedPane tabbedPane = new JTabbedPane(); + + //create contract panel + if(allowContract) { + contractPanel = new OperationContractSelectionPanel(services, + pm, + modality); + contractPanel.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e){ + if(e.getClickCount() == 2){ + okButton.doClick(); + } + } + }); + tabbedPane.addTab("Contract", contractPanel); + } + + //create assumed inv panel + if(allowAssumedInvs) { + assumedInvPanel + = new ClassInvariantSelectionPanel(services, + false, + pm.getContainerType(), + true); + tabbedPane.addTab("Assumed Invariants", assumedInvPanel); + } + + //create ensured inv panel + if(allowEnsuredInvs) { + ensuredInvPanel + = new ClassInvariantSelectionPanel(services, + false, + pm.getContainerType(), + false); + tabbedPane.addTab("Ensured Invariants", ensuredInvPanel); + } + tabbedPane.setPreferredSize(new Dimension(800, 500)); + getContentPane().add(tabbedPane); + + //create button panel + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5)); + Dimension buttonDim = new Dimension(100, 27); + getContentPane().add(buttonPanel); + + //create "ok" button + okButton = new JButton("OK"); + okButton.setPreferredSize(buttonDim); + okButton.setMinimumSize(buttonDim); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + successful = true; + setVisible(false); + } + }); + buttonPanel.add(okButton); + getRootPane().setDefaultButton(okButton); + + //create "cancel" button + cancelButton = new JButton("Cancel"); + cancelButton.setPreferredSize(buttonDim); + cancelButton.setMinimumSize(buttonDim); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + successful = false; + setVisible(false); + } + }); + buttonPanel.add(cancelButton); + ActionListener escapeListener = new ActionListener() { + public void actionPerformed(ActionEvent event) { + if(event.getActionCommand().equals("ESC")) { + cancelButton.doClick(); + } + } + }; + cancelButton.registerKeyboardAction( + escapeListener, + "ESC", + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JButton.WHEN_IN_FOCUSED_WINDOW); + + + //show + getContentPane().setLayout(new BoxLayout(getContentPane(), + BoxLayout.Y_AXIS)); + pack(); + setLocation(70, 70); + setVisible(true); + } + + + public ContractConfigurator(JDialog owner, + Services services, + ProgramMethod pm, + Modality modality, + boolean allowContract, + boolean allowAssumedInvs, + boolean allowEnsuredInvs) { + super(owner, "Contract Configurator", true); + init(services, + pm, + modality, + allowContract, + allowAssumedInvs, + allowEnsuredInvs); + } + + + public ContractConfigurator(Frame owner, + Services services, + ProgramMethod pm, + Modality modality, + boolean allowContract, + boolean allowAssumedInvs, + boolean allowEnsuredInvs) { + super(owner, "Contract Configurator", true); + init(services, + pm, + modality, + allowContract, + allowAssumedInvs, + allowEnsuredInvs); + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + /** + * Tells whether the user clicked "ok". + */ + public boolean wasSuccessful() { + return successful; + } + + + /** + * Returns the selected contract. + */ + public OperationContract getContract() { + return contractPanel.getOperationContract(); + } + + + /** + * Returns the selected set of assumed invariants. + */ + public SetOfClassInvariant getAssumedInvs() { + return assumedInvPanel.getClassInvariants(); + } + + + /** + * Returns the selected set of ensured invariants. + */ + public SetOfClassInvariant getEnsuredInvs() { + return ensuredInvPanel.getClassInvariants(); + } + + + /** + * Returns the selected tuple (contract, assumed invs, ensured invs). + */ + public ContractWithInvs getContractWithInvs() { + return new ContractWithInvs(getContract(), + getAssumedInvs(), + getEnsuredInvs()); + } +} diff --git a/system/de/uka/ilkd/key/gui/ContractSelectionPanel.java b/system/de/uka/ilkd/key/gui/ContractSelectionPanel.java deleted file mode 100644 index 6fa8ea7d037..00000000000 --- a/system/de/uka/ilkd/key/gui/ContractSelectionPanel.java +++ /dev/null @@ -1,166 +0,0 @@ -package de.uka.ilkd.key.gui; - -import java.awt.*; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import javax.swing.*; -import javax.swing.border.Border; -import javax.swing.border.TitledBorder; -import javax.swing.event.ListSelectionListener; - -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.ContractSet; -import de.uka.ilkd.key.proof.mgt.OldOperationContract; -import de.uka.ilkd.key.proof.mgt.ProofStatus; - -public class ContractSelectionPanel extends JPanel { - - static final Icon keyIcon = IconFactory.keyHole(20,20); - static final Icon keyClosedIcon = IconFactory.keyHoleClosed(20,20); - static final Icon keyAlmostClosedIcon = IconFactory.keyHoleAlmostClosed(20,20); - - - private JList list; - private JComponent comp; - - public ContractSelectionPanel(ContractSet ctSet, boolean dlchooser) { - if(ctSet != null) - list = new JList(sortContracts(ctSet)); - else - list = new JList(); - list.setSelectedIndex(0); - if(!dlchooser) { - list.setPreferredSize(new Dimension(800, list.getHeight())); - comp = new JScrollPane(list); - }else{ - comp = list; - } - add(comp); - list.setCellRenderer(new ContractListCellRenderer()); - } - - public void setContracts(ContractSet ctSet) { - remove(comp); - list = new JList(sortContracts(ctSet)); - list.setSelectedIndex(0); - comp = list; - add(comp); - list.setCellRenderer(new ContractListCellRenderer()); - } - - private Object[] sortContracts(ContractSet ctSet) { - Object[] cl = ctSet.toArray(); - Arrays.sort(cl, new ContractComparator()); - return cl; - } - - public Contract getCurrentSelection() { - if (list.getSelectedIndex()<0) { - return null; - } - return (Contract) list.getSelectedValue(); - } - - public void addListSelectionListener(ListSelectionListener listener) { - list.addListSelectionListener(listener); - } - - - class ContractListCellRenderer extends DefaultListCellRenderer { - - JPanel panel; - JLabel text; - private Color selBgColor; - - public ContractListCellRenderer() { - setOpaque(true); - FlowLayout lay = new FlowLayout(); - lay.setAlignment(FlowLayout.LEFT); - panel = new JPanel(lay); - text = new JLabel(); - panel.add(text); - } - - public Component getListCellRendererComponent( - JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus) - { - if (value instanceof OldOperationContract) { - if (isSelected && selBgColor==null) { - Component sup = super.getListCellRendererComponent - (list, value, index, isSelected, cellHasFocus); - selBgColor = sup.getBackground(); - } - OldOperationContract mc = (OldOperationContract) value; - text.setText(mc.getHTMLText()); - panel.setBorder(new StatusTitledBorder(BorderFactory.createEtchedBorder(), - mc.getName(), value)); - text.setVerticalAlignment(SwingConstants.TOP); - if (isSelected) { - text.setBackground(selBgColor); - panel.setBackground(selBgColor); - } else { - text.setBackground(Color.white); - panel.setBackground(Color.white); - } - } else { - return super.getListCellRendererComponent( - list,value,index,isSelected,cellHasFocus); - } - return panel; - } - } - - class StatusTitledBorder extends TitledBorder { - - private Object value; - - StatusTitledBorder(Border b, String s, Object value) { - super(b,s); - this.value = value; - } - - - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - title = " "+title; - super.paintBorder(c, g, x, y, width, height); - List proofs = ((OldOperationContract)value).getProofs(); - Iterator it = proofs.iterator(); - while (it.hasNext()) { - ProofAggregate pl = (ProofAggregate) it.next(); - ProofStatus ps = pl.getStatus(); - x=x+6; - g.setColor(c.getBackground()); - g.fillRect(x, y, keyClosedIcon.getIconWidth(), - keyClosedIcon.getIconHeight()); - if (ps.getProofClosedButLemmasLeft()) { - keyAlmostClosedIcon.paintIcon(c, g, x, y); - } else if (ps.getProofClosed()) { - keyClosedIcon.paintIcon(c, g, x, y); - } else if (ps.getProofOpen()) { - keyIcon.paintIcon(c, g, x, y); - } - } - } - - } - - private class ContractComparator implements Comparator { - public int compare(Object o1, Object o2) { - if(!(o1 instanceof Contract & o2 instanceof Contract)) - return 0; - return ((Contract)o1).getName().compareTo(((Contract)o2).getName()); - } - } - - -} - - diff --git a/system/de/uka/ilkd/key/gui/DefaultContractConfigurator.java b/system/de/uka/ilkd/key/gui/DefaultContractConfigurator.java deleted file mode 100644 index 3d976d815c1..00000000000 --- a/system/de/uka/ilkd/key/gui/DefaultContractConfigurator.java +++ /dev/null @@ -1,229 +0,0 @@ -package de.uka.ilkd.key.gui; - -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Font; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -import javax.swing.*; -import javax.swing.border.TitledBorder; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; - -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.logic.op.ListOfProgramMethod; -import de.uka.ilkd.key.logic.op.Modality; -import de.uka.ilkd.key.proof.mgt.ContractSet; -import de.uka.ilkd.key.proof.mgt.OldOperationContract; -import de.uka.ilkd.key.proof.mgt.SpecificationRepository; -import de.uka.ilkd.key.rule.ContractConfigurator; -import de.uka.ilkd.key.speclang.IteratorOfClassInvariant; -import de.uka.ilkd.key.speclang.ListOfClassInvariant; -import de.uka.ilkd.key.speclang.SLListOfClassInvariant; - -public class DefaultContractConfigurator extends JDialog - implements ContractConfigurator { - - private SpecificationRepository repos; - private OldOperationContract base; - private Modality modality; - private ListOfClassInvariant preInvs = SLListOfClassInvariant.EMPTY_LIST; - private ListOfClassInvariant postInvs = SLListOfClassInvariant.EMPTY_LIST; - private ListOfProgramMethod programMethods; - private boolean successful; - private JEditorPane contractTextArea; - private boolean allowConfig; - - public DefaultContractConfigurator(String title, JFrame parent) { - super(parent, title, true); - } - - public void setSpecification(SpecificationRepository repos) { - this.repos = repos; - } - - public void setProgramMethods(ListOfProgramMethod pm) { - this.programMethods = pm; - } - - public void setModality(Modality modality) { - this.modality = modality; - } - - public void start() { - getContentPane().removeAll(); - ContractSet ctSet = repos.getContracts(programMethods, modality); - ModelMethod mm = ((OldOperationContract)ctSet.iterator().next()).getModelMethod(); - ModelClass mc = mm.getContainingClass(); - final ClassInvariantSelectionPanel selectionPanelPre - = new ClassInvariantSelectionPanel( - mc.getAllClasses(), - false, - mc, false); - final ClassInvariantSelectionPanel selectionPanelPost - = new ClassInvariantSelectionPanel( - mc.getAllClasses(), - false, - mc, false); - ContractSelectionPanel contractSelectionPanel - = new ContractSelectionPanel(ctSet, false); - - contractSelectionPanel.addListSelectionListener - (new ContractListSelectionListener(this)); - - JComponent tabs; - if (allowConfig) { - tabs = new JTabbedPane(); - ((JTabbedPane)tabs).addTab("Base Contract", new JScrollPane(contractSelectionPanel)); - ((JTabbedPane)tabs).addTab("Assumed Invariants", selectionPanelPre); - ((JTabbedPane)tabs).addTab("Ensured Invariants", selectionPanelPost); - } else { - tabs =new JScrollPane(contractSelectionPanel); - } - tabs.setPreferredSize(new Dimension(800, 500)); - getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); - - contractTextArea = new JEditorPane("text/html","Contract"); - contractTextArea.setEditable(false); - final Font contractTextAreaFont = contractTextArea.getFont().deriveFont(Font.PLAIN, 10); - contractTextArea.setFont(contractTextAreaFont); - JScrollPane scrollPane = new JScrollPane(contractTextArea); - scrollPane.setPreferredSize(new Dimension(200, 150)); - scrollPane.setBorder(new TitledBorder("Configured Contract")); - - JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, tabs, scrollPane); - splitPane.setResizeWeight(.75); - splitPane.setDividerLocation(.75); - splitPane.resetToPreferredSizes(); - getContentPane().add(splitPane); - - JPanel buttons = new JPanel(); - buttons.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5)); - buttons.setPreferredSize(new Dimension(400, 40)); - - Dimension buttonDim = new Dimension(95, 25); - - // create "ok" button - JButton okButton = new JButton("OK"); - okButton.setPreferredSize(buttonDim); - okButton.setMinimumSize(buttonDim); - okButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - successful = true; - setVisible(false); - } - }); - buttons.add(okButton); - getRootPane().setDefaultButton(okButton); - - //create "cancel" button - JButton cancelButton = new JButton("Cancel"); - cancelButton.setPreferredSize(buttonDim); - cancelButton.setMinimumSize(buttonDim); - cancelButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - setVisible(false); - } - }); - buttons.add(cancelButton); - - getContentPane().add(buttons); - - selectionPanelPre.addInvariantSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { - setPreInvs(selectionPanelPre.getClassInvariants()); - } - }); - - selectionPanelPost.addInvariantSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { - setPostInvs(selectionPanelPost.getClassInvariants()); - } - }); - - updateContractWithBase((OldOperationContract)contractSelectionPanel.getCurrentSelection()); - setPostInvs(selectionPanelPost.getClassInvariants()); - setPreInvs(selectionPanelPre.getClassInvariants()); - - pack(); - setVisible(true); - } - - public OldOperationContract getMethodContract() { - return base; - } - - public ListOfClassInvariant getPreInvariants() { - return preInvs; - } - - public ListOfClassInvariant getPostInvariants() { - return postInvs; - } - - public boolean wasSuccessful() { - return successful; - } - - public void updateDisplay() { - StringBuffer sb = new StringBuffer(); - sb.append("

pre: "+ base.getPreText()); - IteratorOfClassInvariant it = preInvs.iterator(); - while (it.hasNext()) { - sb.append("
pre: "); - sb.append(it.next().toString()); - } - sb.append("
modifies: "+base.getModifiesText()); - sb.append("
post: "+ base.getPostText()); - it = postInvs.iterator(); - while (it.hasNext()) { - sb.append("
post: "); - sb.append(it.next().toString()); - } - sb.append("

"); - contractTextArea.setText(sb.toString()); - repaint(); - } - - public void updateContractWithBase(OldOperationContract mc) { - base = mc; - updateDisplay(); - } - - public void setPreInvs(ListOfClassInvariant preInvs) { - this.preInvs = preInvs; - updateDisplay(); - } - - public void setPostInvs(ListOfClassInvariant postInvs) { - this.postInvs = postInvs; - updateDisplay(); - } - - public void clear() { - //do nothing, we create an instance of this class each time - } - - public void allowConfiguration(boolean allowConfig) { - this.allowConfig = allowConfig; - } - - class ContractListSelectionListener implements ListSelectionListener { - - private DefaultContractConfigurator conf; - - ContractListSelectionListener(DefaultContractConfigurator conf) { - this.conf = conf; - } - - public void valueChanged(ListSelectionEvent e) { - conf.updateContractWithBase((OldOperationContract) - ((JList)e.getSource()).getSelectedValue()); - } - - - } - -} diff --git a/system/de/uka/ilkd/key/gui/ExceptionDialog.java b/system/de/uka/ilkd/key/gui/ExceptionDialog.java index 61d79f33ee3..b75cb758d16 100644 --- a/system/de/uka/ilkd/key/gui/ExceptionDialog.java +++ b/system/de/uka/ilkd/key/gui/ExceptionDialog.java @@ -27,6 +27,7 @@ import de.uka.ilkd.key.parser.Location; import de.uka.ilkd.key.parser.ParserException; import de.uka.ilkd.key.proof.SVInstantiationExceptionWithPosition; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; import de.uka.ilkd.key.util.ExtList; public class ExceptionDialog extends JDialog { @@ -47,13 +48,24 @@ private Location getLocation(Object exc){ ((antlr.RecognitionException) exc).getColumn()); } else if (exc instanceof ParserException) { location = ((ParserException) exc).getLocation(); - } else { - if (exc instanceof SVInstantiationExceptionWithPosition) { + } else if (exc instanceof SLTranslationException) { + SLTranslationException ste = (SLTranslationException) exc; + location = new Location(ste.getFileName(), + ste.getLine(), + ste.getColumn()); + } else if (exc instanceof RuntimeException + && ((RuntimeException) exc).getCause() + instanceof SLTranslationException) { + SLTranslationException ste + = (SLTranslationException) ((RuntimeException) exc).getCause(); + location = new Location(ste.getFileName(), + ste.getLine(), + ste.getColumn()); + } else if (exc instanceof SVInstantiationExceptionWithPosition) { location = new Location(null, ((SVInstantiationExceptionWithPosition)exc).getRow(), ((SVInstantiationExceptionWithPosition)exc).getColumn()); - } - } + } return location; } diff --git a/system/de/uka/ilkd/key/gui/IconFactory.java b/system/de/uka/ilkd/key/gui/IconFactory.java index df3dcaed037..9995f6e9e93 100644 --- a/system/de/uka/ilkd/key/gui/IconFactory.java +++ b/system/de/uka/ilkd/key/gui/IconFactory.java @@ -52,6 +52,8 @@ private IconFactory() {} getImage("images/toolbar/decisionProcedureSimplify.png"); private static Image junit = getImage("images/toolbar/junit_logo.png"); + private static Image jml = getImage("images/toolbar/jml.png"); + private static Image uml = getImage("images/toolbar/uml.png"); private static Image openKeYFile = getImage("images/toolbar/open.png"); @@ -126,6 +128,14 @@ public static ImageIcon simplifyLogo(int size) { public static ImageIcon junitLogo(int size) { return scaleIcon(junit, size, size); } + + public static ImageIcon jmlLogo(int size) { + return scaleIcon(jml, size, size); + } + + public static ImageIcon umlLogo(int size) { + return scaleIcon(uml, size, size); + } public static ImageIcon icsLogo(int size) { return scaleIcon(decisionProcedureICS, size, size); diff --git a/system/de/uka/ilkd/key/gui/JMLEclipseAdapter.java b/system/de/uka/ilkd/key/gui/JMLEclipseAdapter.java index 181697fb036..e4b8e738800 100644 --- a/system/de/uka/ilkd/key/gui/JMLEclipseAdapter.java +++ b/system/de/uka/ilkd/key/gui/JMLEclipseAdapter.java @@ -18,12 +18,11 @@ import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; import de.uka.ilkd.key.java.abstraction.SLListOfKeYJavaType; -import de.uka.ilkd.key.jml.*; import de.uka.ilkd.key.logic.op.ProgramMethod; import de.uka.ilkd.key.proof.init.*; -public class JMLEclipseAdapter implements JMLPOAndSpecProvider{ - +public class JMLEclipseAdapter { +/*TODO KeYMediator mediator; Services services; String javaPath; @@ -115,8 +114,9 @@ private ListOfKeYJavaType getSignature(ListOfString l){ return result; } + public void setMainVisible(boolean mainVisible) { this.mainVisible = mainVisible; } - + */ } diff --git a/system/de/uka/ilkd/key/gui/JMLPOAndSpecProvider.java b/system/de/uka/ilkd/key/gui/JMLPOAndSpecProvider.java deleted file mode 100644 index 50ce47e16f1..00000000000 --- a/system/de/uka/ilkd/key/gui/JMLPOAndSpecProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.gui; - -import java.util.Vector; - -import de.uka.ilkd.key.collection.ListOfString; -import de.uka.ilkd.key.jml.JMLSpec; - -public interface JMLPOAndSpecProvider{ - - Vector getMethodSpecs(String className, String methodName, - ListOfString signature); - - /** - * Creates a proof obligation for spec. - * @param allInv true iff it should be assumed that every invariant of - * every class holds for all existing object in the prestate of the method - * that is specified by spec. - * @param invPost if true, the applicable invariants are added to the - * postcondition. - * @param assignable if true, a proof obligation for the assignable clause - * of spec is created. - */ - void createPOandStartProver(JMLSpec spec, boolean allInv, boolean invPost, - boolean assignable); - -} diff --git a/system/de/uka/ilkd/key/gui/JMLSpecBrowser.java b/system/de/uka/ilkd/key/gui/JMLSpecBrowser.java deleted file mode 100644 index 6956b8c1cac..00000000000 --- a/system/de/uka/ilkd/key/gui/JMLSpecBrowser.java +++ /dev/null @@ -1,580 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.gui; - -import java.awt.Color; -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Vector; - -import javax.swing.*; -import javax.swing.border.TitledBorder; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.MutableTreeNode; -import javax.swing.tree.TreeModel; - -import de.uka.ilkd.key.java.JavaInfo; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.declaration.InterfaceDeclaration; -import de.uka.ilkd.key.java.declaration.MethodDeclaration; -import de.uka.ilkd.key.java.recoderext.ClassInitializeMethodBuilder; -import de.uka.ilkd.key.jml.*; -import de.uka.ilkd.key.logic.NamespaceSet; -import de.uka.ilkd.key.logic.op.IteratorOfProgramMethod; -import de.uka.ilkd.key.logic.op.ListOfProgramMethod; -import de.uka.ilkd.key.logic.op.ProgramMethod; -import de.uka.ilkd.key.proof.init.*; - - -public class JMLSpecBrowser extends JDialog { - - /** the package hierarchy as a tree */ - private JTree packageHierarchy; - - private JList methodList; - private JList poList; - - private JCheckBox allInv; - private JCheckBox invPost; - - private Implementation2SpecMap ism; - - - /** true if the JMLSpecBrowser was invoked by Main and we already have - * a proofenvironment for the javaModel we are dealing with. - */ - private boolean envMode = true; - - private KeYMediator mediator; - private Services services; - - private JMLProofOblInput poi = null; - - private String javaPath = ""; - - private Object[] emptyArray = new Object[0]; - - private TreeModel treeModel; - - private static HashMap ism2browser = new HashMap(); - - private boolean inheritedMethods = false; - - //the selected class - private KeYJavaType classType = null; - - private JMLSpecBrowser(KeYMediator mediator) { - super(new JFrame(), "JML Specification Browser", true); - this.services = mediator.getServices(); - ism = services.getImplementation2SpecMap(); - this.mediator = mediator; - this.javaPath = mediator.getProof().env().getJavaModel().getModelDir(); - buildTreeModel(); - layoutJMLSpecBrowser(); - pack(); - setLocation(70, 70); - setVisible(true); - } - - public JMLSpecBrowser(Services services, String javaPath) { - super(new JFrame(), "JML Specification Browser", true); - this.services = services; - ism = services.getImplementation2SpecMap(); - this.javaPath = javaPath; - envMode = false; - buildTreeModel(); - layoutJMLSpecBrowser(); - pack(); - setLocation(70, 70); - setVisible(true); - ism2browser.put(services.getImplementation2SpecMap(), this); - } - - public static JMLSpecBrowser getJMLSpecBrowser(KeYMediator mediator){ - JMLSpecBrowser browser = (JMLSpecBrowser)ism2browser. - get(mediator.getServices().getImplementation2SpecMap()); - if(browser == null) { - browser = new JMLSpecBrowser(mediator); - ism2browser.put(mediator.getServices(). - getImplementation2SpecMap(), - browser); - } - browser.envMode = true; - browser.mediator = mediator; - browser.setModal(true); - browser.setVisible(true); - return browser; - } - - /** - * builds a TreeModel from the package structure of the Java model. - */ - private void buildTreeModel(){ - JavaInfo ji = services.getJavaInfo(); - HashMap package2Node = new HashMap(); - DefaultMutableTreeNode root = new DefaultMutableTreeNode(""); -// ism.checkPurity(); - - Iterator it = ism.getAllClasses().iterator(); - while(it.hasNext()){ - KeYJavaType kjt = (KeYJavaType) it.next(); - String name = ji.getFullName(kjt); - if(name.lastIndexOf(".") != -1){ - DefaultMutableTreeNode parent = - treeHelper(name.substring(0, name.lastIndexOf(".")), - package2Node, root); - parent.add(new DefaultMutableTreeNode(kjt){ - public String toString(){ - final String sortName = - ((KeYJavaType) userObject).getSort().toString(); - return sortName.substring(sortName.lastIndexOf(".")+1); - } - }); - }else{ - root.add(new DefaultMutableTreeNode(kjt){ - public String toString(){ - return ((KeYJavaType) userObject).getSort(). - toString(); - } - }); - } - } - sortTree(root); - if(root.getChildCount() == 1){ - treeModel = new DefaultTreeModel(root.getFirstChild()); - }else{ - treeModel = new DefaultTreeModel(root); - } - packageHierarchy = new JTree(treeModel); - packageHierarchy.addTreeSelectionListener( - new GUIPackageTreeSelectionListener()); - } - - private void sortTree(DefaultMutableTreeNode root){ - for(int i = 0; i 0){ - changed = true; - root.insert((MutableTreeNode)root.getChildAt(i+1), i); - } - } - } - } - - private DefaultMutableTreeNode treeHelper(String pname, HashMap p2n, - DefaultMutableTreeNode root){ - if(p2n.get(pname) != null){ - return (DefaultMutableTreeNode) p2n.get(pname); - }else{ - final int dot = pname.lastIndexOf("."); - DefaultMutableTreeNode node = - new DefaultMutableTreeNode(pname){ - public String toString(){ - return userObject.toString().substring(dot+1); - } - }; - p2n.put(pname, node); - if(dot != -1){ - DefaultMutableTreeNode parent = - treeHelper(pname.substring(0, dot), - p2n, root); - parent.add(node); - }else{ - root.add(node); - } - return node; - } - } - - /** layout */ - protected void layoutJMLSpecBrowser() { - JScrollPane classListScroll = new - JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - classListScroll.getViewport().setView(packageHierarchy); - classListScroll.setBorder(new TitledBorder("Classes")); - - methodList = new JList(); - JPanel methodPanel = new JPanel(); - methodPanel.setLayout(new BoxLayout(methodPanel, BoxLayout.PAGE_AXIS)); - final JButton hide = - new JButton(inheritedMethods ? "Hide Inherited Methods" : - "Show Inherited Methods"); - hide.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - inheritedMethods = !inheritedMethods; - hide.setText(inheritedMethods ? "Hide Inherited Methods" : - "Show Inherited Methods"); - updateMethodList(classType); - } - - }); - methodList.addListSelectionListener(new ListSelectionListener() { - public void valueChanged(ListSelectionEvent e) { - setPOList(); - }}); - methodList.setCellRenderer(new DefaultListCellRenderer(){ - public Component getListCellRendererComponent( - JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus) - { - if(value != null){ - ProgramMethod pm = (ProgramMethod) value; - MethodDeclaration md = pm.getMethodDeclaration(); - String params = md.getParameters().toString(); - setText((md.getTypeReference() == null ? "void" : - md.getTypeReference().getName())+ - " "+md.getFullName()+"("+ - params.substring(1,params.length()-1)+")"); - if (isSelected) { - setBackground(list.getSelectionBackground()); - setForeground(list.getSelectionForeground()); - } - else { - setBackground(list.getBackground()); - setForeground(list.getForeground()); - } - setEnabled(list.isEnabled()); - setFont(list.getFont()); - setOpaque(true); - } - return this; - } - }); - JScrollPane methodListScroll = new - JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - methodListScroll.getViewport().setView(methodList); - methodListScroll.setBorder(new TitledBorder("Methods")); - - poList = new JList(); - - poList.setCellRenderer(new TextAreaRenderer()); - JScrollPane poListScroll = new - JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - poListScroll.getViewport().setView(poList); - poListScroll.setBorder(new TitledBorder("Proof Obligations")); - - JPanel buttonPanel = new JPanel(); - - JPanel optionPanel = new JPanel(); - optionPanel.setLayout(new BoxLayout(optionPanel, BoxLayout.Y_AXIS)); - buttonPanel.add(optionPanel); - - allInv = new JCheckBox("Use all applicable invariants"); - allInv.setToolTipText("
"+
-			      "If selected, the POs change to that effect,
"+ - "that every invariant of every class is added\n"+ - "to the precondition in the case of method\n"+ - "specification POs, or to the pre- and\n"+ - "postcondition in the case of invariant POs.\n "+ - " This changes the semantics of the invariant\n"+ - "PO to that extend that it now expresses that\n"+ - "the method preserves every invariant of every"+ - "\nexisting object and type.\n"+ - " The effect on method spec POs is that they\n"+ - "are then reflecting the fact that a method\n"+ - "can assume all invariants of every existing\n"+ - "object and type to hold in its prestate.\n"+ - "Assuming all invariants to hold in the\n"+ - "prestate of a certain method is often not\n"+ - "necessary when proving its specification!"+ - "
"); - optionPanel.add(allInv); - allInv.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - setPOList(); - } - }); - - invPost = new JCheckBox("Add invariants to postcondition"); - invPost.setToolTipText("
"+
-			       "If selected the history constraints and\n"+
-			       "invariants of the current class are added\n"+
-			       "to the postcondition of the method speccase PO\n"+
-			       "(this is the case if \"Use all applicable\n"+
-			       "invariants\" is not selected otherwise also\n"+
-			       "the invariants of every other class are added)"+
-			       "
"); - optionPanel.add(invPost); - - JButton lo = - new JButton("Load Proof Obligation"); - lo.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if(poList.getSelectedValue() == null){ - JOptionPane.showMessageDialog( - null, "Please select the PO you wish to load!", - "Which Proof Obligation?", - JOptionPane.ERROR_MESSAGE); - }else{ - createProofObl(); - setVisible(false); - setModal(false); -// dispose(); - } - } - }); - buttonPanel.add(lo); - JButton cancel = new JButton("Cancel"); - cancel.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - setVisible(false); - setModal(false); -// dispose(); - } - }); - buttonPanel.add(cancel); - - java.awt.Dimension paneDim = new java.awt.Dimension(220, 400); - classListScroll.setPreferredSize(paneDim); - classListScroll.setMinimumSize(paneDim); - methodListScroll.setMinimumSize(paneDim); - methodListScroll.setPreferredSize(paneDim); - paneDim = new java.awt.Dimension(370, 400); - poListScroll.setMinimumSize(paneDim); - poListScroll.setPreferredSize(paneDim); - methodPanel.add(hide); - methodPanel.add(methodListScroll); - - JPanel listPanel=new JPanel(); - listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.X_AXIS)); - listPanel.add(classListScroll); - listPanel.add(methodPanel); - listPanel.add(poListScroll); - - getContentPane().setLayout(new BoxLayout(getContentPane(), - BoxLayout.Y_AXIS)); - getContentPane().add(listPanel); - getContentPane().add(buttonPanel); - } - - /** - * Sets a new proof obligation list (when the selected method has changed - * for example) - */ - private void setPOList(){ - ProgramMethod m = (ProgramMethod) methodList.getSelectedValue(); - poList.setListData(emptyArray); - if(m != null && !m.isAbstract() && - !(classType.getJavaType() instanceof InterfaceDeclaration)){ - SetOfJMLMethodSpec specs = - ism.getSpecsForMethod(m); - JMLClassSpec cSpec = ism.getSpecForClass(classType); - if(specs != null){ - specs = specs.union(ism.getInheritedMethodSpecs(m, classType)); - }else{ - specs = ism.getInheritedMethodSpecs(m, classType); - } - IteratorOfJMLMethodSpec mit = specs.iterator(); - specs = SetAsListOfJMLMethodSpec.EMPTY_SET; - boolean pureFound = false; - boolean pureInh = false; - while(mit.hasNext()){ - JMLMethodSpec s = mit.next(); - if(s instanceof JMLPuritySpec){ - pureFound = true; - } - if(services.getJavaInfo().getKeYJavaType( - s.getClassDeclaration()) == classType){ - specs = specs.add(s); - } - } - if(pureInh && !pureFound){ - specs = specs.add( - new JMLPuritySpec(m, services, - UsefulTools.buildParamNamespace(m.getMethodDeclaration()), - new LinkedHashMap(), - ism.getSpecForClass(classType), - new NamespaceSet(), javaPath)); - } - if(specs != SetAsListOfJMLMethodSpec.EMPTY_SET || cSpec != null){ - Vector specVector = new Vector(); - if(specs != null){ - IteratorOfJMLMethodSpec it = specs.iterator(); - while(it.hasNext()){ - JMLMethodSpec mSpec = it.next(); - specVector.add(mSpec); - if(mSpec.replaceModelFieldsInAssignable() != null && - !JMLMethodSpec.EVERYTHING. - equals(mSpec.getAssignableMode()) && - // !mSpec.containsQuantifiedAssignableLocation() && - mSpec.isValid()){ - specVector.add(new AssignableCheckProofOblInput( - mSpec, javaPath)); - } - } - } - if(cSpec != null && (cSpec.containsInvOrConst() || - allInv.isSelected())){ - specVector.add(cSpec); - } - poList.setListData(specVector); - } - } - } - - /** - * creates a JMLProofOblInput and starts the proofer. - */ - private void createProofObl(){ - Object spec = poList.getSelectedValue(); - if(spec instanceof JMLMethodSpec){ - if(invPost.isSelected()){ - poi = new JMLPostAndInvPO((JMLMethodSpec) spec, javaPath, - allInv.isSelected()); - }else{ - poi = new JMLPostPO((JMLMethodSpec) spec, javaPath, - allInv.isSelected()); - } - }else if(spec instanceof JMLClassSpec){ - poi = new JMLInvPO((JMLClassSpec) spec, - (ProgramMethod) - methodList.getSelectedValue(), - javaPath, allInv.isSelected()); - }else if(spec instanceof AssignableCheckProofOblInput){ - poi = (AssignableCheckProofOblInput) spec; - ((AssignableCheckProofOblInput) poi).setAllInvariants( - allInv.isSelected()); - } - if(envMode){ - ProblemInitializer pi = new ProblemInitializer(Main.getInstance()); - try { - pi.startProver(mediator.getProof().env(), poi); - } catch(ProofInputException e) { - //too bad - } - } - } - - public JMLProofOblInput getPOI(){ - return poi; - } - - class GUIPackageTreeSelectionListener implements TreeSelectionListener, - java.io.Serializable { - /** - * Sets a new methodlist if the selection in the package tree has - * changed and the selected value is a class. - */ - public void valueChanged(TreeSelectionEvent e) { - Object o = - ((DefaultMutableTreeNode) e.getPath().getLastPathComponent()). - getUserObject(); - if(o instanceof KeYJavaType){ - updateMethodList((KeYJavaType) o); - } - } - } - - private void updateMethodList(KeYJavaType kjt){ - if(kjt != null){ - classType = kjt; - ListOfProgramMethod l = inheritedMethods ? - services.getJavaInfo().getAllProgramMethods(classType) : - services.getJavaInfo().getKeYProgModelInfo(). - getAllProgramMethodsLocallyDeclared(classType); - Vector mVector = new Vector(); - IteratorOfProgramMethod it = l.iterator(); - while(it.hasNext()){ - ProgramMethod pm = it.next(); - MethodDeclaration md = pm.getMethodDeclaration(); - if(!md.getName().startsWith("<") || - md.getName().equals(ClassInitializeMethodBuilder. - CLASS_INITIALIZE_IDENTIFIER)){ - addOrdered(mVector, pm); - } - } - ListOfProgramMethod ml = services.getJavaInfo(). - getKeYProgModelInfo().getConstructors(classType); - IteratorOfProgramMethod mit = ml.iterator(); - while(mit.hasNext()){ - addOrdered(mVector, mit.next()); - } - methodList.setListData(mVector); - } - } - - - private void addOrdered(Vector v, ProgramMethod m){ - for(int i = 0; i 0) { - setSelectedIndex(0); - } - setModel(methodContractListModel); - setCellRenderer(new IconCellRenderer()); - addMouseListener(mouseListener); - updateUI(); - } - - - public void updateUI() { - super.updateUI(); - Font myFont = UIManager.getFont(Config.KEY_FONT_GOAL_LIST_VIEW); - if (myFont != null) { - setFont(myFont); - } else { - Debug.out("goallist: Warning: Use standard font. Could not find font:", - Config.KEY_FONT_GOAL_LIST_VIEW); - } - } - - - public de.uka.ilkd.key.proof.ProofAggregate getProofForCurrentContract() { - if (getSelectedIndex()<0) { - return null; - } - Contract mC = (Contract) - methodContractListModel.getElementAt(getSelectedIndex()); - List mCL = mC.getProofs(); - if (mCL.size()!= 0) { - return (de.uka.ilkd.key.proof.ProofAggregate) mCL.get(0); - } - return null; - } - - public Contract getCurrentContract() { - if (getSelectedIndex()<0) { - return null; - } - return (Contract) - methodContractListModel.getElementAt(getSelectedIndex()); - - } - - - public static Component makeMethodContractDisplay(OldOperationContract mc, - JPanel panel, - JTextArea text, - JPanel statusPanel, - Color c) { - String mcString = mc.toString(); - text.setText(mcString); - List proofs = mc.getProofs(); - Iterator it = proofs.iterator(); - statusPanel.removeAll(); - while (it.hasNext()) { - ProofAggregate pl = (ProofAggregate) it.next(); - ProofStatus ps = pl.getStatus(); - JLabel lab= null; - if (ps!=null) { - if (ps.getProofClosed()) { - lab = keyClosedIcon; - } - if (ps.getProofClosedButLemmasLeft()) { - lab = keyAlmostClosedIcon; - } - if (ps.getProofOpen()) { - lab = keyIcon; - } - } - statusPanel.add(lab); - } - text.setBackground(c); - panel.setBackground(c); - statusPanel.setBackground(c); - return panel; - } - - - //INNER CLASSES - - - static class MethodContractListModel extends AbstractListModel { - - private List ctList; - - MethodContractListModel(List ctList) { - this.ctList=ctList; - } - - public int getSize() { - return ctList.size(); - } - - public Object getElementAt(int i) { - return ctList.get(i); - } - - - class MethodContractListProofTreeListener extends ProofTreeAdapter - implements java.io.Serializable { - - /** invoked if all goals of the proof are closed - */ -// public void proofClosed(ProofTreeEvent e) { -// setAttentive(true); -// clear(); -// } - - } - } - - class IconCellRenderer extends DefaultListCellRenderer - implements ListCellRenderer, - java.io.Serializable { - - JPanel panel; - JPanel statusPanel; - JTextArea text; - private Color selBgColor; - - - public IconCellRenderer() { - FlowLayout lay = new FlowLayout(); - lay.setAlignment(FlowLayout.LEFT); - panel = new JPanel(lay); - statusPanel = new JPanel(lay); - text = new JTextArea(); - MethodContractList.this.setToolTipText("Method Contract"); - panel.add(text); - panel.add(statusPanel); - text.setEditable(false); - text.setCaretPosition(0); - } - - public Component getListCellRendererComponent - (JList list, - Object value, // value to display - int index, // cell index - boolean isSelected, // is the cell selected - boolean cellHasFocus) // the list and the cell have the focus - { - if (value instanceof OldOperationContract) { - if (isSelected && selBgColor==null) { - Component sup = super.getListCellRendererComponent - (list, value, index, isSelected, cellHasFocus); - selBgColor = sup.getBackground(); - } - OldOperationContract mc = (OldOperationContract) value; - return makeMethodContractDisplay(mc, panel, text, statusPanel, - isSelected ? selBgColor - : Color.white); - } else { - return super.getListCellRendererComponent(list, value, - index, isSelected, - cellHasFocus); - } - } - - - } - -} diff --git a/system/de/uka/ilkd/key/gui/OperationContractSelectionPanel.java b/system/de/uka/ilkd/key/gui/OperationContractSelectionPanel.java new file mode 100644 index 00000000000..f9d560e797b --- /dev/null +++ b/system/de/uka/ilkd/key/gui/OperationContractSelectionPanel.java @@ -0,0 +1,175 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.gui; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.event.MouseListener; + +import javax.swing.BorderFactory; +import javax.swing.DefaultListCellRenderer; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; +import javax.swing.SwingConstants; +import javax.swing.border.TitledBorder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.logic.op.Modality; +import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.proof.mgt.SpecificationRepository; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.SetOfOperationContract; + + +/** + * A panel for selecting operation contracts. + */ +class OperationContractSelectionPanel extends JPanel { + + private final JList contractList; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + /** + * Creates a contract selection panel containing the specified contracts. + */ + public OperationContractSelectionPanel(Services services, + SetOfOperationContract contracts, + String title) { + //create scroll pane + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setBorder(new TitledBorder(title)); + Dimension scrollPaneDim = new Dimension(800, 500); + scrollPane.setPreferredSize(scrollPaneDim); + scrollPane.setMinimumSize(scrollPaneDim); + add(scrollPane); + + //create contract list + contractList = new JList(); + contractList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + contractList.setListData(contracts.toArray()); + contractList.setSelectedIndex(0); + contractList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if(contractList.isSelectionEmpty()) { + contractList.setSelectedIndex(e.getFirstIndex()); + } + } + }); + final Services serv = services; + contractList.setCellRenderer(new DefaultListCellRenderer() { + private final Font PLAINFONT = getFont().deriveFont(Font.PLAIN); + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + OperationContract contract = (OperationContract) value; + Component supComp + = super.getListCellRendererComponent(list, + value, + index, + isSelected, + cellHasFocus); + + //create label and enclosing panel + JLabel label = new JLabel(); + label.setText(contract.getHTMLText(serv)); + label.setFont(PLAINFONT); + FlowLayout lay = new FlowLayout(); + lay.setAlignment(FlowLayout.LEFT); + JPanel result = new JPanel(lay); + result.add(label); + label.setVerticalAlignment(SwingConstants.TOP); + + //set background color + result.setBackground(supComp.getBackground()); + + //set border + TitledBorder border = new TitledBorder( + BorderFactory.createEtchedBorder(), + contract.getDisplayName()); + border.setTitleFont(border.getTitleFont() + .deriveFont(Font.BOLD)); + result.setBorder(border); + + return result; + } + }); + scrollPane.setViewportView(contractList); + } + + + private static SetOfOperationContract collectContracts(Services services, + ProgramMethod pm, + Modality modality) { + SpecificationRepository specRepos + = services.getSpecificationRepository(); + SetOfOperationContract result; + if(modality != null) { + result = specRepos.getOperationContracts(pm, modality); + + //in box modalities, diamond contracts may be applied as well + if(modality == Op.BOX) { + result = result.union(services.getSpecificationRepository() + .getOperationContracts(pm, Op.DIA)); + } + } else { + result = specRepos.getOperationContracts(pm); + } + assert result.size() > 0; + return result; + } + + + /** + * Creates a contract selection panel containing all contracts for the + * specified operation with the specified modality. + */ + public OperationContractSelectionPanel(Services services, + ProgramMethod pm, + Modality modality) { + this(services, + collectContracts(services, pm, modality), + "Contracts for \"" + + pm.getFullName() + + "\"" + + (modality != null ? " (" + modality + ")" : "")); + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public void addMouseListener(MouseListener ml) { + contractList.addMouseListener(ml); + } + + + public OperationContract getOperationContract() { + return (OperationContract) contractList.getSelectedValue(); + } +} diff --git a/system/de/uka/ilkd/key/gui/POBrowser.java b/system/de/uka/ilkd/key/gui/POBrowser.java new file mode 100644 index 00000000000..4f368dbf0ac --- /dev/null +++ b/system/de/uka/ilkd/key/gui/POBrowser.java @@ -0,0 +1,532 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.gui; + +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Iterator; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.KeyStroke; +import javax.swing.ListSelectionModel; +import javax.swing.border.TitledBorder; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; + +import de.uka.ilkd.key.collection.ListOfString; +import de.uka.ilkd.key.collection.SLListOfString; +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.IteratorOfKeYJavaType; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.abstraction.SetAsListOfKeYJavaType; +import de.uka.ilkd.key.java.abstraction.SetOfKeYJavaType; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.proof.init.BehaviouralSubtypingInvPO; +import de.uka.ilkd.key.proof.init.EnsuresPostPO; +import de.uka.ilkd.key.proof.init.InitConfig; +import de.uka.ilkd.key.proof.init.PreservesGuardPO; +import de.uka.ilkd.key.proof.init.PreservesInvPO; +import de.uka.ilkd.key.proof.init.PreservesOwnInvPO; +import de.uka.ilkd.key.proof.init.ProofOblInput; +import de.uka.ilkd.key.proof.init.RespectsModifiesPO; +import de.uka.ilkd.key.proof.init.SpecExtPO; +import de.uka.ilkd.key.proof.init.StrongOperationContractPO; +import de.uka.ilkd.key.proof.mgt.SpecificationRepository; + + +public class POBrowser extends JDialog { + + private final InitConfig initConfig; + private final Services services; + private final JavaInfo javaInfo; + private final SpecificationRepository specRepos; + + private final ClassTree classTree; + private final JList poList; + private final JButton startButton; + private final JButton cancelButton; + + private ProofOblInput po; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public POBrowser(InitConfig initConfig, String title) { + super(Main.getInstance(), title, true); + this.initConfig = initConfig; + this.services = initConfig.getServices(); + this.javaInfo = initConfig.getServices().getJavaInfo(); + this.specRepos = initConfig.getServices().getSpecificationRepository(); + + //create class tree + classTree = new ClassTree(true, null, services); + classTree.addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + DefaultMutableTreeNode selectedNode + = (DefaultMutableTreeNode) + e.getPath().getLastPathComponent(); + ClassTree.Entry entry + = (ClassTree.Entry) selectedNode.getUserObject(); + if(entry.kjt != null) { + showPOsFor(entry.kjt); + } else if(entry.pm != null) { + showPOsFor(entry.pm); + } else { + clearPOList(); + } + } + }); + + //create PO list + poList = new JList(); + poList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + poList.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e){ + if(e.getClickCount() == 2){ + startButton.doClick(); + } + } + }); + + //create list panel + JPanel listPanel = new JPanel(); + listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.X_AXIS)); + getContentPane().add(listPanel); + + //create class scroll pane + JScrollPane classScrollPane = new JScrollPane(classTree); + classScrollPane.setBorder(new TitledBorder("Classes and Operations")); + Dimension classScrollPaneDim = new Dimension(400, 400); + classScrollPane.setPreferredSize(classScrollPaneDim); + classScrollPane.setMinimumSize(classScrollPaneDim); + listPanel.add(classScrollPane); + + //create PO scroll pane + JScrollPane poScrollPane = new JScrollPane(poList); + poScrollPane.setBorder(new TitledBorder("Proof Obligations")); + Dimension poScrollPaneDim = new Dimension(250, 400); + poScrollPane.setPreferredSize(poScrollPaneDim); + poScrollPane.setMinimumSize(poScrollPaneDim); + listPanel.add(poScrollPane); + + //create button panel + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5)); + getContentPane().add(buttonPanel); + Dimension buttonDim = new Dimension(100, 27); + + //create "start proof" button + startButton = new JButton("Start Proof"); + startButton.setPreferredSize(buttonDim); + startButton.setMinimumSize(buttonDim); + startButton.setEnabled(false); + startButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + po = createPO(); + if(po != null) { + setVisible(false); + } + } + }); + buttonPanel.add(startButton); + getRootPane().setDefaultButton(startButton); + + //create "cancel" button + cancelButton = new JButton("Cancel"); + cancelButton.setPreferredSize(buttonDim); + cancelButton.setMinimumSize(buttonDim); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + }); + buttonPanel.add(cancelButton); + ActionListener escapeListener = new ActionListener() { + public void actionPerformed(ActionEvent event) { + if(event.getActionCommand().equals("ESC")) { + cancelButton.doClick(); + } + } + }; + cancelButton.registerKeyboardAction( + escapeListener, + "ESC", + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JButton.WHEN_IN_FOCUSED_WINDOW); + + //show + getContentPane().setLayout(new BoxLayout(getContentPane(), + BoxLayout.Y_AXIS)); + pack(); + setLocation(70, 70); + } + + + public POBrowser(InitConfig initConfig) { + this(initConfig, "Proof Obligation Browser"); + setVisible(true); + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private void showPOsFor(KeYJavaType kjt) { + ListOfString pos = SLListOfString.EMPTY_LIST; + + //BehaviouralSubtypingInv + if(specRepos.getClassInvariants(kjt).size() > 0 + && javaInfo.getDirectSuperTypes(kjt).size() > 0) { + pos = pos.append("BehaviouralSubtypingInv"); + } + +/* + //BehaviouralSubtypingOp + ListOfProgramMethod pms = javaInfo.getAllProgramMethods(kjt); + IteratorOfProgramMethod it = pms.iterator(); + boolean foundContract = false; + while(it.hasNext()) { + ProgramMethod pm = it.next(); + if(specRepos.getOperationContracts(pm).size() > 0) { + foundContract = true; + break; + } + } + if(foundContract && javaInfo.getDirectSuperTypes(kjt).size() > 0) { + pos = pos.append("BehaviouralSubtypingOp"); + } +*/ + + //show + poList.setListData(pos.toArray()); + if(pos.size() > 0) { + poList.setSelectedIndex(0); + startButton.setEnabled(true); + } else { + startButton.setEnabled(false); + } + } + + + private void showPOsFor(ProgramMethod pm) { + ListOfString pos = SLListOfString.EMPTY_LIST; + +/* + //BehaviouralSubtypingOpPair + if(specRepos.getOperationContracts(pm).size() > 0 + && javaInfo.getDirectSuperTypes(pm.getContainerType()).size() > 0) { + pos = pos.append("BehaviouralSubtypingOpPair"); + } +*/ + + //StrongOperationContract + if(specRepos.getOperationContracts(pm).size() > 0) { + pos = pos.append("StrongOperationContract"); + } + + //PreservesInv + pos = pos.append("PreservesInv"); + + //PreservesOwnInv + if(specRepos.getClassInvariants(pm.getKeYJavaType()).size() > 0) { + pos = pos.append("PreservesOwnInv"); + } + + //EnsuresPost + if(specRepos.getOperationContracts(pm).size() > 0) { + pos = pos.append("EnsuresPost"); + } + + //RespectsModifies + if(specRepos.getOperationContracts(pm).size() > 0) { + pos = pos.append("RespectsModifies"); + } + + //implemented by mbender for jmltest + //Specification Extraction + if(specRepos.getOperationContracts(pm).size() > 0) { + pos = pos.append("SpecificationExtraction"); + } + + //PreservesGuard + pos = pos.append("PreservesGuard"); + + //show + poList.setListData(pos.toArray()); + if(pos.size() > 0) { + poList.setSelectedValue("EnsuresPost", true); + if(poList.getSelectedIndex() == -1) { + poList.setSelectedIndex(0); + } + startButton.setEnabled(true); + } else { + startButton.setEnabled(false); + } + } + + + private void clearPOList() { + poList.setListData(new Object[0]); + startButton.setEnabled(false); + } + + + /** + * Lets the user select a supertype of subKJT in a dialog window. + */ + private KeYJavaType askUserForSupertype(KeYJavaType subKJT, + JavaInfo javaInfo) { + //collect supertypes + SetOfKeYJavaType superKJTs = SetAsListOfKeYJavaType.EMPTY_SET; + IteratorOfKeYJavaType it = javaInfo.getAllSupertypes(subKJT).iterator(); + while(it.hasNext()) { + superKJTs = superKJTs.add(it.next()); + } + + //ask user + ClassSelectionDialog dlg = new ClassSelectionDialog( + "Please select a supertype", + "Supertypes of " + subKJT.getName(), + superKJTs, + false); + if(!dlg.wasSuccessful()) { + return null; + } + + //return selection + SetOfKeYJavaType selectedKJTs = dlg.getSelection(); + if(selectedKJTs.size() == 0) { + return null; + } else { + return selectedKJTs.iterator().next(); + } + } + + + private ProofOblInput createPO() { + ClassTree.Entry selectedEntry = classTree.getSelectedEntry(); + String poString = (String) poList.getSelectedValue(); + + if (poString.equals("BehaviouralSubtypingInv")) { + assert selectedEntry.kjt != null; + return createBehaviouralSubtypingInvPO(selectedEntry.kjt); + } else if (poString.equals("BehaviouralSubtypingOp")) { + assert selectedEntry.kjt != null; + return createBehaviouralSubtypingOpPO(selectedEntry.kjt); + } else if (poString.equals("BehaviouralSubtypingOpPair")) { + assert selectedEntry.pm != null; + return createBehaviouralSubtypingOpPairPO(selectedEntry.pm); + } else if (poString.equals("StrongOperationContract")) { + assert selectedEntry.pm != null; + return createStrongOperationContractPO(selectedEntry.pm); + } else if (poString.equals("PreservesInv")) { + assert selectedEntry.pm != null; + return createPreservesInvPO(selectedEntry.pm); + } else if (poString.equals("PreservesOwnInv")) { + assert selectedEntry.pm != null; + return createPreservesOwnInvPO(selectedEntry.pm); + } else if (poString.equals("EnsuresPost")) { + assert selectedEntry.pm != null; + return createEnsuresPostPO(selectedEntry.pm); + } else if (poString.equals("RespectsModifies")) { + assert selectedEntry.pm != null; + return createRespectsModifiesPO(selectedEntry.pm); + } else if (poString.equals("PreservesGuard")) { + assert selectedEntry.pm != null; + return createPreservesGuardPO(selectedEntry.pm); + } else if (poString.equals("SpecificationExtraction")) { + assert selectedEntry.pm != null; + return createSpecExtPO(selectedEntry.pm); + } else + assert false; + return null; + } + + + private ProofOblInput createBehaviouralSubtypingInvPO(KeYJavaType kjt) { + KeYJavaType superKJT = askUserForSupertype(kjt, javaInfo); + if(superKJT != null) { + return new BehaviouralSubtypingInvPO(initConfig, + kjt, + superKJT); + } else { + return null; + } + } + + + private ProofOblInput createBehaviouralSubtypingOpPO(KeYJavaType kjt) { + assert false; + return null; //TODO + } + + + private ProofOblInput createBehaviouralSubtypingOpPairPO(ProgramMethod pm) { + assert false; + return null; //TODO + } + + + private ProofOblInput createStrongOperationContractPO(ProgramMethod pm) { + ContractConfigurator cc = new ContractConfigurator(this, + services, + pm, + null, + true, + true, + true); + if(cc.wasSuccessful()) { + return new StrongOperationContractPO(initConfig, + cc.getContract(), + cc.getAssumedInvs(), + cc.getEnsuredInvs()); + } else { + return null; + } + } + + + private ProofOblInput createPreservesInvPO(ProgramMethod pm) { + ContractConfigurator cc = new ContractConfigurator(this, + services, + pm, + null, + false, + true, + true); + if(cc.wasSuccessful()) { + return new PreservesInvPO(initConfig, + pm, + cc.getAssumedInvs(), + cc.getEnsuredInvs()); + } else { + return null; + } + } + + + private ProofOblInput createPreservesOwnInvPO(ProgramMethod pm) { + return new PreservesOwnInvPO(initConfig, pm); + } + + + private ProofOblInput createEnsuresPostPO(ProgramMethod pm) { + ContractConfigurator cc = new ContractConfigurator(this, + services, + pm, + null, + true, + true, + false); + if(cc.wasSuccessful()) { + return new EnsuresPostPO(initConfig, + cc.getContract(), + cc.getAssumedInvs()); + } else { + return null; + } + } + + + private ProofOblInput createRespectsModifiesPO(ProgramMethod pm) { + ContractConfigurator cc = new ContractConfigurator(this, + services, + pm, + null, + true, + true, + false); + if(cc.wasSuccessful()) { + return new RespectsModifiesPO(initConfig, + cc.getContract(), + cc.getAssumedInvs()); + } else { + return null; + } + } + + + private ProofOblInput createPreservesGuardPO(ProgramMethod pm) { + //let the user select the guarded invariants + ClassInvariantSelectionDialog dlg = new ClassInvariantSelectionDialog( + "Please select the guarded invariants", + initConfig.getServices(), + false, + pm.getContainerType()); + if(dlg.wasSuccessful()) { + //let the user select the guard classes + SetOfKeYJavaType allKJTs = SetAsListOfKeYJavaType.EMPTY_SET; + Iterator it = javaInfo.getAllKeYJavaTypes().iterator(); + while(it.hasNext()) { + allKJTs = allKJTs.add((KeYJavaType)it.next()); + } + ClassSelectionDialog dlg2 + = new ClassSelectionDialog("Please select the guard", + "Available classes", + allKJTs, + pm.getContainerType(), + true); + if(dlg2.wasSuccessful()) { + return new PreservesGuardPO(initConfig, + pm, + dlg.getSelection(), + dlg2.getSelection()); + } else { + return null; + } + } else { + return null; + } + } + +// implemented by mbender for jmltest + private ProofOblInput createSpecExtPO(ProgramMethod pm) { + ContractConfigurator cc = new ContractConfigurator(this, + services, + pm, + null, + true, + true, + false); + if(cc.wasSuccessful()) { + return new SpecExtPO(initConfig, + cc.getContract(), + cc.getAssumedInvs(),pm); + } else { + return null; + } + } + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public ProofOblInput getPO() { + return po; + } +} diff --git a/system/de/uka/ilkd/key/gui/RuleView.java b/system/de/uka/ilkd/key/gui/RuleView.java index 2a9d803dbce..6ab8f3c9ca6 100644 --- a/system/de/uka/ilkd/key/gui/RuleView.java +++ b/system/de/uka/ilkd/key/gui/RuleView.java @@ -26,7 +26,6 @@ import javax.swing.tree.TreeCellRenderer; import de.uka.ilkd.key.proof.RuleTreeModel; -import de.uka.ilkd.key.proof.mgt.OldOperationContract; import de.uka.ilkd.key.rule.Taclet; public class RuleView extends JPanel implements TreeSelectionListener, java.io.Serializable { @@ -162,13 +161,6 @@ public Component getTreeCellRendererComponent(JTree tree, DefaultMutableTreeNode node = (DefaultMutableTreeNode)value; - if (node.getUserObject() instanceof OldOperationContract) { - OldOperationContract mc = (OldOperationContract) node.getUserObject(); - comp = MethodContractList.makeMethodContractDisplay - (mc, panel, text, statusPanel, - sel ? super.backgroundSelectionColor : - super.backgroundNonSelectionColor); - } if (node.getUserObject() instanceof Taclet) { Taclet t = (Taclet) node.getUserObject(); diff --git a/system/de/uka/ilkd/key/gui/SuperclassSelectionDialog.java b/system/de/uka/ilkd/key/gui/SuperclassSelectionDialog.java deleted file mode 100644 index f6439076834..00000000000 --- a/system/de/uka/ilkd/key/gui/SuperclassSelectionDialog.java +++ /dev/null @@ -1,56 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.gui; - -import de.uka.ilkd.key.casetool.IteratorOfModelClass; -import de.uka.ilkd.key.casetool.ListOfModelClass; -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.util.Debug; - - -/** - * A dialog for selecting one of a class's superclasses. - */ -public class SuperclassSelectionDialog extends ClassSelectionDialog { - - private static ListOfModelClass getAllSuperclasses(ModelClass subtype) { - ListOfModelClass result = subtype.getMyParents(); - - IteratorOfModelClass it = result.iterator(); - while(it.hasNext()) { - result = result.append(getAllSuperclasses(it.next())); - } - - return result; //TODO: eliminate duplicates - } - - - /** - * Creates and displays a dialog box asking the user to select a superclass. - * @param subclass the class to choose a superclass of - */ - public SuperclassSelectionDialog(ModelClass subclass) { - super("Please select a supertype", - "Supertypes of " + subclass.getClassName(), - getAllSuperclasses(subclass), - false); - } - - - /** - * Returns the selected supertype, or null. - */ - public ModelClass getSuperclass() { - ListOfModelClass selectedClasses = getSelection(); - Debug.assertTrue(selectedClasses.size() <= 1); - return (selectedClasses.isEmpty() ? null : selectedClasses.head()); - } -} diff --git a/system/de/uka/ilkd/key/gui/TacletView.java b/system/de/uka/ilkd/key/gui/TacletView.java index 6e7cb484e8b..8e6dc6dfdfb 100644 --- a/system/de/uka/ilkd/key/gui/TacletView.java +++ b/system/de/uka/ilkd/key/gui/TacletView.java @@ -26,7 +26,6 @@ import de.uka.ilkd.key.pp.LogicPrinter; import de.uka.ilkd.key.pp.NotationInfo; import de.uka.ilkd.key.pp.ProgramPrinter; -import de.uka.ilkd.key.proof.mgt.Contract; import de.uka.ilkd.key.rule.Taclet; public class TacletView implements ActionListener{ @@ -84,8 +83,6 @@ public void showTacletView(DefaultMutableTreeNode node){ Taclet tac = null; if (node.getUserObject() instanceof Taclet) { tac = (Taclet) node.getUserObject(); - } else if (node.getUserObject() instanceof Contract) { - tac = null; //TODO ((Contract)node.getUserObject()).getLemmaAndRegister(); } else return; scrollPane.setBorder(BorderFactory.createTitledBorder (getDisplayName(tac))); diff --git a/system/de/uka/ilkd/key/gui/TaskTree.java b/system/de/uka/ilkd/key/gui/TaskTree.java index b88f114dcfb..07245fdde83 100644 --- a/system/de/uka/ilkd/key/gui/TaskTree.java +++ b/system/de/uka/ilkd/key/gui/TaskTree.java @@ -335,8 +335,9 @@ private void create() { public void actionPerformed(ActionEvent e) { if (e.getSource() == mcList) { - JDialog fr = new UsedMethodContractsList(invokedNode, mediator); - fr.setVisible(true); + new UsedSpecificationsDialog( + mediator.getServices(), + invokedNode.getUsedSpecs()); } else if (e.getSource() == removeTask) { removeTask(invokedNode); } else if (e.getSource() == loadProof) { diff --git a/system/de/uka/ilkd/key/gui/UseMethodContractRuleItem.java b/system/de/uka/ilkd/key/gui/UseMethodContractRuleItem.java deleted file mode 100644 index 488b7fa8514..00000000000 --- a/system/de/uka/ilkd/key/gui/UseMethodContractRuleItem.java +++ /dev/null @@ -1,85 +0,0 @@ -package de.uka.ilkd.key.gui; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import javax.swing.JFrame; -import javax.swing.JMenuItem; - -import de.uka.ilkd.key.gui.nodeviews.BuiltInRuleMenuItem; -import de.uka.ilkd.key.logic.Constraint; -import de.uka.ilkd.key.logic.PosInOccurrence; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.mgt.OldOperationContract; -import de.uka.ilkd.key.rule.BuiltInRule; -import de.uka.ilkd.key.rule.ContractConfigurator; -import de.uka.ilkd.key.rule.MethodContractRuleApp; -import de.uka.ilkd.key.rule.UseMethodContractRule; - -public class UseMethodContractRuleItem extends JMenuItem implements BuiltInRuleMenuItem{ - - private UseMethodContractRule connectedTo; - private Proof proof; - private PosInOccurrence pos; - private MethodContractRuleApp app; - private JFrame parent; - - /** the added action listeners */ - private List listenerList = new LinkedList(); - - - public UseMethodContractRuleItem(JFrame parent, UseMethodContractRule rule, - Proof proof, PosInOccurrence pos) { - super(rule.name().toString()); - this.connectedTo = rule; - this.pos = pos; - this.parent = parent; - this.proof = proof; - - super.addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - openDialog(e); - } - - }); - - } - - public void openDialog(ActionEvent e) { - ContractConfigurator config - = new DefaultContractConfigurator("Contract Configurator", parent); - OldOperationContract mc = connectedTo.selectContract(proof, pos, config); - if (mc!=null) { - app = new MethodContractRuleApp(connectedTo, pos, Constraint.BOTTOM, mc); - processUseMethodContractRuleSelected(e); - } - } - - public BuiltInRule connectedTo() { - return connectedTo; - } - - public MethodContractRuleApp getRuleApp() { - return app; - } - - protected void processUseMethodContractRuleSelected(ActionEvent e) { - final Iterator it = listenerList.iterator(); - while (it.hasNext()) { - ((ActionListener)it.next()).actionPerformed(e); - } - } - - public void addActionListener(ActionListener listener) { - listenerList.add(listener); - } - - public void removeActionListener(ActionListener listener) { - listenerList.remove(listener); - } - -} diff --git a/system/de/uka/ilkd/key/gui/UsedMethodContractsList.java b/system/de/uka/ilkd/key/gui/UsedMethodContractsList.java deleted file mode 100644 index 296345e106b..00000000000 --- a/system/de/uka/ilkd/key/gui/UsedMethodContractsList.java +++ /dev/null @@ -1,211 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// -package de.uka.ilkd.key.gui; - -import java.awt.BorderLayout; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.List; - -import javax.swing.*; - -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.init.ProblemInitializer; -import de.uka.ilkd.key.proof.init.ProofInputException; -import de.uka.ilkd.key.proof.init.ProofOblInput; -import de.uka.ilkd.key.proof.mgt.BasicTask; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.ContractSet; - -public class UsedMethodContractsList extends JDialog { - - private BasicTask invokedNode; - private KeYMediator mediator; - private ContractSelectionPanel mCL; - private Contract contract = null; - private static UsedMethodContractsList instance = null; - private ContractSet cs = null; - private boolean firstPO = false; - private boolean dispose = true; - private JButton jump = null; - - // Some instances are kept, some are created on the fly and - // garbage collected - - public static UsedMethodContractsList getInstance(KeYMediator mediator, - ContractSet contractSet) { - if(instance == null) - instance = new UsedMethodContractsList(null, mediator, "Choose DL Contract"); - instance.setupWindow(null, contractSet, true, false, false); - return instance; - } - - public static UsedMethodContractsList getInstance(KeYMediator mediator) { - if(instance == null) - instance = new UsedMethodContractsList(null, mediator, "Choose DL Contract"); - instance.setupWindow(mediator.getSelectedProof().getBasicTask(), - mediator.getSelectedProof().getBasicTask().getAllDLMethodContracts(), - false, false, true); - return instance; - } - - private void setupWindow(BasicTask invokedNode, - ContractSet contractSet, - boolean firstPO, - boolean dispose, - boolean jumpEnable) { - this.invokedNode = invokedNode; - this.cs = contractSet; - this.firstPO = firstPO; - this.dispose = dispose; - this.mCL.setContracts(cs); - this.jump.setEnabled(jumpEnable); - } - - public UsedMethodContractsList(BasicTask invokedNode, - KeYMediator med) { - this(invokedNode, med, "Used Specifications"); - } - - - private UsedMethodContractsList(BasicTask invokedNode, - KeYMediator med, String title) { - super(new JFrame(), title); - if(invokedNode != null) - setDefaultCloseOperation(DISPOSE_ON_CLOSE); - else - setDefaultCloseOperation(HIDE_ON_CLOSE); - this.invokedNode=invokedNode; - this.mediator=med; - setModal(true); - ContractSet allMC = invokedNode != null ? invokedNode.getAllMethodContracts() : null; - mCL = new ContractSelectionPanel(allMC, true); - JScrollPane scroll = new JScrollPane(); - scroll.setViewportView(mCL); - scroll.setPreferredSize(new java.awt.Dimension(400,500)); - getContentPane().setLayout(new BorderLayout()); - getContentPane().add(scroll, BorderLayout.CENTER); - JButton cancel = new JButton("Cancel"); - cancel.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if(dispose) - ((JDialog)((JButton)e.getSource()) - .getTopLevelAncestor()).dispose(); - else{ - setVisible(false); - } - }}); - jump = new JButton("Go To Proof"); - jump.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - ((JDialog)((JButton)e.getSource()) - .getTopLevelAncestor()).dispose(); - openTaskForCurrentContract(); - }}); - JButton open = new JButton("Start New Proof"); - open.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (dispose) { - ((JDialog)((JButton)e.getSource()) - .getTopLevelAncestor()).dispose(); - Runnable proofLoader = new Runnable() { - public void run() { - openNewProofForCurrentContract(); - } - }; - KeYMediator.invokeAndWait(proofLoader); - } else { - if(firstPO) { - contract = mCL.getCurrentSelection(); - setVisible(false); - }else{ - setVisible(false); - Runnable proofLoader = new Runnable() { - public void run() { - openNewProofForCurrentContract(); - } - }; - KeYMediator.invokeAndWait(proofLoader); - } - } - }}); - - - JPanel p = new JPanel(new GridBagLayout()); - GridBagConstraints c = new GridBagConstraints(); - - c.insets = new Insets(5,20,5,20); - c.gridx = 0; - p.add(jump, c); - - c.gridx = 1; - p.add(open, c); - - c.gridx = 2; - p.add(cancel, c); - p.setAlignmentY(JPanel.BOTTOM_ALIGNMENT); - - getContentPane().add(p, BorderLayout.SOUTH); - getContentPane().add(new JLabel("Specifications:"), - BorderLayout.NORTH); - pack(); - getContentPane().add(scroll); - } - - public void dispose() { - mediator.freeModalAccess(this); - super.dispose(); - } - - public void setVisible(boolean show) { - if(show) - mediator.requestModalAccess(this); - else - mediator.freeModalAccess(this); - super.setVisible(show); - } - - public Contract getContract() { - // You can only ask once for a contract - Contract res = contract; - contract = null; - return res; - } - - private void openTaskForProof(ProofAggregate p) { - mediator.setProof(p.getFirstProof()); - } - - - public void openTaskForCurrentContract() { - Contract mC = mCL.getCurrentSelection(); - List mCL = mC.getProofs(); - if (mCL.size()!= 0) { - openTaskForProof((ProofAggregate)mCL.get(0)); - } - } - - public void openNewProofForCurrentContract() { - Contract mC = mCL.getCurrentSelection(); - if (mC==null) return; - ProofOblInput poin = mC.getProofOblInput(invokedNode.proof()); - if (poin==null) return; - ProblemInitializer pi = new ProblemInitializer(Main.getInstance()); - try { - pi.startProver(invokedNode.proof().env(), poin); - } catch(ProofInputException e) { - //too bad - } - } - -} diff --git a/system/de/uka/ilkd/key/gui/UsedSpecificationsDialog.java b/system/de/uka/ilkd/key/gui/UsedSpecificationsDialog.java new file mode 100644 index 00000000000..956d0b88824 --- /dev/null +++ b/system/de/uka/ilkd/key/gui/UsedSpecificationsDialog.java @@ -0,0 +1,365 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.gui; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.DefaultListCellRenderer; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.KeyStroke; +import javax.swing.ListSelectionModel; +import javax.swing.SwingConstants; +import javax.swing.border.TitledBorder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.proof.IteratorOfProof; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.SetOfProof; +import de.uka.ilkd.key.proof.init.EnsuresPostPO; +import de.uka.ilkd.key.proof.init.InitConfig; +import de.uka.ilkd.key.proof.init.PreservesInvPO; +import de.uka.ilkd.key.proof.init.ProblemInitializer; +import de.uka.ilkd.key.proof.init.ProofInputException; +import de.uka.ilkd.key.proof.init.ProofOblInput; +import de.uka.ilkd.key.proof.init.RespectsModifiesPO; +import de.uka.ilkd.key.proof.mgt.ContractWithInvs; +import de.uka.ilkd.key.proof.mgt.SetOfContractWithInvs; + + +public class UsedSpecificationsDialog extends JDialog { + + private static final ImageIcon keyIcon + = IconFactory.keyHole(20, 20); + private static final ImageIcon keyAlmostClosedIcon + = IconFactory.keyHoleAlmostClosed(20, 20); + private static final ImageIcon keyClosedIcon + = IconFactory.keyHoleClosed(20, 20); + + private final Services services; + private final JList contractAppList; + private final JButton ensuresPostButton; + private final JButton preservesInvButton; + private final JButton respectsModifiesButton; + private final JButton cancelButton; + + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public UsedSpecificationsDialog(Services services, + SetOfContractWithInvs contractApps) { + super(Main.getInstance(), "Used Specifications", true); + this.services = services; + + //create scroll pane + JScrollPane scrollPane = new JScrollPane(); + Dimension scrollPaneDim = new Dimension(800, 500); + scrollPane.setPreferredSize(scrollPaneDim); + scrollPane.setMinimumSize(scrollPaneDim); + getContentPane().add(scrollPane); + + //create contract app list + contractAppList = new JList(); + contractAppList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + contractAppList.setListData(contractApps.toArray()); + contractAppList.setSelectedIndex(0); + contractAppList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + if(contractAppList.isSelectionEmpty()) { + contractAppList.setSelectedIndex(e.getFirstIndex()); + } + updatePOButtons(); + } + }); + contractAppList.setCellRenderer(new DefaultListCellRenderer() { + private final Font PLAINFONT = getFont().deriveFont(Font.PLAIN); + + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + ContractWithInvs cwi = (ContractWithInvs) value; + Component supComp + = super.getListCellRendererComponent(list, + value, + index, + isSelected, + cellHasFocus); + + //create label and enclosing panel + JLabel label = new JLabel(); + label.setText(cwi.getHTMLText( + UsedSpecificationsDialog.this.services)); + label.setFont(PLAINFONT); + FlowLayout lay = new FlowLayout(); + lay.setAlignment(FlowLayout.LEFT); + JPanel result = new JPanel(lay); + result.add(label); + label.setVerticalAlignment(SwingConstants.TOP); + + //set background color + result.setBackground(supComp.getBackground()); + + //set border + TitledBorder border = new TitledBorder( + BorderFactory.createEtchedBorder(), + cwi.contract.getDisplayName()); + border.setTitleFont(border.getTitleFont() + .deriveFont(Font.BOLD)); + result.setBorder(border); + + return result; + } + }); + scrollPane.setViewportView(contractAppList); + + //create button panel + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5)); + Dimension buttonDim = new Dimension(115, 27); + Dimension largeButtonDim = new Dimension(145, 27); + Dimension extraLargeButtonDim = new Dimension(170, 27); + getContentPane().add(buttonPanel); + + //create "EnsuresPost" button + ensuresPostButton = new JButton("EnsuresPost"); + ensuresPostButton.setPreferredSize(largeButtonDim); + ensuresPostButton.setMinimumSize(largeButtonDim); + ensuresPostButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ContractWithInvs cwi + = (ContractWithInvs) contractAppList.getSelectedValue(); + InitConfig initConfig = Main.getInstance().mediator() + .getSelectedProof() + .env() + .getInitConfig(); + ProofOblInput po = new EnsuresPostPO(initConfig, + cwi.contract, + cwi.assumedInvs); + findOrStartProof(initConfig, po); + setVisible(false); + } + }); + buttonPanel.add(ensuresPostButton); + + //create "PreservesInv" button + preservesInvButton = new JButton("PreservesInv"); + preservesInvButton.setPreferredSize(largeButtonDim); + preservesInvButton.setMinimumSize(largeButtonDim); + preservesInvButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ContractWithInvs cwi + = (ContractWithInvs) contractAppList.getSelectedValue(); + InitConfig initConfig = Main.getInstance().mediator() + .getSelectedProof() + .env() + .getInitConfig(); + ProofOblInput po + = new PreservesInvPO(initConfig, + cwi.contract.getProgramMethod(), + cwi.assumedInvs, + cwi.ensuredInvs); + findOrStartProof(initConfig, po); + setVisible(false); + } + }); + buttonPanel.add(preservesInvButton); + + //create "RespectsModifies" button + respectsModifiesButton = new JButton("RespectsModifies"); + respectsModifiesButton.setPreferredSize(extraLargeButtonDim); + respectsModifiesButton.setMinimumSize(extraLargeButtonDim); + respectsModifiesButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ContractWithInvs cwi + = (ContractWithInvs) contractAppList.getSelectedValue(); + InitConfig initConfig = Main.getInstance().mediator() + .getSelectedProof() + .env() + .getInitConfig(); + ProofOblInput po + = new RespectsModifiesPO(initConfig, + cwi.contract, + cwi.assumedInvs); + findOrStartProof(initConfig, po); + setVisible(false); + } + }); + buttonPanel.add(respectsModifiesButton); + + //create "cancel" button + cancelButton = new JButton("Cancel"); + cancelButton.setPreferredSize(buttonDim); + cancelButton.setMinimumSize(buttonDim); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + }); + buttonPanel.add(cancelButton); + getRootPane().setDefaultButton(cancelButton); + ActionListener escapeListener = new ActionListener() { + public void actionPerformed(ActionEvent event) { + if(event.getActionCommand().equals("ESC")) { + cancelButton.doClick(); + } + } + }; + cancelButton.registerKeyboardAction( + escapeListener, + "ESC", + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JButton.WHEN_IN_FOCUSED_WINDOW); + + //disable PO buttons if no specifications + if(contractApps.size() == 0) { + ensuresPostButton.setEnabled(false); + preservesInvButton.setEnabled(false); + respectsModifiesButton.setEnabled(false); + } else { + updatePOButtons(); + } + + //show + getContentPane().setLayout(new BoxLayout(getContentPane(), + BoxLayout.Y_AXIS)); + pack(); + setLocation(70, 70); + setVisible(true); + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private Proof findPreferablyClosedProof(ProofOblInput po) { + SetOfProof proofs + = services.getSpecificationRepository().getProofs(po); + + //no proofs? + if(proofs.size() == 0) { + return null; + } + + //try to find closed proof + IteratorOfProof it = proofs.iterator(); + while(it.hasNext()) { + Proof proof = it.next(); + if(proof.mgt().getStatus().getProofClosed()) { + return proof; + } + } + + //just take any proof + return proofs.iterator().next(); + } + + + private void updatePOButtons() { + InitConfig initConfig = Main.getInstance().mediator() + .getSelectedProof() + .env() + .getInitConfig(); + ContractWithInvs cwi + = (ContractWithInvs) contractAppList.getSelectedValue(); + + //ensuresPost + ProofOblInput ensuresPostPO = new EnsuresPostPO(initConfig, + cwi.contract, + cwi.assumedInvs); + Proof ensuresPostProof = findPreferablyClosedProof(ensuresPostPO); + if(ensuresPostProof == null) { + ensuresPostButton.setIcon(null); + } else if(ensuresPostProof.mgt().getStatus().getProofOpen()) { + ensuresPostButton.setIcon(keyIcon); + } else if(ensuresPostProof.mgt().getStatus() + .getProofClosedButLemmasLeft()) { + ensuresPostButton.setIcon(keyAlmostClosedIcon); + } else { + assert ensuresPostProof.mgt().getStatus().getProofClosed(); + ensuresPostButton.setIcon(keyClosedIcon); + } + + //preservesInv + ProofOblInput preservesInvPO + = new PreservesInvPO(initConfig, + cwi.contract.getProgramMethod(), + cwi.assumedInvs, + cwi.ensuredInvs); + Proof preservesInvProof = findPreferablyClosedProof(preservesInvPO); + if(preservesInvProof == null) { + preservesInvButton.setIcon(null); + } else if(preservesInvProof.mgt().getStatus().getProofOpen()) { + preservesInvButton.setIcon(keyIcon); + } else if(preservesInvProof.mgt().getStatus() + .getProofClosedButLemmasLeft()) { + preservesInvButton.setIcon(keyAlmostClosedIcon); + } else { + assert preservesInvProof.mgt().getStatus().getProofClosed(); + preservesInvButton.setIcon(keyClosedIcon); + } + + //respectsModifies + ProofOblInput respectsModifiesPO + = new RespectsModifiesPO(initConfig, + cwi.contract, + cwi.assumedInvs); + Proof respectsModifiesProof = findPreferablyClosedProof(respectsModifiesPO); + if(respectsModifiesProof == null) { + respectsModifiesButton.setIcon(null); + } else if(respectsModifiesProof.mgt().getStatus().getProofOpen()) { + respectsModifiesButton.setIcon(keyIcon); + } else if(respectsModifiesProof.mgt().getStatus() + .getProofClosedButLemmasLeft()) { + respectsModifiesButton.setIcon(keyAlmostClosedIcon); + } else { + assert respectsModifiesProof.mgt().getStatus().getProofClosed(); + respectsModifiesButton.setIcon(keyClosedIcon); + } + } + + + private void findOrStartProof(InitConfig initConfig, ProofOblInput po) { + Proof proof = findPreferablyClosedProof(po); + if(proof == null) { + ProblemInitializer pi = new ProblemInitializer(Main.getInstance()); + try { + pi.startProver(initConfig, po); + } catch(ProofInputException exc) { + exc.printStackTrace(System.out); + } + } else { + Main.getInstance().mediator().setProof(proof); + } + } +} diff --git a/system/de/uka/ilkd/key/gui/configuration/GeneralSettings.java b/system/de/uka/ilkd/key/gui/configuration/GeneralSettings.java index 76c93aecef2..962aa7bbc40 100644 --- a/system/de/uka/ilkd/key/gui/configuration/GeneralSettings.java +++ b/system/de/uka/ilkd/key/gui/configuration/GeneralSettings.java @@ -25,12 +25,11 @@ public class GeneralSettings implements Settings { private static final String STUPID_MODE_KEY = "[General]StupidMode"; private static final String PROOF_ASSISTANT_MODE_KEY = "[General]ProofAssistant"; - private static final String SUGG_VARNAMES_KEY = "[General]SuggestiveVarNames"; - private static final String OUTER_RENAMING_KEY = "[General]OuterRenaming"; private static final String SOUND_NOTIFICATION_KEY = "[General]SoundNotification"; private static final String DND_DIRECTION_SENSITIVE_KEY = "[General]DnDDirectionSensitive"; + private static final String USE_JML_KEY = "[General]UseJML"; /** minimize interaction is on by default */ private boolean stupidMode = true; @@ -41,14 +40,15 @@ public class GeneralSettings implements Settings { /** suggestive var names are off by default */ private boolean suggestiveVarNames = false; - /** outer renaming is on by default */ - private boolean outerRenaming = false; - /** sound notification is on by default */ private boolean soundNotification = true; /** is drag and drop instantiation direction sensitive */ private boolean dndDirectionSensitive = true; + + /** JML is used by default (otherwise OCL is used) */ + private boolean useJML = true; + private LinkedList listenerList = new LinkedList(); @@ -58,28 +58,31 @@ public boolean stupidMode() { return stupidMode; } + public boolean proofAssistantMode() { return proofAssistantMode; } + public boolean suggestiveVarNames() { return suggestiveVarNames; } - public boolean outerRenaming() { - return outerRenaming; - } public boolean soundNotification() { return soundNotification; } - /** - * returns true if drag and drop shall be direction sensitive - */ + public boolean isDndDirectionSensitive() { return dndDirectionSensitive; } + + + public boolean useJML() { + return useJML; + } + // setter public void setStupidMode(boolean b) { @@ -89,6 +92,7 @@ public void setStupidMode(boolean b) { } } + public void setProofAssistantMode(boolean b) { if(proofAssistantMode != b) { proofAssistantMode = b; @@ -96,19 +100,6 @@ public void setProofAssistantMode(boolean b) { } } - public void setSuggestiveVarNames(boolean b) { - if(suggestiveVarNames != b) { - suggestiveVarNames = b; - fireSettingsChanged(); - } - } - - public void setOuterRenaming(boolean b) { - if (outerRenaming != b) { - outerRenaming = b; - fireSettingsChanged(); - } - } public void setSoundNotification(boolean b) { if (soundNotification != b) { @@ -117,6 +108,7 @@ public void setSoundNotification(boolean b) { } } + public void setDnDDirectionSensitivity(boolean b) { if (dndDirectionSensitive != b) { dndDirectionSensitive = b; @@ -125,6 +117,13 @@ public void setDnDDirectionSensitivity(boolean b) { } + public void setUseJML(boolean b) { + if (useJML != b) { + useJML = b; + fireSettingsChanged(); + } + } + /** gets a Properties object and has to perform the necessary @@ -141,16 +140,6 @@ public void readSettings(Properties props) { if (val != null) { proofAssistantMode = Boolean.valueOf(val).booleanValue(); } - - val = props.getProperty(SUGG_VARNAMES_KEY); - if (val != null) { - suggestiveVarNames = Boolean.valueOf(val).booleanValue(); - } - - val = props.getProperty(OUTER_RENAMING_KEY); - if (val != null) { - outerRenaming = Boolean.valueOf(val).booleanValue(); - } val = props.getProperty(SOUND_NOTIFICATION_KEY); if (val != null) { @@ -161,7 +150,11 @@ public void readSettings(Properties props) { if (val != null) { dndDirectionSensitive = Boolean.valueOf(val).booleanValue(); } - + + val = props.getProperty(USE_JML_KEY); + if (val != null) { + useJML = Boolean.valueOf(val).booleanValue(); + } } @@ -173,10 +166,9 @@ public void readSettings(Properties props) { public void writeSettings(Properties props) { props.setProperty(STUPID_MODE_KEY, "" + stupidMode); props.setProperty(PROOF_ASSISTANT_MODE_KEY, "" + proofAssistantMode); - props.setProperty(SUGG_VARNAMES_KEY, "" + suggestiveVarNames); - props.setProperty(OUTER_RENAMING_KEY, "" + outerRenaming); props.setProperty(SOUND_NOTIFICATION_KEY, "" + soundNotification); props.setProperty(DND_DIRECTION_SENSITIVE_KEY, "" + dndDirectionSensitive); + props.setProperty(USE_JML_KEY, "" + useJML); } /** sends the message that the state of this setting has been @@ -189,6 +181,7 @@ protected void fireSettingsChanged() { } } + /** * adds a listener to the settings object * @param l the listener @@ -196,6 +189,4 @@ protected void fireSettingsChanged() { public void addSettingsListener(SettingsListener l) { listenerList.add(l); } - - } diff --git a/system/de/uka/ilkd/key/gui/nodeviews/InsertSystemInvariantTacletMenuItem.java b/system/de/uka/ilkd/key/gui/nodeviews/InsertSystemInvariantTacletMenuItem.java index 095cfee1d27..85f8c67b26a 100644 --- a/system/de/uka/ilkd/key/gui/nodeviews/InsertSystemInvariantTacletMenuItem.java +++ b/system/de/uka/ilkd/key/gui/nodeviews/InsertSystemInvariantTacletMenuItem.java @@ -41,7 +41,7 @@ public InsertSystemInvariantTacletMenuItem(JFrame parent, */ protected Sequent checkTaclet(Taclet t) { if (!(t instanceof NoFindTaclet) || - !t.displayName().startsWith("Insert invariants of")) { + !t.displayName().startsWith("Insert implicit invariants of")) { return null; } diff --git a/system/de/uka/ilkd/key/gui/nodeviews/TacletMenu.java b/system/de/uka/ilkd/key/gui/nodeviews/TacletMenu.java index bc2348efbcf..0918313265e 100644 --- a/system/de/uka/ilkd/key/gui/nodeviews/TacletMenu.java +++ b/system/de/uka/ilkd/key/gui/nodeviews/TacletMenu.java @@ -20,8 +20,6 @@ import de.uka.ilkd.key.gui.KeYMediator; import de.uka.ilkd.key.gui.Main; -import de.uka.ilkd.key.gui.UseMethodContractRuleItem; -import de.uka.ilkd.key.gui.nodeviews.*; import de.uka.ilkd.key.java.ProgramElement; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.op.IteratorOfSchemaVariable; @@ -156,14 +154,7 @@ private void createBuiltInRuleMenu(ListOfBuiltInRule builtInList, private void addBuiltInRuleItem(BuiltInRule builtInRule, MenuControl control) { JMenuItem item; - if (builtInRule instanceof UseMethodContractRule) { - item = new UseMethodContractRuleItem(mediator.mainFrame(), - (UseMethodContractRule)builtInRule, - mediator.getSelectedProof(), - pos.getPosInOccurrence()); - } else { - item = new DefaultBuiltInRuleMenuItem(builtInRule); - } + item = new DefaultBuiltInRuleMenuItem(builtInRule); item.addActionListener(control); add(item); } @@ -353,9 +344,6 @@ public void actionPerformed(ActionEvent e) { ((SequentView)(getPopupMenu().getInvoker())) .selectedTaclet(((TacletMenuItem) e.getSource()).connectedTo(), pos); - } else if (e.getSource() instanceof UseMethodContractRuleItem) { - mediator.selectedUseMethodContractRule - (((UseMethodContractRuleItem) e.getSource()).getRuleApp()); } else if (e.getSource() instanceof BuiltInRuleMenuItem) { mediator.selectedBuiltInRule (((BuiltInRuleMenuItem) e.getSource()).connectedTo(), @@ -608,7 +596,5 @@ public int compare(Object o1, Object o2) { return 0; } - } - } diff --git a/system/de/uka/ilkd/key/java/Comment.java b/system/de/uka/ilkd/key/java/Comment.java index dafe877d798..3c10ee2d9d9 100644 --- a/system/de/uka/ilkd/key/java/Comment.java +++ b/system/de/uka/ilkd/key/java/Comment.java @@ -24,6 +24,11 @@ public Comment(String text) { this.text = text; } + public Comment(String text, PositionInfo pInfo) { + super(pInfo); + this.text = text; + } + public boolean isPrefixed () { return false; } @@ -41,33 +46,12 @@ public void visit(Visitor v) { public String getText(){ return text; } - - public boolean containsJMLSpec(){ - if(text == null){ - return false; - } - return text.trim().startsWith("/*@") || text.trim().startsWith("//@")|| - text.trim().startsWith("/*+@") || text.trim().startsWith("/*-@")|| - text.indexOf("")!=-1 && text.indexOf("")!=-1; + + + public String toString() { + return getText(); } - public String getJMLSpec(){ - if(!containsJMLSpec()) return null; - if(text.trim().startsWith("/*@")){ - return text.trim().substring(3,text.length()-3); - } - if(text.trim().startsWith("/*+@")){ - return text.trim().substring(4,text.length()-3); - } - if(text.trim().startsWith("/*-@")){ - return text.trim().substring(4,text.length()-3); - } - if(text.trim().startsWith("//@")){ - return text.trim().substring(3); - } - int start = text.indexOf("")+5; - return text.substring(start, text.indexOf("", start)); - } /** comments can be ignored */ @@ -90,6 +74,4 @@ public boolean equals(Object o){ Comment cmp = (Comment)o; return (getText().equals(cmp.getText())); } - - } diff --git a/system/de/uka/ilkd/key/java/CompilationUnit.java b/system/de/uka/ilkd/key/java/CompilationUnit.java index 165ee024b1c..1f80b2d6040 100644 --- a/system/de/uka/ilkd/key/java/CompilationUnit.java +++ b/system/de/uka/ilkd/key/java/CompilationUnit.java @@ -251,5 +251,4 @@ public String toString() { } return sw.toString(); } - } diff --git a/system/de/uka/ilkd/key/java/JavaInfo.java b/system/de/uka/ilkd/key/java/JavaInfo.java index dcdb9cc73cc..0dd07307c0a 100644 --- a/system/de/uka/ilkd/key/java/JavaInfo.java +++ b/system/de/uka/ilkd/key/java/JavaInfo.java @@ -285,7 +285,7 @@ private String translateArrayType(String s) { return "[B"; else if ("jint[]".equals(s) || "int[]".equals(s)) return "[I"; - else if ("jlong[]".equals(s) || "long[]".equals("s")) + else if ("jlong[]".equals(s) || "long[]".equals(s)) return "[J"; else if ("jshort[]".equals(s) || "short[]".equals(s)) return "[S"; diff --git a/system/de/uka/ilkd/key/java/JavaProgramElement.java b/system/de/uka/ilkd/key/java/JavaProgramElement.java index b8789d6799a..978cd884b31 100644 --- a/system/de/uka/ilkd/key/java/JavaProgramElement.java +++ b/system/de/uka/ilkd/key/java/JavaProgramElement.java @@ -13,7 +13,6 @@ import java.io.IOException; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.reference.ExecutionContext; import de.uka.ilkd.key.rule.MatchConditions; import de.uka.ilkd.key.util.Debug; @@ -85,16 +84,6 @@ public Comment[] getComments() { return comments; } - /** - *@return the annotations. - */ - public Annotation[] getAnnotations(){ - return new Annotation[0]; - } - - public int getAnnotationCount(){ - return 0; - } /** * Template Method. Prints DocComments if existing, calls diff --git a/system/de/uka/ilkd/key/java/KeYProgModelInfo.java b/system/de/uka/ilkd/key/java/KeYProgModelInfo.java index eb503925714..99d4193e326 100644 --- a/system/de/uka/ilkd/key/java/KeYProgModelInfo.java +++ b/system/de/uka/ilkd/key/java/KeYProgModelInfo.java @@ -99,8 +99,7 @@ private recoder.list.MethodList getAllRecoderMethods(KeYJavaType kjt){ return rtd.getAllMethods(); } } - return new recoder.list.MethodArrayList(); - + return new recoder.list.MethodArrayList(); } @@ -309,10 +308,16 @@ private boolean isAssignmentCompatible(recoder.abstraction.ArrayType subType, return false; } - private recoder.list.MethodList getRecoderMethods(KeYJavaType ct){ - recoder.abstraction.ClassType rct - = (recoder.abstraction.ClassType) rec2key().toRecoder(ct); - return rct.getProgramModelInfo().getMethods(rct); + private recoder.list.MethodList getRecoderMethods(KeYJavaType kjt){ + if (kjt.getJavaType() instanceof TypeDeclaration) { + Object o = rec2key().toRecoder(kjt); + if (o instanceof recoder.abstraction.ClassType) { + recoder.abstraction.ClassType rct + = (recoder.abstraction.ClassType) o; + return rct.getProgramModelInfo().getMethods(rct); + } + } + return new recoder.list.MethodArrayList(); } private recoder.list.ConstructorList getRecoderConstructors(KeYJavaType ct){ diff --git a/system/de/uka/ilkd/key/java/Position.java b/system/de/uka/ilkd/key/java/Position.java index 9982f2c5c89..32b30323155 100644 --- a/system/de/uka/ilkd/key/java/Position.java +++ b/system/de/uka/ilkd/key/java/Position.java @@ -23,13 +23,13 @@ public class Position { The line number. */ - private int line; + private final int line; /** The column number. */ - private int column; + private final int column; /** The "undefined position" constant used to compare to undefined diff --git a/system/de/uka/ilkd/key/java/PositionInfo.java b/system/de/uka/ilkd/key/java/PositionInfo.java index 299ad417be8..52db4d6d5ef 100644 --- a/system/de/uka/ilkd/key/java/PositionInfo.java +++ b/system/de/uka/ilkd/key/java/PositionInfo.java @@ -16,9 +16,9 @@ */ public class PositionInfo { - Position relPos; - Position startPos; - Position endPos; + final Position relPos; + final Position startPos; + final Position endPos; String fileName=null; protected String parentClass; diff --git a/system/de/uka/ilkd/key/java/PrettyPrinter.java b/system/de/uka/ilkd/key/java/PrettyPrinter.java index bd77748cc31..01372da99ab 100644 --- a/system/de/uka/ilkd/key/java/PrettyPrinter.java +++ b/system/de/uka/ilkd/key/java/PrettyPrinter.java @@ -1020,7 +1020,8 @@ public void printAssert(Assert x) throws java.io.IOException { } public void printArrayDeclaration(ArrayDeclaration type) throws java.io.IOException { - Type baseType = type.getBaseType().getKeYJavaType().getJavaType(); + Type baseType = type.getBaseType().getKeYJavaType().getJavaType(); + assert baseType != null; if (baseType instanceof ArrayDeclaration) { printArrayDeclaration((ArrayDeclaration)baseType); } else { @@ -2009,6 +2010,36 @@ public void printCopyAssignment(CopyAssignment x) throws java.io.IOException { //write("\n"); printFooter(x); } + + public void printSetAssignment(SetAssignment x) throws java.io.IOException { + printHeader(x); + + markStart(0, x); + if (!noLinefeed) { + writeSymbol(1,0, ""); + } + output(); + + boolean wasNoSemicolons = noSemicolons; + boolean wasNoLinefeed = noLinefeed; + noSemicolons=true; + noLinefeed=true; + + write("#set "); + writeElement(0, x.getArguments().getExpression(0)); + writeToken(0, " = ", x); + writeElement(0, x.getArguments().getExpression(1)); + output(); + + noSemicolons = wasNoSemicolons; + noLinefeed = wasNoLinefeed; + + write(";"); + output(); + markEnd(0, x); + + printFooter(x); + } public void printDivideAssignment(DivideAssignment x) throws java.io.IOException { printHeader(x); diff --git a/system/de/uka/ilkd/key/java/ProgramElement.java b/system/de/uka/ilkd/key/java/ProgramElement.java index d6cb5f07024..fbb2be044a3 100644 --- a/system/de/uka/ilkd/key/java/ProgramElement.java +++ b/system/de/uka/ilkd/key/java/ProgramElement.java @@ -11,7 +11,6 @@ package de.uka.ilkd.key.java; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.rule.MatchConditions; /** @@ -27,12 +26,6 @@ public interface ProgramElement extends SourceElement, ModelElement { */ Comment[] getComments(); - /** - *@return the annotations. - */ - Annotation[] getAnnotations(); - - int getAnnotationCount(); /** diff --git a/system/de/uka/ilkd/key/java/Recoder2KeY.java b/system/de/uka/ilkd/key/java/Recoder2KeY.java index c097ea4c20d..29124d55c28 100644 --- a/system/de/uka/ilkd/key/java/Recoder2KeY.java +++ b/system/de/uka/ilkd/key/java/Recoder2KeY.java @@ -29,12 +29,15 @@ import de.uka.ilkd.key.java.abstraction.*; import de.uka.ilkd.key.java.declaration.*; import de.uka.ilkd.key.java.declaration.modifier.*; +import de.uka.ilkd.key.java.declaration.modifier.Ghost; +import de.uka.ilkd.key.java.declaration.modifier.Model; import de.uka.ilkd.key.java.expression.ArrayInitializer; import de.uka.ilkd.key.java.expression.Literal; import de.uka.ilkd.key.java.expression.ParenthesizedExpression; import de.uka.ilkd.key.java.expression.PassiveExpression; import de.uka.ilkd.key.java.expression.literal.*; import de.uka.ilkd.key.java.expression.operator.*; +import de.uka.ilkd.key.java.expression.operator.SetAssignment; import de.uka.ilkd.key.java.recoderext.*; import de.uka.ilkd.key.java.reference.*; import de.uka.ilkd.key.java.reference.ExecutionContext; @@ -44,7 +47,6 @@ import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.logic.sort.*; -import de.uka.ilkd.key.proof.init.KeYUserProblemFile; import de.uka.ilkd.key.util.Debug; import de.uka.ilkd.key.util.ExtList; import de.uka.ilkd.key.util.KeYResourceManager; @@ -413,7 +415,7 @@ public void parseSpecialClasses() { parsingLibs(true); final recoder.list. - CompilationUnitMutableList specialClasses = parseSpecial(KeYUserProblemFile.parseLibSpecs); + CompilationUnitMutableList specialClasses = parseSpecial(false); final ChangeHistory changeHistory = servConf.getChangeHistory(); for (int i = 0, sz = specialClasses.size(); ilhs + */ + public SetAssignment(Expression lhs, Expression rhs) { + super(lhs, rhs); + } + + + /** + * Get arity. + * @return the int value. + */ + public int getArity() { + return 2; + } + + /** + * Get precedence. + * @return the int value. + */ + public int getPrecedence() { + return 13; + } + + /** + * Get notation. + * @return the int value. + */ + public int getNotation() { + return INFIX; + } + + /** calls the corresponding method of a visitor in order to + * perform some action/transformation on this element + * @param v the Visitor + */ + public void visit(Visitor v) { + v.performActionOnSetAssignment(this); + } + + public void prettyPrint(PrettyPrinter p) throws java.io.IOException { + p.printSetAssignment(this); + } +} diff --git a/system/de/uka/ilkd/key/java/recoderext/Ghost.java b/system/de/uka/ilkd/key/java/recoderext/Ghost.java new file mode 100644 index 00000000000..ccb8278fb58 --- /dev/null +++ b/system/de/uka/ilkd/key/java/recoderext/Ghost.java @@ -0,0 +1,37 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + + +package de.uka.ilkd.key.java.recoderext; + +import recoder.java.SourceVisitor; +import recoder.java.declaration.Modifier; + + +public class Ghost extends Modifier { + + public Ghost() { + } + + + protected Ghost(Ghost proto) { + super(proto); + } + + + public Object deepClone() { + return new Ghost(this); + } + + + public void accept(SourceVisitor v) { + assert false; + } + } diff --git a/system/de/uka/ilkd/key/java/recoderext/ImplicitFieldAdder.java b/system/de/uka/ilkd/key/java/recoderext/ImplicitFieldAdder.java index e4c74062262..8ebd9f448eb 100644 --- a/system/de/uka/ilkd/key/java/recoderext/ImplicitFieldAdder.java +++ b/system/de/uka/ilkd/key/java/recoderext/ImplicitFieldAdder.java @@ -6,13 +6,7 @@ // The KeY system is protected by the GNU General Public License. // See LICENSE.TXT for details. // -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2004 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. +// package de.uka.ilkd.key.java.recoderext; import recoder.CrossReferenceServiceConfiguration; @@ -166,24 +160,24 @@ public ProblemReport analyze() { protected void makeExplicit(TypeDeclaration td) { - addImplicitRecoderFields(td); - - int typeCount = td.getTypeDeclarationCount(); - for (int j = 0; j 0; + + //prepend Java modifiers + PositionedString declWithMods = prependJavaMods(decl.getMods(), + decl.getDecl()); + + //only handle ghost fields + //(model fields are handled later in JMLSpecExtractor) + if(!decl.getMods().contains("ghost")) { + if(decl.getMods().contains("model")) { + return; + } else { + throw new SLTranslationException( + "JML field declaration has to be ghost or model!", + declWithMods.fileName, + declWithMods.pos); + } + } + + //determine parent, child index + NonTerminalProgramElement astParent + = originalComments[0].getParent().getASTParent(); + int childIndex + = astParent.getIndexOfChild(originalComments[0].getParent()); + + //parse declaration, attach to AST + Declaration ghostDecl; + try { + if(astParent instanceof TypeDeclaration) { + ghostDecl + = services.getProgramFactory() + .parseFieldDeclaration(declWithMods.text); + updatePositionInformation(ghostDecl, declWithMods.pos); + attach((FieldDeclaration)ghostDecl, + (TypeDeclaration) astParent, + childIndex); + } else { + assert astParent instanceof StatementBlock; + StatementList declStatement + = services.getProgramFactory() + .parseStatements(declWithMods.text); + assert declStatement.size() == 1; + ghostDecl + = (LocalVariableDeclaration) declStatement.getStatement(0); + updatePositionInformation(ghostDecl, declWithMods.pos); + attach((LocalVariableDeclaration)ghostDecl, + (StatementBlock) astParent, + childIndex); + } + } catch(ParserException e) { + throw new SLTranslationException(e.getMessage() + + " (" + + e.getClass().getName() + + ")", + declWithMods.fileName, + declWithMods.pos, + e.getStackTrace()); + } + + //add ghost modifier + ModifierMutableList mods = new ModifierArrayList(); + mods.add(new Ghost()); + ghostDecl.setModifiers(mods); + + //set comments: the original list of comments with the declaration, + //and the JML modifiers + CommentArrayList newComments = new CommentArrayList(originalComments); + Comment jmlComment = new Comment(getJMLModString(decl.getMods())); + jmlComment.setParent(ghostDecl); + newComments.add(jmlComment); + ghostDecl.setComments(newComments); + } + + + private void transformMethodDecl(TextualJMLMethodDecl decl, + Comment[] originalComments) + throws SLTranslationException { + assert originalComments.length > 0; + + //prepend Java modifiers + PositionedString declWithMods = prependJavaMods(decl.getMods(), + decl.getDecl()); + + //only handle model methods + if(!decl.getMods().contains("model")) { + throw new SLTranslationException( + "JML method declaration has to be model!", + declWithMods.fileName, + declWithMods.pos); + } + + //determine parent, child index + TypeDeclaration astParent + = (TypeDeclaration) originalComments[0].getParent().getASTParent(); + int childIndex + = astParent.getIndexOfChild(originalComments[0].getParent()); + + //parse declaration, attach to AST + MethodDeclaration methodDecl; + try { + methodDecl = services.getProgramFactory() + .parseMethodDeclaration(declWithMods.text); + updatePositionInformation(methodDecl, declWithMods.pos); + attach(methodDecl, astParent, childIndex); + } catch(ParserException e) { + throw new SLTranslationException(e.getMessage() + + " (" + + e.getClass().getName() + + ")", + declWithMods.fileName, + declWithMods.pos, + e.getStackTrace()); + } + + //add model modifier + ModifierMutableList mods = new ModifierArrayList(); + mods.add(new Model()); + methodDecl.setModifiers(mods); + + //set comments: the original list of comments with the declaration, + //and the JML modifiers + CommentArrayList newComments = new CommentArrayList(originalComments); + Comment jmlComment = new Comment(getJMLModString(decl.getMods())); + jmlComment.setParent(methodDecl); + newComments.add(jmlComment); + methodDecl.setComments(newComments); + } + + + private void transformSetStatement(TextualJMLSetStatement stat, + Comment[] originalComments) + throws SLTranslationException { + assert originalComments.length > 0; + + //determine parent, child index + StatementBlock astParent + = (StatementBlock) originalComments[0].getParent().getASTParent(); + int childIndex + = astParent.getIndexOfChild(originalComments[0].getParent()); + + //parse statement, attach to AST + try { + StatementMutableList stmtList + = services.getProgramFactory() + .parseStatements(stat.getAssignment().text); + assert stmtList.size() == 1; + CopyAssignment assignStmt + = (CopyAssignment) stmtList.getStatement(0); + SetAssignment setStmt = new SetAssignment(assignStmt); + updatePositionInformation(setStmt, stat.getAssignment().pos); + attach(setStmt, astParent, childIndex); + } catch(ParserException e) { + throw new SLTranslationException(e.getMessage() + + " (" + + e.getClass().getName() + + ")", + stat.getAssignment().fileName, + stat.getAssignment().pos, + e.getStackTrace()); + } + } + + + private void transformClasslevelComments(TypeDeclaration td, + String fileName) + throws SLTranslationException { + //iterate over all pre-existing children + ProgramElement[] children = getChildren(td); + for(int i = 0; i < children.length; i++) { + Comment[] comments = getCommentsAndSetParent(children[i]); + if(comments.length == 0) { + continue; + } + + //concatenate comments of child, determine position + String concatenatedComment = concatenate(comments); + Position recoderPos = comments[0].getStartPosition(); + de.uka.ilkd.key.java.Position pos + = new de.uka.ilkd.key.java.Position(recoderPos.getLine(), + recoderPos.getColumn()); + + //call preparser + KeYJMLPreParser preParser + = new KeYJMLPreParser(concatenatedComment, fileName, pos); + ListOfTextualJMLConstruct constructs + = preParser.parseClasslevelComment(); + + //handle model and ghost declarations in textual constructs + for(IteratorOfTextualJMLConstruct it = constructs.iterator(); + it.hasNext(); ) { + TextualJMLConstruct c = it.next(); + if(c instanceof TextualJMLFieldDecl) { + transformFieldDecl((TextualJMLFieldDecl)c, comments); + } else if(c instanceof TextualJMLMethodDecl) { + transformMethodDecl((TextualJMLMethodDecl)c, comments); + } + } + } + } + + + private void transformMethodlevelCommentsHelper(ProgramElement pe, + String fileName) + throws SLTranslationException { + //recurse to all pre-existing children + ProgramElement[] children = getChildren(pe); + for(int i = 0; i < children.length; i++) { + transformMethodlevelCommentsHelper(children[i], fileName); + } + + //get comments + Comment[] comments = getCommentsAndSetParent(pe); + if(comments.length == 0) { + return; + } + + //concatenate comments, determine position + String concatenatedComment = concatenate(comments); + Position recoderPos = comments[0].getStartPosition(); + de.uka.ilkd.key.java.Position pos + = new de.uka.ilkd.key.java.Position(recoderPos.getLine(), + recoderPos.getColumn()); + + //call preparser + KeYJMLPreParser preParser + = new KeYJMLPreParser(concatenatedComment, fileName, pos); + ListOfTextualJMLConstruct constructs + = preParser.parseMethodlevelComment(); + + //handle model and ghost declarations in textual constructs + for(IteratorOfTextualJMLConstruct it = constructs.iterator(); + it.hasNext(); ) { + TextualJMLConstruct c = it.next(); + if(c instanceof TextualJMLFieldDecl) { + transformFieldDecl((TextualJMLFieldDecl)c, comments); + } else if(c instanceof TextualJMLSetStatement) { + transformSetStatement((TextualJMLSetStatement)c, comments); + } + } + } + + + private void transformMethodlevelComments(MethodDeclaration md, + String fileName) + throws SLTranslationException { + StatementBlock body = md.getBody(); + if(body != null) { + transformMethodlevelCommentsHelper(body, fileName); + } + } + + + + // ------------------------------------------------------------------------- + // RecoderModelTransformer - abstract methods implementation + // ------------------------------------------------------------------------- + + protected void makeExplicit(TypeDeclaration td) { + assert false; + } + + + public void makeExplicit() { + //abort if library class (TODO: remove this) + if(parsingLibs) { + return; + } + + //abort if JML is disabled + if(!ProofSettings.DEFAULT_SETTINGS.getGeneralSettings().useJML()) { + return; + } + + try { + //iterate over all compilation units + for(int i = 0, m = units.size(); i < m; i++) { + CompilationUnit unit = units.getCompilationUnit(i); + + //iterate over all classes + for(int j = 0, n = unit.getTypeDeclarationCount(); j < n; j++) { + TypeDeclaration td = unit.getTypeDeclarationAt(j); + + //collect pre-existing operations + MethodList constructorList = td.getConstructors(); + MethodList methodList = td.getMethods(); + + transformClasslevelComments(td, unit.getName()); + + //iterate over all pre-existing constructors + for(int k = 0, o = constructorList.size(); k < o; k++) { + if(constructorList.getMember(k) + instanceof ConstructorDeclaration) { + ConstructorDeclaration cd + = (ConstructorDeclaration) + constructorList.getMethod(k); + transformMethodlevelComments(cd, unit.getName()); + } + } + + //iterate over all pre-existing methods + for(int k = 0, o = methodList.size(); k < o; k++) { + MethodDeclaration md + = (MethodDeclaration) + methodList.getMethod(k); + transformMethodlevelComments(md, unit.getName()); + } + + td.makeAllParentRolesValid(); + } + } + } catch(SLTranslationException e) { + RuntimeException runtimeE = new RuntimeException(e); + runtimeE.setStackTrace(e.getStackTrace()); + throw runtimeE; + } + } +} diff --git a/system/de/uka/ilkd/key/java/recoderext/Model.java b/system/de/uka/ilkd/key/java/recoderext/Model.java new file mode 100644 index 00000000000..4149a98bb6e --- /dev/null +++ b/system/de/uka/ilkd/key/java/recoderext/Model.java @@ -0,0 +1,37 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + + +package de.uka.ilkd.key.java.recoderext; + +import recoder.java.SourceVisitor; +import recoder.java.declaration.Modifier; + + +public class Model extends Modifier { + + public Model() { + } + + + protected Model(Model proto) { + super(proto); + } + + + public Object deepClone() { + return new Model(this); + } + + + public void accept(SourceVisitor v) { + assert false; + } + } diff --git a/system/de/uka/ilkd/key/java/recoderext/ProofJavaProgramFactory.java b/system/de/uka/ilkd/key/java/recoderext/ProofJavaProgramFactory.java index 3a6b6c985ec..6da431e2b6d 100644 --- a/system/de/uka/ilkd/key/java/recoderext/ProofJavaProgramFactory.java +++ b/system/de/uka/ilkd/key/java/recoderext/ProofJavaProgramFactory.java @@ -376,6 +376,22 @@ public Statement createCatchAllStatement(ParameterDeclaration decl, return new CatchAllStatement(decl, body); } + /** + * Create a comment. + * @param text comment text + */ + public Comment createComment(String text) { + return new Comment(text); + } + + /** + * Create a comment. + * @param text comment text + */ + public Comment createComment(String text, boolean prefixed) { + return new Comment(text, prefixed); + } + /** * Create an {@link ImplicitIdentifier}. */ @@ -387,6 +403,4 @@ public ImplicitIdentifier createImplicitIdentifier(String text) { public Identifier createIdentifier(String text) { return new ExtendedIdentifier(text); } - - } diff --git a/system/de/uka/ilkd/key/java/recoderext/RecoderModelTransformer.java b/system/de/uka/ilkd/key/java/recoderext/RecoderModelTransformer.java index cfbb61a546d..6100d1412b9 100644 --- a/system/de/uka/ilkd/key/java/recoderext/RecoderModelTransformer.java +++ b/system/de/uka/ilkd/key/java/recoderext/RecoderModelTransformer.java @@ -6,13 +6,8 @@ // The KeY system is protected by the GNU General Public License. // See LICENSE.TXT for details. // -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2004 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden // -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. + package de.uka.ilkd.key.java.recoderext; import recoder.CrossReferenceServiceConfiguration; @@ -39,7 +34,7 @@ * The Java DL requires some implicit fields, that are available in each * Java class. The name of the implicit fields is usually enclosed * between two angle brackets. - * Two access the fields in a uniform way, they are added as usual + * To access the fields in a uniform way, they are added as usual * fields to the classes, in particular this allows us to parse them in * more easier. * For further information see also @@ -114,7 +109,7 @@ public void attach(MethodDeclaration md, TypeDeclaration td, /** * returns if changes have to be reported to the change history - * @return true, iff changes have to be reported to the change history + * @return true, if changes have to be reported to the change history */ public boolean isVisible() { return true; @@ -123,7 +118,7 @@ public boolean isVisible() { /** * The method is called for each type declaration of the compilation * unit and initiates the syntactical transformation. If you want to - * descend in inner classes you have to implement the recusrsion by + * descend in inner classes you have to implement the recursion by * yourself. */ protected abstract void makeExplicit(TypeDeclaration td); diff --git a/system/de/uka/ilkd/key/java/recoderext/SetAssignment.java b/system/de/uka/ilkd/key/java/recoderext/SetAssignment.java new file mode 100644 index 00000000000..5999de0d6a7 --- /dev/null +++ b/system/de/uka/ilkd/key/java/recoderext/SetAssignment.java @@ -0,0 +1,68 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + + +package de.uka.ilkd.key.java.recoderext; + +import recoder.java.Expression; +import recoder.java.SourceVisitor; +import recoder.java.expression.Assignment; +import recoder.java.expression.operator.CopyAssignment; + + + +public class SetAssignment extends Assignment { + + public SetAssignment() { + // nothing to do + } + + public SetAssignment(Expression lhs, Expression rhs) { + super(lhs, rhs); + makeParentRoleValid(); + } + + + protected SetAssignment(SetAssignment proto) { + super(proto); + makeParentRoleValid(); + } + + + public SetAssignment(CopyAssignment proto) { + super(proto); + makeParentRoleValid(); + } + + + public Object deepClone() { + return new SetAssignment(this); + } + + + public int getArity() { + return 2; + } + + + public int getPrecedence() { + return 13; + } + + + public int getNotation() { + return INFIX; + } + + + public void accept(SourceVisitor v) { + assert false; //uh oh + } + } diff --git a/system/de/uka/ilkd/key/java/reference/MethodReference.java b/system/de/uka/ilkd/key/java/reference/MethodReference.java index 2e97740acec..3e4058e4a24 100644 --- a/system/de/uka/ilkd/key/java/reference/MethodReference.java +++ b/system/de/uka/ilkd/key/java/reference/MethodReference.java @@ -286,10 +286,6 @@ public ProgramMethod method(Services services, final String methodName = name.toString(); ProgramMethod pm = services.getJavaInfo().getProgramMethod(classType, methodName, signature, context); - if(pm == null){ - pm = services.getImplementation2SpecMap(). - lookupModelMethod(classType, new Name(methodName)); - } return pm; } diff --git a/system/de/uka/ilkd/key/java/statement/Do.java b/system/de/uka/ilkd/key/java/statement/Do.java index 802000c770c..788c4e95d6c 100644 --- a/system/de/uka/ilkd/key/java/statement/Do.java +++ b/system/de/uka/ilkd/key/java/statement/Do.java @@ -12,7 +12,6 @@ package de.uka.ilkd.key.java.statement; import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.visitor.Visitor; import de.uka.ilkd.key.util.ExtList; @@ -51,9 +50,8 @@ public Do(Expression guard, Statement body, ExtList l, PositionInfo pos) { * @param guard an expression. * @param body a statement. */ - public Do(Expression guard, Statement body, PositionInfo pos, - Annotation[] a) { - super(guard, body, a, pos); + public Do(Expression guard, Statement body, PositionInfo pos) { + super(guard, body, pos); } diff --git a/system/de/uka/ilkd/key/java/statement/LoopStatement.java b/system/de/uka/ilkd/key/java/statement/LoopStatement.java index 723b9e133f0..52192487021 100644 --- a/system/de/uka/ilkd/key/java/statement/LoopStatement.java +++ b/system/de/uka/ilkd/key/java/statement/LoopStatement.java @@ -14,8 +14,6 @@ package de.uka.ilkd.key.java.statement; import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.annotation.Annotation; -import de.uka.ilkd.key.java.annotation.LoopInvariantAnnotation; import de.uka.ilkd.key.util.ExtList; /** @@ -49,8 +47,6 @@ public abstract class LoopStatement extends JavaStatement */ protected final Statement body; - protected Annotation[] annotations = new Annotation[0]; - /** * Loop statement. */ @@ -109,22 +105,20 @@ public LoopStatement(Expression guard,Statement body,ExtList comments, PositionI * Loop statement. * @param body a statement. */ - public LoopStatement(Expression guard,Statement body, Annotation[] a) { + public LoopStatement(Expression guard,Statement body) { this.body = body; this.updates = null; this.inits = null; this.guard = new Guard(guard); - this.annotations = a; } public LoopStatement(Expression guard, Statement body, - Annotation[] a, PositionInfo pos) { + PositionInfo pos) { super(add(new ExtList(),pos)); this.body = body; this.updates = null; this.inits = null; this.guard = new Guard(guard); - this.annotations = a; } @@ -165,7 +159,6 @@ public LoopStatement(ILoopInit inits, IGuard guard, this.updates = updates; this.inits = inits; this.guard = guard; - this.annotations = (Annotation[]) comments.collect(Annotation.class); } @@ -177,7 +170,6 @@ public LoopStatement(ILoopInit inits, IGuard guard, this.updates = updates; this.inits = inits; this.guard = guard; - this.annotations = (Annotation[]) comments.collect(Annotation.class); } @@ -381,32 +373,6 @@ public IForUpdates getIForUpdates() { return updates; } - /** - *@return the annotations. - */ - public Annotation[] getAnnotations(){ - return annotations; - } - - public int getAnnotationCount(){ - return annotations.length; - } - - /** - * Don't use this method !!! - */ - // HACK: loop invariants are parsed after this LoopStatement has already - // been created, that's why they are set afterwards. - // TODO: find a better solution which is compatible with the immutability - // of ProgramElements. - public void addLoopInvariant(LoopInvariantAnnotation a){ - Annotation[] result = new Annotation[annotations.length+1]; - for(int i = 0; ia. - */ - protected void performActionOnAnnotationArray(Annotation[] a){ - // do nothing - } - } diff --git a/system/de/uka/ilkd/key/java/visitor/LabelCollector.java b/system/de/uka/ilkd/key/java/visitor/LabelCollector.java index 27066ebc24d..98a1065cbc5 100644 --- a/system/de/uka/ilkd/key/java/visitor/LabelCollector.java +++ b/system/de/uka/ilkd/key/java/visitor/LabelCollector.java @@ -4,6 +4,7 @@ import de.uka.ilkd.key.java.Label; import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.SourceElement; /** @@ -13,8 +14,10 @@ public class LabelCollector extends JavaASTVisitor { private HashSet labels; - public LabelCollector(ProgramElement root, HashSet labels) { - super(root); + public LabelCollector(ProgramElement root, + HashSet labels, + Services services) { + super(root, services); this.labels = labels; } diff --git a/system/de/uka/ilkd/key/java/visitor/ProgVarReplaceVisitor.java b/system/de/uka/ilkd/key/java/visitor/ProgVarReplaceVisitor.java index cb274f3f35d..39b151421b2 100644 --- a/system/de/uka/ilkd/key/java/visitor/ProgVarReplaceVisitor.java +++ b/system/de/uka/ilkd/key/java/visitor/ProgVarReplaceVisitor.java @@ -10,16 +10,19 @@ package de.uka.ilkd.key.java.visitor; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; import de.uka.ilkd.key.java.ProgramElement; -import de.uka.ilkd.key.java.annotation.Annotation; -import de.uka.ilkd.key.java.annotation.LoopInvariantAnnotation; +import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.declaration.ArrayOfVariableSpecification; import de.uka.ilkd.key.java.declaration.LocalVariableDeclaration; +import de.uka.ilkd.key.java.statement.LoopStatement; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.op.*; +import de.uka.ilkd.key.speclang.LoopInvariant; +import de.uka.ilkd.key.speclang.LoopInvariantImpl; import de.uka.ilkd.key.util.Debug; import de.uka.ilkd.key.util.ExtList; @@ -28,43 +31,33 @@ * replaces a number of program variables by others or new ones. */ public class ProgVarReplaceVisitor extends CreatingASTVisitor { - + private ProgramElement result=null; // indicates if ALL program variables are to be replace by new // variables with the same name protected boolean replaceallbynew=true; + /** * stores the program variables to be replaced as keys and the new * program variables as values */ protected Map replaceMap; - /** - * creates a visitor that replaces the program variables in the given - * statement by new ones with the same name - * @param st the statement where the prog vars are replaced - * @param oldPVs the program variables that are replaced - */ - public ProgVarReplaceVisitor(ProgramElement st, ProgramVariable[] oldPVs) { - super(st, true); - replaceMap=new HashMap(); - for (int i=0; iMethodCall to @@ -94,6 +82,7 @@ public static ProgramVariable copy(ProgramVariable pv) { return copy(pv, ""); } + //%%% HACK: there should be a central facility for introducing new program // variables; this method is also used in MethodCall to // create copies of parameter variables @@ -122,6 +111,7 @@ protected void walk(ProgramElement node) { super.walk(node); } + /** the action that is performed just before leaving the node the * last time */ @@ -129,6 +119,7 @@ protected void doAction(ProgramElement node) { node.visit(this); } + /** starts the walker*/ public void start() { stack.push(new ExtList()); @@ -141,10 +132,12 @@ public void start() { result=(ProgramElement) stack.peek().get(i); } + public ProgramElement result() { return result; } + public void performActionOnProgramVariable(ProgramVariable pv) { ProgramElement newPV = (ProgramElement) replaceMap.get(pv); if (newPV!=null) { @@ -155,42 +148,7 @@ public void performActionOnProgramVariable(ProgramVariable pv) { } } - /** - * Performs action on the annotations a. - */ - protected void performActionOnAnnotationArray(Annotation[] a){ - for(int i = 0; i0){ - changed(); - } - } - + private Term replaceVariablesInTerm(Term t){ if(t==null) return null; if (t.op() instanceof ProgramVariable){ @@ -267,22 +225,85 @@ private SetOfLocationDescriptor replaceVariablesInLocs( return res; } - - private ArrayOfTerm replaceVariablesInTerms(ArrayOfTerm terms) { - Term[] res = new Term[terms.size()]; - - for(int i = 0; i < res.length; i++) { - res[i] = replaceVariablesInTerm(terms.getTerm(i)); + + private SetOfTerm replaceVariablesInTerms(SetOfTerm terms) { + SetOfTerm res = SetAsListOfTerm.EMPTY_SET; + + IteratorOfTerm it = terms.iterator(); + while(it.hasNext()) { + res = res.add(replaceVariablesInTerm(it.next())); } - return new ArrayOfTerm(res); + return res; } - + + + private Map /*Operator -> Function*/ replaceVariablesInMap( + Map /*Operator -> Function*/ map) { + Map result = new LinkedHashMap(); + Iterator it = map.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + Operator key = (Operator) entry.getKey(); + Function value = (Function) entry.getValue(); + + Operator newKey = (ProgramVariable) replaceMap.get(key); + if(newKey == null) { + newKey = key; + } + + result.put(newKey, value); + } + return result; + } + + public void performActionOnLocationVariable(LocationVariable x) { performActionOnProgramVariable(x); } + public void performActionOnProgramConstant(ProgramConstant x) { performActionOnProgramVariable(x); } + + + public void performActionOnLoopInvariant(LoopStatement oldLoop, + LoopStatement newLoop) { + LoopInvariant inv + = services.getSpecificationRepository().getLoopInvariant(oldLoop); + if(inv != null) { + ParsableVariable selfVar = ((LoopInvariantImpl) inv).getSelfVar(); + Term selfTerm = (selfVar != null + ? TermBuilder.DF.var(selfVar) + : null); + Term newInvariant + = replaceVariablesInTerm(inv.getInvariant(selfTerm)); + SetOfTerm newPredicates + = replaceVariablesInTerms(inv.getPredicates(selfTerm)); + boolean newPredicateHeuristicsAllowed + = inv.getPredicateHeuristicsAllowed(); + SetOfLocationDescriptor newModifies + = replaceVariablesInLocs(inv.getModifies(selfTerm)); + Term newVariant + = replaceVariablesInTerm(inv.getVariant(selfTerm)); + ParsableVariable newSelfVar + = (ProgramVariable)replaceMap.get(selfVar); + Map newAtPreFunctions + = replaceVariablesInMap(inv.getAtPreFunctions()); + if(newSelfVar == null) { + newSelfVar = selfVar; + } + LoopInvariant newInv + = new LoopInvariantImpl(newLoop, + newInvariant, + newPredicates, + newModifies, + newVariant, + newSelfVar, + newAtPreFunctions, + newPredicateHeuristicsAllowed); + services.getSpecificationRepository().setLoopInvariant(newInv); + } + } } diff --git a/system/de/uka/ilkd/key/java/visitor/ProgramReplaceVisitor.java b/system/de/uka/ilkd/key/java/visitor/ProgramReplaceVisitor.java index 8caab77c345..458d4170994 100644 --- a/system/de/uka/ilkd/key/java/visitor/ProgramReplaceVisitor.java +++ b/system/de/uka/ilkd/key/java/visitor/ProgramReplaceVisitor.java @@ -32,7 +32,6 @@ public class ProgramReplaceVisitor extends CreatingASTVisitor { private ProgramElement result = null; - private Services services; private SVInstantiations svinsts; private boolean allowPartialReplacement; @@ -45,8 +44,7 @@ public ProgramReplaceVisitor(ProgramElement root, Services services, SVInstantiations svi, boolean allowPartialReplacement) { - super(root, false); - this.services = services; + super(root, false, services); svinsts = svi; this.allowPartialReplacement=allowPartialReplacement; } diff --git a/system/de/uka/ilkd/key/java/visitor/ProgramSVCollector.java b/system/de/uka/ilkd/key/java/visitor/ProgramSVCollector.java index f98e65e6687..8a630fe7411 100644 --- a/system/de/uka/ilkd/key/java/visitor/ProgramSVCollector.java +++ b/system/de/uka/ilkd/key/java/visitor/ProgramSVCollector.java @@ -8,17 +8,12 @@ // // package de.uka.ilkd.key.java.visitor; -import de.uka.ilkd.key.java.JavaProgramElement; import de.uka.ilkd.key.java.ProgramElement; -import de.uka.ilkd.key.java.annotation.Annotation; -import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.op.ListOfSchemaVariable; import de.uka.ilkd.key.logic.op.SLListOfSchemaVariable; import de.uka.ilkd.key.logic.op.SchemaVariable; import de.uka.ilkd.key.rule.inst.SVInstantiations; -import de.uka.ilkd.key.rule.metaconstruct.UnwindLoop; -import de.uka.ilkd.key.rule.metaconstruct.WhileInvRule; -import de.uka.ilkd.key.rule.metaconstruct.WhileInvRuleWrapper; +import de.uka.ilkd.key.rule.metaconstruct.MetaConstructWithSV; /** * This visitor is used to collect all appearing SchemaVariables in a @@ -68,28 +63,21 @@ public ListOfSchemaVariable getSchemaVariables() { return result; } - /** the action that is performed just before leaving the node the - * last time + /** + * the action that is performed just before leaving the node the last time. + * Not only schema variables must be taken into consideration, but also + * program meta constructs with implicit schema variables containment + * + * @see MetaConstructWithSV */ protected void doAction(ProgramElement node) { - // System.out.println("bbbbbbbbbbbbbbb "+node+(node instanceof WhileInvRuleWrapper)); + // System.out.println("bbbbbbbbbbbbbbb "+node+(node instanceof + // WhileInvRuleWrapper)); if (node instanceof SchemaVariable) { - result = result.prepend((SchemaVariable)node); - } else if (node instanceof UnwindLoop) { - final UnwindLoop uwl = (UnwindLoop)node; - result= result.prepend(uwl.getInnerLabelSV()).prepend(uwl.getOuterLabelSV()); - } else if (node instanceof WhileInvRuleWrapper) { - Term t = ((WhileInvRuleWrapper)node).unwrap(); - WhileInvRule wir = (WhileInvRule)t.op(); - JavaProgramElement jpe = t.sub(0).javaBlock().program(); - result = - result.prepend(wir.neededInstantiations - ((ProgramElement)jpe, instantiations)); + result = result.prepend((SchemaVariable) node); + } else if (node instanceof MetaConstructWithSV) { + MetaConstructWithSV mc = (MetaConstructWithSV)node; + result = result.prepend(mc.neededInstantiations(instantiations)); } } - - protected void performActionOnAnnotationArray(Annotation[] a){ - // do nothing - } - } diff --git a/system/de/uka/ilkd/key/java/visitor/ProgramTypeCollector.java b/system/de/uka/ilkd/key/java/visitor/ProgramTypeCollector.java index f2de05a897e..9e7e5721685 100644 --- a/system/de/uka/ilkd/key/java/visitor/ProgramTypeCollector.java +++ b/system/de/uka/ilkd/key/java/visitor/ProgramTypeCollector.java @@ -37,28 +37,19 @@ public class ProgramTypeCollector extends JavaASTVisitor { private HashSet result = new HashSet(); private HashSet programMethods = new HashSet(); private KeYJavaType type; - private Services services; private ProgramVariable self; private Set alreadyVisitedProgramMethods; public ProgramTypeCollector(ProgramElement root, ProgramVariable self, KeYJavaType type, Services services, Set alreadyVisitedProgramMethods) { - super(root); + super(root, services); this.type = type; this.self=self; - this.services = services; this.alreadyVisitedProgramMethods = alreadyVisitedProgramMethods; } - /** the action that is performed just before leaving the node the - * last time - */ - protected void doAction(ProgramElement node) { - node.visit(this); - } - /** starts the walker*/ public void start() { walk(root()); diff --git a/system/de/uka/ilkd/key/java/visitor/ProgramVariableCollector.java b/system/de/uka/ilkd/key/java/visitor/ProgramVariableCollector.java index a1bc6a1dfe0..cfe3522ad8c 100644 --- a/system/de/uka/ilkd/key/java/visitor/ProgramVariableCollector.java +++ b/system/de/uka/ilkd/key/java/visitor/ProgramVariableCollector.java @@ -12,15 +12,16 @@ import java.util.HashSet; import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.SourceElement; -import de.uka.ilkd.key.java.annotation.Annotation; -import de.uka.ilkd.key.java.annotation.LoopInvariantAnnotation; -import de.uka.ilkd.key.logic.ArrayOfTerm; +import de.uka.ilkd.key.logic.IteratorOfTerm; import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.op.AttributeOp; +import de.uka.ilkd.key.logic.TermBuilder; import de.uka.ilkd.key.logic.op.LocationVariable; import de.uka.ilkd.key.logic.op.ProgramConstant; import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.rule.soundness.TermProgramVariableCollector; +import de.uka.ilkd.key.speclang.LoopInvariant; /** * Walks through a java AST in depth-left-fist-order. @@ -28,36 +29,18 @@ */ public class ProgramVariableCollector extends JavaASTVisitor { - private HashSet result = new HashSet(); - private boolean wAnnotations; + private static final TermBuilder TB = TermBuilder.DF; + private final HashSet result = new HashSet(); /** * collects all program variables occuring in the AST root * using this constructor is equivalent to ProggramVariableCollector(root, false) * @param root the ProgramElement which is the root of the AST + * @param services the Services object */ - public ProgramVariableCollector(ProgramElement root) { - super(root); - } - - /** - * collects all program variables occuring in the AST root - * - * @param root the ProgramElement which is the root of the AST - * @param wAnnotations a boolean flag, if set to true program variables in - * annotations will be collected, too - */ - public ProgramVariableCollector(ProgramElement root, boolean wAnnotations) { - super(root); - this.wAnnotations = wAnnotations; - } - - - /** the action that is performed just before leaving the node the - * last time - */ - protected void doAction(ProgramElement node) { - node.visit(this); + public ProgramVariableCollector(ProgramElement root, Services services) { + super(root, services); + assert services != null; } /** starts the walker*/ @@ -79,51 +62,7 @@ protected void doDefaultAction(SourceElement x) { public void performActionOnProgramVariable(ProgramVariable pv) { result.add(pv); } - - private void performActionOnTerm(Term t) { - if(t != null){ - if (t.op() instanceof AttributeOp) { - result.add(((AttributeOp) t.op()).attribute()); - } else if (t.op() instanceof ProgramVariable) { - result.add(t.op()); - } - - for (int i = 0, ar = t.arity(); imd. - */ - public void clearSpecsForMethod(ProgramMethod md){ - method2specs.remove(md); - } - - public void addModifier(ProgramMethod md, String modifier){ - if(method2JMLModifiers.get(md) == null){ - method2JMLModifiers.put(md, SetAsListOfString.EMPTY_SET.add( - modifier)); - }else{ - method2JMLModifiers.put( - md,((SetAsListOfString) method2JMLModifiers.get(md)). - add(modifier)); - } - } - - public void addLoopSpec(LoopInvariant l){ - loop2spec.put(l.getLoop(), l); - } - - public void clearSpecsForLoop(LoopStatement ls){ - loop2spec.remove(ls); - } - - public LoopInvariant getSpecForLoop(LoopStatement ls){ - return (LoopInvariant) loop2spec.get(ls); - } - - /** - * Creates LoopInvariantAnnotations from the parsed loop specifications and - * adds them to the correcponding loop statements. - */ - public void createLoopAnnotations(){ - Iterator it = loop2spec.keySet().iterator(); - while(it.hasNext()){ - LoopStatement loop = (LoopStatement) it.next(); - LoopInvariant li = (LoopInvariant) loop2spec.get(loop); - SetOfLocationDescriptor assignable; - if("nothing".equals(li.getAssignableMode())){ - assignable = SetAsListOfLocationDescriptor.EMPTY_SET; - }else if("everything".equals(li.getAssignableMode())){ - assignable = SetAsListOfLocationDescriptor.EMPTY_SET.add( - EverythingLocationDescriptor.INSTANCE); - }else{ - assignable = li.getAssignable(); - } - Term[] olds = new Term[2*li.getTerm2Old().size()]; - Iterator kit = li.getTerm2Old().keySet().iterator(); - int i = 0; - while(kit.hasNext()){ - Term t = (Term) kit.next(); - olds[i++] = t; - olds[i++] = (Term) li.getTerm2Old().get(t); - } - loop.addLoopInvariant(new LoopInvariantAnnotation( - li.getInvariant(), assignable, - new ArrayOfTerm(olds), li.getVariant(), - li.getPost(), li.getSelfVar())); - } - } - - /** - * adds the pure-modifier to every constructor and instance method declared - * in kjt - */ - public void setPure(KeYJavaType kjt, NamespaceSet nss, String javaPath){ - ListOfProgramMethod l = services.getJavaInfo().getAllProgramMethods(kjt); - IteratorOfProgramMethod it = l.iterator(); - ProgramMethod md; - while(it.hasNext()){ - md = it.next(); - if(!md.isStatic()){ - new JMLPuritySpec(md, services, - UsefulTools.buildParamNamespace(md.getMethodDeclaration()), - new LinkedHashMap(), getSpecForClass(kjt), nss, javaPath); - //%% How get the java path here??? - addModifier(md, "pure"); - } - } - } - - /** - * returns a list of KeYJavaTypes, that contain a specification for the - * method with the name name, in depth first order. - */ - public ListOfKeYJavaType findSpecifications(String name, - KeYJavaType classType){ - ListOfKeYJavaType types = findSpecificationsInSubT(name, classType); - types = types.append(findSpecificationsInSuperT(name, classType)); - return types; - } - - private ListOfKeYJavaType findSpecificationsInSubT(String name, - KeYJavaType classType) { - ListOfKeYJavaType types = SLListOfKeYJavaType.EMPTY_LIST; - JMLClassSpec cSpec = getSpecForClass(classType); - // TypeDeclaration td = cSpec.getClassDeclaration(); - // %%RB are here all subtypes needed or only the direct ones - ListOfKeYJavaType subtypes = - services.getJavaInfo().getAllSubtypes(classType); - if(cSpec != null && cSpec.lookupModelMethodLocally(name) != null){ - types = types.prepend(classType); - } - IteratorOfKeYJavaType it = subtypes.iterator(); - while(it.hasNext()){ - types = types.prepend(findSpecificationsInSubT(name, it.next())); - } - return types; - } - - private ListOfKeYJavaType findSpecificationsInSuperT(String name, - KeYJavaType classType){ - ListOfKeYJavaType result = SLListOfKeYJavaType.EMPTY_LIST; - ListOfKeYJavaType sts = - ((TypeDeclaration) classType.getJavaType()).getSupertypes(); - IteratorOfKeYJavaType it = sts.iterator(); - while(it.hasNext()){ - KeYJavaType current = it.next(); - JMLClassSpec cSpec = getSpecForClass(current); - if(cSpec != null && cSpec.lookupModelMethodLocally(name) != null){ - return result.append(current); - }else{ - result = findSpecificationsInSuperT(name, current); - if(result != SLListOfKeYJavaType.EMPTY_LIST){ - return result; - } - } - } - return SLListOfKeYJavaType.EMPTY_LIST; - } - - /** - * returns the method methodName if such a method is declared - * in classType, null otherwise. - */ - public ProgramMethod lookupModelMethod(KeYJavaType classType, - Name methodName){ - JMLClassSpec spec = getSpecForClass(classType); - ProgramMethod pm = null; - if(spec != null){ - try{ - pm = spec.lookupModelMethod(methodName); - }catch(AmbigiousModelElementException e){ - System.err.println(e.toString()); - } - } - return pm; - } - - - /** - * returns the field fieldName if such an attribute is - * declared in classType, null otherwise. - */ - public ProgramVariable lookupModelField(KeYJavaType classType, - String fieldName){ - JMLClassSpec spec = getSpecForClass(classType); - ProgramVariable v = null; - if(spec != null){ - try{ - v = spec.lookupModelField(new Name(fieldName)); - }catch(AmbigiousModelElementException e){ - System.err.println(e.toString()); - } - } - return v; - } - - public SetOfString getModifiers(ProgramMethod md){ - if(method2JMLModifiers.get(md) != null){ - return (SetOfString) method2JMLModifiers.get(md); - }else{ - return SetAsListOfString.EMPTY_SET; - } - } - - /** checks whether the methods annotated with the pureModifier really - * have no side effect. This is done by allowing only normal_behavior - * specs with \nothing as assignable clause which is slightly different - * to jml definition of purity which allows the possibility of throwing - * exceptions. - */ -/* public void checkPurity(){ - Iterator it = method2JMLModifiers.keySet().iterator(); - while(it.hasNext()){ - MethodDeclaration md = (MethodDeclaration) it.next(); - SetOfString set = (SetOfString) method2JMLModifiers.get(md); - if(set.contains("pure")){ - SetOfJMLMethodSpec specs = getSpecsForMethod(md); - if(specs != null){ - IteratorOfJMLMethodSpec spit = specs.iterator(); - while(spit.hasNext()){ - JMLMethodSpec spec = spit.next(); - if(!(spec instanceof JMLNormalMethodSpec)){ - JOptionPane.showConfirmDialog - (null, - "One of your specification cases for the "+ - "pure method\n"+md.getName()+ - "\nis not a normal_behavior specification case", - "Warning", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE); - } - if(!spec.terminates()){ - JOptionPane.showConfirmDialog - (null, - "Your specification for the pure method\n"+ - md.getName()+ - "\nallows nontermination", - "Warning", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE); - } - if(!(md instanceof ConstructorDeclaration)){ - if(!"nothing".equals(spec.getAssignableMode())){ - JOptionPane.showConfirmDialog - (null, - "Pure Methods may not"+ - " assign to any fields. "+ - "\nplease check your specifications for "+ - md.getName(), - "Inconsistent Specification", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE); - } - }else{ - IteratorOfTerm itt = - spec.getAssignable().iterator(); - while(itt.hasNext()){ - checkStatic(itt.next(), md); - } - } - } - } - } - } - } - - private void checkStatic(Term t, MethodDeclaration md){ - if(t.op() instanceof ProgramVariable && - !((ProgramVariable) t.op()).isStatic()){ - JOptionPane.showConfirmDialog - (null, - "Pure Constructors may only"+ - " assign to static fields. "+ - "\nthat's why "+ - md.getName()+" can't be declared pure", - "Inconsistent Specification", - JOptionPane.DEFAULT_OPTION, - JOptionPane.WARNING_MESSAGE); - } - if(t.op() instanceof AttributeOp){ - checkStatic(t.sub(0), md); - } - if(t.op() instanceof ArrayOp){ - checkStatic(t.sub(0), md); - checkStatic(t.sub(1), md); - } - } -*/ - - public void addClassSpec(JMLClassSpec cs){ - class2spec.put(services.getJavaInfo(). - getKeYJavaType(cs.getClassDeclaration()), cs); - } - - public JMLClassSpec getSpecForClass(KeYJavaType classType){ - return (JMLClassSpec) class2spec.get(classType); - } - - public void removeMethodSpec(JMLMethodSpec ms){ - if(method2specs.get(ms.getProgramMethod()) != null){ - method2specs.put(ms.getProgramMethod(), - ((SetOfJMLMethodSpec) method2specs. - get(ms.getProgramMethod())).remove(ms)); - } - } - - public void removeClassSpec(JMLClassSpec cs){ - class2spec.remove(services.getJavaInfo(). - getKeYJavaType(cs.getClassDeclaration())); - } - - public Implementation2SpecMap copy(Services serv){ - Implementation2SpecMap ism = - new Implementation2SpecMap((HashMap)method2specs.clone(), - (TreeMap)class2spec.clone(), - (HashMap)method2JMLModifiers.clone(), - (HashMap)inheritedSpecCache.clone(), - (HashMap)loop2spec.clone(), - serv); - // ism.setProgVarNS(getProgVarNS()); - return ism; - } - - public boolean equals(Object o){ - if(!(o instanceof Implementation2SpecMap)){ - return false; - } - Implementation2SpecMap ism = (Implementation2SpecMap) o; - return ism.method2specs.equals(method2specs) && ism.class2spec. - equals(class2spec) && ism.loop2spec.equals(loop2spec); - } - - public int hashCode(){ - return method2specs.hashCode() + 5*class2spec.hashCode() + - 17*loop2spec.hashCode(); - } - - /** - * returns all methoddeclarations in this map. - */ - public Set getAllMethods(){ - return method2specs.keySet(); - } - - /** - * returns all classtypes in this map. - */ - public Set getAllClasses(){ - return class2spec.keySet(); - } - - public SetOfJMLMethodSpec getInheritedMethodSpecs(ProgramMethod md, - KeYJavaType classType){ - InhKey key = new InhKey(md, classType); - if(inheritedSpecCache.get(key) != null){ - return (SetOfJMLMethodSpec) inheritedSpecCache.get(key); - } - SetOfJMLMethodSpec inh = SetAsListOfJMLMethodSpec.EMPTY_SET; - if(classType.getJavaType() instanceof InterfaceDeclaration || - /*"equals".equals(md.getName()) ||*/ "finalize".equals(md.getName()) || - "wait".equals(md.getName()) || "getClass".equals(md.getName())){ - return inh; - } - ListOfKeYJavaType st = - services.getJavaInfo().getAllSupertypes(classType); - IteratorOfKeYJavaType it = st.iterator(); - ListOfKeYJavaType alreadyVisited = SLListOfKeYJavaType.EMPTY_LIST; - alreadyVisited = alreadyVisited.append(classType); - while(it.hasNext()){ - KeYJavaType current = it.next(); - if(alreadyVisited.contains(current)){ - continue; - }else{ - alreadyVisited = alreadyVisited.append(current); - } - ListOfProgramMethod l = - services.getJavaInfo().getAllProgramMethods(current); - IteratorOfProgramMethod pmIt = l.iterator(); - while(pmIt.hasNext()){ - SetOfJMLMethodSpec specs = getSpecsForMethod(pmIt.next()); - if(specs != null){ - IteratorOfJMLMethodSpec sIt = specs.iterator(); - while(sIt.hasNext()){ - JMLMethodSpec spec = sIt.next(); - if(!(spec instanceof JMLPuritySpec) && - spec.isCloneableFor(md) && - getSpecForClass(classType) != null && - spec.getInheritedPrefix() == null){ - inh = inh.add(spec.cloneFor(md, - getSpecForClass(classType))); - }else if(!spec.isCloneableFor(md)){ - break; - } - } - } - } - } - inheritedSpecCache.put(key, inh); - return inh; - } - - final static class TypeComparator implements Comparator { - - public int compare(Object o1, Object o2) { - final KeYJavaType type1 = (KeYJavaType) o1; - final KeYJavaType type2 = (KeYJavaType) o2; - // attention this is only sane as long as types - // are uniquely identified by their name - return type1.getFullName().compareTo(type2.getFullName()); - } - } - - private static class InhKey{ - - protected ProgramMethod md; - protected KeYJavaType ct; - - public InhKey(ProgramMethod md, KeYJavaType ct){ - this.md = md; - this.ct = ct; - } - - public boolean equals(Object o){ - if(!(o instanceof InhKey)) return false; - return ((InhKey) o).md == md && ((InhKey) o).ct == ct; - } - - public int hashCode(){ - return md.hashCode() + 31*ct.hashCode(); - } - } -} diff --git a/system/de/uka/ilkd/key/jml/JMLClassSpec.java b/system/de/uka/ilkd/key/jml/JMLClassSpec.java deleted file mode 100644 index 3bcd043187d..00000000000 --- a/system/de/uka/ilkd/key/jml/JMLClassSpec.java +++ /dev/null @@ -1,824 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2003 Universitaet Karlsruhe, Germany -// and Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.jml; - -import java.util.HashMap; -import java.util.LinkedHashMap; - -import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.abstraction.Constructor; -import de.uka.ilkd.key.java.abstraction.IteratorOfKeYJavaType; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; -import de.uka.ilkd.key.java.declaration.*; -import de.uka.ilkd.key.java.declaration.modifier.Model; -import de.uka.ilkd.key.java.declaration.modifier.Public; -import de.uka.ilkd.key.java.declaration.modifier.Static; -import de.uka.ilkd.key.java.expression.operator.CopyAssignment; -import de.uka.ilkd.key.java.expression.operator.New; -import de.uka.ilkd.key.java.recoderext.ClassInitializeMethodBuilder; -import de.uka.ilkd.key.java.recoderext.ImplicitFieldAdder; -import de.uka.ilkd.key.java.reference.ExecutionContext; -import de.uka.ilkd.key.java.reference.ReferencePrefix; -import de.uka.ilkd.key.java.reference.TypeRef; -import de.uka.ilkd.key.java.statement.*; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.util.ExtList; - -/** wraps specifications that are valid for the entire class (e.g. invariants - * or history constraints) or interface - */ -public class JMLClassSpec extends JMLSpec { - - private Term instInv, instCon, staticInv, staticCon; - private LinkedHashMap term2old; - private LinkedHashMap represents; -// private HashMap suchthat; - private ReferencePrefix staticPrefix; - private ReferencePrefix instancePrefix; - private Services services; - /** the class or interfacedeclaration this specification refers to */ - private TypeDeclaration cd; - // the KeYJavaType of cd - private KeYJavaType type; - private Namespace modelVars; - private Namespace modelMethods; - private NamespaceSet nss; - private KeYJavaType objectKeYJavaType; - protected static Term trueTerm = null; - protected static Term falseTerm = null; - private String javaPath; - - // flag which is set to false iff static initialisation features should be suppressed - protected boolean staticInit=false; - - public JMLClassSpec(Services services, TypeDeclaration cd, - NamespaceSet nss, String javaPath){ - - progVarNS = new Namespace(); - funcNS = new Namespace(); - - - term2old = new LinkedHashMap(); - this.services = services; - objectKeYJavaType = services.getJavaInfo().getJavaLangObject(); - - this.cd = cd; - instCon = null; - staticCon = null; - instInv = null; - staticInv = null; - - type = services.getJavaInfo().getKeYJavaType(cd); - staticPrefix = new TypeRef(type); - instancePrefix = new LocationVariable( - new ProgramElementName("self_"+cd.getName().replace('.', '_') - .replace('<', '_').replace('>', '_')), - type); - progVarNS.add((ProgramVariable) instancePrefix); - modelVars = new Namespace(); - modelMethods = new Namespace(); - represents = new LinkedHashMap(); -// suchthat = new HashMap(); - this.nss = nss; - services.getImplementation2SpecMap().addClassSpec(this); - if(trueTerm == null){ - trueTerm = tt(); - } - if(falseTerm == null){ - falseTerm = ff(); - } - this.javaPath = javaPath; - } - - public boolean containsInvOrConst(){ - return (staticCon != null || - staticInv != null || - instCon != null || - instInv != null); - } - - public Services getServices(){ - return services; - } - - /** - * returns the class or interfacedeclaration this specification refers to. - */ - public TypeDeclaration getClassDeclaration(){ - return cd; - } - - public ReferencePrefix getInstancePrefix(){ - return instancePrefix; - } - - public ReferencePrefix getStaticPrefix(){ - return staticPrefix; - } - - public void addInstanceInvariant(Term t){ - instInv = UsefulTools.makeConjunction(instInv,t); - } - - public void addStaticInvariant(Term t){ - staticInv = UsefulTools.makeConjunction(staticInv, t); - } - - public void addInstanceConstraint(Term t){ - instCon = UsefulTools.makeConjunction(instCon, t); - } - - public void addStaticConstraint(Term t){ - staticCon = UsefulTools.makeConjunction(staticCon, t); - } - - public void addModelVariable(ProgramVariable v){ - // nss.programVariables().add(v); - modelVars.add(v); - if(cd instanceof InterfaceDeclaration){ - addRepresents(v, null); - } - } - - public void addModelMethod(ProgramMethod pm){ - modelMethods.add(pm); - } - - /** - * returns the model variables declared in this class - */ - public Namespace getModelVars(){ - return modelVars; - } - - /** - * returns the model methods declared in this class - */ - public Namespace getModelMethods(){ - return modelMethods; - } - - /** - * adds the representation rep for the model variable - * var. - */ - public void addRepresents(Term loc, Term rep) { - addRepresents(getPV((Location) loc.op()), rep); - } - - /** - * adds the representation rep for the model variable - * var. - */ - public void addRepresents(ProgramVariable v, Term rep){ - ProgramMethod pm =createProgramMethodForMV(v); - modelMethods.add(pm); - if (rep != null) { - JMLMethodSpec spec = new JMLNormalMethodSpec(pm, services, - new Namespace(), new LinkedHashMap(), this, nss, javaPath); - spec.setAssignableMode("nothing"); - if (rep.sort() == Sort.FORMULA) { - if ((rep.op() instanceof Equality) && rep.sub(1) != null - && rep.sub(1).equals(JMLMethodSpec.BOOL_TRUE)) { - spec.addPost(equals(var(spec.getResultVar()), rep.sub(0))); - } else if (rep.op() == Op.TRUE) { - spec.addPost(equals(var(spec.getResultVar()), JMLMethodSpec.BOOL_TRUE)); - } else { - Term eq = equals(var(spec.getResultVar()), JMLMethodSpec.BOOL_TRUE); - spec.addPost(equiv(eq, rep)); - } - } else { - spec.addPost(equals(var(spec.getResultVar()), rep)); - } - } - represents.put(v, getTermForModelMethod(pm)); - } - - /** - * the loc is either a programvariable or an attribute - * in the first case loc itself in the latter one loc.attribute() - * is returned - */ - private ProgramVariable getPV(Location loc) { - if(loc instanceof ProgramVariable){ - return (ProgramVariable) loc; - } - return (ProgramVariable) ((AttributeOp) loc).attribute(); - } - - public void addSuchThat(Term t_loc, Term axiom) { - ProgramVariable v = getPV((Location)t_loc.op()); - ProgramMethod pm = createProgramMethodForMV(v); - - - represents.put(v, getTermForModelMethod(pm)); - modelMethods.add(pm); - JMLMethodSpec spec = new JMLNormalMethodSpec( - pm, services, - new Namespace(), new LinkedHashMap(), this, nss, javaPath); - spec.setAssignableMode("nothing"); - spec.addPost(tf.createUpdateTerm( - t_loc, - var(spec.getResultVar()), - axiom)); - spec.addPre(getExTermForModelVar(t_loc, axiom)); - } - - /** - * returns a mapping from modelmethods to their specifications. - */ - public HashMap buildModelMethod2Specs(){ - HashMap modelMethod2Specs = new HashMap(); - IteratorOfNamed it = modelMethods.allElements().iterator(); - Implementation2SpecMap ism = services.getImplementation2SpecMap(); - while(it.hasNext()){ - ProgramMethod pm = (ProgramMethod) it.next(); - modelMethod2Specs.put(pm, - ism.getSpecsForMethod(pm)); - } - return modelMethod2Specs; - } - - /** - * returns a HashMap that contains the locally defined and inherited - * represents relations. - */ - public HashMap getRepresents(){ - HashMap result = new HashMap(); - KeYJavaType kjt = services.getJavaInfo().getSuperclass(type); - if(kjt == null){ - kjt = objectKeYJavaType; - } - JMLClassSpec superSpec = - services.getImplementation2SpecMap().getSpecForClass(kjt); - if(superSpec != null && (cd instanceof ClassDeclaration) && - type != objectKeYJavaType){ - result.putAll(superSpec.getRepresents()); - } - result.putAll(represents); - return result; - } - - public LinkedHashMap getTerm2Old(){ - return term2old; - } - - public Term getLocalInstanceInvariants(){ - return instInv; - } - - public SetOfTerm getAllQuantifiedInvariants() { - return getQuantifiedInstanceInvariants().add(staticInv); - } - - public SetOfTerm getQuantifiedInstanceInvariants() { - Term result = null; - Term self = tf.createVariableTerm((ProgramVariable) instancePrefix); - if(getInstanceInvariants() != null && - !trueTerm.equals(getInstanceInvariants())){ - Term eqn = not(equals(self, NULL(services))); - ProgramVariable created = services.getJavaInfo().getAttribute( - ImplicitFieldAdder.IMPLICIT_CREATED, objectKeYJavaType); - Term eqc = equals(dot(self, created), JMLMethodSpec.BOOL_TRUE); - result = imp(and(eqn, eqc), getInstanceInvariants()); - result = UsefulTools.addRepresents(result, services, - (ProgramVariable) instancePrefix); - LogicVariable selfLv = - new LogicVariable(new Name("self_"+cd.getName()+ - "_lv"), - self.sort()); - result = tf.createUpdateTerm(self, var(selfLv), result); - result = all(selfLv, result); - } - if(result == null){ - return SetAsListOfTerm.EMPTY_SET; - } - result = UsefulTools.addRepresents(result, services, - (ProgramVariable) instancePrefix); - return SetAsListOfTerm.EMPTY_SET.add(result); - } - - /** - * returns locally declared and inherited instance invariants. - */ - public Term getInstanceInvariants(){ - Term result = UsefulTools.makeConjunction(null, instInv); - Implementation2SpecMap ism = services.getImplementation2SpecMap(); - ListOfKeYJavaType l = cd.getSupertypes(); - IteratorOfKeYJavaType it = l.iterator(); - while(it.hasNext()){ - JMLClassSpec cs = ism.getSpecForClass(it.next()); - if(cs != null){ - Term ii = cs.getInstanceInvariants(); - if(ii != null){ - Term upd = tf.createUpdateTerm( - var((ProgramVariable)cs.getInstancePrefix()), - var((ProgramVariable)getInstancePrefix()), - ii); - result = UsefulTools.makeConjunction(result, upd); - progVarNS.add(cs.getProgramVariableNS().allElements()); - } - } - } - return result; - } - - public Term getLocalStaticInvariants(){ - return staticInv; - } - - public Term getStaticInvariants(){ - Term result = staticInv; - Implementation2SpecMap ism = services.getImplementation2SpecMap(); - ListOfKeYJavaType l = cd.getSupertypes(); - IteratorOfKeYJavaType it = l.iterator(); - while(it.hasNext()){ - JMLClassSpec cs = ism.getSpecForClass(it.next()); - if(cs != null){ - result = UsefulTools.makeConjunction( - result, cs.getStaticInvariants()); - progVarNS.add(cs.getProgramVariableNS().allElements()); - } - } - return result; - } - - public Term getLocalInstanceConstraints(){ - return instCon; - } - - public Term getInstanceConstraints(){ - Term result = instCon; - Implementation2SpecMap ism = services.getImplementation2SpecMap(); - ListOfKeYJavaType l = cd.getSupertypes(); - IteratorOfKeYJavaType it = l.iterator(); - while(it.hasNext()){ - JMLClassSpec cs = ism.getSpecForClass(it.next()); - if(cs != null){ - Term ic = cs.getInstanceConstraints(); - if(ic != null){ - Term upd = tf.createUpdateTerm( - var((ProgramVariable)cs.getInstancePrefix()), - var((ProgramVariable)getInstancePrefix()), - ic); - result = UsefulTools.makeConjunction(result, upd); - progVarNS.add(cs.getProgramVariableNS().allElements()); - } - } - } - return result; - } - - public Term getLocalStaticConstraints(){ - return staticCon; - } - - public Term getStaticConstraints(){ - Term result = staticCon; - Implementation2SpecMap ism = services.getImplementation2SpecMap(); - ListOfKeYJavaType l = cd.getSupertypes(); - IteratorOfKeYJavaType it = l.iterator(); - while(it.hasNext()){ - JMLClassSpec cs = ism.getSpecForClass(it.next()); - if(cs != null){ - result = UsefulTools.makeConjunction( - result, cs.getStaticConstraints()); - progVarNS.add(cs.getProgramVariableNS().allElements()); - } - } - return result; - } - - /** generates \exists x . p(x) where p is the relation for - * modelvar described by its represents-such_that clause. - */ - public Term getExTermForModelVar(Term modelVar, Term axiom){ - LogicVariable lv = new LogicVariable(new Name(modelVar.toString()+ - "_jml_lv"), modelVar.sort()); - Term result = tf.createUpdateTerm(modelVar, var(lv), axiom); - return ex(lv, result); - } - - public ProgramVariable lookupModelField(Name name) - throws AmbigiousModelElementException{ - if(modelVars.lookup(name) != null){ - return (ProgramVariable) modelVars.lookup(name); - } - Implementation2SpecMap ism = services.getImplementation2SpecMap(); - ListOfKeYJavaType st = cd.getSupertypes(); - boolean hasNonInterfaceST = false; - IteratorOfKeYJavaType it = st.iterator(); - ProgramVariable result = null; - while(it.hasNext()){ - KeYJavaType kjt = it.next(); - if((kjt.getJavaType() instanceof ClassDeclaration)){ - hasNonInterfaceST = true; - } - JMLClassSpec cs = ism.getSpecForClass(kjt); - if(cs != null){ - ProgramVariable p = cs.lookupModelField(name); - if(p != null){ - if(result == null){ - result = p; - }else{ - // throw new AmbigiousModelElementException(result); - } - } - } - } - if(result == null && type != objectKeYJavaType && !hasNonInterfaceST ){ - if(ism.getSpecForClass(objectKeYJavaType) == null){ - return result; - } - result = ism.getSpecForClass(objectKeYJavaType). - lookupModelField(name); - } - return result; - } - - /** - * Returns the Term ((self!=null & self.created=true) -> instanceInvariants - * ) & staticInvariants, which is sometimes needed in POs. - */ - public Term getAllLocalInvariants(){ - Term result = null; - Term self = var((ProgramVariable) instancePrefix); - if(getLocalInstanceInvariants() != null && - !trueTerm.equals(getLocalInstanceInvariants())){ - final Term eqn = not ( equals(self, NULL(services)) ); - final Term eqc = UsefulTools.isCreated(self, services); - - result = imp ( and ( eqn, eqc ), getLocalInstanceInvariants() ); - - result = UsefulTools.addRepresents(result, services, - (ProgramVariable) instancePrefix); - LogicVariable selfLv = - new LogicVariable(new Name("self_"+cd.getName()+ - "_lv"), - self.sort()); - result = tf.createUpdateTerm(self, var(selfLv), result); - result = all(selfLv, result); - } - if(getLocalStaticInvariants() != null && - !trueTerm.equals(getLocalStaticInvariants())){ - Term si; - if(staticInit){ - ProgramVariable ci = services.getJavaInfo().getAttribute( - ImplicitFieldAdder.IMPLICIT_CLASS_INITIALIZED, type); - si = equals ( var(ci), JMLMethodSpec.BOOL_TRUE ); - si = imp ( si, getLocalStaticInvariants() ); - }else{ - si = getLocalStaticInvariants(); - } - si = UsefulTools.addRepresents(si, services, - (ProgramVariable) instancePrefix); - result = UsefulTools.makeConjunction(result, si); - } - if(result == null){ - return null; - } - result = UsefulTools.addRepresents(result, services, - (ProgramVariable) instancePrefix); - return result; - } - - /** - * returns the model method with the name name, - * iff it is loacally declared within the type that is specified by this - * specification. - */ - public ProgramMethod lookupModelMethodLocally(String name){ - if(modelMethods.lookup(new Name(type.getSort().toString()+ - "::"+name)) != null){ - return (ProgramMethod) modelMethods.lookup( - new Name(type.getSort().toString()+"::"+name.toString())); - } - return null; - } - - public ProgramMethod lookupModelMethod(Name name) - throws AmbigiousModelElementException{ - if(modelMethods.lookup(new Name(type.getSort().toString()+ - "::"+name.toString())) != null){ - return (ProgramMethod) modelMethods.lookup( - new Name(type.getSort().toString()+"::"+name.toString())); - } - Implementation2SpecMap ism = services.getImplementation2SpecMap(); - ListOfKeYJavaType st = cd.getSupertypes(); - IteratorOfKeYJavaType it = st.iterator(); - ProgramMethod result = null; - while(it.hasNext()){ - KeYJavaType kjt = it.next(); - if(ism.getSpecForClass(kjt) != null && - ism.getSpecForClass(kjt).lookupModelMethod(name) != null){ - if(result == null){ - result = ism.getSpecForClass(kjt).lookupModelMethod(name); - }else{ - throw new AmbigiousModelElementException(result); - } - } - } - return result; - } - - protected Term getTermForModelMethod(ProgramMethod pm){ - Term[] sub; - if(pm.isStatic()){ - sub = new Term[0]; - }else{ - sub = new Term[1]; - sub[0] = var((ProgramVariable) instancePrefix); - } - return func(pm, sub); - } - - /** - * creates a ProgramMethod and the Term for substituting the - * corresponding Model Variable. - */ - private ProgramMethod createProgramMethodForMV(ProgramVariable mv){ - ExtList l = new ExtList(); - l.add(new ProgramElementName(mv.name().toString()+"_rep")); - if(mv.isStatic()){ - l.add(new Static()); - } - l.add(new Model()); - l.add(new Public()); - l.add(new TypeRef(mv.getKeYJavaType())); - MethodDeclaration md = new MethodDeclaration(l, false); - ProgramMethod pm = new ProgramMethod(md, type, - mv.getKeYJavaType(), - PositionInfo.UNDEFINED); - services.getImplementation2SpecMap().addModifier(pm, "pure"); - services.getImplementation2SpecMap().addModifier(pm, "helper"); - if(nss.functions().lookup(pm.name()) == null){ - nss.functions().add(pm); - } - return pm; - } - - /** - * returns a term of the form inv -> <{try{ m();}catch(Exception e)}>inv - * If allInv is true, inv is a conjunction of all - * (static and instance) invariants of every existing type or just - * the invariants of this type specification otherwise. - */ - public Term getPreservesInvariantBehavior(ProgramMethod md, - boolean allInv){ - if(!services.getImplementation2SpecMap(). - getModifiers(md).contains("helper") && ( - !md.isStatic() &&(getInstanceInvariants()!=null || - getInstanceConstraints()!=null) || - getStaticInvariants() != null || - getStaticConstraints() != null || allInv)){ - Term excPre, excPost, result; - result = excPre = excPost = null; - KeYJavaType exc = - services.getJavaInfo().getTypeByClassName("java.lang.Exception"); - Branch[] catches = new Branch[1]; - StatementBlock catchBody = new StatementBlock(); - ProgramVariable e = new LocationVariable( - new ProgramElementName("_exc"+ - (JMLMethodSpec.exceptionVarCount++)), - exc); - progVarNS.add(e); - ParameterDeclaration param = - new ParameterDeclaration(new Modifier[0], new TypeRef(exc), - new VariableSpecification(e), false); - catches[0] = new Catch(param, catchBody); - excPost = addClassSpec2Post(excPost, true, !allInv, md, this); - excPost = UsefulTools.addRepresents(excPost, services, - (ProgramVariable) instancePrefix); - if(allInv){ - Term ai = UsefulTools. - allInvariants(services.getImplementation2SpecMap()); - excPre = UsefulTools.makeConjunction(ai, excPre); - excPost = UsefulTools.makeConjunction(ai, excPost); - }else{ - excPre = addClassSpec2Pre(excPre, md, this); - } - StatementBlock tryBlock = - new StatementBlock(new Try(makeMBS(md.getMethodDeclaration()), - catches)); - - JavaBlock jb = JavaBlock.createJavaBlock(tryBlock); - if(excPost == null){ - return trueTerm; - } - excPost = box(jb, excPost); - if(excPre == null){ - result = excPost; - }else{ - result =imp(excPre,excPost); - } - result = JMLMethodSpec. - addOldQuantifiers(result, getTerm2Old(), false, null); - result = UsefulTools.addRepresents(result, services, - (ProgramVariable) instancePrefix); -/* if(UsefulTools.purityCheck(result, - services.getImplementation2SpecMap()) - != null){ - throw new RuntimeException("Nonpure method "+ - UsefulTools.purityCheck(result, - services. - getImplementation2SpecMap())+ - " used in the "+ - "specification for class/interface " - + cd.getName()); - }*/ - - //disjoins the methods preconditions - SetOfJMLMethodSpec specs = - services.getImplementation2SpecMap().getSpecsForMethod(md); - if(specs != null){ - specs = specs.union(services.getImplementation2SpecMap(). - getInheritedMethodSpecs(md, type)); - } - if(specs != null){ - Term invPre = falseTerm; - IteratorOfJMLMethodSpec it = specs.iterator(); - while(it.hasNext()){ - JMLMethodSpec ms = it.next(); - if(!(ms instanceof JMLPuritySpec)){ - invPre = or ( ms.getCompletePre(false, false, false), - invPre ); - } - } - if(invPre != falseTerm){ - result = imp ( invPre, result ); - } - } - result = imp ( selfIsCreatedAndNotNull((ProgramVariable) getInstancePrefix()), - result ); - result = UsefulTools.quantifySelf(result, md.getMethodDeclaration(), - (ProgramVariable) getInstancePrefix()); - result = UsefulTools.quantifyProgramVariables(result, - UsefulTools.getParameters(md.getMethodDeclaration()).iterator(), - Op.ALL, services); - return imp(func(services.getJavaInfo().getInReachableState()), result); - }else{ - return trueTerm; - } - } - - private Term selfIsCreatedAndNotNull(ProgramVariable self) { - final Term selfAsTerm = var(self); - return and ( not ( equals ( selfAsTerm, NULL(services) ) ), - UsefulTools.isCreated(selfAsTerm, services) ); - - } - - /** Adds the applicable invariants of cSpec to the precondition of md - * iff md isn't declared with the modifier helper. md must be a member - * method of cSpec. - */ - public Term addClassSpec2Pre(Term pre, ProgramMethod md, - JMLClassSpec cSpec){ - Term result; - if(md.getName().equals - (ClassInitializeMethodBuilder.CLASS_INITIALIZE_IDENTIFIER)){ - - final ProgramVariable classInit = services.getJavaInfo().getAttribute( - ImplicitFieldAdder.IMPLICIT_CLASS_INITIALIZED, type); - - result = equals ( var(classInit), JMLMethodSpec.BOOL_FALSE ); - if (pre != null) { result = and ( pre, result ); } - - - final ProgramVariable classErroneous = services.getJavaInfo().getAttribute - (ImplicitFieldAdder.IMPLICIT_CLASS_ERRONEOUS, type); - result = and ( result, - equals(var(classErroneous), JMLMethodSpec.BOOL_FALSE)); - - final ProgramVariable classInitInProgress = services.getJavaInfo(). - getAttribute(ImplicitFieldAdder.IMPLICIT_CLASS_INIT_IN_PROGRESS, - type); - return and ( result, equals( var(classInitInProgress), - JMLMethodSpec.BOOL_FALSE ) ); - } else { - result = pre; - } - - if(cSpec == null || md.getName().startsWith("<") || - services.getImplementation2SpecMap().getModifiers(md).contains("helper")){ - return pre; - } - - result = UsefulTools.makeConjunction(result, cSpec.getStaticInvariants()); - - if(!md.isStatic() && - !(md.getMethodDeclaration() instanceof ConstructorDeclaration)){ - result = UsefulTools.makeConjunction( - result, cSpec.getInstanceInvariants()); - } -// result = addAxioms2Pre(result, true, false); - return result; - } - - /** Adds invariants and history constraints to the postcondition iff md - * isn't declared with the modifier helper. - */ - public Term addClassSpec2Post(Term post, boolean constraints, - boolean invariants, - ProgramMethod md, - JMLClassSpec cSpec){ - if(cSpec == null || - services.getImplementation2SpecMap().getModifiers(md). - contains("helper")){ - return post; - } - Term result = post == null ? tt() : post; - if((!md.getName().startsWith("<") || - md.getName().equals - (ClassInitializeMethodBuilder.CLASS_INITIALIZE_IDENTIFIER)) && - invariants){ - result = UsefulTools.makeConjunction( - result, cSpec.getStaticInvariants()); - } - if(constraints && !md.getName().startsWith("<")){ - result = UsefulTools.makeConjunction( - result, cSpec.getStaticConstraints()); - } - if(!md.isStatic() && !md.getName().startsWith("<")){ - if(invariants){ - result = UsefulTools.makeConjunction( - result, cSpec.getInstanceInvariants()); - } - if (constraints && !(md.isConstructor())){ - result = UsefulTools.makeConjunction( - result, cSpec.getInstanceConstraints()); - } - } - return and(func(services.getJavaInfo().getInReachableState()), - result); - } - - private StatementBlock makeMBS(MethodDeclaration md){ - StatementBlock mBS; - ArrayOfParameterDeclaration params = md.getParameters(); - Expression[] aop = new Expression[md.getParameters().size()]; - ProgramVariable result = null; - for(int i=0; i\old<\code>*/ - ListOfQuantifierPrefixEntry getOldLVs(); - - /** returns the "\old<\code>-equations"*/ - Term getPi1(); - - /** returns postcondition with represents relations applied */ - Term getCompletePost(boolean withClassSpec, boolean allInv); - - /** returns the modifies clause*/ - SetOfLocationDescriptor replaceModelFieldsInAssignable(); - - /** returns the ProgramElement used in the findpart of the lemmataclet*/ - ProgramElement getProofStatement(); - - /** returns true iff the specification demands termination (normally or by - * throwing an exception). - */ - boolean terminates(); - - /** returns true if this specification is prevented from being used for - * generating a lemma rule for any reason. - */ -// boolean otherObstacles(); - -} diff --git a/system/de/uka/ilkd/key/jml/JMLMethodSpec.java b/system/de/uka/ilkd/key/jml/JMLMethodSpec.java deleted file mode 100644 index d2fdecf9ba4..00000000000 --- a/system/de/uka/ilkd/key/jml/JMLMethodSpec.java +++ /dev/null @@ -1,1271 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.jml; - -import java.util.*; - -import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.abstraction.Constructor; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.declaration.*; -import de.uka.ilkd.key.java.declaration.modifier.Public; -import de.uka.ilkd.key.java.expression.operator.CopyAssignment; -import de.uka.ilkd.key.java.expression.operator.New; -import de.uka.ilkd.key.java.recoderext.ClassInitializeMethodBuilder; -import de.uka.ilkd.key.java.recoderext.ImplicitFieldAdder; -import de.uka.ilkd.key.java.reference.ExecutionContext; -import de.uka.ilkd.key.java.reference.ReferencePrefix; -import de.uka.ilkd.key.java.reference.TypeRef; -import de.uka.ilkd.key.java.reference.TypeReference; -import de.uka.ilkd.key.java.statement.CatchAllStatement; -import de.uka.ilkd.key.java.statement.MethodBodyStatement; -import de.uka.ilkd.key.java.statement.MethodFrame; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.logic.sort.ObjectSort; -import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.logic.sort.SortDefiningSymbols; -import de.uka.ilkd.key.proof.ProofSaver; -import de.uka.ilkd.key.proof.mgt.JavaModelMethod; -import de.uka.ilkd.key.proof.mgt.ListOfQuantifierPrefixEntry; -import de.uka.ilkd.key.proof.mgt.QuantifierPrefixEntry; -import de.uka.ilkd.key.rule.UpdateSimplifier; -import de.uka.ilkd.key.util.Debug; - -/** - * A generic jml methodspecification used for encapsulating lightweight - * and behavioral methodspecifications - * @deprecated - */ -public class JMLMethodSpec extends JMLSpec implements JMLLemmaMethodSpec, - AssignableSpec{ - - public static final String EVERYTHING = "everything"; - - protected class ModTermKey{ - - private boolean desugar, withInv, allInv; - - private int hashValue; - private Term post; - - public ModTermKey(Term post, boolean desugar, boolean withInv, - boolean allInv){ - hashValue = 13*post.hashCode() + 3*(desugar ? 1 : 0) + - 5*(withInv ? 1 : 0) + 7*(allInv ? 1 : 0); - this.post = post; - this.desugar = desugar; - this.withInv = withInv; - this.allInv = allInv; - } - - public boolean equals(Object o){ - if(!(o instanceof ModTermKey)) return false; - ModTermKey k = (ModTermKey) o; - return k.desugar==desugar && k.withInv==withInv && k.allInv==allInv - && post.equals(k.post); - } - - public int hashCode(){ - return hashValue; - } - } - - private static final java.util.Comparator comparator = new java.util.Comparator() { - public int compare(Object o1, Object o2) { - return (""+o1+o1.hashCode()).compareTo((""+o2+o2.hashCode()).toString()); - } - }; - - - protected static int excCondCount = 0; - protected static int exceptionVarCount = 0; - protected static Term BOOL_FALSE = null; - protected static Term BOOL_TRUE = null; - protected static int logicVarCount = 0; - - protected static Term nullTerm = null; - protected static int resultVarCount = 0; - private static final UpdateSimplifier simplifier = new UpdateSimplifier(); - - - private static Term addOldQuantifierHelp(Term a, Term t, Term old, - boolean useQuantifiers){ - - TermBuilder df = TermBuilder.DF; - if(UsefulTools.occursIn(old, a, false)){ - if(useQuantifiers){ - LinkedList l = new LinkedList(); - Term t1 = createEqualityTermForOldLV(t, old, l, l, null); - a = df.imp(t1, a); - - if(t.sort() == Sort.FORMULA){ - old = old.sub(0); - } - if(old.op() instanceof ProgramVariable){ - a = UsefulTools.createQuantifierTermWithPV( - Op.ALL, old, (LogicVariable) l.getFirst(), a); - } - }else { - if(t.sort() != Sort.FORMULA && - old.op() instanceof ProgramVariable){ - a = TermFactory.DEFAULT.createUpdateTerm(old,t,a); - }else if(t.sort() == Sort.FORMULA && - old.sub(0).op() instanceof ProgramVariable){ - Term oldVTerm = old.sub(0); - LogicVariable oldlv = - new LogicVariable( - new Name(oldVTerm.op().name().toString()+ - "_lv"), - BOOL_FALSE.sort()); - - final Term t1 = df.equals(df.var(oldlv), BOOL_TRUE); - t = df.equiv(t, t1); - a = UsefulTools.createQuantifierTermWithPV( - Op.ALL, oldVTerm, oldlv, - df.imp(t, a)); - }else{ - t = createEqualityTermForOldLV(t, old, null, null, null); - a = df.imp(t, a); - } - } - } - return a; - } - /** Applies the transformation tau_update to a iff - * useQuantifiers == false or tau_old otherwise. - */ - public static Term addOldQuantifiers(Term a, Map term2old, - boolean useQuantifiers, - Namespace params){ - if(a==null) return a; - final TreeMap param2old = new TreeMap(comparator); - final Set sortedKeys; - if (term2old instanceof SortedMap) { - sortedKeys = term2old.keySet(); - } else { - sortedKeys = new TreeSet(comparator); - sortedKeys.addAll(term2old.keySet()); - } - final Iterator it = sortedKeys.iterator(); - while(it.hasNext()){ - Term t = (Term) it.next(); - Term old = (Term) term2old.get(t); - if(params != null && t!=null && - params.lookup(t.op().name()) != null && - params.lookup(t.op().name()).equals(t.op())){ - param2old.put(t, old); - }else{ - a = addOldQuantifierHelp(a, t, old, useQuantifiers); - } - } - // it is necessary that old-variables associated with parameters are - // updated first because parameters are always implicitely refered to - // in their prestate, which - // can lead to nested old-expressions. - // example: let x be a parameter: - // transforming

(... \old(x[i]) ...) to - // {old1:=old2[i]}{old2:=x}

(... old1 ...) is obviously wrong - // since x has not yet been assigned to old2 when the update - // {old1:=old2[i]} is applied. - // the correct transformation would be: - // {old2:=x}{old1:=old2[i]}

(... old1 ...) - if(params != null && !param2old.isEmpty()){ - a = addOldQuantifiers(a, param2old, useQuantifiers, null); - } - return a; - } - - - protected static Term createEqualityTermForOldLV( - Term t, Term old, LinkedList l, LinkedList oldFS, Map lv2old){ - TermFactory tf0 = TermFactory.DEFAULT; - Term lvTerm = null; - Term lvEq = null; - LogicVariable oldlv=null; - if(!(old.op() instanceof ProgramVariable) || - old.sort() == Sort.FORMULA && - !(old.sub(0).op() instanceof ProgramVariable)){ - Term oldFTerm = (t.sort() == Sort.FORMULA ? - old.sub(0) : old); - t = tf0.createEqualityTerm(old, t); - if(oldFS!=null){ - if(oldFTerm.op() instanceof ArrayOp){ - oldFS.add(oldFTerm.sub(0).op()); - }else{ - oldFS.add(oldFTerm.op()); - } - } - for(int i = (oldFTerm.op() instanceof ArrayOp)? 1 : 0; - icopy of this. - */ - protected JMLMethodSpec copyHelper(JMLMethodSpec copy){ - copy.services = services; - copy.progVarNS = progVarNS.copy(); - copy.funcNS = funcNS.copy(); - copy.tb = tb; - copy.nss = nss; - copy.params = params; - copy.pre = pre; - copy.post = post; - copy.resultVar = resultVar; - copy.assignableMode = getAssignableMode(); - copy.diverges = diverges; - copy.term2old = (LinkedHashMap) term2old.clone(); - copy.assignableVariables = assignableVariables; - copy.signals = signals; - copy.excVar = excVar; - copy.exc = exc; - copy.specVars = specVars; - copy.nsEx = nsEx; - copy.ji = services.getJavaInfo(); - return copy; - } - - protected JMLMethodSpec cloneForHelper(JMLMethodSpec clone, - ProgramMethod pm, - JMLClassSpec cSpec){ - clone = copyHelper(clone); - clone.id = id; - clone.inhFrom = inhFrom.equals("") ? - "inherited from "+cd.getName()+" " : inhFrom; - clone.cSpec = cSpec; - //set new prefix - if(!pm.isStatic()){ - if(inheritedPrefix == null){ - clone.inheritedPrefix = getPrefix(); - }else{ - clone.inheritedPrefix = inheritedPrefix; - } - clone.self = (ProgramVariable) cSpec.getInstancePrefix(); - } - clone.cd = cSpec.getClassDeclaration(); - KeYJavaType returnType; - if(pm.getTypeReference() == null){ - returnType = ji.getKeYJavaType("void"); - }else{ - returnType = pm.getTypeReference().getKeYJavaType(); - } - - //replace the old arguments by the new ones - Namespace newPNS = UsefulTools.buildParamNamespace(pm.getMethodDeclaration()); - Namespace oldPNS = clone.params; - ArrayOfParameterDeclaration oldParams = this.pm.getParameters(); - ArrayOfParameterDeclaration newParams = pm.getParameters(); - clone.progVarNS.add(oldPNS.allElements()); - clone.params = newPNS; - clone.post = updateParameters(oldParams, newParams, clone.post); - clone.pre = updateParameters(oldParams, newParams, clone.pre); - clone.pm = - new ProgramMethod(pm.getMethodDeclaration(), - ji.getKeYJavaType(cSpec.getClassDeclaration()), - returnType, PositionInfo.UNDEFINED); - SetOfSignals si = SetAsListOfSignals.EMPTY_SET; - IteratorOfSignals it = clone.signals.iterator(); - while(it.hasNext()){ - Signals s = it.next(); - si = si.add(new Signals(s.type(), s.variable(), - s.condition() == null? null : - clone.updatePrefix( - updateParameters(oldParams, newParams, - s.condition())))); - } - clone.signals = si; - Iterator kit = term2old.keySet().iterator(); - clone.term2old = new LinkedHashMap(); - while(kit.hasNext()){ - Term t = (Term) kit.next(); - clone.term2old.put(clone.updatePrefix( - updateParameters(oldParams, newParams, t)), - term2old.get(t)); - } - - clone.progVarNS.add(cSpec.getProgramVariableNS()); - clone.funcNS.add(cSpec.getFunctionNS()); - - if(staticInit && !pm.getName().equals - (ClassInitializeMethodBuilder.CLASS_INITIALIZE_IDENTIFIER) && - !(cSpec.getClassDeclaration() instanceof InterfaceDeclaration)){ - ProgramVariable ci = - services.getJavaInfo().getAttribute - (ImplicitFieldAdder.IMPLICIT_CLASS_INITIALIZED, - ji.getKeYJavaType(cSpec.getClassDeclaration())); - if(ci != null){ - clone.addPre(equals(tf.createVariableTerm(ci), BOOL_TRUE)); - } - } - clone.updateAssignableLocations(); - clone.javaPath = javaPath; - return clone; - } - - /** - * @param t1 the precondition. - * @param jb the JavaBlock used in the modality. - */ - protected Term createDiverges(){ - if(diverges != null && !ff().equals(diverges)){ - final Term div = tf.createDiamondTerm(catchAllJB(true), tt()); - final Term divPre = updatePrefix(not(diverges)); - return imp(divPre, div); - } - return tt(); - } - - /** Creates a DL formula from this method specification: - * ((pre & inv) -> [{methodbody}]post) & ((pre & inv & !diverges) -> <{methodbody}>post) - * (This is the DL formula that is needed for an "ensured postcondition - * proofobligation") - * @param withInvariant: iff true the invariant of the containing type - * is added to the postcondition which is needed for JMLPostAndInvPOs - * created by JMLMethodContracts. - * @param allInvariants: iff true all existing invariants for every - * existing type are added to the precondition (and postcondition if - * withInvariant is also true). - */ - public Term createDLFormula(boolean withPostInvariant, - boolean allInvariants){ - Term result,t1,t2; - result = t2 = null; - t1 = getPre(); - if(allInvariants && !services.getImplementation2SpecMap(). - getModifiers(pm).contains("helper")){ - Term ai = UsefulTools.allInvariants( - services.getImplementation2SpecMap()); - t1 = UsefulTools.makeConjunction(t1, ai); - }else{ - t1 = cSpec.addClassSpec2Pre(t1, pm, cSpec); - } - t2 = getPost(); - if(t2 == null){ - result= createModalityTermForEnsures(tt(), true, - withPostInvariant, - allInvariants); - }else{ - result= createModalityTermForEnsures(t2, true, - withPostInvariant, - allInvariants); - } - if(diverges != null && !ff().equals(diverges)){ - result = and(result, createDiverges()); - } - if(t1 != null){ - result = imp(t1, result); - } - result = addOldQuantifiers(result, term2old, false, params); - - if(cSpec!=null){ - result = addOldQuantifiers(result, cSpec.getTerm2Old(), false, - null); - } - - if(!pm.isStatic()){ - result = updatePrefix(result); - } - - result = UsefulTools.addRepresents(result, services, - (ProgramVariable) - cSpec.getInstancePrefix()); -/* if(UsefulTools.purityCheck(result, - services.getImplementation2SpecMap()) - != null){ - throw new RuntimeException("Nonpure method "+ - UsefulTools.purityCheck(result, - services.getImplementation2SpecMap())+ - " used in the "+ - "specification for method "+ - pm.getName()); - }*/ - if(!pm.isStatic()){ - result = UsefulTools.quantifySelf(result, pm.getMethodDeclaration(), - (ProgramVariable)getPrefix()); - } - result = bindSpecVars(result); - return imp(func(services.getJavaInfo().getInReachableState()), - UsefulTools.quantifyProgramVariables(result, - params.allElements().iterator(), Op.ALL, services)); - } - - public Term bindSpecVars(Term t){ - IteratorOfNamed it= specVars.iterator(); - while(it.hasNext()){ - LogicVariable lv = (LogicVariable) it.next(); - t = tf.createQuantifierTerm(Op.ALL, lv, t); - } - return t; - } - - public void addPre(Term t){ - if(t != null){ - pre = and(pre, t); - } - } - - public void addPost(Term t){ - if(t != null){ - post = and(post, t); - } - } - - public void setSpecVars(ListOfNamed svs){ - specVars = svs; - } - - public ListOfNamed getSpecVars(){ - return specVars; - } - - public void addDiverges(Term t){ - if(t != null){ - diverges = or(diverges, t); - } - } - - private Term createdOrNull(ProgramVariable var) { - final Term tVar = var(var); - return or(equals(tVar, NULL(services)), - UsefulTools.isCreated(tVar, services)); - } - - protected Term createModalityTermForEnsures(Term post, boolean desugar, - boolean withInv, - boolean allInv){ - ModTermKey key = new ModTermKey(post, desugar, withInv, allInv); - Term c = (Term) modalityTermForEnsuresCache.get(key); - if(c != null){ - return c; - } - Term excPost = tt(); - Term excVarTerm = var(excVar); - post = imp(equals(excVarTerm, nullTerm), post); - final IteratorOfSignals it = signals.iterator(); - while(it.hasNext()){ - final Signals sig = it.next(); - final SortDefiningSymbols s = (SortDefiningSymbols)(sig.type().getSort()); - final InstanceofSymbol func - = (InstanceofSymbol)s.lookupSymbol(InstanceofSymbol.NAME); - - Term post1 = - imp(equals(func(func, excVarTerm), BOOL_TRUE), sig.condition()); - - if(sig.variable() != null){ - post1 = tf.createUpdateTerm(var(sig.variable()), excVarTerm, post1); - } - excPost = and(excPost, post1); - } - - final JavaBlock jb = catchAllJB(desugar); - if(excPost != null){ - excPost = imp ( not ( equals (excVarTerm, nullTerm) ), excPost); - post = and(post, excPost); - } - if(withInv && !services.getImplementation2SpecMap(). - getModifiers(pm).contains("helper")){ - post = cSpec.addClassSpec2Post(post, true, !allInv, pm, cSpec); - if(allInv){ - Term ai = UsefulTools.allInvariants( - services.getImplementation2SpecMap()); - if(ai != null){ - post = and(ai, post); - } - } - } - post = updatePrefix(post); - post = UsefulTools.addRepresents(post, services, - (ProgramVariable) - cSpec.getInstancePrefix()); - if(diverges == null || ff().equals(diverges)){ - c = dia(jb, post); - }else{ - c = box(jb, post); - } - modalityTermForEnsuresCache.put(key, c); - return c; - } - - /** - * creates and sets the self (this) prefix variable. In addition implicit - * method preconditions are added. Implicit means the JML semantics requires them to - * be fulfilled and therefore the specifier does not need to state them explicitly. - * Such invariants are, e.g. - *

    - *
  • "this" (self) is not null and it is a created object
  • - *
- */ - private void createSelfAndAddImplicitPreconditions(ProgramMethod pm, - Services services, JMLClassSpec cSpec) { - self = (ProgramVariable)cSpec.getInstancePrefix(); - Term t_self = var(self); - //adds self!=null && self. == true or - //self. == true to the precondition - if(!(pm.getMethodDeclaration() instanceof Constructor)){ - addPre(not(equals(t_self, nullTerm))); - addPre(UsefulTools.isCreated(t_self, services)); - } - } - - /** - * add implicit preconditions for static methods, like: - * class is initialized etc. - */ - private void addImplicitPreconditionsForStaticMethods(Services services) { - final ProgramVariable ci = ji.getAttribute - (ImplicitFieldAdder.IMPLICIT_CLASS_INITIALIZED, - services.getJavaInfo().getKeYJavaType(cd)); - addPre(equals(var(ci), BOOL_TRUE)); - } - - public boolean containsQuantifiedAssignableLocation(){ - IteratorOfLocationDescriptor it = assignableVariables.iterator(); - while(it.hasNext()){ - LocationDescriptor loc = it.next(); - if(containsQuantifiedLocationHelp(loc)){ - return true; - } - } - return false; - } - - private boolean containsQuantifiedLocationHelp(LocationDescriptor loc){ - if(loc instanceof BasicLocationDescriptor) { - BasicLocationDescriptor bloc = (BasicLocationDescriptor) loc; - return !bloc.getFormula().equals(tt()) - || bloc.getLocTerm().freeVars().size() > 0; - } - return false; - } - - - - public String getAssignableMode(){ - if(services.getImplementation2SpecMap().getModifiers(pm). - contains("pure") && - assignableVariables == SetAsListOfLocationDescriptor.EMPTY_SET){ - return "nothing"; - } - if(assignableVariables == SetAsListOfLocationDescriptor.EMPTY_SET && - assignableMode == null){ - return EVERYTHING; - } - // an inconsistent case - if(assignableVariables != SetAsListOfLocationDescriptor.EMPTY_SET && - "nothing".equals(assignableMode)){ - return null; - } - return assignableMode; - } - - public CatchAllStatement getCatchAllStatement() { - return catchAllStmt; - } - - public TypeDeclaration getClassDeclaration(){ - return cd; - } - - public Term getCompletePost(boolean withClassSpec, boolean allInv){ - Term result; - if(oldLVs == null){ - getPi1(); - } - if(getPost() == null){ - result = - createModalityTermForEnsures(tt(), false, withClassSpec, - allInv); - }else{ - result = - createModalityTermForEnsures(getPost(), false, withClassSpec, - allInv); - } - result = result.sub(0); - result = addOldQuantifiers(result, lv2old, false, params); - if(!(pm.getMethodDeclaration() instanceof Constructor)){ - result = updatePrefix(result); - } - if (resultVar != null && - resultVar.sort() instanceof ObjectSort) { - result = and(result, createdOrNull(resultVar)); - } - return result; - } - - public Term getCompletePostFunctional(boolean withClassSpec, boolean allInv){ - Term t = getCompletePost(withClassSpec, allInv); - return replaceFreeVarsWithConsts(t); - } - - /** - * returns the precondition + represents for model fields - * (+ invariants iff withClassSpec = true, + the negation of the diverges - * clause in order to retrieve a precondition under which the method must - * terminate). - */ - public Term getCompletePre(boolean withClassSpec, boolean allInv, - boolean terminationCase){ - Term t = getPre(); - if(withClassSpec){ - if(allInv && !services.getImplementation2SpecMap(). - getModifiers(pm).contains("helper")){ - Term ai = UsefulTools.allInvariants( - services.getImplementation2SpecMap()); - t = UsefulTools.makeConjunction(t, ai); - }else{ - t = cSpec.addClassSpec2Pre(t, pm, cSpec); - } - } - if(terminationCase && diverges != null && !ff().equals(diverges)){ - Term divPre = not (diverges); - divPre = updatePrefix(divPre); - t = and(divPre, t); - } - t = UsefulTools.addRepresents(t, services, - (ProgramVariable) - cSpec.getInstancePrefix()); - t = updatePrefix(t); - return t==null? tt() : t; - } - - /** - * returns the ProgramVariable that is used for expressing the excetional - * behavior of a method. - */ - public ProgramVariable getExceptionVariable(){ - return excVar; - } - - public ReferencePrefix getInheritedPrefix(){ - return inheritedPrefix; - } - - public String getJavaPath() { - return javaPath; - } - - public MethodDeclaration getMethodDeclaration(){ - return pm.getMethodDeclaration(); - } - - public JavaModelMethod getModelMethod() { - return new JavaModelMethod(getProgramMethod(), javaPath, services); - } - - public NamespaceSet getNamespaces() { - return nss; - } - - public ProgramVariable getParameterAt(int i) { - return (ProgramVariable) pm.getParameters().getParameterDeclaration(i) - .getVariableSpecification().getProgramVariable(); - } - - public ListOfQuantifierPrefixEntry getOldLVs(){ - if(oldLVs == null){ - getPi1(); - } - return oldLVs; - } - - public ListOfOperator getOldFuncSymbols(){ - if(oldFuncSymbols == null){ - getPi1(); - } - return oldFuncSymbols; - } - - public Term getPi1(){ - if(pi1 == null){ - lv2old = new TreeMap(comparator); - LinkedList l = new LinkedList(); - LinkedList oldFS = new LinkedList(); - pi1 = getPi1Helper(tt(), l, oldFS, term2old); - pi1 = getPi1Helper(pi1, l, oldFS, cSpec.getTerm2Old()); - pi1 = UsefulTools.addRepresents(pi1, services, - (ProgramVariable) - cSpec.getInstancePrefix()); - oldLVs = QuantifierPrefixEntry.toUniversalList ( l.iterator () ); - oldFuncSymbols = toOpList(oldFS); - } - return pi1; - } - - private ListOfOperator toOpList(List l){ - ListOfOperator result = SLListOfOperator.EMPTY_LIST; - Iterator it = l.iterator(); - while(it.hasNext()){ - result = result.append((Operator) it.next()); - } - return result; - } - - public Term getPi1Functional() { - return replaceFreeVarsWithConsts(getPi1()); - } - - private Term getPi1Helper(Term pi1, LinkedList l, - LinkedList oldFS, HashMap map){ - Set sortedKeyset = new TreeSet(comparator); - sortedKeyset.addAll(map.keySet()); - final Iterator it = sortedKeyset.iterator(); - Term postAndInvTerm = - createModalityTermForEnsures(getPost() == null? - tt() : getPost(), - false, true, false); - while(it.hasNext()){ - Term t = (Term) it.next(); - Term old = (Term) map.get(t); - if(UsefulTools.occursIn(old, postAndInvTerm, false)){ - Term t1 = createEqualityTermForOldLV(t, old, l, oldFS, lv2old); - if(pi1 == tt()){ - pi1 = t1; - }else{ - pi1 = and(pi1, t1); - } - } - } - return pi1; - } - - - /** - * returns the locally declared postcondition - */ - public Term getPost(){ - return post; - } - - /** - * returns the locally declared precondition - */ - public Term getPre(){ - return pre; - } - - public ReferencePrefix getPrefix(){ - if(pm != null && pm.isStatic()){ - return cSpec.getStaticPrefix(); - }else{ - return cSpec.getInstancePrefix(); - } - } - - public ProgramMethod getProgramMethod(){ - return pm; - } - - public ProgramElement getProofStatement(){ - return createModalityTermForEnsures(post == null ? tt() : post, - false, false, false). - javaBlock().program(); - } - - public ProgramVariable getResultVar(){ - if(resultVar == null){ - resultVar = makeResultVar(); - } - return resultVar; - } - - public ProgramVariable getSelf() { - return self; - } - - public Services getServices() { - return services; - } - - public SetOfSignals getSignals(){ - return signals; - } - - public LinkedHashMap getTerm2Old(){ - return term2old; - } - - public int id(){ - return id; - } - - - /** - * Checks if name, signature, accessibility and so on are equal for - * this.pm and pm. If this.pm and pm occur on the same branch in the - * class hierarchy must be checked somewhere else! - */ - public boolean isCloneableFor(ProgramMethod method){ - if(!method.getName().equals(this.pm.getName())){ - return false; - } - - final TypeReference methTypeRef = method.getTypeReference(); - if((methTypeRef != null && - !methTypeRef.equals(this.pm.getTypeReference())) || - (methTypeRef == null && this.pm.getTypeReference() != null)){ - return false; - } - - final Throws methThrown = method.getThrown(); - if((methThrown != null && - !methThrown.equals(this.pm.getThrown())) || - (methThrown == null && this.pm.getThrown() != null)){ - return false; - } - - if(method.getParameterDeclarationCount() != - this.pm.getParameterDeclarationCount()){ - return false; - } - for(int i = 0; it
with the current prefix and the current parameters, - * respectively. - */ - private Term replaceSelf(Term t){ - if(t.op() == inheritedPrefix){ - return var(self); - }else if(t.op() instanceof ProgramVariable){ - if(params.lookup(t.op().name()) != null){ - return var((ProgramVariable)params.lookup(t.op().name())); - } - return t; - }else{ - Term[] subs = new Term[t.arity()]; - for(int i = 0; inormal_behavior*/ -public class JMLNormalMethodSpec extends JMLMethodSpec { - - public JMLNormalMethodSpec(ProgramMethod pm, Services services, - Namespace params, LinkedHashMap term2old, JMLClassSpec cSpec, - NamespaceSet nss, String javaPath) { - - super(pm, services, params, term2old, cSpec, nss, javaPath); - addSignals(exc, null, ff()); - - } - - protected JMLNormalMethodSpec(){ - super(); - } - - /** - * This is used for modelling specification inheritance for overwriten - * methods. - */ - public JMLMethodSpec cloneFor(ProgramMethod method, JMLClassSpec jmlClassSpec){ - if(!isCloneableFor(method)) return null; - JMLNormalMethodSpec cloned = new JMLNormalMethodSpec(); - return cloneForHelper(cloned, method, jmlClassSpec); - } - - public ProgramElement getProofStatement(){ - return makeMBS().getStatementAt(0); - } - - protected Term createModalityTermForEnsures(Term post, boolean desugar, - boolean withInv, - boolean allInv){ - ModTermKey key = new ModTermKey(post, desugar, withInv, allInv); - Term c = (Term) modalityTermForEnsuresCache.get(key); - if(c != null){ - return c; - } - if(diverges == null || ff().equals(diverges)){ - JavaBlock jb = - JavaBlock.createJavaBlock(new StatementBlock(makeMBS())); - if(withInv && !services.getImplementation2SpecMap(). - getModifiers(pm).contains("helper")){ - post = cSpec.addClassSpec2Post(post, true, !allInv, pm, cSpec); - if(allInv){ - Term ai = UsefulTools.allInvariants( - services.getImplementation2SpecMap()); - if(ai != null){ - post = and ( ai, post ); - } - } - } - post = updatePrefix(post); - post = UsefulTools.addRepresents(post, services,(ProgramVariable) - cSpec.getInstancePrefix()); - c = dia(jb, post); - }else{ - final Term excVarTerm = var(excVar); - post = and ( equals(excVarTerm, nullTerm), post); - final JavaBlock jb = catchAllJB(desugar); - - if(withInv && !services.getImplementation2SpecMap(). - getModifiers(pm).contains("helper")){ - post = cSpec.addClassSpec2Post(post, true, !allInv, pm, cSpec); - if(allInv){ - Term ai = UsefulTools.allInvariants( - services.getImplementation2SpecMap()); - if(ai != null){ - post = and(ai, post); - } - } - } - post = updatePrefix(post); - post = UsefulTools.addRepresents(post, services,(ProgramVariable) - cSpec.getInstancePrefix()); - c = box(jb, post); - } - modalityTermForEnsuresCache.put(key, c); - return c; - } - - public JMLMethodSpec copy(){ - final JMLNormalMethodSpec copy = - new JMLNormalMethodSpec(pm, services, params, - term2old, cSpec, nss, getJavaPath()); - return copyHelper(copy); - } - - public String toString(){ - return toStringHelper("normal_behavior speccase"); - } -} - diff --git a/system/de/uka/ilkd/key/jml/JMLPuritySpec.java b/system/de/uka/ilkd/key/jml/JMLPuritySpec.java deleted file mode 100644 index a78cdf6d527..00000000000 --- a/system/de/uka/ilkd/key/jml/JMLPuritySpec.java +++ /dev/null @@ -1,46 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2003 Universitaet Karlsruhe, Germany -// and Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.jml; - -import java.util.LinkedHashMap; - -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.Namespace; -import de.uka.ilkd.key.logic.NamespaceSet; -import de.uka.ilkd.key.logic.op.ProgramMethod; - -/** - * A generic method spec used to desugar the pure modifier: - * - * behavior - * assignable \nothing; - */ -public class JMLPuritySpec extends JMLMethodSpec{ - - public JMLPuritySpec(ProgramMethod md, - Services services, Namespace params, - LinkedHashMap term2old, JMLClassSpec cSpec, - NamespaceSet nss, String javaPath){ - super(md, services, params, term2old, cSpec, nss, javaPath); - this.setAssignableMode("nothing"); - } - - public String toString(){ - return "Purity specification for method "+pm.getName()+ - " \nin context "+cd.getName(); - } -} diff --git a/system/de/uka/ilkd/key/jml/JMLSpec.java b/system/de/uka/ilkd/key/jml/JMLSpec.java deleted file mode 100644 index e6b6156315c..00000000000 --- a/system/de/uka/ilkd/key/jml/JMLSpec.java +++ /dev/null @@ -1,49 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2003 Universitaet Karlsruhe, Germany -// and Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.jml; - -import java.util.LinkedHashMap; - -import de.uka.ilkd.key.logic.Namespace; -import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.parser.jml.NotSupportedExpressionException; - -public abstract class JMLSpec extends TermBuilder { - - protected Namespace progVarNS = null; - protected Namespace funcNS = null; - protected NotSupportedExpressionException nsEx = null; - - public abstract LinkedHashMap getTerm2Old(); - - public Namespace getProgramVariableNS(){ - return progVarNS; - } - - public Namespace getFunctionNS(){ - return funcNS; - } - - public void setInvalid(NotSupportedExpressionException nsEx){ - this.nsEx = nsEx; - } - - public boolean isValid(){ - return nsEx == null; - } - -} diff --git a/system/de/uka/ilkd/key/jml/LoopInvariant.java b/system/de/uka/ilkd/key/jml/LoopInvariant.java deleted file mode 100644 index 69ad55e9ad4..00000000000 --- a/system/de/uka/ilkd/key/jml/LoopInvariant.java +++ /dev/null @@ -1,122 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - - -package de.uka.ilkd.key.jml; - -import java.util.LinkedHashMap; - -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.statement.LoopStatement; -import de.uka.ilkd.key.logic.SetAsListOfLocationDescriptor; -import de.uka.ilkd.key.logic.SetOfLocationDescriptor; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.op.Op; -import de.uka.ilkd.key.logic.op.ProgramVariable; - -public class LoopInvariant extends JMLSpec implements AssignableSpec { - - private Services services; - - // contains an assignable keyword (like nothing, everithing, ...), - // if one occurd in the specification. - private String assignableMode = null; - protected SetOfLocationDescriptor assignableLocations - = SetAsListOfLocationDescriptor.EMPTY_SET; - - private LoopStatement loop; - - private Term variant = null; - private Term invariant = null; - - //post condition for loop. Only used by VBT specific rules. - private Term post; - - private LinkedHashMap term2old; - - private TermBuilder df = TermBuilder.DF; - - private final ProgramVariable selfVar; - - public LoopInvariant(LoopStatement loop, Services services, ProgramVariable selfVar){ - this.services = services; - post = invariant = df.tt(); - this.loop = loop; - this.term2old = new LinkedHashMap(); - this.selfVar = selfVar; - } - - public void addInvariant(Term t){ - invariant = df.and(invariant, t); - } - - public void setVariant(Term t){ - variant = t; - } - - public Term getInvariant(){ - return invariant; - } - - public Term getVariant(){ - return variant; - } - - public LoopStatement getLoop(){ - return loop; - } - - public void register(){ - services.getImplementation2SpecMap().addLoopSpec(this); - } - - public void addAssignable(SetOfLocationDescriptor locations){ - assignableLocations = assignableLocations.union(locations); - } - - public SetOfLocationDescriptor getAssignable(){ - return assignableLocations; - } - - public void setAssignableMode(String s){ - assignableMode = s; - } - - public LinkedHashMap getTerm2Old(){ - return term2old; - } - - public void addPost(Term t){ - if(t != null){ - post = tf.createJunctorTermAndSimplify(Op.AND, post, t); - } - } - - public Term getPost(){ - return post; - } - - public String getAssignableMode(){ - if(assignableLocations.size() == 0 && assignableMode == null){ - return "everything"; - } - // an inconsistent case - if(assignableLocations.size() > 0 && - "nothing".equals(assignableMode)){ - return null; - } - return assignableMode; - } - - public ProgramVariable getSelfVar() { - return selfVar; - } - -} diff --git a/system/de/uka/ilkd/key/jml/Signals.java b/system/de/uka/ilkd/key/jml/Signals.java deleted file mode 100644 index a35dc984578..00000000000 --- a/system/de/uka/ilkd/key/jml/Signals.java +++ /dev/null @@ -1,49 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2003 Universitaet Karlsruhe, Germany -// and Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.jml; - -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.op.ProgramVariable; - -/** - * Provides an encapsulation for a single signals clause. - */ -public class Signals{ - - private final KeYJavaType kjt; - private final ProgramVariable v; - private final Term cond; - - public Signals(KeYJavaType kjt, ProgramVariable v, Term cond){ - this.kjt = kjt; - this.v = v; - this.cond = cond; - } - - public KeYJavaType type(){ - return kjt; - } - - public ProgramVariable variable(){ - return v; - } - - public Term condition(){ - return cond; - } -} diff --git a/system/de/uka/ilkd/key/jml/UsefulTools.java b/system/de/uka/ilkd/key/jml/UsefulTools.java deleted file mode 100644 index 18d73ef94ac..00000000000 --- a/system/de/uka/ilkd/key/jml/UsefulTools.java +++ /dev/null @@ -1,545 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2003 Universitaet Karlsruhe, Germany -// and Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.jml; - -import java.util.HashMap; -import java.util.Iterator; - -import de.uka.ilkd.key.java.Comment; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.StatementBlock; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.declaration.*; -import de.uka.ilkd.key.java.recoderext.ImplicitFieldAdder; -import de.uka.ilkd.key.java.reference.ReferencePrefix; -import de.uka.ilkd.key.java.reference.TypeRef; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.logic.sort.ObjectSort; -import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.rule.UpdateSimplifier; -import de.uka.ilkd.key.rule.updatesimplifier.Update; - -public class UsefulTools { - - private static final UpdateSimplifier simplifier = new UpdateSimplifier(); - - - private UsefulTools(){ - } - - /** - * Checks whether a occurs in b or not. If - * ignoreMod is true, subterms with a modality as top operant - * are ignored. - */ - public static boolean occursIn(Term a, Term b, boolean ignoreMod){ - if(a == null || b == null){ - return false; - } - if(a.equals(b)){ - return true; - }else if(b.op() instanceof Modality && ignoreMod){ - return false; - }else{ - for(int i=0;iattr occurs in b and - * returns the terms of the form t.attr that have been found in - * b. If ignoreMod is true, - * subterms with a modality as top operant are ignored. - */ - public static ListOfTerm occursAsAttr(ProgramVariable attr, - Term b, boolean ignoreMod){ - ListOfTerm result = SLListOfTerm.EMPTY_LIST; - if (b == null){ - return result; - } - if ((b.op() instanceof AttributeOp) && - ((AttributeOp) b.op()).attribute() == attr) { - return result.append(b); - } - if (b.op() instanceof Modality && ignoreMod){ - return result; - } - for(int i=0;ib. - * If ignoreMod is true, - * subterms with a modality as top operant are ignored. - */ - public static SetOfTerm collectModelVariables(Term b, boolean ignoreMod){ - SetOfTerm result = SetAsListOfTerm.EMPTY_SET; - if(b == null){ - return result; - } - if((b.op() instanceof AttributeOp) && - (((AttributeOp) b.op()).attribute() instanceof ProgramVariable) && - ((ProgramVariable) ((AttributeOp) b.op()).attribute()).isModel()){ - return result.add(b); - } - if((b.op() instanceof ProgramVariable) && - ((ProgramVariable) b.op()).isModel()){ - return result.add(b); - } - if(b.op() instanceof Modality && ignoreMod){ - return result; - } - for(int i=0;ia is a function term for a query. If the specification - * of this query has a postcondition of the form \result == b then - * b is returned otherwise a is returned. - * - */ - private static Term simplifyRepresentsMethod(Term a, - Services services, - ProgramVariable self){ - Implementation2SpecMap ism = services.getImplementation2SpecMap(); - if(a.arity()>0 && a.sub(0).op()==self){ - TermFactory tf = TermFactory.DEFAULT; - ProgramMethod pm = (ProgramMethod) a.op(); - if(ism.getSpecsForMethod(pm) == null) return a; - JMLMethodSpec spec = ism.getSpecsForMethod(pm).iterator().next(); - Term post = spec.getPost(); - if(post.op() instanceof Equality && - collectModelVariables(post, false)==SetAsListOfTerm.EMPTY_SET){ - if(spec.getPrefix() instanceof ProgramVariable && - spec.getPrefix() != self){ - post = tf.createUpdateTerm( - tf.createVariableTerm((ProgramVariable) - spec.getPrefix()), - tf.createVariableTerm(self), - post); - post = simplifier.simplify(post, services); - - } - if(post.sub(0).op() == spec.getResultVar()){ - return post.sub(1); - }else if(post.sub(1).op() == spec.getResultVar()){ - return post.sub(0); - } - } - } - return a; - } - - /** - * Checks whether only pure methods have been used in this specification or - * not. - * @return null iff every method used in this term is declared - * with the jml-modifier pure or a method that isn't declared - * with pure otherwise. - */ - public static ProgramMethod purityCheck(JMLMethodSpec spec, - Implementation2SpecMap ism){ - Term t = spec.createDLFormula(true, false); - return purityCheck(t, ism); - } - - /** - * Checks whether only pure methods have been used in this term or - * not. - * @return null iff every method used in this term is declared - * with the jml-modifier pure or a method that isn't declared - * with pure otherwise. - */ - public static ProgramMethod purityCheck(Term t, - Implementation2SpecMap ism){ - if ( t.op() instanceof ProgramMethod ) { - if(!ism.getModifiers((ProgramMethod)t.op()).contains("pure")){ - return (ProgramMethod) t.op(); - } - } - - for(int i=0;it is neither - * static nor a constructor or t otherwise. - */ - public static Term quantifySelf(Term t, MethodDeclaration md, - ProgramVariable self){ - if(!md.isStatic() && !(md instanceof ConstructorDeclaration)){ - TermFactory tf = TermFactory.DEFAULT; - Term vTerm = tf.createVariableTerm(self); - LogicVariable lv = new LogicVariable(new Name(self.name()+"_lv"), - self.sort()); - Term lvTerm = tf.createVariableTerm(lv); - t = tf.createUpdateTerm(vTerm, lvTerm, t); - t = TermBuilder.DF.all(lv, t); - } - return t; - } - - /** Creates a quantified LogicVariable lv_i for ProgramVariabes p_i in - * t that aren't contained in the Namespace ns. - * @return q lv_1...lv_n {p_1 := lv_1}..{p_n := lv_n} t. - */ - public static Term quantifyProgramVariables(Term t, Namespace ns, - Quantifier q, Services serv){ - SetOfNamed pvs = helpQuantify(t, ns.allElements()); - IteratorOfNamed it = pvs.iterator(); - return quantifyProgramVariables(t, it, q, serv); - } - - public static Term quantifyProgramVariables(Term t, IteratorOfNamed it, - Quantifier q, Services serv){ - while(it.hasNext()){ - ProgramVariable v = (ProgramVariable) it.next(); - t = quantifyProgramVariable(t, v, q, serv); - } - return t; - } - - /** - * Returns q lv . {v := lv}t - */ - public static Term quantifyProgramVariable(Term t, ProgramVariable v, - Quantifier q, Services serv){ - final TermFactory tf = TermFactory.DEFAULT; - final TermBuilder df = TermBuilder.DF; - Term vTerm = tf.createVariableTerm(v); - - final Sort intSort = serv.getTypeConverter(). - getIntegerLDT().targetSort(); - final Sort sort; - - if (v.sort().extendsTrans(intSort)) { - sort = intSort; - } else { - sort = v.sort(); - } - - LogicVariable lv = new LogicVariable(new Name(v.name()+"_lv"), sort); - if(v.getKeYJavaType().getSort() instanceof ObjectSort){ - - Term nullComp = df.equals(vTerm, df.NULL(serv)); - Term cnCond = df.and(isCreated(vTerm, serv), - df.not(nullComp)); - cnCond = df.or(cnCond, nullComp); - - if (q == Op.ALL){ - t = df.imp(cnCond, t); - }else{ - t = df.and(cnCond, t); - } - } - Term lvTerm = tf.createVariableTerm(lv); - t = tf.createUpdateTerm(vTerm, lvTerm, t); - t = tf.createQuantifierTerm(q, lv, t); - return t; - } - - public static Term isCreated(Term objectToGuard, Services s) { - if (!(objectToGuard.sort() instanceof ObjectSort)) { - throw new IllegalArgumentException( - "Only reference objects can be guarded."); - } - - final TermBuilder df = TermBuilder.DF; - - final ProgramVariable created = s.getJavaInfo().getAttribute( - ImplicitFieldAdder.IMPLICIT_CREATED, - s.getJavaInfo().getJavaLangObject()); - - if (created == null) { - throw new IllegalStateException("missing implict attribute for " - + objectToGuard.sort()); - } - - return df.equals(df.dot(objectToGuard, created), - df.TRUE(s)); - } - - /** - * returns all program variables that occur in t and ns. - */ - private static SetOfNamed helpQuantify(Term t, ListOfNamed ns){ - SetOfNamed pvs = SetAsListOfNamed.EMPTY_SET; - if(t.op() instanceof ProgramVariable && - !ns.contains(t.op())){ - pvs = pvs.add(t.op()); - } - for(int i = 0; i q lv ({vTerm := lv} body) - * where v = vTerm.op() - */ - public static Term createQuantifierTermWithPV( - Quantifier q, Term vTerm, LogicVariable lv, Term body){ - TermFactory tf = TermFactory.DEFAULT; - Term result; - body = tf.createUpdateTerm(vTerm, tf.createVariableTerm(lv), body); - result = tf.createQuantifierTerm(q, lv, body); - //adds a declaration for the programvariable if necessary - ProgramVariable v = (ProgramVariable) vTerm.op(); - LocalVariableDeclaration vDecl = new LocalVariableDeclaration - (new TypeRef(v.getKeYJavaType()), - new VariableSpecification(v)); - JavaBlock jb = - JavaBlock.createJavaBlock(new StatementBlock(vDecl)); - result = tf.createDiamondTerm(jb, result); - return result; - } - - /** - * Returns a conjunction of the terms returned by getAllInvariants() for - * every JMLClassSpec. - */ - public static Term allInvariants(Implementation2SpecMap ism){ - if(ism.allInvariants() != null) return ism.allInvariants(); - Term result = null; - - Iterator it = ism.getAllClasses().iterator(); - Namespace ns = new Namespace(); - - while(it.hasNext()){ - KeYJavaType kjt = (KeYJavaType) it.next(); - JMLClassSpec cs = ism.getSpecForClass(kjt); - Term inv = cs.getAllLocalInvariants(); - ns.add(cs.getProgramVariableNS().allElements()); - if(inv != null){ - if(result == null){ - result = inv; - }else{ - result = TermBuilder.DF.and(result, inv); - } - } - } - ism.setAllInvPVNS(ns); - ism.setAllInvariants(result); - return result; - } - - private static boolean containsQuery(Term t){ - if(t.op() instanceof ProgramMethod){ - return true; - } - for(int i=0; i 0) { + final StringBuffer result = new StringBuffer(translate(pairs + .getAssignmentPair(0).locationAsTerm()) + + " == \\old(" + + translate((Term) pairs.getAssignmentPair(0).value()) + + ")"); + for (int i = 1; i < pairs.size(); ++i) { + result + .append(" && " + + translate(pairs.getAssignmentPair(i) + .locationAsTerm()) + + " == \\old(" + + translate((Term) pairs.getAssignmentPair(i) + .value()) + ")"); + } + return result.toString(); + } else { + return "true"; + } + } +} diff --git a/system/de/uka/ilkd/key/jmltest/JMLLogicPrinter.java b/system/de/uka/ilkd/key/jmltest/JMLLogicPrinter.java new file mode 100755 index 00000000000..398f06474f8 --- /dev/null +++ b/system/de/uka/ilkd/key/jmltest/JMLLogicPrinter.java @@ -0,0 +1,163 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.jmltest; + +/** + * @author mbender@uni-koblenz.de + */ + +import java.io.IOException; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.op.ArrayOfQuantifiableVariable; +import de.uka.ilkd.key.logic.op.CastFunctionSymbol; +import de.uka.ilkd.key.logic.op.LogicVariable; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.pp.LogicPrinter; +import de.uka.ilkd.key.pp.NotationInfo; +import de.uka.ilkd.key.pp.ProgramPrinter; +import de.uka.ilkd.key.proof.init.SpecExtPO; +import de.uka.ilkd.key.util.pp.Layouter; +import de.uka.ilkd.key.util.pp.StringBackend; + +public class JMLLogicPrinter extends LogicPrinter { + + public static final int DLW = 100000; + + private SpecExtPO po; + + public JMLLogicPrinter(ProgramPrinter pgr, NotationInfo notaInfo, + Services serv, SpecExtPO po) { + super(pgr, notaInfo, serv, true); + this.po = po; + lineWidth = DLW; + backend = new StringBackend(DLW); + layouter = new Layouter(backend, 0); + + // pure = true; + // backend = new PosTableStringBackend(5000); + // layouter = new Layouter(backend, 100); + // this.notaInfo = notaInfo; + // prgPrinter = new JMLProgPrinter(true, true); + } + + public void printIfThenElseTerm(Term t, String keyword) throws IOException { + startTerm(t.arity()); + layouter.beginC(0); + layouter.print(keyword); + if (t.varsBoundHere(0).size() > 0) { +// layouter.print(" "); + printVariables(t.varsBoundHere(0)); + } +// layouter.print(" "); + markStartSub(); + printTerm(t.sub(0)); + markEndSub(); +// layouter.print(" "); + for (int i = 1; i < t.arity(); ++i) { + layouter.brk(1, 3); + if (i == 1) { + layouter.print("? "); + } else { + layouter.print(": "); + } + markStartSub(); + printTerm(t.sub(i)); + markEndSub(); +// layouter.print(" "); + } + layouter.print(")"); + layouter.end(); + } + + public void printPrefixTerm(String name, Term t, int ass) + throws IOException { + startTerm(1); + layouter.print(name); + layouter.print("("); + maybeParens(t, ass); + layouter.print(")"); + } + + public void printQuantifierTerm(String name, + ArrayOfQuantifiableVariable vars, Term phi, int ass) + throws IOException { + layouter.beginC(2); + layouter.print("("); + layouter.print(name).print(" "); + printVariables(vars); + layouter.print("true;"); + layouter.brk(); + startTerm(1); + maybeParens(phi, ass); + layouter.print(")"); + layouter.end(); + } + + public void printFunctionTerm(String name, Term t) throws IOException { + startTerm(t.arity()); + + LogicVariable selfLogic = po.getSelfVarAsLogicVar(); + ProgramVariable selfProg = po.getSelfVarAsProgVar(); + ProgramVariable result = po.getResult(); + if (((selfLogic != null) && (t.op().toString().equals(selfLogic + .toString()))) + || ((selfProg != null) && t.op().toString().equals( + selfProg.toString()))) { + layouter.print("this"); + } else if ((result != null) + && (t.op().toString().equals(result.toString()))) { + layouter.print("\\result"); + } else if (name.equals("TRUE")) { + layouter.print("true"); + } else if (name.equals("FALSE")) { + layouter.print("false"); + } else { + layouter.print(name); + } + + if (t.arity() > 0 || t.op() instanceof ProgramMethod) { + layouter.print("(").beginC(0); + for (int i = 0; i < t.arity(); i++) { + markStartSub(); + printTerm(t.sub(i)); + markEndSub(); + if (i < t.arity() - 1) { + layouter.print(",").brk(1, 0); + } + } + layouter.print(")").end(); + } + } + + public void printCast(String pre, String post, Term t, int ass) + throws IOException { + final CastFunctionSymbol cast = (CastFunctionSymbol) t.op(); + startTerm(t.arity()); + layouter.print(pre); + layouter.print((services.getTypeConverter().getModelFor( + cast.getSortDependingOn()).javaType()).toString()); + layouter.print(post); + maybeParens(t.sub(0), ass); + } + + public StringBuffer result() { + try { + layouter.flush(); + } catch (IOException e) { + throw new RuntimeException("IO Exception in pretty printer:\n" + e); + } + return new StringBuffer(((StringBackend) backend).getString()); + } + +} diff --git a/system/de/uka/ilkd/key/jmltest/JMLNotationInfo.java b/system/de/uka/ilkd/key/jmltest/JMLNotationInfo.java new file mode 100755 index 00000000000..843e8bdcd4a --- /dev/null +++ b/system/de/uka/ilkd/key/jmltest/JMLNotationInfo.java @@ -0,0 +1,105 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.jmltest; + +/** + * @author mbender@uni-koblenz.de + */ + +import de.uka.ilkd.key.logic.op.AnonymousUpdate; +import de.uka.ilkd.key.logic.op.ArrayOp; +import de.uka.ilkd.key.logic.op.AttributeOp; +import de.uka.ilkd.key.logic.op.CastFunctionSymbol; +import de.uka.ilkd.key.logic.op.Equality; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.logic.op.LogicVariable; +import de.uka.ilkd.key.logic.op.Metavariable; +import de.uka.ilkd.key.logic.op.ModalOperatorSV; +import de.uka.ilkd.key.logic.op.Modality; +import de.uka.ilkd.key.logic.op.NRFunctionWithExplicitDependencies; +import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.logic.op.QuanUpdateOperator; +import de.uka.ilkd.key.logic.op.ShadowArrayOp; +import de.uka.ilkd.key.logic.op.ShadowAttributeOp; +import de.uka.ilkd.key.logic.op.SortedSchemaVariable; +import de.uka.ilkd.key.pp.Notation; +import de.uka.ilkd.key.pp.NotationInfo; + +public class JMLNotationInfo extends NotationInfo { + + public JMLNotationInfo() { + super(); + } + + protected void createDefaultOpNotation() { + tbl.put(Op.TRUE, new Notation.Constant("true", 130)); + tbl.put(Op.FALSE, new Notation.Constant("false", 130)); + tbl.put(Op.NOT, new Notation.Prefix("!", 60, 60)); + + tbl.put(Op.AND, new Notation.Infix("&&", 50, 50, 60)); + tbl.put(Op.OR, new Notation.Infix("||", 40, 40, 50)); + tbl.put(Op.IMP, new Notation.Infix("==>", 30, 40, 30)); + tbl.put(Op.EQV, new Notation.Infix("<==>", 20, 20, 30)); + + tbl.put(Op.ALL, new Notation.Quantifier("\\forall", 60, 60)); + tbl.put(Op.EX, new Notation.Quantifier("\\exists", 60, 60)); + tbl.put(Op.DIA, new Notation.Modality("\\<", "\\>", 60, 60)); + tbl.put(Op.BOX, new Notation.Modality("\\[", "\\]", 60, 60)); + tbl.put(Op.TOUT, new Notation.Modality("\\[[", "\\]]", 60, 60)); + Modality modalities[] = { Op.DIATRC, Op.BOXTRC, Op.TOUTTRC, Op.DIATRA, + Op.BOXTRA, Op.TOUTTRA, Op.DIASUSP, Op.BOXSUSP, Op.TOUTSUSP }; + for (int i = 0; i < modalities.length; i++) + tbl + .put(modalities[i], new Notation.Modality("\\" + + modalities[i].name().toString(), "\\endmodality", + 60, 60)); + + tbl.put(Op.IF_THEN_ELSE, new Notation.IfThenElse(130, "(")); + tbl.put(Op.IF_EX_THEN_ELSE, new Notation.IfThenElse(130, "\\ifEx")); + + tbl.put(Op.COMPUTE_SPEC_OP, new Notation.Prefix("^", 60, 60)); + + // createNumLitNotation(IntegerLDT.getStaticNumberSymbol()); + + tbl.put(Op.SUBST, new Notation.Subst()); + + } + + protected void createDefaultTermSymbolNotation() { + tbl.put(Function.class, new Notation.Function()); + tbl.put(LogicVariable.class, new Notation.VariableNotation()); + // tbl.put(SchemaVariable.class, new Notation.Variable()); + tbl.put(Metavariable.class, new Notation.MetavariableNotation()); + tbl.put(ProgramVariable.class, new Notation.VariableNotation()); + tbl.put(ProgramMethod.class, new Notation.JMLProgramMethod(121)); + tbl.put(Equality.class, new Notation.Infix("==", 70, 80, 80)); + tbl.put(QuanUpdateOperator.class, new Notation.QuanUpdate()); + tbl.put(AnonymousUpdate.class, new Notation.AnonymousUpdate()); + tbl + .put(ShadowAttributeOp.class, new Notation.ShadowAttribute(121, + 121)); + tbl.put(AttributeOp.class, new Notation.Attribute(121, 121)); + tbl.put(ShadowArrayOp.class, new Notation.ArrayNot(new String[] { "[", + "]", "" }, 130, new int[] { 121, 0, 0 })); + tbl.put(ArrayOp.class, new Notation.ArrayNot(new String[] { "[", "]" }, + 130, new int[] { 121, 0 })); + tbl.put(CastFunctionSymbol.class, new Notation.CastFunction("(", ")", + 120, 140)); + tbl.put(NRFunctionWithExplicitDependencies.class, + new Notation.NRFunctionWithDependenciesNotation()); + tbl.put(ModalOperatorSV.class, new Notation.ModalSVNotation(60, 60)); + tbl.put(SortedSchemaVariable.class, + new Notation.SortedSchemaVariableNotation()); + } + +} diff --git a/system/de/uka/ilkd/key/jmltest/JMLTestFileCreator.java b/system/de/uka/ilkd/key/jmltest/JMLTestFileCreator.java new file mode 100755 index 00000000000..8fd89f0699c --- /dev/null +++ b/system/de/uka/ilkd/key/jmltest/JMLTestFileCreator.java @@ -0,0 +1,176 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.jmltest; + +import javax.swing.JOptionPane; + +import de.uka.ilkd.key.gui.AutoModeListener; +import de.uka.ilkd.key.gui.InteractiveProver; +import de.uka.ilkd.key.gui.JRadioButtonHashMap; +import de.uka.ilkd.key.gui.KeYMediator; +import de.uka.ilkd.key.gui.Main; +import de.uka.ilkd.key.proof.ProofEvent; +import de.uka.ilkd.key.proof.init.SpecExtPO; +import de.uka.ilkd.key.strategy.StrategyProperties; + +/** + * This class is the first step of the jml-wrapper-creation. It calls the + * Interactiveprover two times. First to try to create a bunch of branches to + * get many paths which is similar to getting much information about the interna + * of a program. In the second call the prover settings are changed to try to + * get a secific structure of the open goals and to try to close infeasible + * paths. After this steps a new thread of WrapperCreator is created an started. + * At the end, the prover setting were set back. + * + * @author mbender@uni-koblenz.de + * + */ +public class JMLTestFileCreator { + + private final AutoModeListener aml; + + private final KeYMediator medi; + + private final InteractiveProver iProver; + + private String oldMethodProp; + + private String oldLoopProp; + + private int steps; + + /** + * Creates a new JMLTestFileCreator for the Proof proof + */ + public JMLTestFileCreator() { + medi = Main.getInstance().mediator(); + iProver = medi.getInteractiveProver(); + aml = new MyAutoModeListener(this); + oldLoopProp = null; + oldMethodProp = null; + + } + + /** + * This method does the main job. If not in JMLWrapper mode (po not + * instanceof SpecExtPo) then print a Dialog. Else call the prover, change + * the setting, call the prover with new settings and then start Creation of + * the Wrapper file + * + */ + public final void createWrapper() { + + if (medi.getSelectedProof().getPO() instanceof SpecExtPO) { + + iProver.addAutoModeListener(aml); + + iProver.startAutoMode(); + } else { + JOptionPane + .showMessageDialog( + Main.getInstance(), + "Please choos the -PO if you want to use this feature.", + "Wrong Proof Obligation chosen!", + JOptionPane.WARNING_MESSAGE); + + } + + } + + /** + * Saves old proof settings an switches to METHOD_NONE and LOOP_NONE + */ + private final void setProperties() { + // Save max step an set steps to oldNumber times 5 + steps = medi.getMaxAutomaticSteps(); + medi.setMaxAutomaticSteps(steps * 5); + + // Save old method-handling property, set new to NONE + if (JRadioButtonHashMap.getButton(StrategyProperties.METHOD_EXPAND) + .isSelected()) { + oldMethodProp = StrategyProperties.METHOD_EXPAND; + } else if (JRadioButtonHashMap.getButton( + StrategyProperties.METHOD_CONTRACT).isSelected()) { + oldMethodProp = StrategyProperties.METHOD_CONTRACT; + } else if (JRadioButtonHashMap + .getButton(StrategyProperties.METHOD_NONE).isSelected()) { + oldMethodProp = StrategyProperties.METHOD_NONE; + } + JRadioButtonHashMap.getButton(StrategyProperties.METHOD_NONE).doClick(); + + // Save old loop-handling property, set new to NONE + if (JRadioButtonHashMap.getButton(StrategyProperties.LOOP_EXPAND) + .isSelected()) { + oldLoopProp = StrategyProperties.LOOP_EXPAND; + } else if (JRadioButtonHashMap.getButton( + StrategyProperties.LOOP_INVARIANT).isSelected()) { + oldLoopProp = StrategyProperties.LOOP_INVARIANT; + } else if (JRadioButtonHashMap.getButton(StrategyProperties.LOOP_NONE) + .isSelected()) { + oldLoopProp = StrategyProperties.LOOP_NONE; + } + JRadioButtonHashMap.getButton(StrategyProperties.LOOP_NONE).doClick(); + } + + /** + * Resets the properties for loop- and method-handling to original values. + * Removes the AutoModeListener from InteractiveProver + * + */ + public final void resetProperties() { + + if (oldMethodProp != null) { + JRadioButtonHashMap.getButton(oldMethodProp).doClick(); + } + + if (oldLoopProp != null) { + JRadioButtonHashMap.getButton(oldLoopProp).doClick(); + } + medi.setMaxAutomaticSteps(steps); + iProver.removeAutoModeListener(aml); + + } + + /** + * Just an AutoModeListener needed for internal use + */ + private final class MyAutoModeListener implements AutoModeListener { + + private final JMLTestFileCreator jmltfc; + + private MyAutoModeListener(JMLTestFileCreator jmltfc) { + this.jmltfc = jmltfc; + } + + public void autoModeStarted(ProofEvent e) { + } + + /** + * After first run off Prover is finished, change setting and start + * prover again. After second iteration is finished start creation of + * wrapper file + * + * @see de.uka.ilkd.key.gui.AutoModeListener#autoModeStopped(de.uka.ilkd.key.proof.ProofEvent) + */ + public void autoModeStopped(ProofEvent e) { + if ((oldLoopProp == null) && (oldMethodProp == null)) { + setProperties(); + medi.getInteractiveProver().startAutoMode(); + } else { + final WrapperConstructor wc = new WrapperConstructor(jmltfc, + medi.getSelectedProof()); + wc.start(); + } + + } + } + +} diff --git a/system/de/uka/ilkd/key/jmltest/WrapperConstructor.java b/system/de/uka/ilkd/key/jmltest/WrapperConstructor.java new file mode 100644 index 00000000000..8aa06b41968 --- /dev/null +++ b/system/de/uka/ilkd/key/jmltest/WrapperConstructor.java @@ -0,0 +1,624 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.jmltest; + +import de.uka.ilkd.key.gui.Main; +import de.uka.ilkd.key.java.declaration.ArrayOfParameterDeclaration; +import de.uka.ilkd.key.logic.IteratorOfConstrainedFormula; +import de.uka.ilkd.key.logic.op.IteratorOfProgramMethod; +import de.uka.ilkd.key.proof.IteratorOfGoal; +import de.uka.ilkd.key.rule.updatesimplifier.ArrayOfAssignmentPair; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.util.Vector; + +import javax.swing.JOptionPane; + +import de.uka.ilkd.key.java.Comment; +import de.uka.ilkd.key.java.Expression; +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.PrettyPrinter; +import de.uka.ilkd.key.java.StatementBlock; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.declaration.ClassDeclaration; +import de.uka.ilkd.key.java.declaration.ConstructorDeclaration; +import de.uka.ilkd.key.java.declaration.Extends; +import de.uka.ilkd.key.java.declaration.MethodDeclaration; +import de.uka.ilkd.key.java.declaration.modifier.Public; +import de.uka.ilkd.key.java.declaration.modifier.Static; +import de.uka.ilkd.key.java.reference.MethodReference; +import de.uka.ilkd.key.java.reference.TypeRef; +import de.uka.ilkd.key.java.reference.TypeReference; +import de.uka.ilkd.key.java.statement.Return; +import de.uka.ilkd.key.logic.ConstrainedFormula; +import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermFactory; +import de.uka.ilkd.key.logic.op.AttributeOp; +import de.uka.ilkd.key.logic.op.CastFunctionSymbol; +import de.uka.ilkd.key.logic.op.IUpdateOperator; +import de.uka.ilkd.key.logic.op.LocationVariable; +import de.uka.ilkd.key.logic.op.Modality; +import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.RigidFunction; +import de.uka.ilkd.key.proof.Goal; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.init.SpecExtPO; +import de.uka.ilkd.key.rule.updatesimplifier.AssignmentPair; +import de.uka.ilkd.key.rule.updatesimplifier.QuanAssignmentPairLazy; +import de.uka.ilkd.key.rule.updatesimplifier.Update; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.OperationContractImpl; +import de.uka.ilkd.key.util.ExtList; + +/** + * This class contains methods, that gather all needed information from current + * proof and that are needed to create a wrapper-file + * + * @author mbender@uni-koblenz.de + */ +public class WrapperConstructor extends Thread { + + private final JMLTestFileCreator jmltfc; + + private final SpecExtPO po; + + private final String className; + + private final Proof proof; + + private final JMLExport jmlEx; + + private final ProgramMethod pm; + + public WrapperConstructor(JMLTestFileCreator jmltfc, Proof proof) { + this.jmltfc = jmltfc; + this.proof = proof; + po = proof.getPO(); + pm = po.getProgramMethod(); + className = pm.getContainerType().getName(); + jmlEx = new JMLExport(po); + + } + + public final void run() { + try { + JOptionPane.showMessageDialog(Main.getInstance(), + "File succesfully written to:\n" + createTestFile(), + "Creation finished", JOptionPane.INFORMATION_MESSAGE); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Creates a class that is extended from the Class containing the method + * that was chosen in the JMLSpecBrowser. Writes this class to a file. + * + * @return The path where the file is stored + * @throws IOException + */ + public final String createTestFile() throws IOException { + + final KeYJavaType supertypeKey = pm.getContainerType(); + + final JavaInfo ji = proof.getJavaInfo(); + + final ExtList l = new ExtList(); + + // Add class frame + // First add public modifier, then add name consisting of "Test" + old + // class name + // also adds the extends clause with source class as super class + l.add(new Public()); + l.add(new ProgramElementName("Test" + className)); + + final TypeReference supertype = new TypeRef(supertypeKey); + l.add(new Extends(supertype)); + + // Add all Constructors to l by iterating over all program methods + // If the name of the current method equals "" a new constructor + // with the signature of the current method is added to l + // Correct constructor is created by CreateMethod(met.getParameters(), + // true) + final IteratorOfProgramMethod iter = ji.getAllProgramMethods( + supertypeKey).iterator(); + while (iter.hasNext()) { + ProgramMethod met = (ProgramMethod) iter.next(); + if (met.getTypeReference() != null) { + if (met.getTypeReference().equals(supertype)) { + if (met.getFullName().equals("")) { + l.add(createMethod(met.getParameters(), true)); + } + } + } + } + + // Add the method to test + l.add(createMethod(pm.getParameters(), false)); + + // Create the wrapper class + final ClassDeclaration classDecl = new ClassDeclaration(l, + new ProgramElementName("Test" + className), false); + + // Try to write the wrapper class to an StringWriter sw + final StringWriter sw = new StringWriter(); + final PrettyPrinter pp = new PrettyPrinter(sw, false, true); + pp.printClassDeclaration(classDecl); + return writeToFile(sw); + } + + /** + * Creates a method or a constructor with the parameters given in args, + * depending on the parameter isConstructor. Body of method is just a call + * of the source method Body of constructor is just a super call + * + * @param args + * @param isConstructor + * @return MethodDeclaration or ConstructorDeclaration + */ + private final MethodDeclaration createMethod( + ArrayOfParameterDeclaration args, boolean isConstructor) { + final ExtList l = new ExtList(); + + // Choose name of method/constructor and add it to list + // For a constructor, the name is the name of the class with prepended + // "Test" + // For method, the original name is get from + // JMLMethodSpec.getMethodDeclaration().getName() and "test" is + // prepended + final String name; + if (isConstructor) { + name = "Test" + className; + } else { + name = "test" + pm.getName(); + } + l.add(new ProgramElementName(name)); + + // Iterates over the ArrayOfParameterDeclaration args to get all + // Parameters + // ParameterDeclarations are added to list l so that new + // method/constructor has correct numbers of parameters + // Also adds correct parameters to params, so that the signature of + // method/constructor that is called in body is correct + final ExtList params = new ExtList(); + for (int i = 0; i < args.size(); i++) { + l.add(args.getParameterDeclaration(i)); + params.add((Expression) args.getProgramElement(i).getLastElement()); + } + + // Add the modifier public to method/constructor + // Also adds modifier static if source method is static + l.add(new Public()); + if (!isConstructor && pm.isStatic()) { + l.add(new Static()); + } + + // Add the specifications for the wrapper method + if (!isConstructor) { + l.add(new Comment(getSpecs())); + } + + // Choose name of method to call in body + // For a constructor the super-constructor is called + // For the method the source method is called + // You get source method by + // JMLMethodSpec.getMethodDeclaration().getName() + final String calleeName; + if (isConstructor) { + calleeName = "super"; + } else { + calleeName = pm.getName(); + } + + // Add return type and add the method body + final StatementBlock mBody; + // Return types just for methods, not for constructors + if (!isConstructor) { + // For all non-void methods + // Wrapper method has the same return type as source method + // The source method is called in the return clause of wrapper + // method + if (!(pm.getTypeReference() == null)) { + l.add(pm.getTypeReference()); + mBody = new StatementBlock(new Return(new MethodReference( + params, new ProgramElementName(calleeName), null))); + + } + // For void methods + // If source method has no return type and no return clause + // Wrapper method also has no return type an no return clause + // The source method is called in body + else { + + mBody = new StatementBlock(new MethodReference(params, + new ProgramElementName(calleeName), null)); + + } + } + // For constructors + // Constructors have no return type and no return clause + // super constructor is called in body + else { + mBody = new StatementBlock(new MethodReference(params, + new ProgramElementName(calleeName), null)); + + } + // Add the body/return to the method + l.add(mBody); + + // Add throws Exception if needed + l.add(pm.getThrown()); + + // Return method/constructor + if (isConstructor) { + return new ConstructorDeclaration(l, false); + } else { + return new MethodDeclaration(l, false); + } + + } + + /** + * @return The a string of comments of the method chosen in JMLSpecBrowser + * _AND_ the additional information get from every not-closed goal + */ + private final String getSpecs() { + + final StringBuffer result = new StringBuffer( + "/*@ public normal_behavior\n"); + + // Get all OperationContracts for method from the + // SpecificationRepositorie and converts them to an array + final OperationContract[] opCon = proof.getServices() + .getSpecificationRepository().getOperationContracts(pm) + .toArray(); + for (int i = 0; i < opCon.length; i++) { + if (opCon[i] instanceof OperationContractImpl) { + + // Append the requires term + result.append("@ requires " + + (jmlEx.translate(((OperationContractImpl) opCon[i]) + .getOriginalPre().getFormula())) + ";"); + + // Apend the ensures term + result + .append("\n@ ensures " + + (jmlEx + .translate(excFreeTerm(((OperationContractImpl) opCon[i]) + .getOriginalPost().getFormula()))) + + ";"); + // Append the concatinating 'also' + result.append("\n@ also \n"); + } + } + result.append(collectAllSpecs()); + result.append("@"); + return result.toString(); + } + + /** + * Iterates through all open goals and creates an JML-comment of structure + * + * @requires ... + * @ensures ... + * @also + * @requires ... + * @ensures ... + * + * where every open goal leads to a new block of specification with its + * generated requires- and ensures-clause + * + * @return + */ + private final StringBuffer collectAllSpecs() { + final StringBuffer result = new StringBuffer(); + + final IteratorOfGoal iter = proof.openGoals().iterator(); + + // Iterates through all open goals in current proof and creates term for + // requires and ensures + while (iter.hasNext()) { + + // the current goal + final Goal currentGoal = (Goal) iter.next(); + + // An iterator over the antecedent of the current goal + final IteratorOfConstrainedFormula antIterator = currentGoal + .sequent().antecedent().toList().iterator(); + + // An iterator over the succedent of the current goal + final IteratorOfConstrainedFormula sucIterator = currentGoal + .sequent().succedent().toList().iterator(); + + // The term, that represents the new requires-clause + Term requiresTerm = TermFactory.DEFAULT.createJunctorTerm(Op.TRUE); + + // Iterates through the antecedent in current goal. Creates + // conjunction of the the elements + while (antIterator.hasNext()) { + + // The current constrained formula + final ConstrainedFormula currentAnt = (ConstrainedFormula) antIterator + .next(); + + // If current term is "inReachableState" or of structure *<.*>.* + // (an implicite PO) + // it is not conjuncted to the requires-term + if (checkTerm(currentAnt.formula())) { + requiresTerm = TermFactory.DEFAULT.createJunctorTerm( + Op.AND, requiresTerm, currentAnt.formula()); + } + } + + // flag for the structure { update }STOP! + boolean isInCorrectForm = false; + + // Iterates through the succedent in current goal. Negates Terms + // and adds them to the term from the anteccedent + Term term = null; + + // Iterates through the succedent in current goal. Creates + // conjunction of the elements + while (sucIterator.hasNext()) { + + // The current constrained formula + ConstrainedFormula suc = (ConstrainedFormula) sucIterator + .next(); + + // Checks if the ConstrainedFormula has the structure { update + // }STOP!. + // In this case, we know, that the program of current goal is + // completly symbolicly executed + // So we set the flag isInCorrectForm. + if (suc.formula().op() instanceof IUpdateOperator) { + final IUpdateOperator update = (IUpdateOperator) suc + .formula().op(); + if ((update.target(suc.formula())).op().equals( + Op.COMPUTE_SPEC_OP)) { + term = suc.formula(); + isInCorrectForm = true; + } + } else { + + // Checks that the current formula is not the STOPTOKEN + if (!(suc.formula().op().equals(Op.COMPUTE_SPEC_OP))) { + + // Checks that the current term is neither a Modality, + // nor the "InReachableState" nor + // an implicite proof obligation ( like etc) + if (checkTerm(suc.formula()) + && !(suc.formula().op() instanceof IUpdateOperator)) { + + // Negation of the current formula is added to the + // term of the requires clause + requiresTerm = TermFactory.DEFAULT + .createJunctorTerm(Op.AND, requiresTerm, + TermFactory.DEFAULT + .createJunctorTerm(Op.NOT, + suc.formula())); + } + } + + } + + } + + // The correct result ist build + + // The requires clause is allways written an consists of all + // formulas, that were in the + // antecedent and the negation of the formulas in the succedent + result + .append("@ requires " + jmlEx.translate(requiresTerm) + + ";\n"); + + // If the flag is true, we know, that there was a modality, that was + // completly symbolicaly executed + // So we could add all assignment pairs in the update to the ensures + // clause with structure following structure + // If there is an update {a :=b} the term a == \old(b) is add to the + // ensures clause + // If the flag is false the ensures clause just consists of true + if (isInCorrectForm) { + result + .append("@ ensures " + + jmlEx.translate(cleanUpdate(term))); + } else { + result.append("@ ensures true "); + } + + // If there is another open goal, the "@ also" is added + if (iter.hasNext()) { + result.append(";\n @ also \n"); + } else { + result.append(";\n"); + } + + } + return result; + } + + /** + * Writes a classDeclaration contained in StringWriter sw to a file + * + * @param sw + * the StringWriter where the class is stored + * @return the path where the file was written + * @throws IOException + */ + private final String writeToFile(StringWriter sw) throws IOException { + + // Select path or create new if not exist + final File dir = new File(System.getProperty("user.home") + + File.separator + "JMLTestFiles"); + if (!dir.exists()) { + dir.mkdir(); + } + + // Create new File with correct name an path + final File pcFile = new File(dir, "Test" + className + ".java"); + final String path = pcFile.getAbsolutePath(); + + // Write content to file + final BufferedWriter bw = new BufferedWriter(new FileWriter(pcFile)); + bw.write(sw.toString()); + bw.close(); + jmltfc.resetProperties(); + return path; + } + + /** + * Checks if the AssignementPairs of the given update are useful for our + * task and returns an Update that just contains usefull Terms + * + * @see de.uka.ilka.key.jmltest.WrapperConstructor#checkTerm + * @see de.uka.ilka.key.jmltest.WrapperConstructor#isUsefulPair + * @param upTerm + * The Term thats needs to be cleaned up + * @return An ArrayOfAssignmentPairs containing only good Terms + */ + private ArrayOfAssignmentPair cleanUpdate(Term upTerm) { + + final ArrayOfAssignmentPair pairs = Update.createUpdate(upTerm) + .getAllAssignmentPairs(); + + final Vector tmpVect = new Vector(); + + // Iterate over all existing Assignment pairs and adds good pairs in a + // Vector + for (int i = 0; i < pairs.size(); ++i) { + final AssignmentPair currPair = pairs.getAssignmentPair(i); + + if (checkTerm(currPair.locationAsTerm()) + && checkTerm((Term) currPair.value()) + && isUsefulPair(currPair)) { + tmpVect.add(currPair); + } + } + // If there is at least one good Term, create a new + // ArrayOfAssignmentPair containing good terms + if (tmpVect.size() > 0) { + final AssignmentPair[] tmp = new QuanAssignmentPairLazy[tmpVect + .size()]; + for (int i = 0; i < tmpVect.size(); i++) { + tmp[i] = (QuanAssignmentPairLazy) tmpVect.elementAt(i); + } + return new ArrayOfAssignmentPair(tmp); + } + // No good terms --> return empty Array + return new ArrayOfAssignmentPair(); + } + + /** + * This method checks if we want this term for getting additional + * information. TODO atm done by blacklisting, whitlisting is better + * + * @param t + * The Term, to be checked + * @return true if we want to keep this Term false else + */ + private final boolean checkTerm(Term t) { + if ( + + // Implicit condition for key + t.op().toString().matches(".*<.*>.*") || + // The term InReachableState + t.op().equals(proof.getJavaInfo().getInReachableState()) || + // InBound + proof.getServices().getTypeConverter().getIntLDT() + .getInBounds().equals(t.op()) || + // We don't want Modalities + t.op() instanceof Modality || + // We don't want Updates + t.op() instanceof IUpdateOperator + // We don't want anything like null.a + || ((t.op() instanceof AttributeOp) && (t.sub(0).op() + .equals(Op.NULL)))) { + return false; + } + // Iterates over all subterms + for (int i = 0; i < t.arity(); i++) { + if (!(checkTerm(t.sub(i)))) + return false; + } + + // Term must be good :) + return true; + } + + /** + * This Method checks if both sides of an Assignment are useful + * + * @see de.uka.ilka.key.jmltest.WrapperConstructor#isUsefulPair + * @param currPair + * @return true if pair is usefull false else + */ + private final boolean isUsefulPair(AssignmentPair currPair) { + return (isUseful(currPair.locationAsTerm()) && isUseful(currPair + .value())); + } + + /** + * This method checks if the given Term is useful for our purpose. Primary + * target is the filtering of local Variables cause those are not known + * outside and would lead to errors if they occur in specification + * + * @param The Term t to be checked + * @return true if t is an Attribute, Parameter, \result, Constant; false else + */ + private final boolean isUseful(Term t) { + + if (t.op() instanceof LocationVariable) { + final LocationVariable tmp = (LocationVariable) t.op(); + // We want Attributes, Parameters and the result of the term (\result) + if ((tmp.isMember()) + || (po.getParams().contains(tmp)) + || ((po.getResult() != null) && (po.getResult().equals(tmp)))) { + + return true; + } + //Other LocationVariables are local Variables, we don't like them + return false; + } + // Constants, Typecast are ok + if ((t.op() instanceof CastFunctionSymbol) + || (t.op() instanceof RigidFunction)) { + return true; + } + assert false : "This location shall not be reached. Term: " + t + + " Op: " + t.op(); + return false; + } + + /** + * Checks if the last conjungt is the ExceptionTerm and removes this Term. + * @param t The Term to be checked + * @return A Term without the ExceptionTerm + */ + private final Term excFreeTerm(Term t) { + if (t.op().equals(Op.AND)) { + final Term excTerm = t.sub(1); + if ((excTerm.op().equals(Op.EQUALS)) + && (excTerm.sub(0).sort().equals(po.getExcVar().sort()) && (excTerm + .sub(1).op().equals(Op.NULL)))) { + return t.sub(0); + } + } + assert false :("DEBUG: Something wrong happend. It is assumed that the second subterm of the conjungtion originalPre is equals(exc,null). This is not the case at the moment. (excFreeTerm(Term t)@JMLTestFileCreator)"); + return t; + } +} diff --git a/system/de/uka/ilkd/key/logic/AnonymisingUpdateFactory.java b/system/de/uka/ilkd/key/logic/AnonymisingUpdateFactory.java index 3d6b87f4b85..1ba6f495f45 100644 --- a/system/de/uka/ilkd/key/logic/AnonymisingUpdateFactory.java +++ b/system/de/uka/ilkd/key/logic/AnonymisingUpdateFactory.java @@ -278,7 +278,7 @@ private Term createGuard(BasicLocationDescriptor bloc, Services services) { return guardTerm; ProgramVariable lengthPV = services.getJavaInfo ().getArrayLength (); - Function sub = services.getTypeConverter ().getIntegerLDT ().getArithSubstraction (); + Function sub = services.getTypeConverter ().getIntegerLDT ().getSub (); Term varTerm = TB.var ( (LogicVariable)locTerm.sub ( 1 ).op () ); Term lengthTerm = TB.dot ( locTerm.sub ( 0 ), lengthPV ); diff --git a/system/de/uka/ilkd/key/logic/BasicLocationDescriptor.java b/system/de/uka/ilkd/key/logic/BasicLocationDescriptor.java index 55bff17996d..22390a906f7 100644 --- a/system/de/uka/ilkd/key/logic/BasicLocationDescriptor.java +++ b/system/de/uka/ilkd/key/logic/BasicLocationDescriptor.java @@ -10,14 +10,14 @@ package de.uka.ilkd.key.logic; import de.uka.ilkd.key.logic.op.Location; -import de.uka.ilkd.key.logic.op.Op; import de.uka.ilkd.key.logic.sort.Sort; public class BasicLocationDescriptor implements LocationDescriptor { + private final static Term trueTerm = TermBuilder.DF.tt(); private final Term fma; private final Term locTerm; - private final static Term trueTerm = TermFactory.DEFAULT.createJunctorTerm(Op.TRUE); + public BasicLocationDescriptor(Term fma, Term locTerm) { assert fma != null && fma.sort() == Sort.FORMULA && locTerm != null; @@ -29,18 +29,22 @@ public BasicLocationDescriptor(Term fma, Term locTerm) { this.locTerm = locTerm; } + public BasicLocationDescriptor(Term locTerm) { this(trueTerm, locTerm); } + public Term getFormula() { return fma; } + public Term getLocTerm() { return locTerm; } + public boolean equals(Object o) { if(!(o instanceof BasicLocationDescriptor)) { return false; @@ -49,13 +53,15 @@ public boolean equals(Object o) { return fma.equals(ld.fma) && locTerm.equals(ld.locTerm); } + public int hashCode() { return fma.hashCode() + locTerm.hashCode(); } + public String toString() { return (fma.equals(trueTerm) ? locTerm.toString() - : "(" + fma + "," + locTerm + ")"); + : "\\if" + fma + "; " + locTerm); } } diff --git a/system/de/uka/ilkd/key/logic/EverythingLocationDescriptor.java b/system/de/uka/ilkd/key/logic/EverythingLocationDescriptor.java index 56a5f2ea5f9..5289a37b9d8 100644 --- a/system/de/uka/ilkd/key/logic/EverythingLocationDescriptor.java +++ b/system/de/uka/ilkd/key/logic/EverythingLocationDescriptor.java @@ -14,6 +14,9 @@ public class EverythingLocationDescriptor implements LocationDescriptor { public static final EverythingLocationDescriptor INSTANCE = new EverythingLocationDescriptor(); + public static final SetOfLocationDescriptor INSTANCE_AS_SET + = SetAsListOfLocationDescriptor.EMPTY_SET.add(INSTANCE); + private EverythingLocationDescriptor() {} public String toString() { diff --git a/system/de/uka/ilkd/key/logic/InnerVariableNamer.java b/system/de/uka/ilkd/key/logic/InnerVariableNamer.java index bff8d6cdbfd..a9854650538 100644 --- a/system/de/uka/ilkd/key/logic/InnerVariableNamer.java +++ b/system/de/uka/ilkd/key/logic/InnerVariableNamer.java @@ -55,7 +55,7 @@ public ProgramVariable rename(ProgramVariable var, ProgramElementName name = var.getProgramElementName(); BasenameAndIndex bai = getBasenameAndIndex(name); Globals globals = wrapGlobals(goal.getGlobalProgVars()); - map = new HashMap(); + map.clear(); //prepare renaming of inner var final NameCreationInfo nci = getMethodStack(posOfFind); @@ -79,7 +79,7 @@ public ProgramVariable rename(ProgramVariable var, map.put(var, newvar); renamingHistory = map; //execute renaming - ProgVarReplacer pvr = new ProgVarReplacer(map); + ProgVarReplacer pvr = new ProgVarReplacer(map, services); pvr.replace(goal); } diff --git a/system/de/uka/ilkd/key/logic/ProgramElementName.java b/system/de/uka/ilkd/key/logic/ProgramElementName.java index 16db5026f7e..aa465b3d717 100644 --- a/system/de/uka/ilkd/key/logic/ProgramElementName.java +++ b/system/de/uka/ilkd/key/logic/ProgramElementName.java @@ -14,7 +14,6 @@ import org.apache.log4j.Logger; import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.reference.MethodName; import de.uka.ilkd.key.java.reference.ReferenceSuffix; import de.uka.ilkd.key.java.visitor.Visitor; @@ -180,17 +179,6 @@ public NameCreationInfo getCreationInfo() { return creationInfo; } - /** - *@return the annotations. - */ - public Annotation[] getAnnotations(){ - return new Annotation[0]; - } - - public int getAnnotationCount(){ - return 0; - } - public MatchConditions match(SourceData source, MatchConditions matchCond) { final ProgramElement src = source.getSource(); if (this.equals(src)) { diff --git a/system/de/uka/ilkd/key/logic/TermBuilder.java b/system/de/uka/ilkd/key/logic/TermBuilder.java index 96b244f4e45..5705f46b5c0 100644 --- a/system/de/uka/ilkd/key/logic/TermBuilder.java +++ b/system/de/uka/ilkd/key/logic/TermBuilder.java @@ -46,29 +46,29 @@ public Term ff() { return ff; } - // To be more general: shouldn't lv be a QuantifiableVariable? Sure! - public Term all(QuantifiableVariable lv, Term t2) { - if ( !t2.freeVars.contains ( lv ) ) return t2; - return tf.createQuantifierTerm ( Op.ALL, lv, t2 ); + + public Term all(QuantifiableVariable qv, Term t2) { + if ( !t2.freeVars.contains ( qv ) ) return t2; + return tf.createQuantifierTerm ( Op.ALL, qv, t2 ); } - public Term all(QuantifiableVariable[] lv, Term t2) { + public Term all(QuantifiableVariable[] qv, Term t2) { Term result = t2; - for (int i=lv.length-1; i>=0; i--) { - result = all(lv[i], result); + for (int i=qv.length-1; i>=0; i--) { + result = all(qv[i], result); } return result; } - public Term ex(QuantifiableVariable lv, Term t2) { - if ( !t2.freeVars.contains ( lv ) ) return t2; - return tf.createQuantifierTerm(Op.EX, lv, t2); + public Term ex(QuantifiableVariable qv, Term t2) { + if ( !t2.freeVars.contains ( qv ) ) return t2; + return tf.createQuantifierTerm(Op.EX, qv, t2); } - public Term ex(QuantifiableVariable[] lv, Term t2) { + public Term ex(QuantifiableVariable[] qv, Term t2) { Term result = t2; - for (int i=lv.length-1; i>=0; i--) { - result = ex(lv[i], result); + for (int i=qv.length-1; i>=0; i--) { + result = ex(qv[i], result); } return result; } @@ -238,6 +238,10 @@ public Term box(JavaBlock jb, Term t) { public Term dia(JavaBlock jb, Term t) { return tf.createDiamondTerm(jb, t); } + + public Term prog(Modality mod, JavaBlock jb, Term t) { + return tf.createProgramTerm(mod, jb, t); + } public Term ife(Term cond, Term _then, Term _else) { return tf.createIfThenElseTerm(cond, _then, _else); diff --git a/system/de/uka/ilkd/key/logic/TermCreationException.java b/system/de/uka/ilkd/key/logic/TermCreationException.java index 41fc47526f7..fd9f08bd4ff 100644 --- a/system/de/uka/ilkd/key/logic/TermCreationException.java +++ b/system/de/uka/ilkd/key/logic/TermCreationException.java @@ -36,6 +36,7 @@ public TermCreationException(String errorMessage) { Term[] subs = new Term[failed.arity()]; for (int i = 0; ivar, i.e. carry out the update * update in parallel for all values of var diff --git a/system/de/uka/ilkd/key/logic/VariableNamer.java b/system/de/uka/ilkd/key/logic/VariableNamer.java index 962a8383b9d..5229ee79c97 100644 --- a/system/de/uka/ilkd/key/logic/VariableNamer.java +++ b/system/de/uka/ilkd/key/logic/VariableNamer.java @@ -10,7 +10,8 @@ package de.uka.ilkd.key.logic; -import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; import de.uka.ilkd.key.collection.IteratorOfString; import de.uka.ilkd.key.collection.ListOfString; @@ -71,10 +72,10 @@ public abstract class VariableNamer implements InstantiationProposer { /** * pointer to services object */ - private final Services services; + protected final Services services; - protected HashMap map = new HashMap(); - protected HashMap renamingHistory = new HashMap(); + protected final Map map = new LinkedHashMap(); + protected Map renamingHistory = new LinkedHashMap(); //------------------------------------------------------------------------- //constructors @@ -122,7 +123,7 @@ && parseName(name.toString()) instanceof IndProgramElementName) { } - public HashMap getRenamingMap(){ + public Map getRenamingMap(){ return renamingHistory; } @@ -504,6 +505,10 @@ public String getProposal(TacletApp app, } } } + + if(!(var instanceof SortedSchemaVariable)) { + return null; + } //get the proposal ProgramElementName name diff --git a/system/de/uka/ilkd/key/logic/ldt/ADT.java b/system/de/uka/ilkd/key/logic/ldt/ADT.java index b5cae4ece04..c4aab7f8c5c 100644 --- a/system/de/uka/ilkd/key/logic/ldt/ADT.java +++ b/system/de/uka/ilkd/key/logic/ldt/ADT.java @@ -84,5 +84,4 @@ public Vector getSorts(){ public Vector getAxioms(){ return axioms; } - } diff --git a/system/de/uka/ilkd/key/logic/ldt/AbstractIntegerLDT.java b/system/de/uka/ilkd/key/logic/ldt/AbstractIntegerLDT.java index bd03f5fcd97..9d2d932b847 100644 --- a/system/de/uka/ilkd/key/logic/ldt/AbstractIntegerLDT.java +++ b/system/de/uka/ilkd/key/logic/ldt/AbstractIntegerLDT.java @@ -11,8 +11,6 @@ import de.uka.ilkd.key.java.Expression; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.abstraction.PrimitiveType; import de.uka.ilkd.key.java.abstraction.Type; import de.uka.ilkd.key.java.expression.Literal; import de.uka.ilkd.key.java.expression.Operator; @@ -32,41 +30,32 @@ /** * This class inherits from LDT and implements all method that are - * necessary to handle integers, shorts and bytes. - * It loads the needed rule file and offers method to convert java - * number types to their logic counterpart + * necessary to handle integers, shorts and bytes. It caches the symbols + * declared in integerHeader.key and offers methods to convert java + * number types to their logic counterpart. */ public abstract class AbstractIntegerLDT extends LDT { - /** - * Public name constants - */ + //public name constants public static final String NEGATIVE_LITERAL_STRING = "neglit"; public static final Name NUMBERS_NAME = new Name("Z"); public static final Name CHAR_ID_NAME = new Name("C"); - - /** the function symbols used to represent literals */ - protected final Function numbers; - protected final Function charID; + + //the following fields cache the symbols from integerHeader.key. + //(explanations see there) protected final Function sharp; protected final Function numberSymbol[] = new Function[10]; - - /** the function symbols for the integer operations. - * Used as shortcuts. - */ - protected final Function greaterThan; - protected final Function greaterOrEquals; - protected final Function lessThan; - protected final Function lessOrEquals; + protected final Function numbers; + protected final Function negativeNumber; + protected final Function charID; protected final Function plus; + protected final Function negative; protected final Function minus; protected final Function times; protected final Function divide; protected final Function modulo; protected final Function jDivide; protected final Function jModulo; - protected final Function negative; - protected final Function negativeNumber; protected final Function unaryMinusJint; protected final Function unaryMinusJlong; protected final Function addJint; @@ -91,227 +80,304 @@ public abstract class AbstractIntegerLDT extends LDT { protected final Function andJlong; protected final Function xorJint; protected final Function xorJlong; - - /** the predicate symbols for being within boundaries*/ + protected final Function moduloByte; + protected final Function moduloShort; + protected final Function moduloInt; + protected final Function moduloLong; + protected final Function moduloChar; + protected final Function javaUnaryMinusInt; + protected final Function javaUnaryMinusLong; + protected final Function javaBitwiseNegation; + protected final Function javaAddInt; + protected final Function javaAddLong; + protected final Function javaSubInt; + protected final Function javaSubLong; + protected final Function javaMulInt; + protected final Function javaMulLong; + protected final Function javaMod; + protected final Function javaDivInt; + protected final Function javaDivLong; + protected final Function javaShiftRightInt; + protected final Function javaShiftRightLong; + protected final Function javaShiftLeftInt; + protected final Function javaShiftLeftLong; + protected final Function javaUnsignedShiftRightInt; + protected final Function javaUnsignedShiftRightLong; + protected final Function javaBitwiseOrInt; + protected final Function javaBitwiseOrLong; + protected final Function javaBitwiseAndInt; + protected final Function javaBitwiseAndLong; + protected final Function javaBitwiseXOrInt; + protected final Function javaBitwiseXOrLong; + protected final Function javaCastByte; + protected final Function javaCastShort; + protected final Function javaCastInt; + protected final Function javaCastLong; + protected final Function javaCastChar; + protected final Function lessThan; + protected final Function greaterThan; + protected final Function greaterOrEquals; + protected final Function lessOrEquals; protected final Function inByte; - protected Function inShort; - protected Function inInt; - protected Function inLong; - protected Function inChar; - - // these functions are used to represent Java operators - // the taclets moving an integer expression to logic use them. - // At a later stage they are interpreted depending on the chosen - // integer semantics. - private Function javaUnaryMinusInt; - private Function javaUnaryMinusLong; - private Function javaBitwiseNegation; - private Function javaAddInt; - private Function javaAddLong; - private Function javaSubInt; - private Function javaSubLong; - private Function javaMulInt; - private Function javaMulLong; - private Function javaMod; - private Function javaDivInt; - private Function javaDivLong; - private Function javaShiftRightInt; - private Function javaShiftRightLong; - private Function javaShiftLeftInt; - private Function javaShiftLeftLong; - private Function javaUnsignedShiftRightInt; - private Function javaUnsignedShiftRightLong; - private Function javaBitwiseOrInt; - private Function javaBitwiseOrLong; - private Function javaBitwiseAndInt; - private Function javaBitwiseAndLong; - private Function javaBitwiseXOrInt; - private Function javaBitwiseXOrLong; - private Function javaCastByte; - private Function javaCastShort; - private Function javaCastInt; - private Function javaCastLong; - private Function javaCastChar; - - + protected final Function inShort; + protected final Function inInt; + protected final Function inLong; + protected final Function inChar; + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- protected AbstractIntegerLDT(Name name, Namespace sorts, Namespace functions, Type javaType) { super(name, sorts, javaType); - - numbers = addFunction(functions, NUMBERS_NAME.toString()); - charID = addFunction(functions, CHAR_ID_NAME.toString()); - sharp = addFunction(functions, "#"); - assert sharp.sort() == numbers.argSort(0); + + //initialise caches for function symbols from integerHeader.key + sharp = addFunction(functions, "#"); for (int i = 0; i < 10; i++) { numberSymbol[i] = addFunction(functions, ""+i); - assert numberSymbol[i].sort() == numbers.argSort(0); } - - greaterThan = addFunction(functions, "gt"); - greaterOrEquals = addFunction(functions, "geq"); - lessThan = addFunction(functions, "lt"); - lessOrEquals = addFunction(functions, "leq"); - plus = addFunction(functions, "add"); - minus = addFunction(functions, "sub"); - times = addFunction(functions, "mul"); - divide = addFunction(functions, "div"); - modulo = addFunction(functions, "mod"); - jDivide = addFunction(functions, "div"); - jModulo = addFunction(functions, "mod"); - negative = addFunction(functions, "neg"); - negativeNumber = addFunction(functions, NEGATIVE_LITERAL_STRING); - unaryMinusJint = addFunction(functions, "unaryMinusJint"); - unaryMinusJlong = addFunction(functions, "unaryMinusJlong"); - addJint = addFunction(functions, "addJint"); - addJlong = addFunction(functions, "addJlong"); - subJint = addFunction(functions, "subJint"); - subJlong = addFunction(functions, "subJlong"); - mulJint = addFunction(functions, "mulJint"); - mulJlong = addFunction(functions, "mulJlong"); - modJint = addFunction(functions, "modJint"); - modJlong = addFunction(functions, "modJlong"); - divJint = addFunction(functions, "divJint"); - divJlong = addFunction(functions, "divJlong"); - shiftrightJint = addFunction(functions, "shiftrightJint"); - shiftrightJlong = addFunction(functions, "shiftrightJlong"); - shiftleftJint = addFunction(functions, "shiftleftJint"); - shiftleftJlong = addFunction(functions, "shiftleftJlong"); - unsignedshiftrightJint = - addFunction(functions, "unsignedshiftrightJint"); - unsignedshiftrightJlong = - addFunction(functions, "unsignedshiftrightJlong"); - orJint = addFunction(functions, "orJint"); - orJlong = addFunction(functions, "orJlong"); - andJint = addFunction(functions, "andJint"); - andJlong = addFunction(functions, "andJlong"); - xorJint = addFunction(functions, "xorJint"); - xorJlong = addFunction(functions, "xorJlong"); - - inByte = addFunction(functions, "inByte"); - inShort = addFunction(functions, "inShort"); - inInt = addFunction(functions, "inInt"); - inLong = addFunction(functions, "inLong"); - inChar = addFunction(functions, "inChar"); - - - // functions representing the Java operators directly - // these are ximoatised depending on the chosen integer semantics - javaUnaryMinusInt = addFunction(functions, "javaUnaryMinusInt"); - javaUnaryMinusLong = addFunction(functions, "javaUnaryMinusLong"); + numbers = addFunction(functions, NUMBERS_NAME.toString()); + assert sharp.sort() == numbers.argSort(0); + negativeNumber = addFunction(functions, NEGATIVE_LITERAL_STRING); + charID = addFunction(functions, CHAR_ID_NAME.toString()); + plus = addFunction(functions, "add"); + negative = addFunction(functions, "neg"); + minus = addFunction(functions, "sub"); + times = addFunction(functions, "mul"); + divide = addFunction(functions, "div"); + modulo = addFunction(functions, "mod"); + jDivide = addFunction(functions, "jdiv"); + jModulo = addFunction(functions, "jmod"); + unaryMinusJint = addFunction(functions, "unaryMinusJint"); + unaryMinusJlong = addFunction(functions, "unaryMinusJlong"); + addJint = addFunction(functions, "addJint"); + addJlong = addFunction(functions, "addJlong"); + subJint = addFunction(functions, "subJint"); + subJlong = addFunction(functions, "subJlong"); + mulJint = addFunction(functions, "mulJint"); + mulJlong = addFunction(functions, "mulJlong"); + modJint = addFunction(functions, "modJint"); + modJlong = addFunction(functions, "modJlong"); + divJint = addFunction(functions, "divJint"); + divJlong = addFunction(functions, "divJlong"); + shiftrightJint = addFunction(functions, "shiftrightJint"); + shiftrightJlong = addFunction(functions, "shiftrightJlong"); + shiftleftJint = addFunction(functions, "shiftleftJint"); + shiftleftJlong = addFunction(functions, "shiftleftJlong"); + unsignedshiftrightJint + = addFunction(functions, "unsignedshiftrightJint"); + unsignedshiftrightJlong + = addFunction(functions, "unsignedshiftrightJlong"); + orJint = addFunction(functions, "orJint"); + orJlong = addFunction(functions, "orJlong"); + andJint = addFunction(functions, "andJint"); + andJlong = addFunction(functions, "andJlong"); + xorJint = addFunction(functions, "xorJint"); + xorJlong = addFunction(functions, "xorJlong"); + moduloByte = addFunction(functions, "moduloByte"); + moduloShort = addFunction(functions, "moduloShort"); + moduloInt = addFunction(functions, "moduloInt"); + moduloLong = addFunction(functions, "moduloLong"); + moduloChar = addFunction(functions, "moduloChar"); + javaUnaryMinusInt = addFunction(functions, "javaUnaryMinusInt"); + javaUnaryMinusLong = addFunction(functions, "javaUnaryMinusLong"); javaBitwiseNegation = addFunction(functions, "javaBitwiseNegation"); + javaAddInt = addFunction(functions, "javaAddInt"); + javaAddLong = addFunction(functions, "javaAddLong"); + javaSubInt = addFunction(functions, "javaSubInt"); + javaSubLong = addFunction(functions, "javaSubLong"); + javaMulInt = addFunction(functions, "javaMulInt"); + javaMulLong = addFunction(functions, "javaMulLong"); + javaMod = addFunction(functions, "javaMod"); + javaDivInt = addFunction(functions, "javaDivInt"); + javaDivLong = addFunction(functions, "javaDivLong"); + javaShiftRightInt = addFunction(functions, "javaShiftRightInt"); + javaShiftRightLong = addFunction(functions, "javaShiftRightLong"); + javaShiftLeftInt = addFunction(functions, "javaShiftLeftInt"); + javaShiftLeftLong = addFunction(functions, "javaShiftLeftLong"); + javaUnsignedShiftRightInt + = addFunction(functions, "javaUnsignedShiftRightInt"); + javaUnsignedShiftRightLong + = addFunction(functions, "javaUnsignedShiftRightLong"); + javaBitwiseOrInt = addFunction(functions, "javaBitwiseOrInt"); + javaBitwiseOrLong = addFunction(functions, "javaBitwiseOrLong"); + javaBitwiseAndInt = addFunction(functions, "javaBitwiseAndInt"); + javaBitwiseAndLong = addFunction(functions, "javaBitwiseAndLong"); + javaBitwiseXOrInt = addFunction(functions, "javaBitwiseXOrInt"); + javaBitwiseXOrLong = addFunction(functions, "javaBitwiseXOrLong"); + javaCastByte = addFunction(functions, "javaCastByte"); + javaCastShort = addFunction(functions, "javaCastShort"); + javaCastInt = addFunction(functions, "javaCastInt"); + javaCastLong = addFunction(functions, "javaCastLong"); + javaCastChar = addFunction(functions, "javaCastChar"); + lessThan = addFunction(functions, "lt"); + greaterThan = addFunction(functions, "gt"); + greaterOrEquals = addFunction(functions, "geq"); + lessOrEquals = addFunction(functions, "leq"); + inByte = addFunction(functions, "inByte"); + inShort = addFunction(functions, "inShort"); + inInt = addFunction(functions, "inInt"); + inLong = addFunction(functions, "inLong"); + inChar = addFunction(functions, "inChar"); + } + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private boolean isNumberLiteral(Function f) { + char c=f.name().toString().charAt(0); + return (c-'0'>=0) && (c-'0'<=9); + } - javaAddInt = addFunction(functions, "javaAddInt"); - javaAddLong = addFunction(functions, "javaAddLong"); - javaSubInt = addFunction(functions, "javaSubInt"); - javaSubLong = addFunction(functions, "javaSubLong"); - javaMulInt = addFunction(functions, "javaMulInt"); - javaMulLong = addFunction(functions, "javaMulLong"); - javaMod = addFunction(functions, "javaMod"); - javaDivInt = addFunction(functions, "javaDivInt"); - javaDivLong = addFunction(functions, "javaDivLong"); - javaShiftRightInt = addFunction(functions, "javaShiftRightInt"); - javaShiftRightLong = addFunction(functions, "javaShiftRightLong"); - javaShiftLeftInt = addFunction(functions, "javaShiftLeftInt"); - javaShiftLeftLong = addFunction(functions, "javaShiftLeftLong"); - javaUnsignedShiftRightInt = addFunction(functions, "javaUnsignedShiftRightInt"); - javaUnsignedShiftRightLong = addFunction(functions, "javaUnsignedShiftRightLong"); - javaBitwiseOrInt = addFunction(functions, "javaBitwiseOrInt"); - javaBitwiseOrLong = addFunction(functions, "javaBitwiseOrLong"); - javaBitwiseAndInt = addFunction(functions, "javaBitwiseAndInt"); - javaBitwiseAndLong = addFunction(functions, "javaBitwiseAndLong"); - javaBitwiseXOrInt = addFunction(functions, "javaBitwiseXOrInt"); - javaBitwiseXOrLong = addFunction(functions, "javaBitwiseXOrLong"); - javaCastByte = addFunction(functions, "javaCastByte"); - javaCastShort = addFunction(functions, "javaCastShort"); - javaCastInt = addFunction(functions, "javaCastInt"); - javaCastLong = addFunction(functions, "javaCastLong"); - javaCastChar = addFunction(functions, "javaCastChar"); + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public Function getNumberTerminator() { + return sharp; } + + + public Function getNumberLiteralFor(int number) { + if (number < 0 || number > 9) { + throw new IllegalArgumentException + ("Number literal symbols range from 0 to 9. Requested was:" + number); + } + return numberSymbol[number]; + } + + + public Function getNumberSymbol() { + return numbers; + } + + + public Function getNegativeNumberSign() { + return negativeNumber; + } + + + public Function getCharSymbol() { + return charID; + } + + + public abstract Function getAdd(); + + + public Function getNeg() { + return negative; + } + + + public abstract Function getSub(); + + + public abstract Function getMul(); + + + public abstract Function getDiv(); + + + public abstract Function getMod(); + + + public abstract Function getShiftLeft(); + + + public abstract Function getShiftRight(); + + + public abstract Function getUnsignedShiftRight(); + + + public abstract Function getBitwiseOr(); + + + public abstract Function getBitwiseAnd(); + + + public abstract Function getBitwiseXor(); + + + public abstract Function getBitwiseNegation(); + + + public abstract Function getCast(); + + + public abstract Function getLessThan(); + + + public abstract Function getGreaterThan(); + + + public abstract Function getGreaterOrEquals(); + + public abstract Function getLessOrEquals(); + + + public abstract Function getInBounds(); + + /** returns the function symbol for the given operation * null if no function is found for the given operator * @return the function symbol for the given operation */ public Function getFunctionFor - (de.uka.ilkd.key.java.expression.Operator op, + (de.uka.ilkd.key.java.expression.Operator op, Services serv, ExecutionContext ec) { - final KeYJavaType opReturnType = - op.getKeYJavaType(serv, ec); + //final KeYJavaType opReturnType = op.getKeYJavaType(serv, ec); if (op instanceof GreaterThan) { - return greaterThan; - } else if (op instanceof GreaterOrEquals) { - return greaterOrEquals; - } else if (op instanceof LessThan) { - return lessThan; - } else if (op instanceof LessOrEquals) { - return lessOrEquals; - } else if (op instanceof Divide) { - return - opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaDivLong() : getJavaDivInt(); - } else if (op instanceof Times) { - return - opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaMulLong() : getJavaMulInt(); - } else if (op instanceof Plus) { - return - opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaAddLong() : getJavaAddInt(); - } else if (op instanceof Minus) { - return - opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaSubLong() : getJavaSubInt(); - } else if (op instanceof Modulo) { - return getJavaMod(); - } else if (op instanceof ShiftLeft) { - return - opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaShiftLeftLong() : getJavaShiftLeftInt(); - } else if (op instanceof ShiftRight) { - return opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaShiftRightLong() : getJavaShiftRightInt(); - } else if (op instanceof UnsignedShiftRight) { - return opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaUnsignedShiftRightLong() : getJavaUnsignedShiftRightInt(); + return getGreaterThan(); + } else if (op instanceof GreaterOrEquals) { + return getGreaterOrEquals(); + } else if (op instanceof LessThan) { + return getLessThan(); + } else if (op instanceof LessOrEquals) { + return getLessOrEquals(); + } else if (op instanceof Divide) { + return getDiv(); + } else if (op instanceof Times) { + return getMul(); + } else if (op instanceof Plus) { + return getAdd(); + } else if (op instanceof Minus) { + return getSub(); + } else if (op instanceof Modulo) { + return getMod(); + } else if (op instanceof ShiftLeft) { + return getShiftLeft(); + } else if (op instanceof ShiftRight) { + return getShiftRight(); + } else if (op instanceof UnsignedShiftRight) { + return getUnsignedShiftRight(); } else if (op instanceof BinaryAnd) { - assert opReturnType.getJavaType() != PrimitiveType.JAVA_BOOLEAN; - return opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaBitwiseAndLong() : getJavaBitwiseAndInt(); - } else if (op instanceof BinaryNot) { - assert opReturnType.getJavaType() != PrimitiveType.JAVA_BOOLEAN; - return getJavaBitwiseNegation(); - } else if (op instanceof BinaryOr) { - assert opReturnType.getJavaType() != PrimitiveType.JAVA_BOOLEAN; - return opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaBitwiseOrLong() : getJavaBitwiseOrInt(); - } else if (op instanceof BinaryXOr) { - assert opReturnType.getJavaType() != PrimitiveType.JAVA_BOOLEAN; - return opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaBitwiseOrLong() : getJavaBitwiseOrInt(); - } else if (op instanceof Negative) { - return opReturnType.getJavaType() == PrimitiveType.JAVA_LONG - ? getJavaUnaryMinusLong() : getJavaUnaryMinusLong(); - } else if (op instanceof TypeCast) { - if (opReturnType.getJavaType() == PrimitiveType.JAVA_CHAR) { - return getJavaCastChar(); - } else if (opReturnType.getJavaType() == PrimitiveType.JAVA_BYTE) { - return getJavaCastByte(); - } else if (opReturnType.getJavaType() == PrimitiveType.JAVA_SHORT) { - return getJavaCastShort(); - } else if (opReturnType.getJavaType() == PrimitiveType.JAVA_INT) { - return getJavaCastInt(); - } else if (opReturnType.getJavaType() == PrimitiveType.JAVA_LONG) { - return getJavaCastLong(); - } + return getBitwiseAnd(); + } else if (op instanceof BinaryNot) { + return getBitwiseNegation(); + } else if (op instanceof BinaryOr) { + return getBitwiseOr(); + } else if (op instanceof BinaryXOr) { + return getBitwiseXor(); + } else if (op instanceof Negative) { + return getNeg(); + } else if (op instanceof TypeCast) { + return getCast(); + } else { + return null; } - return null; } @@ -379,202 +445,118 @@ public boolean isResponsible(Operator op, Term sub, Services services, Execution * form */ public Term translateLiteral(Literal lit) { - int length=0; - boolean minusFlag = false; - Debug.assertTrue(lit instanceof IntLiteral || - lit instanceof LongLiteral || - lit instanceof CharLiteral, - "Literal '"+lit+"' is not an integer literal."); - - char[] int_ch=null; - assert sharp != null; - Term result = TermFactory.DEFAULT.createFunctionTerm(sharp); - - Function identifier=numbers; - if (lit instanceof CharLiteral) { - lit = new IntLiteral(""+ (int)(((CharLiteral)lit) - .getCharValue()) ) ; - identifier = charID; - } - - String literalString = ""; - if (lit instanceof IntLiteral) { - literalString = ((IntLiteral)lit).getValue(); - } else { - Debug.assertTrue(lit instanceof LongLiteral); - literalString = ((LongLiteral)lit).getValue(); - } - - if (literalString.charAt(0) == '-') { - minusFlag = true; - literalString = - literalString.substring(1); - } - if (lit instanceof IntLiteral) { - if (literalString.startsWith("0x")) { + int length=0; + boolean minusFlag = false; + Debug.assertTrue(lit instanceof IntLiteral || + lit instanceof LongLiteral || + lit instanceof CharLiteral, + "Literal '"+lit+"' is not an integer literal."); + + char[] int_ch=null; + assert sharp != null; + Term result = TermFactory.DEFAULT.createFunctionTerm(sharp); + + Function identifier=numbers; + if (lit instanceof CharLiteral) { + lit = new IntLiteral(""+ (int)(((CharLiteral)lit) + .getCharValue()) ) ; + identifier = charID; + } + + String literalString = ""; + if (lit instanceof IntLiteral) { + literalString = ((IntLiteral)lit).getValue(); + } else { + Debug.assertTrue(lit instanceof LongLiteral); + literalString = ((LongLiteral)lit).getValue(); + } + + if (literalString.charAt(0) == '-') { + minusFlag = true; + literalString = + literalString.substring(1); + } + if (lit instanceof IntLiteral) { + if (literalString.startsWith("0x")) { try { int i = Integer.parseInt - (literalString.substring(2),16); + (literalString.substring(2),16); int_ch=(""+i).toCharArray(); }catch(NumberFormatException nfe) { Debug.fail("Not a hexadecimal constant!"); - } + } } else { - int_ch = literalString.toCharArray(); + int_ch = literalString.toCharArray(); } length = int_ch.length; - } else if (lit instanceof LongLiteral) { - if (literalString.startsWith("0x")) { - try { - // long literals have an 'L' as last sign; we have - // to skip it + } else if (lit instanceof LongLiteral) { + if (literalString.startsWith("0x")) { + try { + // long literals have an 'L' as last sign; we have + // to skip it final long l = Long.parseLong - (literalString.substring(2, - literalString.length() - 1), - 16); + (literalString.substring(2, + literalString.length() - 1), + 16); int_ch=(""+l).toCharArray(); } catch (NumberFormatException nfe) { Debug.fail("Not a hexadecimal constant!"); - } - length = int_ch.length; - } else { - // long literals have an 'L' as last sign; skip it - int_ch = literalString.toCharArray(); - length = int_ch.length - 1; - } - } - + } + length = int_ch.length; + } else { + // long literals have an 'L' as last sign; skip it + int_ch = literalString.toCharArray(); + length = int_ch.length - 1; + } + } + for (int i = 0; i < length; i++) { - result = TermFactory.DEFAULT.createFunctionTerm - (numberSymbol[int_ch[i]-'0'], result); + result = TermFactory.DEFAULT.createFunctionTerm + (numberSymbol[int_ch[i]-'0'], result); } - if (minusFlag) { - result = TermFactory.DEFAULT.createFunctionTerm - (negativeNumber, result); - } - result = TermFactory.DEFAULT.createFunctionTerm - (identifier, result); - - Debug.out("integerldt: result of translating literal (lit, result):", - lit, result); + if (minusFlag) { + result = TermFactory.DEFAULT.createFunctionTerm + (negativeNumber, result); + } + result = TermFactory.DEFAULT.createFunctionTerm + (identifier, result); - return result; + Debug.out("integerldt: result of translating literal (lit, result):", + lit, result); + return result; } - - - public Function getNumberTerminator(){ - return sharp; - } - - - public Function getNumberSymbol() { - return numbers; - } - - public Function getCharSymbol() { - return charID; - } - - public Function getNumberLiteralFor(int number) { - if (number < 0 || number > 9) { - throw new IllegalArgumentException - ("Number literal symbols range from 0 to 9. Requested was:" + number); - } - - return numberSymbol[number]; - } - - private boolean isNumberLiteral(Function f) { - char c=f.name().toString().charAt(0); - return (c-'0'>=0) && (c-'0'<=9); - } - public boolean hasLiteralFunction(Function f) { - return containsFunction(f) && (f.arity()==0 || isNumberLiteral(f)); - } - - public Expression translateTerm(Term t, ExtList children) { - if (!containsFunction((Function) t.op())) return null; - Function f = (Function)t.op(); - if (isNumberLiteral(f) || f == numbers || f ==charID) { - StringBuffer sb = new StringBuffer(""); - Term it = t; - if (f == charID || f == numbers) { - it = it.sub(0); - f = (Function)it.op(); - } - while (isNumberLiteral(f)) { - sb.insert(0, f.name().toString().charAt(0)); - it=it.sub(0); - f = (Function)it.op(); - } - // numbers must end with a sharp - if (f == sharp) { - return new IntLiteral(sb.toString()); - } - } - throw new RuntimeException("IntegerLDT: Cannot convert term to program: " - +t); - } - - /** - * returns the unary function symbol for representing a negative - * number literal - * @return the function symbol used to represent negative number literals - */ - public Function getNegativeNumberSign() { - return negativeNumber; + return containsFunction(f) && (f.arity()==0 || isNumberLiteral(f)); } - - /** - * returns the unary function symbol for representing the negative value - * e.g. -(var) - * @return the function symbol used to represent the negative sign - */ - public Function getNegativeSign() { - return negative; - } - - /** - * returns the function symbol used to represent addition of - * arithmetical integers - * @return the function symbol for integer addition - */ - public Function getArithAddition() { - return plus; - } - /** - * returns the function symbol used to represent substraction of - * arithmetical integers - * @return the function symbol for integer substraction - */ - public Function getArithSubstraction() { - return minus; - } - - - /** - * returns the function symbol used to represent multiplication on - * the arithmetical integers - * @return the function symbol used to represent integer multiplication - */ - public Function getArithMultiplication() { - return times; + public Expression translateTerm(Term t, ExtList children) { + if (!containsFunction((Function) t.op())) return null; + Function f = (Function)t.op(); + if (isNumberLiteral(f) || f == numbers || f ==charID) { + StringBuffer sb = new StringBuffer(""); + Term it = t; + if (f == charID || f == numbers) { + it = it.sub(0); + f = (Function)it.op(); + } + while (isNumberLiteral(f)) { + sb.insert(0, f.name().toString().charAt(0)); + it=it.sub(0); + f = (Function)it.op(); + } + // numbers must end with a sharp + if (f == sharp) { + return new IntLiteral(sb.toString()); + } + } + throw new RuntimeException("AbstractIntegerLDT: Cannot convert term to program: " + +t); } - /** - * returns the function symbol used to represent division of - * the arithmetical integers - * @return the function symbol used to represent integer division - */ - public Function getArithDivision() { - return divide; - } /** * returns the function symbol used to represent java-like division of @@ -603,47 +585,6 @@ public Function getJModulo() { return jModulo; } - - /** - * returns the boolean function symbol to compare two integer values - * val1, val2 if val1 is lesser or equal than - * val2 - * @return the boolean function symbol to compare two integer values - */ - public Function getLessOrEquals() { - return lessOrEquals; - } - - /** - * returns the boolean function symbol to compare two integer values - * val1, val2 if val1 is lesser than - * val2 - * @return the boolean function symbol to compare two integer values - */ - public Function getLessThan() { - return lessThan; - } - - /** - * returns the boolean function symbol to compare two integer values - * val1, val2 if val1 is greater or equals - * val2 - * @return the boolean function symbol to compare two integer values - */ - public Function getGreaterOrEquals() { - return greaterOrEquals; - } - - /** - * returns the boolean function symbol to compare two integer values - * val1, val2 if val1 is greater than - * val2 - * @return the boolean function symbol to compare two integer values - */ - public Function getGreaterThan() { - return greaterThan; - } - /** returns a function mapping an arithmetic integer to its Java long representation */ public Function getModuloLong() { return modJlong; @@ -666,8 +607,6 @@ public Function getArithJavaIntAddition() { return addJint; } - public abstract Function getInBoundsPredicate(); - /** * the function representing the Java operator when one of the diff --git a/system/de/uka/ilkd/key/logic/ldt/ByteLDT.java b/system/de/uka/ilkd/key/logic/ldt/ByteLDT.java index 036271533d0..4052117d6e9 100644 --- a/system/de/uka/ilkd/key/logic/ldt/ByteLDT.java +++ b/system/de/uka/ilkd/key/logic/ldt/ByteLDT.java @@ -1,3 +1,12 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// package de.uka.ilkd.key.logic.ldt; import de.uka.ilkd.key.java.abstraction.PrimitiveType; @@ -11,9 +20,94 @@ public class ByteLDT extends AbstractIntegerLDT { public ByteLDT(Namespace sorts, Namespace functions) { super(new Name("jbyte"), sorts, functions, PrimitiveType.JAVA_BYTE); } + + + public Function getAdd() { + return javaAddInt; + } + + + public Function getSub() { + return javaSubInt; + } + + + public Function getMul() { + return javaMulInt; + } + + + public Function getDiv() { + return javaDivInt; + } + + + public Function getMod() { + return javaMod; + } + + + public Function getShiftLeft() { + return javaShiftLeftInt; + } + + + public Function getShiftRight() { + return javaShiftRightInt; + } + + + public Function getUnsignedShiftRight() { + return javaUnsignedShiftRightInt; + } + + + public Function getBitwiseOr() { + return javaBitwiseOrInt; + } + + + public Function getBitwiseAnd() { + return javaBitwiseAndInt; + } + + + public Function getBitwiseXor() { + return javaBitwiseXOrInt; + } + + + public Function getBitwiseNegation() { + return javaBitwiseNegation; + } + + + public Function getCast() { + return javaCastByte; + } + + + public Function getLessThan() { + return lessThan; + } + + + public Function getGreaterThan() { + return greaterThan; + } + + + public Function getGreaterOrEquals() { + return greaterOrEquals; + } + + + public Function getLessOrEquals() { + return lessOrEquals; + } - public Function getInBoundsPredicate() { - return inByte; + public Function getInBounds() { + return inByte; } } diff --git a/system/de/uka/ilkd/key/logic/ldt/CharLDT.java b/system/de/uka/ilkd/key/logic/ldt/CharLDT.java index 628c25df637..81ccd1549e3 100644 --- a/system/de/uka/ilkd/key/logic/ldt/CharLDT.java +++ b/system/de/uka/ilkd/key/logic/ldt/CharLDT.java @@ -1,3 +1,12 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// package de.uka.ilkd.key.logic.ldt; import de.uka.ilkd.key.java.abstraction.PrimitiveType; @@ -13,7 +22,92 @@ public CharLDT(Namespace sorts, Namespace functions) { } - public Function getInBoundsPredicate() { - return inChar; + public Function getAdd() { + return javaAddInt; + } + + + public Function getSub() { + return javaSubInt; + } + + + public Function getMul() { + return javaMulInt; + } + + + public Function getDiv() { + return javaDivInt; + } + + + public Function getMod() { + return javaMod; + } + + + public Function getShiftLeft() { + return javaShiftLeftInt; + } + + + public Function getShiftRight() { + return javaShiftRightInt; + } + + + public Function getUnsignedShiftRight() { + return javaUnsignedShiftRightInt; + } + + + public Function getBitwiseOr() { + return javaBitwiseOrInt; + } + + + public Function getBitwiseAnd() { + return javaBitwiseAndInt; + } + + + public Function getBitwiseXor() { + return javaBitwiseXOrInt; + } + + + public Function getBitwiseNegation() { + return javaBitwiseNegation; + } + + + public Function getCast() { + return javaCastChar; + } + + + public Function getLessThan() { + return lessThan; + } + + + public Function getGreaterThan() { + return greaterThan; + } + + + public Function getGreaterOrEquals() { + return greaterOrEquals; + } + + + public Function getLessOrEquals() { + return lessOrEquals; + } + + + public Function getInBounds() { + return inChar; } } diff --git a/system/de/uka/ilkd/key/logic/ldt/IntLDT.java b/system/de/uka/ilkd/key/logic/ldt/IntLDT.java index 5fbb8ebecdd..8f9b8589d88 100644 --- a/system/de/uka/ilkd/key/logic/ldt/IntLDT.java +++ b/system/de/uka/ilkd/key/logic/ldt/IntLDT.java @@ -1,3 +1,12 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// package de.uka.ilkd.key.logic.ldt; import de.uka.ilkd.key.java.abstraction.PrimitiveType; @@ -13,7 +22,92 @@ public IntLDT(Namespace sorts, Namespace functions) { } - public Function getInBoundsPredicate() { - return inInt; + public Function getAdd() { + return javaAddInt; + } + + + public Function getSub() { + return javaSubInt; + } + + + public Function getMul() { + return javaMulInt; + } + + + public Function getDiv() { + return javaDivInt; + } + + + public Function getMod() { + return javaMod; + } + + + public Function getShiftLeft() { + return javaShiftLeftInt; + } + + + public Function getShiftRight() { + return javaShiftRightInt; + } + + + public Function getUnsignedShiftRight() { + return javaUnsignedShiftRightInt; + } + + + public Function getBitwiseOr() { + return javaBitwiseOrInt; + } + + + public Function getBitwiseAnd() { + return javaBitwiseAndInt; + } + + + public Function getBitwiseXor() { + return javaBitwiseXOrInt; + } + + + public Function getBitwiseNegation() { + return javaBitwiseNegation; + } + + + public Function getCast() { + return javaCastInt; + } + + + public Function getLessThan() { + return lessThan; + } + + + public Function getGreaterThan() { + return greaterThan; + } + + + public Function getGreaterOrEquals() { + return greaterOrEquals; + } + + + public Function getLessOrEquals() { + return lessOrEquals; + } + + + public Function getInBounds() { + return inInt; } } diff --git a/system/de/uka/ilkd/key/logic/ldt/IntegerDomainLDT.java b/system/de/uka/ilkd/key/logic/ldt/IntegerDomainLDT.java index 440336e2a57..2ab167631fc 100644 --- a/system/de/uka/ilkd/key/logic/ldt/IntegerDomainLDT.java +++ b/system/de/uka/ilkd/key/logic/ldt/IntegerDomainLDT.java @@ -1,3 +1,12 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// package de.uka.ilkd.key.logic.ldt; import de.uka.ilkd.key.logic.Name; @@ -10,9 +19,93 @@ public class IntegerDomainLDT extends AbstractIntegerLDT { public IntegerDomainLDT(Namespace sorts, Namespace functions) { super(new Name("integerDomain"), sorts, functions, null); } + + public Function getAdd() { + return null; + } + + + public Function getSub() { + return null; + } + + + public Function getMul() { + return null; + } + + + public Function getDiv() { + return null; + } + + + public Function getMod() { + return null; + } + + + public Function getShiftLeft() { + return null; + } + + + public Function getShiftRight() { + return null; + } + + + public Function getUnsignedShiftRight() { + return null; + } + + + public Function getBitwiseOr() { + return null; + } + + + public Function getBitwiseAnd() { + return null; + } + + + public Function getBitwiseXor() { + return null; + } + + + public Function getBitwiseNegation() { + return null; + } + + + public Function getCast() { + return null; + } + + + public Function getLessThan() { + return null; + } + + + public Function getGreaterThan() { + return null; + } + + + public Function getGreaterOrEquals() { + return null; + } + + + public Function getLessOrEquals() { + return null; + } - public Function getInBoundsPredicate() { - return null; + public Function getInBounds() { + return null; } } diff --git a/system/de/uka/ilkd/key/logic/ldt/IntegerLDT.java b/system/de/uka/ilkd/key/logic/ldt/IntegerLDT.java index 2c0245b5604..c6205e71435 100644 --- a/system/de/uka/ilkd/key/logic/ldt/IntegerLDT.java +++ b/system/de/uka/ilkd/key/logic/ldt/IntegerLDT.java @@ -1,3 +1,12 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// package de.uka.ilkd.key.logic.ldt; import de.uka.ilkd.key.logic.Name; @@ -11,8 +20,93 @@ public IntegerLDT(Namespace sorts, Namespace functions) { super(new Name("int"), sorts, functions, null); } + + public Function getAdd() { + return plus; + } + + + public Function getSub() { + return minus; + } + + + public Function getMul() { + return times; + } + + + public Function getDiv() { + return divide; + } + + + public Function getMod() { + return modulo; + } + + + public Function getShiftRight() { + return null; + } + + + public Function getShiftLeft() { + return null; + } - public Function getInBoundsPredicate() { - return null; + + public Function getUnsignedShiftRight() { + return null; + } + + + public Function getBitwiseOr() { + return null; + } + + + public Function getBitwiseAnd() { + return null; + } + + + public Function getBitwiseXor() { + return null; + } + + + public Function getBitwiseNegation() { + return null; + } + + + public Function getCast() { + return null; + } + + + public Function getLessThan() { + return lessThan; + } + + + public Function getGreaterThan() { + return greaterThan; + } + + + public Function getGreaterOrEquals() { + return greaterOrEquals; + } + + + public Function getLessOrEquals() { + return lessOrEquals; + } + + + public Function getInBounds() { + return null; } } diff --git a/system/de/uka/ilkd/key/logic/ldt/LDT.java b/system/de/uka/ilkd/key/logic/ldt/LDT.java index ccb2aa419ff..e8f35da94bd 100644 --- a/system/de/uka/ilkd/key/logic/ldt/LDT.java +++ b/system/de/uka/ilkd/key/logic/ldt/LDT.java @@ -86,10 +86,10 @@ public Function addFunction(Function f) { */ public Function addFunction(Namespace funcNS, String funcName) { final Function f = (Function)funcNS.lookup(new Name(funcName)); - functions.add(f); if (f==null) { - System.out.println("IntegerLDT: Function " + funcName + " not found"); - } + throw new RuntimeException("IntegerLDT: Function " + funcName + " not found"); + } + addFunction(f); return f; } diff --git a/system/de/uka/ilkd/key/logic/ldt/LongLDT.java b/system/de/uka/ilkd/key/logic/ldt/LongLDT.java index 4fcd61a6fe3..47f9d6a4d78 100644 --- a/system/de/uka/ilkd/key/logic/ldt/LongLDT.java +++ b/system/de/uka/ilkd/key/logic/ldt/LongLDT.java @@ -1,3 +1,12 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// package de.uka.ilkd.key.logic.ldt; import de.uka.ilkd.key.java.abstraction.PrimitiveType; @@ -12,8 +21,93 @@ public LongLDT(Namespace sorts, Namespace functions) { super(new Name("jlong"), sorts, functions, PrimitiveType.JAVA_LONG); } + + public Function getAdd() { + return javaAddLong; + } + + + public Function getSub() { + return javaSubLong; + } + + + public Function getMul() { + return javaMulLong; + } + + + public Function getDiv() { + return javaDivLong; + } + + + public Function getMod() { + return javaMod; + } + + + public Function getShiftLeft() { + return javaShiftLeftLong; + } + + + public Function getShiftRight() { + return javaShiftRightLong; + } + + + public Function getUnsignedShiftRight() { + return javaUnsignedShiftRightLong; + } + + + public Function getBitwiseOr() { + return javaBitwiseOrLong; + } + + + public Function getBitwiseAnd() { + return javaBitwiseAndLong; + } + + + public Function getBitwiseXor() { + return javaBitwiseXOrLong; + } + + + public Function getBitwiseNegation() { + return javaBitwiseNegation; + } + + + public Function getCast() { + return javaCastLong; + } + + + public Function getLessThan() { + return lessThan; + } + + + public Function getGreaterThan() { + return greaterThan; + } + + + public Function getGreaterOrEquals() { + return greaterOrEquals; + } + + + public Function getLessOrEquals() { + return lessOrEquals; + } + - public Function getInBoundsPredicate() { - return inLong; + public Function getInBounds() { + return inLong; } } diff --git a/system/de/uka/ilkd/key/logic/ldt/ShortLDT.java b/system/de/uka/ilkd/key/logic/ldt/ShortLDT.java index 77fbcc36fad..cea1070dc42 100644 --- a/system/de/uka/ilkd/key/logic/ldt/ShortLDT.java +++ b/system/de/uka/ilkd/key/logic/ldt/ShortLDT.java @@ -1,3 +1,12 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// package de.uka.ilkd.key.logic.ldt; import de.uka.ilkd.key.java.abstraction.PrimitiveType; @@ -13,7 +22,92 @@ public ShortLDT(Namespace sorts, Namespace functions) { } - public Function getInBoundsPredicate() { - return inShort; + + public Function getAdd() { + return javaAddInt; + } + + + public Function getSub() { + return javaSubInt; + } + + + public Function getMul() { + return javaMulInt; + } + + + public Function getDiv() { + return javaDivInt; + } + + + public Function getMod() { + return javaMod; } -} + + + public Function getShiftLeft() { + return javaShiftLeftInt; + } + + + public Function getShiftRight() { + return javaShiftRightInt; + } + + + public Function getUnsignedShiftRight() { + return javaUnsignedShiftRightInt; + } + + + public Function getBitwiseOr() { + return javaBitwiseOrInt; + } + + + public Function getBitwiseAnd() { + return javaBitwiseAndInt; + } + + + public Function getBitwiseXor() { + return javaBitwiseXOrInt; + } + + + public Function getBitwiseNegation() { + return javaBitwiseNegation; + } + + + public Function getCast() { + return javaCastShort; + } + + + public Function getLessThan() { + return lessThan; + } + + + public Function getGreaterThan() { + return greaterThan; + } + + + public Function getGreaterOrEquals() { + return greaterOrEquals; + } + + + public Function getLessOrEquals() { + return lessOrEquals; + } + + + public Function getInBounds() { + return inShort; + }} diff --git a/system/de/uka/ilkd/key/logic/op/AbstractMetaOperator.java b/system/de/uka/ilkd/key/logic/op/AbstractMetaOperator.java index 9c61b43a051..f3012a4fb0a 100644 --- a/system/de/uka/ilkd/key/logic/op/AbstractMetaOperator.java +++ b/system/de/uka/ilkd/key/logic/op/AbstractMetaOperator.java @@ -123,6 +123,8 @@ public abstract class AbstractMetaOperator extends Op implements MetaOperator { public static final AbstractMetaOperator CREATE_IN_REACHABLE_STATE_PO = new CreateInReachableStatePO (); + public static final AbstractMetaOperator INTRODUCE_ATPRE_DEFINITIONS = new IntroAtPreDefsOp(); + public static final AbstractMetaOperator AT_PRE_EQUATIONS = new AtPreEquations(); public static final AbstractMetaOperator LOCATION_DEPENDENT_FUNCTION = new LocationDependentFunction(); diff --git a/system/de/uka/ilkd/key/logic/op/AnonymousUpdate.java b/system/de/uka/ilkd/key/logic/op/AnonymousUpdate.java index 55ef5219c4a..3dfa9a49581 100644 --- a/system/de/uka/ilkd/key/logic/op/AnonymousUpdate.java +++ b/system/de/uka/ilkd/key/logic/op/AnonymousUpdate.java @@ -140,7 +140,7 @@ public int entryEnd (int locPos) { public int[] getLocationPos (Operator loc) { Debug.fail("Method not implemented for anonymous update"); - return null; // unreachable + return new int[0]; // unreachable } public Location location (int n) { diff --git a/system/de/uka/ilkd/key/logic/op/NonRigidFunctionLocation.java b/system/de/uka/ilkd/key/logic/op/NonRigidFunctionLocation.java index e6662a7e7d7..8d1171e1011 100644 --- a/system/de/uka/ilkd/key/logic/op/NonRigidFunctionLocation.java +++ b/system/de/uka/ilkd/key/logic/op/NonRigidFunctionLocation.java @@ -50,6 +50,7 @@ public boolean mayBeAliasedBy(Location loc){ return (this==loc); } + public String proofToString() { return "\\nonRigid[Location] " + super.proofToString(); } diff --git a/system/de/uka/ilkd/key/logic/op/Op.java b/system/de/uka/ilkd/key/logic/op/Op.java index 84ec712b369..4e8456cf0d9 100644 --- a/system/de/uka/ilkd/key/logic/op/Op.java +++ b/system/de/uka/ilkd/key/logic/op/Op.java @@ -135,7 +135,7 @@ public abstract class Op implements Operator { /** control operator required for specification computation */ public static final Junctor COMPUTE_SPEC_OP = new ComputeSpecOp(); - + protected final Name name; protected Op(Name name) { diff --git a/system/de/uka/ilkd/key/logic/op/ProgramMethod.java b/system/de/uka/ilkd/key/logic/op/ProgramMethod.java index 210c8986b2c..4161307bf1f 100644 --- a/system/de/uka/ilkd/key/logic/op/ProgramMethod.java +++ b/system/de/uka/ilkd/key/logic/op/ProgramMethod.java @@ -18,7 +18,6 @@ import de.uka.ilkd.key.java.*; import de.uka.ilkd.key.java.abstraction.Constructor; import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.declaration.*; import de.uka.ilkd.key.java.reference.MethodReference; import de.uka.ilkd.key.java.reference.ReferencePrefix; @@ -29,7 +28,6 @@ import de.uka.ilkd.key.logic.ProgramInLogic; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.proof.mgt.Contractable; import de.uka.ilkd.key.rule.MatchConditions; import de.uka.ilkd.key.util.Debug; import de.uka.ilkd.key.util.ExtList; @@ -41,7 +39,7 @@ */ public class ProgramMethod extends NonRigidFunction implements SourceElement, ProgramElement, - MemberDeclaration, ProgramInLogic, Contractable { + MemberDeclaration, ProgramInLogic { private final MethodDeclaration method; private final KeYJavaType kjt; @@ -148,17 +146,6 @@ public Comment[] getComments() { return method.getComments(); } - /** - *@return the annotations. - */ - public Annotation[] getAnnotations(){ - return new Annotation[0]; - } - - public int getAnnotationCount(){ - return 0; - } - public void prettyPrint(PrettyPrinter w) throws IOException { method.prettyPrint(w); } @@ -313,12 +300,6 @@ public String getFullName() { public String getName() { return getMethodDeclaration().getName(); } - - public boolean equalContractable(Contractable c) { - return equals(c) - && getContainerType().equals - (((ProgramMethod)c).getContainerType()); - } public boolean isAbstract() { return getMethodDeclaration().isAbstract(); diff --git a/system/de/uka/ilkd/key/logic/op/ProgramSV.java b/system/de/uka/ilkd/key/logic/op/ProgramSV.java index c871e4cac5a..56406d41ba7 100644 --- a/system/de/uka/ilkd/key/logic/op/ProgramSV.java +++ b/system/de/uka/ilkd/key/logic/op/ProgramSV.java @@ -14,7 +14,6 @@ import de.uka.ilkd.key.java.*; import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.reference.ExecutionContext; import de.uka.ilkd.key.java.reference.PackageReference; import de.uka.ilkd.key.java.reference.ReferencePrefix; @@ -73,17 +72,6 @@ public SourceElement getLastElement(){ return this; } - /** - *@return the annotations. - */ - public Annotation[] getAnnotations(){ - return new Annotation[0]; - } - - public int getAnnotationCount(){ - return 0; - } - /** * Returns the start position of the primary token of this element. * To get the start position of the syntactical first token, diff --git a/system/de/uka/ilkd/key/logic/op/ProgramVariable.java b/system/de/uka/ilkd/key/logic/op/ProgramVariable.java index ba5ed3f6f3f..8f44eba07a4 100644 --- a/system/de/uka/ilkd/key/logic/op/ProgramVariable.java +++ b/system/de/uka/ilkd/key/logic/op/ProgramVariable.java @@ -15,7 +15,6 @@ import de.uka.ilkd.key.java.abstraction.ArrayType; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.java.abstraction.Type; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.reference.*; import de.uka.ilkd.key.logic.ProgramElementName; import de.uka.ilkd.key.logic.ProgramInLogic; @@ -195,17 +194,6 @@ public KeYJavaType getKeYJavaType(Services javaServ, return getKeYJavaType(); } - /** - *@return the annotations. - */ - public Annotation[] getAnnotations(){ - return new Annotation[0]; - } - - public int getAnnotationCount(){ - return 0; - } - /** * We do not have a prefix, so fake it! diff --git a/system/de/uka/ilkd/key/logic/op/RigidFunction.java b/system/de/uka/ilkd/key/logic/op/RigidFunction.java index d4a7871e573..c49b8930904 100644 --- a/system/de/uka/ilkd/key/logic/op/RigidFunction.java +++ b/system/de/uka/ilkd/key/logic/op/RigidFunction.java @@ -31,6 +31,6 @@ public RigidFunction(Name name, Sort sort, Sort[] argSorts) { * @param argSorts */ public RigidFunction(Name name, Sort sort, ArrayOfSort argSorts) { - super(name, sort, argSorts); + super(name, sort, argSorts); } } diff --git a/system/de/uka/ilkd/key/logic/sort/ArraySortImpl.java b/system/de/uka/ilkd/key/logic/sort/ArraySortImpl.java index 122beb27f6b..b4c9833f808 100644 --- a/system/de/uka/ilkd/key/logic/sort/ArraySortImpl.java +++ b/system/de/uka/ilkd/key/logic/sort/ArraySortImpl.java @@ -88,10 +88,10 @@ public static ArraySort getArraySort(Sort elemSort, Sort serializableSort){ // this wrapper is required as some element sorts are shared among // several environments (int, boolean) - final SortKey sk = new SortKey(elemSort, objectSort, + final SortKey sortKey = new SortKey(elemSort, objectSort, cloneableSort, serializableSort); - ArraySort as = aSH.containsKey(sk) ? - (ArraySort) ((WeakReference)aSH.get(sk)).get() : null; + ArraySort as = aSH.containsKey(sortKey) ? + (ArraySort) ((WeakReference)aSH.get(sortKey)).get() : null; if (as == null){ // HACK: this simple handling of sort creation does not treat @@ -99,8 +99,8 @@ public static ArraySort getArraySort(Sort elemSort, SetOfSort localExtendsSorts = getArraySuperSorts(elemSort, objectSort, cloneableSort, serializableSort); - as = new ArraySortImpl(localExtendsSorts, sk); - aSH.put(sk, new WeakReference(as)); + as = new ArraySortImpl(localExtendsSorts, sortKey); + aSH.put(sortKey, new WeakReference(as)); } return as; diff --git a/system/de/uka/ilkd/key/logic/sort/ProgramSVSort.java b/system/de/uka/ilkd/key/logic/sort/ProgramSVSort.java index 65d9751a24e..73974ed3b0a 100644 --- a/system/de/uka/ilkd/key/logic/sort/ProgramSVSort.java +++ b/system/de/uka/ilkd/key/logic/sort/ProgramSVSort.java @@ -215,6 +215,8 @@ public abstract class ProgramSVSort extends PrimitiveSort { public static final ProgramSVSort GUARD = new GuardSort(); public static final ProgramSVSort FORUPDATES = new ForUpdatesSort(); + + public static final ProgramSVSort FORLOOP = new ForLoopSort(); public static final ProgramSVSort MULTIPLEVARDECL = new MultipleVariableDeclarationSort(); @@ -783,9 +785,12 @@ protected boolean canStandFor(ProgramElement pe, Services services) { final ProgramMethod pm = ((MethodBodyStatement) pe).getProgramMethod(services); + if(pm == null) { + return false; + } final MethodDeclaration methodDeclaration = pm.getMethodDeclaration(); - return !(pm.isModel() || + return !(//pm.isModel() || methodDeclaration.getBody() == null) || (methodDeclaration instanceof ConstructorDeclaration); } @@ -1107,6 +1112,15 @@ protected boolean canStandFor(ProgramElement check, Services services) { } } + + private static class ForLoopSort extends ProgramSVSort { + public ForLoopSort() { + super(new Name("ForLoop")); + } + protected boolean canStandFor(ProgramElement check, Services services) { + return (check instanceof For); + } + } private static class SwitchSVSort extends ProgramSVSort{ public SwitchSVSort(){ @@ -1572,4 +1586,4 @@ public static HashMap name2sort() { return name2sort; } -} +} \ No newline at end of file diff --git a/system/de/uka/ilkd/key/ocl/gf/GFinterface.java b/system/de/uka/ilkd/key/ocl/gf/GFinterface.java index 9e65e6e4217..c89683e7328 100755 --- a/system/de/uka/ilkd/key/ocl/gf/GFinterface.java +++ b/system/de/uka/ilkd/key/ocl/gf/GFinterface.java @@ -23,7 +23,7 @@ import javax.swing.ProgressMonitor; import de.uka.ilkd.key.casetool.UMLOCLModel; -import de.uka.ilkd.key.proof.mgt.JavaModelMethod; +import de.uka.ilkd.key.casetool.together.TogetherModelMethod; /** * control object interfacing KeY with GF. @@ -57,6 +57,7 @@ public abstract class GFinterface { */ protected String projectRoot; + /** * Creates a new temporary directory and copies the grammars * in a subdirectory called grammars2 of it. @@ -318,9 +319,9 @@ private String constructClassNameForGF(final String colonNotation) { String newName = colonNotation.replaceAll("Sequence \\((.*)\\)","Sequence_$1"); if (newName.indexOf("::") == -1) { if (logger.isLoggable(Level.FINER)) { - logger.finer("transformTypeJava2OCL :" + JavaModelMethod.transformTypeJava2OCL(colonNotation)); + logger.finer("transformTypeJava2OCL :" + TogetherModelMethod.transformTypeJava2OCL(colonNotation)); } - if (colonNotation != JavaModelMethod.transformTypeJava2OCL(colonNotation)) { + if (colonNotation != TogetherModelMethod.transformTypeJava2OCL(colonNotation)) { newName = "NOPACKAGEP_" + newName; } newName = newName + "C"; diff --git a/system/de/uka/ilkd/key/logic/AtPreNamespace.java b/system/de/uka/ilkd/key/parser/AtPreNamespace.java similarity index 92% rename from system/de/uka/ilkd/key/logic/AtPreNamespace.java rename to system/de/uka/ilkd/key/parser/AtPreNamespace.java index 8359575ca7d..3eeb787ff86 100644 --- a/system/de/uka/ilkd/key/logic/AtPreNamespace.java +++ b/system/de/uka/ilkd/key/parser/AtPreNamespace.java @@ -1,15 +1,21 @@ -package de.uka.ilkd.key.logic; +package de.uka.ilkd.key.parser; import java.util.HashMap; import java.util.Map; import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.Named; +import de.uka.ilkd.key.logic.Namespace; import de.uka.ilkd.key.logic.op.Function; import de.uka.ilkd.key.logic.op.ProgramVariable; import de.uka.ilkd.key.logic.op.RigidFunction; import de.uka.ilkd.key.logic.sort.ArrayOfSort; import de.uka.ilkd.key.logic.sort.Sort; +/** + * Used by the parser to create @pre-functions on demand. + */ public class AtPreNamespace extends Namespace { private final Map atPreMapping; diff --git a/system/de/uka/ilkd/key/parser/jml/ArithOpProvider.java b/system/de/uka/ilkd/key/parser/jml/ArithOpProvider.java deleted file mode 100644 index 954bba1f4e3..00000000000 --- a/system/de/uka/ilkd/key/parser/jml/ArithOpProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2003 Universitaet Karlsruhe, Germany -// and Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.parser.jml; - -import de.uka.ilkd.key.logic.Namespace; -import de.uka.ilkd.key.logic.op.Function; - -public interface ArithOpProvider{ - - public Namespace getFunctions(); - - public void setFunctions(Namespace functions); - - public Function getAdd(boolean l); - - public Function getSub(boolean l); - - public Function getMinus(boolean l); - - public Function getMul(boolean l); - - public Function getDiv(boolean l); - - public Function getMod(boolean l); - - public Function getOr(boolean l); - - public Function getAnd(boolean l); - - public Function getXor(boolean l); - - public Function getNeg(boolean l); - - public Function getShiftRight(boolean l); - - public Function getShiftLeft(boolean l); - - public Function getMin(boolean l); - - public Function getMax(boolean l); - - public Function getCastToByte(); - - public Function getCastToShort(); - - public Function getCastToInt(); - - public Function getCastToLong(); - - public Function getUnsignedShiftRight(boolean l); - -} diff --git a/system/de/uka/ilkd/key/parser/jml/DefaultArithOpProvider.java b/system/de/uka/ilkd/key/parser/jml/DefaultArithOpProvider.java deleted file mode 100644 index 48e490f130d..00000000000 --- a/system/de/uka/ilkd/key/parser/jml/DefaultArithOpProvider.java +++ /dev/null @@ -1,145 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2003 Universitaet Karlsruhe, Germany -// and Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.parser.jml; - -import de.uka.ilkd.key.jml.WrongIntSemanticsException; -import de.uka.ilkd.key.logic.Name; -import de.uka.ilkd.key.logic.Namespace; -import de.uka.ilkd.key.logic.op.Function; - -public class DefaultArithOpProvider implements ArithOpProvider{ - - protected Namespace functions; - private boolean javaSemantics; - - public DefaultArithOpProvider(Namespace functions, boolean javaSemantics){ - this.functions = functions; - this.javaSemantics = javaSemantics; - } - - public Namespace getFunctions(){ - return functions; - } - - public void setFunctions(Namespace functions){ - this.functions = functions; - } - - public Function getMin(boolean l){ - return getFunction(l, "long_MIN", "int_MIN", null, "minimum"); - } - - public Function getMax(boolean l){ - return getFunction(l, "long_MAX", "int_MAX", null, "maximum"); - } - - public Function getAdd(boolean l){ - return getFunction(l, "addJlong", "addJint", "add", "addition"); - } - - public Function getSub(boolean l){ - return getFunction(l, "subJlong", "subJint", "sub", "subtraction"); - } - - public Function getMinus(boolean l){ - return getFunction(l, "unaryMinusJlong", "unaryMinusJint", "neg", - "negation"); - } - - public Function getMul(boolean l){ - return getFunction(l, "mulJlong", "mulJint", "mul", "multiplication"); - } - - public Function getDiv(boolean l){ - return getFunction(l, "divJlong", "divJint", "jdiv", "division"); - } - - public Function getMod(boolean l){ - return getFunction(l, "modJlong", "modJint", "jmod", "modulo"); - } - - public Function getOr(boolean l){ - return getFunction(l, "orJlong", "orJint", "binaryOr", "bitwise or"); - } - - public Function getAnd(boolean l){ - return getFunction(l, "andJlong", "andJint", "binaryAnd", "bitwise and"); - } - - public Function getXor(boolean l){ - return getFunction(l, "xorJlong", "xorJint", "binaryXor", "bitwise xor"); - } - - public Function getNeg(boolean l){ - return getFunction(l, "negJlong", "negJint", "invertBits", - "bitwise negation"); - } - - public Function getShiftRight(boolean l){ - return getFunction(l, "shiftrightJlong", "shiftrightJint", - "binaryShiftRight", "shift right"); - } - - public Function getShiftLeft(boolean l){ - return getFunction(l, "shiftleftJlong", "shiftleftJint", - "binaryShiftLeft", "shift left"); - } - - public Function getUnsignedShiftRight(boolean l){ - return getFunction(l, "unsignedshiftrightJlong", - "unsignedshiftrightJint", "binaryUnsignedShiftRight", - "unsigned shift right"); - } - - public Function getCastToByte(){ - return (Function) functions.lookup(new Name("moduloByte")); - } - - public Function getCastToShort(){ - return (Function) functions.lookup(new Name("moduloShort")); - } - - - public Function getCastToInt(){ - return (Function) functions.lookup(new Name("moduloInt")); - } - - public Function getCastToLong(){ - return (Function) functions.lookup(new Name("moduloLong")); - } - - private Function getFunction(boolean l, String sLong, String sInt, - String sDefault, String description){ - Function f = null; - if (javaSemantics) { - if (l){ - f = (Function) functions.lookup(new Name(sLong)); - }else{ - f = (Function) functions.lookup(new Name(sInt)); - } - } else { - f = (Function) functions.lookup(new Name(sDefault)); - } - - if(f == null){ - throw new WrongIntSemanticsException(description); - } - return f; - } - - -} diff --git a/system/de/uka/ilkd/key/parser/jml/JMLSpecBuilder.java b/system/de/uka/ilkd/key/parser/jml/JMLSpecBuilder.java deleted file mode 100644 index dbb9cc84f14..00000000000 --- a/system/de/uka/ilkd/key/parser/jml/JMLSpecBuilder.java +++ /dev/null @@ -1,549 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.parser.jml; - -import java.io.StringReader; -import java.util.*; - -import antlr.RecognitionException; - -import de.uka.ilkd.key.java.Comment; -import de.uka.ilkd.key.java.IteratorOfProgramElement; -import de.uka.ilkd.key.java.ListOfProgramElement; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.declaration.MethodDeclaration; -import de.uka.ilkd.key.java.declaration.TypeDeclaration; -import de.uka.ilkd.key.java.recoderext.ClassInitializeMethodBuilder; -import de.uka.ilkd.key.java.statement.LoopStatement; -import de.uka.ilkd.key.java.visitor.JavaASTCollector; -import de.uka.ilkd.key.jml.*; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.IteratorOfProgramMethod; -import de.uka.ilkd.key.logic.op.ListOfProgramMethod; -import de.uka.ilkd.key.logic.op.Op; -import de.uka.ilkd.key.logic.op.ProgramMethod; -import de.uka.ilkd.key.proof.init.ProofInputException; -import de.uka.ilkd.key.util.ExceptionHandlerException; - -/** - * provides methods for parsing the specifications of a single class/interface. - */ -public class JMLSpecBuilder { - - private TypeDeclaration cd; - private Services services; - private NamespaceSet nss; - private TermBuilder tb; - private boolean parsedMethods = false; - private boolean parsedClass = false; - private LinkedHashMap method2specs = new LinkedHashMap(); - private LinkedHashMap method2term = null; - private JMLClassSpec classSpec = null; - private ArithOpProvider aOP = null; - //contains jml-comments in cd - private LinkedHashSet jmlComments = null; - //contains jml-comments without model method declarations. - private LinkedHashSet jmlCommentsWithoutMM = null; - //contains jml-comments without model method and model field declarations. - private LinkedHashSet jmlCommentsWithoutMFMM = null; - //where the sources for the input are below - private String javaPath; - - public JMLSpecBuilder(TypeDeclaration cd, Services services, - NamespaceSet nss, TermBuilder tb, String javaPath, - boolean javaSemantics){ - this.cd = cd; - this.services = services; - this.nss = nss; - this.tb = tb; - aOP = new DefaultArithOpProvider(nss.functions(), javaSemantics); - Comment[] comments = cd.getComments(); - if(comments != null){ - jmlComments = new LinkedHashSet(); - for(int i=0; ipm and the invariant and constraint proofobligation - * for the containing class. - */ - public Term buildProofObligation(ProgramMethod pm){ - Implementation2SpecMap ism = services.getImplementation2SpecMap(); - SetOfJMLMethodSpec specs = ism.getSpecsForMethod(pm); - classSpec = ism.getSpecForClass(pm.getContainerType()); - return makeConjunction(specs, pm); - } - - /** - * parses jml model fields declared in cd. - * Can't be called before parseModelMethodDecls() has been called - */ - public void parseModelFieldDecls() throws ProofInputException { - if(jmlCommentsWithoutMFMM == null && jmlCommentsWithoutMM != null){ - jmlCommentsWithoutMFMM = new LinkedHashSet(); - Iterator it = jmlCommentsWithoutMM.iterator(); - while(it.hasNext()){ - String s = (String) it.next(); - parseFieldDecl(s, jmlCommentsWithoutMFMM, classSpec); - } - }else{ - throw new ProofInputException(jmlCommentsWithoutMFMM == null? - "Tried to parse model field "+ - "declarations before parsing "+ - "model method declarations": - "already parsed model field "+ - "declarations for class/interface "+ - cd); - } - } - - /** - * parses jml model methods declared in cd. - */ - public void parseModelMethodDecls() throws ProofInputException { - if(jmlCommentsWithoutMM == null){ - classSpec = new JMLClassSpec(services, cd, nss, javaPath); - jmlCommentsWithoutMM = new LinkedHashSet(); - Iterator it = jmlComments.iterator(); - while(it.hasNext()){ - String s = (String) it.next(); - parseMethodDecl(s, jmlCommentsWithoutMM, classSpec); - } - }else{ - throw new ProofInputException("already parsed model method "+ - "declarations for class/interface "+ - cd); - } - } - - /** - * parses jml specification like invariants, constraints or represents - * in cd. parseModelMethodDecls() and parseModelFieldDecls() - * have to be called first. - */ - public void parseJMLClassSpec() throws ProofInputException { - if(!parsedClass && jmlCommentsWithoutMFMM != null){ - Iterator it = jmlCommentsWithoutMFMM.iterator(); - while(it.hasNext()){ - String s = (String) it.next(); - if(s.trim().equals("") || s.matches("@?\\s*in \\w+;")) continue; - StringReader stream = new StringReader(s); - KeYJMLParser parser = - new KeYJMLParser(new KeYJMLLexer(stream), - "no file, parsing comment from "+ - cd.getName(), services, nss, - TermFactory.DEFAULT, cd, - null, classSpec, aOP, javaPath); - try{ - parser.parseClassSpec(); - } catch(ExceptionHandlerException e1){ - if(!(e1.getCause() instanceof - NotSupportedExpressionException)){ - if (e1.getCause() instanceof RecognitionException) { - reportRecognitionException((RecognitionException) e1.getCause()); - } else { - throw e1; - } - }else{ - services.getExceptionHandler().clear(); - } - } catch (antlr.RecognitionException e) { - reportRecognitionException(e); - }catch (antlr.ANTLRException e) { - throw new ProofInputException(e); - } - } - parsedClass = true; - }else{ - if(jmlCommentsWithoutMFMM == null){ - throw new ProofInputException("tried to parse class spec "+ - "without parsing model "+ - "declarations for class "+ - cd+" first"); - } - } - } - - /** - * @param e1 - * @throws ProofInputException - */ - private void reportRecognitionException(RecognitionException e) - throws ProofInputException { - int line = e.getLine(); - int column = e.getColumn(); - throw - new ProofInputException(e.getFilename()+ - "("+line+","+column+"): "+e.getMessage()); - } - - public NamespaceSet namespaces(){ - return nss; - } - - private void parseMethodDecl (String s, Set otherSpecs, JMLClassSpec cs) - throws ProofInputException{ - int mIndex = s.indexOf("model "); - if(mIndex == -1 || (s.indexOf("_behavior") == -1 && - s.indexOf("requires") == -1)){ - otherSpecs.add(s); - return; - } - int start = s.substring(0, mIndex+1).lastIndexOf("\n") + 1; - int end = s.indexOf(";", mIndex); - int lbIndex = s.indexOf("{", mIndex); - if(end == -1 || (end > lbIndex && lbIndex != -1)){ - end = s.length()-1; - } - int pIndex = s.indexOf("(", mIndex); - if(pIndex > end || pIndex == -1){ - if(end == s.length()-1 || pIndex == -1){ - otherSpecs.add(s); - }else{ - otherSpecs.add(s.substring(0,end)); - parseMethodDecl(s.substring(end+1), otherSpecs, cs); - } - return; - } - String methDecl = s.substring(start, end+1); - StringReader stream = new StringReader(methDecl); - String nonMethSpec; - if(s.indexOf("_behavior") != -1){ - nonMethSpec = - s.substring(0,start).split("public +[a-z]+_behavior" , 2)[0]; - }else{ - nonMethSpec = - s.substring(0,start).split("requires" , 2)[0]; - } - String methSpec = - "/*@ "+s.substring(0,start).substring(nonMethSpec.length())+" @*/"; - otherSpecs.add(nonMethSpec); - - KeYJMLParser parser = - new KeYJMLParser(new KeYJMLLexer(stream), - "parsing comment from "+ - cd.getName(), - services, nss, - TermFactory.DEFAULT, cd, - null, cs, aOP, javaPath); - try{ - parser.parseMethodDecl(methSpec); - }catch(ExceptionHandlerException e1){ - if(!(e1.getCause() instanceof - NotSupportedExpressionException)){ - if (e1.getCause() instanceof RecognitionException) { - reportRecognitionException((RecognitionException) e1.getCause()); - } else { - throw e1; - } - }else{ - services.getExceptionHandler().clear(); - } - } catch (RecognitionException e) { - reportRecognitionException(e); - } catch (antlr.ANTLRException e) { - throw new ProofInputException(e); - } - parseMethodDecl(s.substring(end+1), otherSpecs, cs); - } - - private void parseFieldDecl (String s, Set otherSpecs, JMLClassSpec cs) - throws ProofInputException{ - - int mIndex = s.indexOf("model "); - if(mIndex == -1) mIndex = s.indexOf("ghost"); - if(mIndex != -1){ - int start = s.substring(0, mIndex+1).lastIndexOf("\n"); - int end = s.indexOf(";", mIndex); - int endNextLine = s.indexOf(";", end+1); - if(s.indexOf("in", end) != -1 && - s.indexOf("in", end) < endNextLine){ - end = endNextLine; - } - otherSpecs.add(s.substring(0, start+1)); - StringReader stream = - new StringReader(s.substring(start+1, end+1)); - KeYJMLParser parser = - new KeYJMLParser(new KeYJMLLexer(stream), - "parsing comment from "+ - cd.getName(), - services, nss, - TermFactory.DEFAULT, cd, - null, cs, aOP, javaPath); - try{ - parser.parseFieldDecl(); - - }catch(ExceptionHandlerException e1){ - if(!(e1.getCause() instanceof - NotSupportedExpressionException)){ - if (e1.getCause() instanceof RecognitionException) { - reportRecognitionException((RecognitionException) e1.getCause()); - } else { - throw e1; - } - }else{ - services.getExceptionHandler().clear(); - } - } catch (RecognitionException e) { - reportRecognitionException(e); - } catch (antlr.ANTLRException e) { - throw new ProofInputException(e); - } - parseFieldDecl(s.substring(end+1), otherSpecs, cs); - }else{ - otherSpecs.add(s); - } - } - - /** - * parses the specifications attached as comments to m. - */ - protected SetOfJMLMethodSpec parseJMLMethodSpec(ProgramMethod m) - throws ProofInputException { - SetOfJMLMethodSpec result = SetAsListOfJMLMethodSpec.EMPTY_SET; - if (m.getMethodDeclaration()==null){ - return result; - } - MethodDeclaration md = m.getMethodDeclaration(); - Comment[] comments = md.getComments(); - if(comments != null){ - for(int i=0; imd - * generated from specs. - * obsolete (but for testing reasons still there). - */ - private Term makeConjunction(SetOfJMLMethodSpec specs, - ProgramMethod md){ - Term result = null; - Term a, inv, invPre; - JMLMethodSpec spec; - if(specs != SetAsListOfJMLMethodSpec.EMPTY_SET){ - IteratorOfJMLMethodSpec it = specs.iterator(); - spec = it.next(); - result = spec.createDLFormula(false, false); - inv = classSpec.getPreservesInvariantBehavior(md, false); - invPre = spec.getCompletePre(false, false, false); - while(it.hasNext()){ - spec = it.next(); - a = spec.createDLFormula(false, false); - invPre = tb.or(spec.getCompletePre(false, false, false), invPre); - if(a != null){ - if(result.op() != Op.TRUE){ - result = tb.and(result, a); - }else{ - result = a; - } - } - } - if(inv != null){ - inv = tb.imp(invPre, inv); - } - if(result != null && result.op() != Op.TRUE){ - if(inv != null){ - result = tb.and(result, inv); - } - }else{ - result = inv; - } - // the method has no specification, but maybe it has to preserve - // invariants, etc. - // implicit methods need a special treatment. - }else if(!md.getName().startsWith("<") && ( - !md.isStatic() && - (classSpec.getInstanceInvariants()!=null || - classSpec.getInstanceConstraints()!=null) - || classSpec.getStaticConstraints()!=null) - || classSpec.getStaticInvariants()!=null - && (!md.getName().startsWith("<") || - md.getName().equals(ClassInitializeMethodBuilder.CLASS_INITIALIZE_IDENTIFIER))){ - result = classSpec.getPreservesInvariantBehavior(md, false); - } - return result; - } - - /** - * returns a map from methods to the specs which have been parsed by this - * JMLSpecBuilder. - */ - public HashMap getMethod2Specs(){ - try{ - parseSpecs(); - }catch(ProofInputException e){ - e.printStackTrace(); - } - return method2specs; - } - - /** - * returns a map with the model methods and their specs - * parsed by this JMLSpecBuilder. - */ - public HashMap getModelMethod2Specs(){ - try{ - parseSpecs(); - }catch(ProofInputException e){ - e.printStackTrace(); - } - return classSpec.buildModelMethod2Specs(); - } - - /** - * Parses the specs of the methods declared in cd - */ - public void parseJMLMethodSpecs() throws ProofInputException { - if(parsedMethods){ - return; - } - if(cd.getFullName().indexOf("jmlspecs.models") == -1){ - KeYJavaType kjt = services.getJavaInfo().getKeYJavaType(cd); - ListOfProgramMethod ms = - services.getJavaInfo().getKeYProgModelInfo(). - getAllProgramMethodsLocallyDeclared(kjt).append( - services.getJavaInfo().getKeYProgModelInfo(). - getConstructors(kjt)); - IteratorOfProgramMethod it = ms.iterator(); - while(it.hasNext()){ - ProgramMethod m = it.next(); - if(m != null){ - method2specs.put(m, parseJMLMethodSpec(m)); - } - } - - } - IteratorOfNamed mmit = - classSpec.getModelMethods().allElements().iterator(); - while(mmit.hasNext()){ - ProgramMethod m = (ProgramMethod) mmit.next(); - parseJMLMethodSpec(m); - } - parsedMethods = true; - } - - private void parseSpecs() throws ProofInputException{ - parseJMLClassSpec(); - parseJMLMethodSpecs(); - } -} - diff --git a/system/de/uka/ilkd/key/parser/jml/JMLTranslator.java b/system/de/uka/ilkd/key/parser/jml/JMLTranslator.java deleted file mode 100644 index 4449cd5e0ba..00000000000 --- a/system/de/uka/ilkd/key/parser/jml/JMLTranslator.java +++ /dev/null @@ -1,458 +0,0 @@ -package de.uka.ilkd.key.parser.jml; - -import java.util.LinkedHashMap; - -import de.uka.ilkd.key.gui.Main; -import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.abstraction.PrimitiveType; -import de.uka.ilkd.key.java.declaration.InterfaceDeclaration; -import de.uka.ilkd.key.java.declaration.MethodDeclaration; -import de.uka.ilkd.key.java.declaration.TypeDeclaration; -import de.uka.ilkd.key.java.declaration.VariableDeclaration; -import de.uka.ilkd.key.java.declaration.modifier.Model; -import de.uka.ilkd.key.java.declaration.modifier.Public; -import de.uka.ilkd.key.java.declaration.modifier.Static; -import de.uka.ilkd.key.java.reference.ReferencePrefix; -import de.uka.ilkd.key.java.reference.TypeRef; -import de.uka.ilkd.key.java.visitor.ProgramVariableCollector; -import de.uka.ilkd.key.jml.JMLClassSpec; -import de.uka.ilkd.key.jml.JMLNormalMethodSpec; -import de.uka.ilkd.key.jml.JMLSpec; -import de.uka.ilkd.key.jml.UsefulTools; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.logic.sort.ArraySort; -import de.uka.ilkd.key.logic.sort.ArraySortImpl; -import de.uka.ilkd.key.logic.sort.ObjectSort; -import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.util.ExtList; - - -/** - * This class is used to decouple JML parser and JMLDL translation - * (further refactoring needs to be done) - */ -public class JMLTranslator extends TermBuilder { - - private static int oldVarCount = 0; - - private final ArithOpProvider aOP; - - private final TypeDeclaration cld; - - private KeYJMLParser parser; - - private final Services services; - - private final KeYJavaType cldKeYJavaType; - - - private ReferencePrefix prefix; - - - - public JMLTranslator(TypeDeclaration cld, Services services, - KeYJMLParser parser, ArithOpProvider aOP) { - this.cld = cld; - this.services = services; - this.aOP = aOP; - this.parser = parser; - cldKeYJavaType = services.getJavaInfo().getKeYJavaType(cld); - //this.allInt = allInt; - } - - public ReferencePrefix prefix() { - return prefix; - } - - public void setPrefix(ReferencePrefix prefix) { - this.prefix = prefix; - } - - public boolean isInterface() { - return cld instanceof InterfaceDeclaration; - } - - public KeYJavaType getCLDKeYJavaType() { - return cldKeYJavaType; - } - - public KeYJavaType getArrayTypeAndEnsureExistence(Sort baseSort, - int dim){ - final JavaInfo ji = getJavaInfo(); - Sort as = ArraySortImpl.getArraySortForDim( - baseSort, dim, - ji.getJavaLangObjectAsSort(), - ji.getJavaLangCloneableAsSort(), - ji.getJavaIoSerializableAsSort()); - KeYJavaType kjt = ji.getKeYJavaType(as); - if(kjt == null || baseSort.toString().equals("int")){ - JavaBlock jb = ji.readJavaBlock("{"+as+" v;}"); - return ((VariableDeclaration) - ((StatementBlock) jb.program()).getChildAt(0)). - getTypeReference().getKeYJavaType(); - } - return kjt; - } - - public Term buildQuantifierTerm(String q, ListOfNamed l, Term a, Term t, - JMLSpec currentSpec) throws NotSupportedExpressionException { - - checkSupportedQuantifier(q); - - Term body = t; - - if (q.equals("\\min") || q.equals("\\max")) { - boolean isLong = isLong(t); - Function comp; - Function minmax; - ProgramVariable mv; - String varName; - - if (q.equals("\\min")) { - varName = "_min"; - minmax = aOP.getMax(isLong); - comp = (Function) functions().lookup(new Name("leq")); - } else { - varName = "_max"; - minmax = aOP.getMin(isLong); - comp = (Function) functions().lookup(new Name("geq")); - } - - mv = new LocationVariable(new ProgramElementName(varName - + (KeYJMLParser.paramVarCount++)), services.getJavaInfo() - .getKeYJavaType(isLong ? "long" : "int")); - currentSpec.getProgramVariableNS().add(mv); - final Term mvTerm = var(mv); - - final Term ex1 = and(not(parser.buildQuantifierTerm("\\exists", l, - null, a)), equals(func(minmax), mvTerm)); - final Term ex2 = parser.buildQuantifierTerm("\\exists", l, a, - equals(mvTerm, t)); - - final Term allq = parser.buildQuantifierTerm("\\forall", l, a, tf - .createFunctionTerm(comp, new Term[] { mvTerm, t })); - - return parser.createModelMethod( - q.substring(1) + (KeYJMLParser.mmCount++), mvTerm, null, or(ex1, - and(allq, ex2))); - } - - if (l == SLListOfNamed.EMPTY_LIST) { - if (a != null) { - if (q.equals("\\exists")) { - body = and(a, body); - } else { - body = imp(a, body); - } - } - return body; - } else { - Quantifier op = null; - if (q.equals("\\forall")) { - op = Op.ALL; - } else if (q.equals("\\exists")) { - op = Op.EX; - } else { - throw new IllegalArgumentException("Quantifier " + q - + " not supported"); - } - body = parser.buildQuantifierTerm(q, l.tail(), a, t); - final LogicVariable lv = (LogicVariable) l.head(); - - final Term vTerm = var(lv); - // if the quantified variables have an objecttype, we only quantify - // over objects that are already created (nevertheless the - // quantified variable may be null) - if (lv.sort() instanceof ObjectSort) { - final Term createdTerm = UsefulTools.isCreated(vTerm, services); - - final Term nullComp = equals(vTerm, NULL(services)); - final Term cnCond = or(and(createdTerm, not(nullComp)), - nullComp); - if (op == Op.ALL) { - body = imp(cnCond, body); - } else { - body = and(cnCond, body); - } - } - return tf.createQuantifierTerm(op, lv, body); - } - } - - private void checkSupportedQuantifier(String str) - throws NotSupportedExpressionException { - final String[] notSupported = { "\\sum", "\\product", "\\num_of" }; - - for (int i = 0; i < notSupported.length; i++) { - if (str.equals(notSupported[i])) { - throw new NotSupportedExpressionException("Quantifier " + str); - } - } - } - - /** - * creates a model method and adds it to the class specification - */ - public Term createModelMethod(String name, Term result, Term pre, - Term post, final JMLClassSpec cSpec, final boolean staticMode) { - final ExtList el = new ExtList(); - - ListOfTerm pvs = UsefulTools.getProgramVariablesFromTerm(result, - SLListOfTerm.EMPTY_LIST); - pvs = UsefulTools.getProgramVariablesFromTerm(pre, pvs); - pvs = UsefulTools.getProgramVariablesFromTerm(post, pvs); - - el.add(new Public()); - if (staticMode) { - el.add(new Static()); - } else { - pvs = pvs.removeAll(var((ProgramVariable) parser.prefix())); - } - IteratorOfTerm it = pvs.iterator(); - while (it.hasNext()) { - el.add(UsefulTools.getParameterDeclForVar(it.next(), services)); - } - el.add(new ProgramElementName(name)); - final KeYJavaType type = services.getJavaInfo().getKeYJavaType(result.sort()); - el.add(new TypeRef(type)); - el.add(new Model()); - - final MethodDeclaration meth = new MethodDeclaration(el, false); - final ProgramMethod pm = new ProgramMethod(meth, getCLDKeYJavaType(), - type, PositionInfo.UNDEFINED); - cSpec.addModelMethod(pm); - final JMLNormalMethodSpec spec = new JMLNormalMethodSpec(pm, - services, new Namespace(), new LinkedHashMap(), cSpec, parser.namespaces(), - parser.javaPath()); - - result = equals(result, var(spec.getResultVar())); - if (pre != null) { - spec.addPre(pre); - } - spec.addPost(result); - if (post != null) { - spec.addPost(post); - } - spec.setAssignableMode("nothing"); - services.getImplementation2SpecMap().addModifier(pm, "pure"); - services.getImplementation2SpecMap().addModifier(pm, "helper"); - return UsefulTools.createTermForQuery(pm, pvs, parser.prefix()); - } - - public TypeDeclaration cld() { - return cld; - } - - private Namespace functions() { - return parser.functions(); - } - - private JavaInfo getJavaInfo() { - return services.getJavaInfo(); - } - - private String getNameForOld(Term t) { - if (t.op() instanceof ProgramVariable) { - return ("_old" + (oldVarCount++) + "_" + (t.toString().length() > 25 ? t - .toString().substring(0, 25) - : t.toString())).replace('.', '_').replace(':', '_'); - } else { - return ("_old" + (oldVarCount++)); - } - } - - /** - * checks if term t contains the Named object o - * @return true if o occurs in the term and is instance of Term, - * ProgramVariable, QuantifiableVariable, SchemaVariable or Operator. - */ - public boolean occurCheck(Term t, Named o){ - if(t.op().equals(o) || this.equals(o)) return true; - if(o instanceof ProgramVariable && t.javaBlock().program()!=null){ - ProgramVariableCollector collector= - new ProgramVariableCollector(t.javaBlock().program()); - collector.start(); - if(collector.result().contains(o)) return true; - } - if(o instanceof QuantifiableVariable){ - if(t.freeVars().contains((QuantifiableVariable) o)) return true; - for(int i=0;ia == true which can be simplified to a - * a query isn't necessary. - * @returns a simplification of arg in some special cases - * or arg otherwise. - */ - protected Term simplifyArgument(Term arg){ - if (arg.op() == Op.TRUE){ - return BOOL_TRUE; - } - if (arg.op() == Op.FALSE){ - return BOOL_FALSE; - } - if(arg.op() instanceof Equality){ - if (arg.sub(0) == BOOL_TRUE || arg.sub(0).op() == Op.TRUE){ - return simplifyArgument(arg.sub(1)); - } - if(arg.sub(1) == BOOL_TRUE || arg.sub(1).op() == Op.TRUE){ - return simplifyArgument(arg.sub(0)); - } - } - return arg; - } - - private ListOfKeYJavaType getTypeList(ListOfTerm tl){ - final TypeConverter typeConverter = services.getTypeConverter(); - final Sort intSort = typeConverter.getIntegerLDT().targetSort(); - final Sort intDomainSort = typeConverter.getIntegerDomainLDT().targetSort(); - IteratorOfTerm it = tl.iterator(); - ListOfKeYJavaType sig = SLListOfKeYJavaType.EMPTY_LIST; - Term temp; - while(it.hasNext()){ - temp = it.next(); - if(temp.sort() == Sort.FORMULA){ - sig = sig.append(getJavaInfo().getKeYJavaType( - PrimitiveType.JAVA_BOOLEAN)); - }else{ - KeYJavaType sigkjt=null; - try{ - sigkjt = services.getTypeConverter(). - getKeYJavaType(temp); - }catch(Exception e){} - if(sigkjt == null){ - if (temp.sort() == intSort || temp.sort() == intDomainSort) { - // these sorts have no integer domain - sigkjt = getJavaInfo().getKeYJavaType(typeConverter.getIntLDT().targetSort()); - } else { - sigkjt = getJavaInfo().getKeYJavaType(temp.sort()); - } - - } - sig = sig.append(sigkjt); - } - } - return sig; - } - - /** - * returns the translation of \\nonnullelements(t). - */ - protected Term nonNullElements(Term t){ - return translator.nonNullElements(t, currentSpec); - } - - /** - * creates a model method and adds it to the class specification - */ - protected Term createModelMethod(String name, Term result, Term pre, Term post){ - return translator.createModelMethod(name, result, pre, post, cSpec, staticMode); - } - - private boolean isLong(Term t){ - return translator.isLong(t); - } - - public JavaInfo getJavaInfo() { - return getServices().getJavaInfo(); - } - - public Services getServices() { - return services; - } - - public NamespaceSet namespaces(){ - return nss; - } - - public Namespace sorts() { - return namespaces().sorts(); - } - - public Namespace variables() { - return namespaces().variables(); - } - - public Namespace functions() { - return namespaces().functions(); - } - - public Namespace choices(){ - return namespaces().choices(); - } - - public void parseClassSpec() throws antlr.ANTLRException { - top(); - } - - public void parseMethodDecl(String comments) throws antlr.ANTLRException { - methoddecl2(comments); - } - - public void parseFieldDecl() throws antlr.ANTLRException { - field(); - } - - public Term toZNotation(String s){ - Term number; - - final Function numberTerminator = (Function) functions().lookup(new Name("#")); - number = df.func(numberTerminator); - - Function numberSymbol = (Function) functions().lookup(new Name(s.substring(0,1))); - number = df.func(numberSymbol, number); - - for(int i=1; i "pure" - { - services.getImplementation2SpecMap().setPure(translator.getCLDKeYJavaType(), - nss, javaPath); - } - | - (field)* - ; - -loop_spec [LoopInvariant l] -{ - this.term2old = l.getTerm2Old(); - isOldAllowed = false; -}: - ( - "set" - { - throw new NotSupportedExpressionException("set", true); - } - | - loop_invariant[l] - | - assignableclause[l] - | - variant_function[l] - | - loop_post[l] - )+ - { isOldAllowed = true; } - ; - -loop_post[LoopInvariant l] -{ - Term t=null; -}: - ensureskeyword {setPreMode(false);} t=predornot - { - if(t!=null) l.addPost(t); - } - ";" - ; - -loop_invariant[LoopInvariant l] -{ - Term t; -}: - maintaining_keyword t = predicate ";" - { - l.addInvariant( df.and(t, df.func(getJavaInfo().getInReachableState())) ); - } -; - -maintaining_keyword : - "maintaining" - | - "maintaining_redundantly" - | - "loop_invariant" - | - "loop_invariant_redundantly" -; - -variant_function[LoopInvariant l] -{ - Term t; -}: - decreasing_keyword t=specexpression ";" - { - l.setVariant(t); - } - ; - -decreasing_keyword : - "decreasing" - | - "decreasing_redundantly" - | - "decreases" - | - "decreases_redundantly" - ; - - - -field -{ - SetOfString mods=SetAsListOfString.EMPTY_SET; -}: - { - term2old = cSpec.getTerm2Old(); - setPrefix(cSpec.getInstancePrefix());} - ( - (("model")? "import") => import_definition - | - ( - mods=modifiers - ( - jmldeclaration[mods] - | - memberdecl[mods] - ) - ) - ) - ; - -import_definition : - ("model")? "import" name_star ";" - ; - -name_star : - IDENT (DOT (IDENT | MULT))* - ; - -memberdecl[SetOfString mods] : - variabledecls[mods] - ; - -//not used due to the necessity that the methoddeclaration has to be parsed -//before the method specification -//methoddecl : -// methodspecification -// methoddecl2[""] -// { -// addMethod2Specs(); -// } -//; - -methoddecl2[String comments] -{ - KeYJavaType type = null; - KeYJavaType dummyType; - SetOfString mods=SetAsListOfString.EMPTY_SET; -}: - mods=modifiers - ( - (type IDENT) => type=typespec - )? - methodhead[type, mods, comments] - // "throws" is ignored - (THROWS dummyType=type ("," dummyType=type)*)? - ( - ";" - | - LBRACE - { - throw new NotSupportedExpressionException( - "Implementation for modelmethod"); - } - ) - ; - -methodhead[KeYJavaType type, SetOfString mods, String comments] -{ - LinkedList l = new LinkedList(); -}: - id:IDENT "(" (l = paramdeclarationlist)? ")" - { - ExtList el = new ExtList(); - if(comments != null){ - el.add(new Comment(comments)); - } - el.add(new Public()); - if(mods.contains("static")){ - el.add(new Static()); - } - if(mods.contains("private")){ - el.add(new Private()); - }else if(mods.contains("public")){ - el.add(new Public()); - }else if(mods.contains("protected")){ - el.add(new Protected()); - } - el.add(new Model()); - Object[] oarr = l.toArray(); - for(int i=0; i jml_datagroup_clause)? - ; - -//datagroups -//not implemented ---> -jml_datagroup_clause : - in_group_clause | maps_into_clause - ; - -in_group_clause : - in_keyword group_list ";" - ; - -in_keyword : - "in" | "in_redundantly" - ; - -group_list : - group_name ("," group_name)* - ; - -group_name : - (group_name_prefix)? IDENT - ; - -group_name_prefix : - "this" DOT | "super" DOT - ; - -maps_into_clause : - maps_keyword member_field_ref INTO group_list ";" - ; - -maps_keyword : - "maps" | "maps_redundantly" -; - -member_field_ref : - (IDENT DOT) => IDENT DOT maps_member_ref_expr - | - maps_array_ref_expr ( DOT maps_member_ref_expr )? - ; - -maps_member_ref_expr : - IDENT | MULT - ; - -maps_array_ref_expr : - IDENT maps_spec_array_dim ( maps_spec_array_dim )* -; - -maps_spec_array_dim -{ - ArraySpecIndexBound l; -}: - "[" l = specarrayrefexpr[null] "]" - ; - -// <--- not implemented - -variabledeclarators[KeYJavaType type, SetOfString mods]: - variabledeclarator[type, mods] ("," variabledeclarator[type, mods])* - ; - -variabledeclarator[KeYJavaType type, SetOfString mods] -{ - int dim = 0; -}: - id:IDENT (dim=dims)? - { - if(dim!=0){ - type = getArrayTypeAndEnsureExistence(type.getSort(), dim); - } - - cSpec.addModelVariable(new LocationVariable( - new ProgramElementName(id.getText()),type, - translator.getCLDKeYJavaType(), - mods != null && mods.contains("static") || - translator.isInterface() && - !mods.contains("instance"), - mods.contains("model"), mods.contains("ghost"))); - } - ; - -modifiers returns[SetOfString mods=SetAsListOfString.EMPTY_SET] -{ - String m; -}: - (m=modifier {mods = mods.add(m);})* - ; - -modifier returns[String s=null]: - s=privacy - | - "instance" {s="instance"; setPrefix(cSpec.getInstancePrefix());} - | - "static" {s="static";} - | - "model" {s = "model";} - | - "pure" {s = "pure";} - | - "helper" {s = "helper";} - | - "ghost" - | - "uninitialized" - | - "spec_java_math" - | - "spec_safe_math" - | - "spec_bigint_math" - | - "code_java_math" - | - "code_safe_math" - | - "code_bigint_math" - | - "non_null" - ; - -privacy returns[String s=null]: - "public" {s="public";} - | - "protected" {s="protected";} - | - "private" {s="private";} - | - "spec_public" - | - "spec_protected" - ; - -jmldeclaration[SetOfString mods] : - invariant[mods] - | - historyconstraint[mods] - | - representsdecl[mods] - | - initially_clause - | - monitors_for_clause - | - readable_if_clause - | - writable_if_clause - | - "axiom" dummy = predicate ";" - | - //HACK: jml-datagroup-clauses refering to a real field can occur here, - //which doesn't harm right now as they are ignored anyway. - jml_datagroup_clause - ; - -//not implemented ---> -initially_clause : - "initially" dummy = predicate ";" - ; - -readable_if_clause : - "readable" IDENT "if" dummy = predicate ";" - ; - -writable_if_clause : - "writable" IDENT "if" dummy = predicate ";" - ; - -monitors_for_clause : - "monitors_for" IDENT - l_arrow_or_eq spec_expression_list ";" - ; -// <--- not implemented - -representsdecl[SetOfString mods] -{ - Term t1,t2; -}: - representskeyword t1=storerefexpression - ( - l_arrow_or_eq t2=specexpression - { - cSpec.addRepresents(t1, t2); - } - | - SUCH_THAT t2=predicate - { - cSpec.addSuchThat(t1, t2); - } - ) - ";" - ; - -representskeyword: - "represents" - | - "represents_redundantly" - ; - -l_arrow_or_eq: - "<-" - | - "=" - ; - -invariant[SetOfString mods]{ - Term t=null; -} : - invariantkeyword - { - if(mods.contains("static") || translator.isInterface() && - !mods.contains("instance")){ - staticMode = true; - }else{ - staticMode = false; - } - } - t=predicate ";" - { - if(staticMode){ - cSpec.addStaticInvariant(t); - }else{ - cSpec.addInstanceInvariant(t); - } - } - ; - -invariantkeyword : - "invariant" - | - "invariant_redundantly" - ; - -historyconstraint[SetOfString mods]{ - Term t=null; -} : - constraintkeyword {staticMode = mods.contains("static");} - t=predicate ";" - { - if(mods.contains("static")){ - cSpec.addStaticConstraint(t); - }else{ - cSpec.addInstanceConstraint(t); - } - } - ; - -constraintkeyword : - "constraint" - | - "constraint_redundantly" - ; - -methodspecification : - (pure_helper) => (pure_helper)* - | - specification - | - extendingspecification - | - //HACK these tokens shouldn't occur in this place. - "assume" - { - throw new NotSupportedExpressionException("assume", true); - } - | - "assert" - { - throw new NotSupportedExpressionException("assert", true); - } - | - "nowarn" - { - throw new NotSupportedExpressionException("nowarn", true); - } - | - "set" - { - throw new NotSupportedExpressionException("set", true); - } - | - jml_datagroup_clause - ; - -pure_helper -{ - String p; -}: - (p=privacy)? - ( - "pure" - { - if(!services.getImplementation2SpecMap(). - getModifiers(md).contains("pure")){ - new JMLPuritySpec(md, services, param_ns, - term2old, cSpec, nss, javaPath); - services.getImplementation2SpecMap(). - addModifier(md, "pure"); - } - } - | - "helper" - { - if(!md.isPrivate()){ - throw new KeYSemanticException("Helper methods must be "+ - "private but "+md.getName()+" isn't", - getLine(), getColumn(), getFilename()); - } - services.getImplementation2SpecMap().addModifier(md, "helper"); - } - | - "non_null" - { - JMLNormalMethodSpec s = new JMLNormalMethodSpec( - md, services, param_ns, term2old, cSpec, nss, javaPath); - Term t = df.not(df.equals(df.var(s.getResultVar()), df.NULL(services))); - s.addPost(t); - } - ) - ; - -extendingspecification : - "also" specification - ; - -specification : - speccaseseq (redundant_spec)? - | - redundant_spec - ; - -// redundant specifications are not supported -//------------------> - -//implementation not complete -redundant_spec : - ( - implications - | - examples - ) - { - throw new NotSupportedExpressionException( - "redundant specification", true); - } - ; - -examples : - "for_example" - ; - -implications : - "implies_that" - ; - // <----------------- - -speccaseseq : - speccase (ALSO speccase)* - ; - -speccase : - ((dummyString=privacy)? "model_program") => model_program - | - lightweightspeccase - | - heavyweightspeccase - | - code_contract_spec - ; - -//not implemented ---> -code_contract_spec : - "code_contract" (code_contract_clause)+ - ; - -code_contract_clause : - accessible_clause - | - callable_clause - | - measured_clause - ; - -measured_clause : - measured_by_keyword - ( - NOT_SPECIFIED ";" - | - dummy=specexpression ( "if" dummy=predicate )? ";" - ) - ; - -measured_by_keyword : - "measured_by" - | - "measured_by_redundantly" - ; - -accessible_clause -{ - SetOfLocationDescriptor locs; -}: - accessible_keyword locs=conditionalstorereflist[null] ";" - ; - -accessible_keyword : - "accessible" - | - "accessible_redundantly" - ; - -callable_clause : - callable_keyword callable_methods_list ";" - ; - -callable_keyword : - "callable" - | - "callable_redundantly" - ; - -callable_methods_list : - method_name_list | dummyString=storerefkeyword[null] - ; - -method_name_list : - method_name ( "," method_name )* - ; - -method_name : - method_ref ( "(" ( param_disambig_list )? ")" )? - ; - -method_ref : - method_ref_start ( DOT method_ref_rest )* - | - "new" dt=referencetype - ; - -method_ref_start : - "super" | "this" | IDENT | OTHER - ; - -method_ref_rest : - "this" | IDENT | OTHER - ; - -param_disambig_list : - param_disambig ( "," param_disambig )* - ; - -param_disambig -{ - int d; -}: - dt=typespec ( IDENT ( d=dims )? )? - ; - -model_program : - ( dummyString=privacy )? - { - throw new NotSupportedExpressionException("Model Program"); - } - "model_program" LBRACE - ; - -// <--- not implemented - -lightweightspeccase -{ - JMLMethodSpec s=new JMLMethodSpec(md, services, - param_ns, term2old, cSpec, nss, javaPath); -}: - genericspeccase[s] - ; - -heavyweightspeccase -{ - String p = null; -}: - (p=privacy)? - ( - "normal_behavior" - normalspeccase[new JMLNormalMethodSpec(md, services, - param_ns, term2old, cSpec, nss, javaPath)] - | - "behavior" genericspeccase[new JMLMethodSpec(md, - services, param_ns, term2old, cSpec, nss, javaPath)] - | - "exceptional_behavior" - exceptionalspeccase[new JMLExceptionalMethodSpec(md, - services, param_ns, term2old, cSpec, nss, javaPath)] - ) - ; - -genericspeccase [JMLMethodSpec s] -{ - result = s.getResultVar(); - setPrefix(s.getPrefix()); - addSpec(s); - ListOfNamed lvs=SLListOfNamed.EMPTY_LIST; -}: - (lvs=spec_var_decls[s])? - { - s.setSpecVars(lvs); - bindVars(lvs); - } - ( - specheader[s] (genericspecbody[s])? - | - genericspecbody[s] - ) - { - unbindVars(); - } - ; - -spec_var_decls[JMLMethodSpec s] returns - [ListOfNamed lvs=SLListOfNamed.EMPTY_LIST]: - ( - "old" - { - throw new NotSupportedExpressionException( - "Specification Variable Declaration"); - } - | - lvs=forall_var_decls[s] - ) - ; - -forall_var_decls[JMLMethodSpec s] returns - [ListOfNamed lvs=SLListOfNamed.EMPTY_LIST] -{ - LogicVariable lv; -}: - (lv=forall_var_declarator[s] {lvs = lvs.append(lv);})+ - ; - -forall_var_declarator[JMLMethodSpec s] returns [LogicVariable lv=null] -{ - KeYJavaType kjt; -} : - "forall" kjt=typespec lv=quantifiedvariabledeclarator[kjt] ";" -; - -normalspeccase [JMLNormalMethodSpec s] -{ - result = s.getResultVar(); - setPrefix(s.getPrefix()); - addSpec(s); - ListOfNamed lvs=SLListOfNamed.EMPTY_LIST; -} : - (lvs=spec_var_decls[s])? - { - s.setSpecVars(lvs); - bindVars(lvs); - } - ( - specheader[s] (normalspecbody[s])? - | - normalspecbody[s] - ) - { - unbindVars(); - } - ; - -exceptionalspeccase [JMLExceptionalMethodSpec s] -{ - result = s.getResultVar(); - setPrefix(s.getPrefix()); - addSpec(s); - ListOfNamed lvs=SLListOfNamed.EMPTY_LIST; -} : - (lvs=spec_var_decls[s])? - { - s.setSpecVars(lvs); - bindVars(lvs); - } - ( - specheader[s] (exceptionalspecbody[s])? - | - exceptionalspecbody[s] - ) - { - unbindVars(); - } - ; - - -specheader[JMLMethodSpec s] : - requiresclause[s] (requiresclause[s])* - ; - -genericspecbody[JMLMethodSpec s] : - simplespecbodyclause[s] (simplespecbodyclause[s])* - | - LBRACE "|" genericspeccaseseq[s] "|" RBRACE - ; - -genericspeccaseseq[JMLMethodSpec s] -{ - JMLMethodSpec copy = s.copy(); - services.getImplementation2SpecMap().removeMethodSpec(copy); -}: - genericspeccase[s] ( "also" genericspeccase[copy.copy()] )* -; - -normalspecbody[JMLNormalMethodSpec s] : - normalspecclause[s] (normalspecclause[s])* - | - LBRACE "|" normalspeccaseseq[s] "|" RBRACE - ; - -normalspeccaseseq[JMLNormalMethodSpec s] -{ - JMLNormalMethodSpec copy = (JMLNormalMethodSpec) s.copy(); - services.getImplementation2SpecMap().removeMethodSpec(copy); -}: - normalspeccase[s] - ( - "also" normalspeccase[(JMLNormalMethodSpec) copy.copy()] - )* -; - -exceptionalspecbody[JMLExceptionalMethodSpec s] : - exceptionalspecclause[s] (exceptionalspecclause[s])* - | - LBRACE "|" exceptionalspeccaseseq[s] "|" RBRACE - ; - -exceptionalspeccaseseq[JMLExceptionalMethodSpec s] -{ - JMLExceptionalMethodSpec copy = (JMLExceptionalMethodSpec) s.copy(); - services.getImplementation2SpecMap().removeMethodSpec(copy); -}: - exceptionalspeccase[s] - ( - "also" exceptionalspeccase[(JMLExceptionalMethodSpec) copy.copy()] - )* -; - -normalspecclause[JMLMethodSpec s] : - ensuresclause[s] - | - assignableclause[s] - | - divergesclause[s] - | - whenclause[s] - | - durationclause[s] - | - workingspaceclause[s] - ; - -simplespecbodyclause[JMLMethodSpec s] : - normalspecclause[s] - | - signalsclause[s] - | - signalsonlyclause[s] - ; - -exceptionalspecclause[JMLMethodSpec s] : - assignableclause[s] - | - signalsclause[s] - | - signalsonlyclause[s] - | - divergesclause[s] - | - whenclause[s] - | - durationclause[s] - | - workingspaceclause[s] - ; - -//not implemented -whenclause[JMLMethodSpec s] : - whenkeyword dummy = predornot ";" - ; - -whenkeyword: - "when" - | - "when_redundantly" - ; - - -//not implemented -durationclause[JMLMethodSpec s] : - durationkeyword dummy = predornot ";" - ; - -durationkeyword: - "duration" - | - "duration_redundantly" - ; - -//not implemented -workingspaceclause[JMLMethodSpec s] : - workingspacekeyword - ( - NOT_SPECIFIED - | - dummy = specexpression (IF dummy = predicate)? - ) - ";" - ; - -workingspacekeyword: - "working_space" - | - "working_space_redundantly" - ; - -divergesclause[JMLMethodSpec s] -{ - Term t=null; -}: - divergeskeyword - { - setPreMode(true); - } - t=predornot - { - s.addDiverges(t); - } - ";" -; - -divergeskeyword : - "diverges" - | - "diverges_redundantly" - ; - -assignableclause[AssignableSpec s] -{ - SetOfLocationDescriptor locs = null; -}: - assignablekeyword {setPreMode(true);} locs = conditionalstorereflist[s] ";" - { - s.addAssignable(locs); - } -; - -assignablekeyword : - "assignable" - | - "modifies" - | - "modifiable" - | - "assignable_redundantly" - | - "modifiable_redundantly" - | - "modifies_redundantly" -; - -conditionalstorereflist[AssignableSpec s] - returns [SetOfLocationDescriptor set = SetAsListOfLocationDescriptor.EMPTY_SET] -{ - LocationDescriptor loc=null; -} : - loc=conditionalstoreref[s] - { - if(loc != null){ - set = set.add(loc); - } - } - ( - "," loc=conditionalstoreref[s] - { - if(loc != null){ - set = set.add(loc); - } - } - )* -; - -conditionalstoreref[AssignableSpec s] returns [LocationDescriptor loc=null] -{ - Term t; - Term t1=null; -}: - { - quantifiedArrayGuard = tf.createJunctorTerm(Op.TRUE); - } - t=storeref[s] ("if" t1=predicate)? - { - if(t != null) { - if (t.op() instanceof Location) { - loc = new BasicLocationDescriptor(quantifiedArrayGuard, t); - } else { - reportError(new KeYSemanticException("Invalid assignable clause. " + - "Expected a location, but " + t + " denotes a " + t.op().getClass().getName(), - getFilename(), getLine(), getColumn())); - } - } - quantifiedArrayGuard = null; - } -; - -// not implemented -storereflist : - dummy=storeref[null] ("," dummy=storeref[null])* -; - -storeref[AssignableSpec spec] returns [Term t=null] -{ - String s; -}: - t = storerefexpression - | - s = storerefkeyword[spec] - | - INFORMAL_DESCRIPTION -; - -storerefkeyword[AssignableSpec spec] returns [String s=null]: - ( - NOTHING {s="nothing";} - | - EVERYTHING { - s = "everything"; - spec.addAssignable(SetAsListOfLocationDescriptor. - EMPTY_SET.add(EverythingLocationDescriptor.INSTANCE)); - } - - | - NOT_SPECIFIED {s="not_specified";} - | - PRIVATEDATA {s="private_data";} - ) - { - if(spec != null){ - spec.setAssignableMode(s); - } - } -; - -storerefexpression returns [Term t=null] -{ - String s; - KeYJavaType kjt = null; -}: - s=storerefname - { - if(s.equals("this")){ - if (staticMode){ - throw new KeYSemanticException("this in static context", - getLine(), getColumn(), getFilename()); - } - t = getTermForVariable((ProgramVariable) prefix()); - }else{ - t = lookupVar(new Name(s)); - } - if(t == null){ - kjt = getJavaInfo().getTypeByClassName(s); - } - } - ( - t=storerefnamesuffix[t, kjt] - )* - ; - -storerefnamesuffix[Term localPrefix, KeYJavaType kjt] returns [Term t=null] -{ - String s; - ArraySpecIndexBound aib = null; -}: - ( - (DOT "this") => DOT "this" - { - t = getTermForVariable((ProgramVariable) prefix()); - } - | - DOT id:IDENT - { - s = id.getText(); - if(localPrefix != null){ - kjt = services.getTypeConverter().getKeYJavaType( - localPrefix); - } - if(kjt != null){ - //%%RB I do not think this is okay, visible contexts? - ProgramVariable v = (ProgramVariable) getJavaInfo().lookupVisibleAttribute(s, kjt); - if ( v == null){ - JMLClassSpec cs = - services.getImplementation2SpecMap().getSpecForClass(kjt); - if(cs != null){ - try{ - v = cs.lookupModelField(new Name(id.getText())); - }catch(AmbigiousModelElementException e){ - throw new KeYSemanticException( - "Ambigious Model Element name", - getLine(), getColumn(), getFilename()); - } - } - } - if ( v == null) { - throw new NotDeclException("Attribute ", s, - getFilename(), getLine(), getColumn()); - } - t = (v.isStatic() ? getTermForVariable(v) : df.dot(localPrefix, v)); - } - } - | - "[" aib = specarrayrefexpr[localPrefix] "]" - { - if(aib != null && localPrefix != null){ - Term indexTerm; - - if (aib.singleValue()) { - indexTerm = aib.lower(); - } else { - if(quantifiedArrayGuard == null) { - throw new KeYSemanticException( - "Quantified array expressions are " - + "only allowed in locations.", - getLine(), - getColumn(), - getFilename()); - } - final LogicVariable indexVar = - new LogicVariable( - new Name("i"), (Sort) sorts().lookup(new Name("int"))); - indexTerm = df.var(indexVar); - if (aib.isStar()) { - quantifiedArrayGuard = df.and(quantifiedArrayGuard, df.tt()); - } else { - Term fromTerm = df.leq(aib.lower(), indexTerm, getServices()); - Term toTerm = df.leq(indexTerm, aib.upper(), getServices()); - Term guardTerm = df.and(fromTerm, toTerm); - quantifiedArrayGuard = df.and(quantifiedArrayGuard, guardTerm); - } - } - t = df.array(localPrefix, indexTerm); - } - } - ) - ; - -specarrayrefexpr[Term prefix] returns [ArraySpecIndexBound aib = new ArraySpecIndexBound()] -{ - Term t; -}: - ( - t=specexpression { aib.setLower(t); } - ( - DOTDOT t = specexpression - { - aib.setUpper(t); - } - )? - ) - | - MULT - { - aib.setStar(true); - } - ; - -storerefname returns [String s=null] : - id:IDENT {s=id.getText();} - | - "this" - { - s = "this"; - } - | - "super" - { - s = "super"; - } -; - -signalsonlyclause[JMLMethodSpec s] -{ - KeYJavaType exc=getReferenceType("Exception"); - KeYJavaType only = null; - Term t = df.ff(); - Term instof = null; - ProgramVariable v = new LocationVariable(new ProgramElementName("e"), exc); - Term vTerm = df.var(v); -}: - "signals_only" {setPreMode(false);} - { - bindProgVars(v); - } - ( - only = referencetype (",")? - { - SortDefiningSymbols os = (SortDefiningSymbols)(only.getSort()); - InstanceofSymbol func - = (InstanceofSymbol)os.lookupSymbol(InstanceofSymbol.NAME); - instof = df.equals(df.func(func, vTerm), BOOL_TRUE); - t = df.or(t, instof); - } - )+ - ";" - { - s.addSignals(exc, v, t); - unbindProgVars(); - } -; exception - catch [RuntimeException th] { - unbindProgVars(); - throw th; - } - - -signalsclause[JMLMethodSpec s]{ - KeYJavaType exc=null; - Term t = df.tt(); - ProgramVariable v = null; - boolean bound = false; -}: - signalskeyword {setPreMode(false);} - "(" exc = referencetype - (id:IDENT - { - v = new LocationVariable( - new ProgramElementName(id.getText()), exc); - bindProgVars(v); - bound = true; - } - )? - ")" (t=predornot)? ";" - { - if(t != null){ - s.addSignals(exc, v, t); - } - if(v != null){ - unbindProgVars(); - } - } -; exception - catch [RuntimeException th] { - if (bound) unbindProgVars(); - throw th; - } - - -signalskeyword: - ( - "signals" - | - "exsures" - | - "signals_redundantly" - | - "exsures_redundantly" - ) -; - -requiresclause[JMLMethodSpec s] -{ - Term t=null; -}: - requireskeyword {setPreMode(true);} t=predornot - { - if(t!=null) s.addPre(t); - } - ";" - ; - -requireskeyword : - ( - "requires" - | - "pre" - | - "requires_redundantly" - | - "pre_redundantly" - ) - ; - -ensuresclause[JMLMethodSpec s] -{ - Term t=null; -}: - ensureskeyword {setPreMode(false);} t=predornot - { - if(t!=null) s.addPost(t); - } - ";" - ; - -ensureskeyword : - ( - "ensures" - | - "post" - | - "ensures_redundantly" - | - "post_redundantly" - ) - ; - -predornot returns [Term t=null]: - t = predicate - | - NOT_SPECIFIED - ; - -predicate returns [Term t=null]: - t = specexpression - ; - -specexpression returns [Term t=null]: - t = expression - ; - -spec_expression_list : - dummy = specexpression ("," dummy = specexpression)* - ; - -expression returns [Term t=null]: - t=assignmentexpr - ; - -assignmentexpr returns [Term t=null]: - t=conditionalexpr - ; - -conditionalexpr returns [Term t=null] -{ - Term t1,t2; -}: - t=equivalenceexpr - ( - "?" t1=conditionalexpr ":" t2=conditionalexpr - { - t = tf.createIfThenElseTerm(t, t1, t2); - } - )? - ; - -equivalenceexpr returns [Term t=null] -{ - Term a=null; -}: - t=impliesexpr - ( - EQV a=equivalenceexpr - { - t = df.equiv(t,a); - } - | - ANTIV a=equivalenceexpr - { - t = df.not(df.equiv(t, a)); - } - )? - ; - -impliesexpr returns [Term t=null] -{ - Term a=null; -}: - t=logicalorexpr - ( - "==>" a=impliesnonbackwardexpr - { - t = df.imp(t,a); - } - | - ( - "<==" a=logicalorexpr - { - t = df.imp(a,t); - } - )+ - )? -; - -impliesnonbackwardexpr returns [Term t=null] -{ - Term a=null; -}: - t=logicalorexpr ("==>" a=impliesnonbackwardexpr - { t = df.imp(t,a); })? -; - -logicalorexpr returns [Term t=null] -{ - Term a=null; -}: - t=logicalandexpr ("||" a=logicalorexpr {t = df.or(t, a);})? -; - -logicalandexpr returns [Term t=null] -{ - Term a=null; -}: - t=inclusiveorexpr ("&&" a=logicalandexpr - {t = df.and(t, a);})? -; - -inclusiveorexpr returns [Term t=null] -{ - Term a=null; -}: - t=exclusiveorexpr - ( - "|" a=inclusiveorexpr - { - if(t.sort() == Sort.FORMULA && a.sort() == Sort.FORMULA){ - t = df.or(t, a); - }else if(t.sort().equals(a.sort())){ - t = df.func(aOP.getOr(isLong(t) || isLong(a)), new Term[]{t,a}); - }else{ - throw new antlr.SemanticException( - "Bitwise-Or not valid with subterms "+t+" and "+a); - } - } - )? -; - -exclusiveorexpr returns [Term t=null] -{ - Term a; -}: - t=andexpr - (XOR a=exclusiveorexpr - { - if(t.sort() == Sort.FORMULA && a.sort() == Sort.FORMULA){ - final Term nt = df.not(t); - t = df.or(df.and(nt, df.not(a)), df.and(nt, a)); - }else if(t.sort().equals(a.sort())){ - t = df.func(aOP.getXor(isLong(t) || isLong(a)), new Term[]{t,a}); - }else{ - throw new antlr.SemanticException( - "Bitwise-Xor not valid with subterms "+t+" and "+a); - } - } - )? -; - -andexpr returns [Term t=null] -{ - Term a=null; -}: - t=equalityexpr - ( - "&" a=andexpr - { - if(t.sort() == Sort.FORMULA && a.sort() == Sort.FORMULA){ - t = df.and(t,a); - }else if(t.sort().extendsTrans(a.sort()) || - a.sort().extendsTrans(t.sort())){ - t = df.func(aOP.getAnd(isLong(t) || isLong(a)), new Term[]{t,a}); - }else{ - throw new antlr.SemanticException( - "Bitwise-And not valid with subterms "+t+" and "+a); - } - } - )? -; - -equalityexpr returns [Term t=null] -{ - Term a1; -}: - t=relationalexpr - ( - "==" a1=equalityexpr { t = tf.createEqualityTerm(t, a1);} - | - "!=" a1=equalityexpr - { - t = df.not(tf.createEqualityTerm(t, a1)); - } - )? -; - -relationalexpr returns [Term t=null] -{ - Term a1; - Function f; - KeYJavaType type; -}: - t=shiftexpr - ( - LT a1=shiftexpr - { - f = (Function) functions().lookup(new Name("lt")); - t = tf.createFunctionTerm(f, t, a1); - } - | - GT a1=shiftexpr - { - f = (Function) functions().lookup(new Name("gt")); - t = df.func(f, t, a1); - } - | - LEQ a1=shiftexpr - { - f = (Function) functions().lookup(new Name("leq")); - t = df.func(f, t, a1); - } - | - GEQ a1=shiftexpr - { - f = (Function) functions().lookup(new Name("geq")); - t = df.func(f, t, a1); - } - | - "instanceof" type=typespec - { - SortDefiningSymbols s = (SortDefiningSymbols)(type.getSort()); - InstanceofSymbol func - = (InstanceofSymbol)s.lookupSymbol(InstanceofSymbol.NAME); - final Term object = t; - t = df.and(df.equals(df.func(func, t), BOOL_TRUE), - df.not(df.equals(object, df.NULL(services)))); - } - | - ST a1 = shiftexpr - { - throw new NotSupportedExpressionException("<:"); - } - - )? -; - -shiftexpr returns [Term t=null] -{ - Term a=null; -}: - t=additiveexpr - ( - ">>" a=additiveexpr - { - Function f = aOP.getShiftRight(isLong(t)); - t = df.func(f, t, a); - } - | - "<<" a=additiveexpr - { - Function f = aOP.getShiftLeft(isLong(t)); - t = df.func(f, t, a); - } - | - ">>>" a=additiveexpr - { - Function f = aOP.getUnsignedShiftRight(isLong(t)); - t = df.func(f, t, a); - } - )* -; - -additiveexpr returns [Term t=null] -{ - Term a1; - Function f; -}: - t=multexpr - ( - "+" a1=multexpr - { - f = aOP.getAdd(isLong(t) || isLong(a1)); - t = df.func(f, t, a1); - } - | - "-" a1=multexpr - { - f = aOP.getSub(isLong(t) || isLong(a1)); - t = df.func(f, t, a1); - } - )* -; - -multexpr returns [Term t=null] -{ - Term a1; - Function f; -}: - t=unaryexpr - ( - MULT a1=unaryexpr - { - f = aOP.getMul(isLong(t) || isLong(a1)); - t = df.func(f, t, a1); - } - | - DIV a1=unaryexpr - { - f = aOP.getDiv(isLong(t) || isLong(a1)); - t = df.func(f, t, a1); - } - | - "%" a1=unaryexpr - { - f = aOP.getMod(isLong(t) || isLong(a1)); - t = df.func(f, t, a1); - } - )* -; - -unaryexpr returns [Term t=null]{ - Function neg; - KeYJavaType type; -}: - "+" t=unaryexpr - | - "-" t=unaryexpr - { - neg = aOP.getMinus(isLong(t)); - t = tf.createFunctionTerm(neg,new Term[]{t}); - } - | - ("(" builtintype ")") => - "(" type=builtintype ")" t=unaryexpr - { - if(PrimitiveType.JAVA_BYTE.equals(type.getJavaType())){ - if(aOP.getCastToByte() != null){ - t = tf.createFunctionTerm(aOP.getCastToByte(),t); - } - }else if(PrimitiveType.JAVA_SHORT.equals(type.getJavaType())){ - if(aOP.getCastToShort() != null){ - t = tf.createFunctionTerm(aOP.getCastToShort(),t); - } - }else if(PrimitiveType.JAVA_INT.equals(type.getJavaType())){ - if(aOP.getCastToInt() != null){ - t = tf.createFunctionTerm(aOP.getCastToInt(),t); - } - }else if(PrimitiveType.JAVA_LONG.equals(type.getJavaType())){ - if(aOP.getCastToLong() != null){ - t = tf.createFunctionTerm(aOP.getCastToLong(),t); - } - } - } - | - ("(" referencetype ")" ) => - "(" type=referencetype ")" t=unaryexpr - { - t = tf.createCastTerm((AbstractSort)type.getSort(),t); - } - | - t = unaryexprnotplusminus -; - -unaryexprnotplusminus returns [Term t=null]: - "!" t=unaryexpr {t = df.not(t);} - | - "~" t=unaryexpr - { - Function f = aOP.getNeg(isLong(t)); - t = tf.createFunctionTerm(f,new Term[]{t}); - } - | - t=postfixexpr -; - -postfixexpr returns [Term t=null] -{ - tempkjt = translator.getCLDKeYJavaType(); -}: - t = primaryexpr (t = primarysuffix[tempkjt, t])* - { - if(t == null){ - throw new NotDeclException("variable or method ", - packageName, getFilename(), getLine(), getColumn()); - } - } -; - -primaryexpr returns [Term t=null] -{ - KeYJavaType kjt = null; - ProgramVariable v = null; -}: - t=constant - | id:IDENT - { - tempkjt = translator.getCLDKeYJavaType(); - if(LA(1)==LPAREN){ - methodname = id.getText(); - return null; - } - t = lookupVar(new Name(id.getText())); - if(t == null) { - try { - kjt = getJavaInfo().getTypeByClassName(id.getText()); - } catch(RuntimeException e){} - if(kjt == null){ - packageName = id.getText(); - }else{ - packageName = ""; - } - } else { - if(t.op() instanceof ProgramVariable){ - kjt = ((ProgramVariable) t.op()).getKeYJavaType(); - }else if (t.op() instanceof AttributeOp){ - kjt = (((AttributeOp) t.op()).attribute()).getKeYJavaType(); - }else if(t.op() instanceof LogicVariable){ - kjt = getJavaInfo().getKeYJavaType(t.sort()); - } - if(PrimitiveType.JAVA_BOOLEAN.equals(kjt.getJavaType())){ - t = df.equals(t, BOOL_TRUE); - } - } - tempkjt = kjt; - } - | "true" { t = df.tt(); } - | "false" { t = df.ff(); } - | "null" { t = df.NULL(services);} - | t = jmlprimary - | "this" - { - t = df.var((ProgramVariable) prefix()); - tempkjt = ((ProgramVariable) prefix()).getKeYJavaType(); - } - | t = new_expr -; - -primarysuffix[KeYJavaType kjt, Term t] returns [Term result = null]{ - ListOfTerm l=SLListOfTerm.EMPTY_LIST; - Term arg = null; - String mName = methodname; - methodname = null; -}: - (DOT id:IDENT - { - if(LA(1)==LPAREN){ - methodname = id.getText(); - packageName = ""; - return t; - } - if(t != null && t.sort() instanceof ObjectSort){ - kjt = getJavaInfo().getKeYJavaType(t.sort()); - } - ProgramVariable v = null; - if(kjt != null){ - v = (ProgramVariable) getJavaInfo(). - lookupVisibleAttribute(id.getText(), kjt); - } - if(v==null && kjt != null){ - JMLClassSpec cs = services.getImplementation2SpecMap().getSpecForClass(kjt); - if(cs != null){ - try { - v = cs.lookupModelField(new Name(id.getText())); - } catch(AmbigiousModelElementException e){ - throw new KeYSemanticException( - "Ambigious Model Element name", - getLine(), getColumn(), getFilename()); - } - } - } - if ( v == null /*&& !("length").equals(id.getText())*/ ) { - KeYJavaType classType = null; - try { - classType = getJavaInfo().getTypeByClassName( - packageName + "." + id.getText()); - } catch(RuntimeException e) {} - if(classType == null){ - packageName += "."+id.getText(); - }else{ - packageName = ""; - this.tempkjt = classType; - } - }else{ - if (v.isStatic()) { - result = df.var(v); - } else { - result = df.dot(t, v); - } - this.tempkjt = v.getKeYJavaType(); - if (PrimitiveType.JAVA_BOOLEAN.equals(this.tempkjt.getJavaType())){ - result = df.equals(result, BOOL_TRUE); - } - } - } - ) - | - "(" (l=expressionlist)? ")" - { - ListOfKeYJavaType sig = getTypeList(l); - - if (t != null && t.sort() instanceof ObjectSort){ - kjt = getJavaInfo().getKeYJavaType(t.sort()); - } - - ProgramMethod pm = getJavaInfo().getProgramMethod(kjt, mName, - sig, translator.getCLDKeYJavaType()); - // maybe it's a model method - if(pm == null){ - JMLClassSpec cs = - services.getImplementation2SpecMap().getSpecForClass(kjt); - if(cs != null){ - try{ - pm = cs.lookupModelMethod( - new Name(kjt.getSort()+ "::" + mName)); - if(pm == null){ - pm = cs.lookupModelMethod(new Name(mName)); - } - - }catch(AmbigiousModelElementException e){ - System.err.println(e.toString()); - } - } - } - if(pm == null){ - throw new NotDeclException("method", - mName, getFilename(), getLine(), getColumn(), "in type "+kjt); - } - if(!pm.isStatic() && staticMode && (t==null || t.op().equals(prefix()))){ - throw new KeYSemanticException("Call to instance method "+ - "in static context", - getLine(), getColumn(), getFilename()); - } - Term[] sub; - int i=0; - if(pm.isStatic()){ - sub = new Term[sig.size()]; - }else{ - sub = new Term[sig.size()+1]; - if(t==null){ - sub[i++] = df.var((ProgramVariable) prefix()); - }else{ - sub[i++] = t; - } - } - final IteratorOfTerm it = l.iterator(); - while (it.hasNext()) { - Term temp = simplifyArgument(it.next()); - if (temp.sort() == Sort.FORMULA){ - final Term var = - df.var(new LocationVariable(new ProgramElementName("jml_p" +(paramVarCount++)), - getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_BOOLEAN))); - sub[i++] = createModelMethod("formula"+(mmCount++), var, null, - df.equiv(temp, df.equals(var, BOOL_TRUE))); - } else { - sub[i++] = temp; - } - } - result = df.func(pm, sub); - if (PrimitiveType.JAVA_BOOLEAN.equals(pm.getKeYJavaType().getJavaType())){ - result = df.equals(result, BOOL_TRUE); - } - this.tempkjt = pm.getKeYJavaType(); - } - | - "["arg = expression "]" - { - result = df.array(t, arg); - this.tempkjt = services.getTypeConverter().getKeYJavaType(result); - if (PrimitiveType.JAVA_BOOLEAN.equals(tempkjt.getJavaType())) { - result = df.equals(result, BOOL_TRUE); - } - } -; - -new_expr returns [Term t=null] -{ - KeYJavaType kjt; - ListOfTerm l; -}: - "new" kjt=type l = new_suffix - { - final ListOfKeYJavaType sig = getTypeList(l); - final Constructor c = - getJavaInfo().getKeYProgModelInfo().getConstructor(kjt, sig); - if (!(c instanceof ConstructorDeclaration)) { - throw new NotSupportedExpressionException("Default Constructor"); - } - ProgramMethod cm = - new ProgramMethod((ConstructorDeclaration) c, kjt, - translator.getCLDKeYJavaType(), PositionInfo.UNDEFINED); - - int i=0; - final Term[] sub = new Term[sig.size()]; - final IteratorOfTerm it = l.iterator(); - while ( it.hasNext() ) { - final Term temp = simplifyArgument(it.next()); - if(temp.sort() == Sort.FORMULA){ - final Term var = df.var(new LocationVariable( - new ProgramElementName("_param"+(paramVarCount++)), - getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_BOOLEAN))); - sub[i] = createModelMethod("formula"+(mmCount++), var, - null, - df.equiv(temp, df.equals(var, BOOL_TRUE))); - } else { - sub[i] = temp; - } - i++; - } - t = df.func(cm, sub); - if (PrimitiveType.JAVA_BOOLEAN.equals(cm.getKeYJavaType().getJavaType())){ - t = df.equals(t, BOOL_TRUE); - } - this.tempkjt = kjt; - } - ; - -new_suffix returns [ListOfTerm l = SLListOfTerm.EMPTY_LIST]: - "(" ( l=expressionlist )? ")" - ; - -expressionlist returns [ListOfTerm l = SLListOfTerm.EMPTY_LIST] -{ - Term t; -}: - t = expression {l=l.append(t);} ("," t=expression {l=l.append(t);})* -; - -constant returns [Term t=null]: - t=javaliteral -; - -javaliteral returns [Term t=null]: - t=integerliteral - | - STRING_LITERAL - { - throw new NotSupportedExpressionException("String literal"); - } - | - CHAR_LITERAL - { - throw new NotSupportedExpressionException("Char literal"); - } - ; - -integerliteral returns [Term t=null]: - t=decimalintegerliteral -; - -decimalintegerliteral returns [Term t=null]: - t=decimalnumeral -; - -decimalnumeral returns [Term t=null]: - n:DIGITS {t = toZNotation(n.getText());} -; - -jmlprimary returns [Term t=null] -{ - KeYJavaType dummykjt; -}: - RESULT - { - t = df.var((ProgramVariable) result); - if (PrimitiveType.JAVA_BOOLEAN.equals(result.getKeYJavaType().getJavaType())){ - t = df.equals(t, BOOL_TRUE); - } - tempkjt = result.getKeYJavaType(); - } - | - ("(" QUANTIFIER) => t=specquantifiedexpression - | - OLD { inOld = true; } "(" t=specexpression ")" - { - if (isOldAllowed) { - t = getOld(t); - } else { - throw new KeYSemanticException("JML construct "+ - "\\old not allowed in this context,"+ - "e.g. in loop invariants", - getFilename(), getLine(), getColumn()); - } - inOld = false; - } - | CREATED "(" t = specexpression ")" - { - if (!(t.sort() instanceof ObjectSort)) { - throw new KeYSemanticException("\\created can only be applied on objects."); - } - ProgramVariable created = services.getJavaInfo(). - getAttribute(ImplicitFieldAdder.IMPLICIT_CREATED, - services.getJavaInfo().getJavaLangObject()); - t = df.equals(df.dot(t, created), df.TRUE(services)); - } - | - NONNULLELEMENTS "(" t=specexpression ")" - { - t = nonNullElements(t); - } - | INFORMAL_DESCRIPTION - { - throw new NotSupportedExpressionException("JML construct "+ - "informal description"); - } - | NOT_MODIFIED "(" storereflist ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\not_modified"); - } - | FRESH "(" spec_expression_list ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\fresh"); - } - | REACH "(" dummy = specexpression ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\reach"); - } - | DURATION "(" dummy = expression ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\duration"); - } - | SPACE "(" dummy = specexpression ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\space"); - } - | WORKINGSPACE "(" dummy = expression ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\working_space"); - } -// | QUANTIFIER "(" dummy = expression ")" - | TYPEOF "(" dummy = specexpression ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\typeof"); - } - | ELEMTYPE "(" dummy = specexpression ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\elemtype"); - } - | TYPE_SMALL "(" dummykjt = type ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\type"); - } - | LOCKSET - { - throw new NotSupportedExpressionException("JML construct "+ - "\\lockset"); - } - | IS_INITIALIZED "(" dummykjt=referencetype ")" - { - ProgramVariable ci = - services.getJavaInfo().getAttribute - (ImplicitFieldAdder.IMPLICIT_CLASS_INITIALIZED, dummykjt); - t = df.equals(df.var(ci), BOOL_TRUE); - } - | INVARIANT_FOR "(" dummy=specexpression ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\invariant_for"); - } - | ( "(" LBLNEG ) => "(" LBLNEG IDENT dummy=specexpression ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\lblneg"); - } - | ( "(" LBLPOS ) => "(" LBLPOS IDENT dummy=specexpression ")" - { - throw new NotSupportedExpressionException("JML construct "+ - "\\lblpos"); - } - | - NOWARN - { - throw new NotSupportedExpressionException("\\nowarn", true); - } - | - "(" t=expression ")" - -; - -specquantifiedexpression returns [Term t=null] -{ - Term a=null; - ListOfNamed decls=null; -}: - "(" - q:QUANTIFIER decls=quantifiedvardecls {bindVars(decls);} ";" - ( - ((predicate)? ";" ) => (a=predicate)? ";" t=specexpression - | - (";")? t=specexpression - ) - { - t = buildQuantifierTerm(q.getText(), decls, a, t); - unbindVars(); - } - ")" -; -exception - catch [NotSupportedExpressionException ex] { - unbindVars(); - throw ex; - } - -quantifiedvardecls returns [ListOfNamed decls=SLListOfNamed.EMPTY_LIST] -{ - KeYJavaType kjt = null; - LogicVariable v = null; -}: - kjt = typespec v = quantifiedvariabledeclarator[kjt] - { decls=decls.append(v); } - ("," v = quantifiedvariabledeclarator[kjt] { decls=decls.append(v); })* -; - -typespec returns [KeYJavaType kjt = null]{ - int dim = 0; -}: - kjt=type - (dim = dims - { - if(dim != 0){ - kjt = getArrayTypeAndEnsureExistence(kjt.getSort(), dim); - } - } - )? -; - -dims returns [int dim = 0]: - ("[" "]" {dim++;} )+ - ; - -type returns [KeYJavaType kjt = null]: - (builtintype) => kjt = builtintype - | - kjt = referencetype - | - // \TYPE not supported - TYPE - { - kjt = getJavaInfo().getJavaLangObject(); - } -; - -referencetype returns [KeYJavaType kjt = null] -{ - String n = null; -}: - n=name - { - kjt = getReferenceType(n); - } -; - -builtintype returns [KeYJavaType kjt = null] -{ - String type = null; -}: - ( - "byte" {type = "byte";} - | - "short" {type = "short";} - | - "int" {type = "int";} - | - "long" {type = "long";} - | - "boolean" {type = "boolean";} - | - "void" {type = "void";} - | - //no support for bigint yet - BIGINT {type = "long";} - | - REAL - { - throw new NotSupportedExpressionException("Type real"); - } - ) - { - kjt = getJavaInfo().getKeYJavaType(type); - if (kjt == null) { - throw new NotDeclException("type", type, getFilename(), getLine(), getColumn()); - } - } -; - -name returns [String s = null]: - id:IDENT {s=id.getText();} (DOT id2:IDENT {s+="."+id2.getText();})* -; - -quantifiedvariabledeclarator[KeYJavaType kjt] returns [LogicVariable v=null] -{ - int dim = 0; -}: - id:IDENT (dim=dims)? - { - if (dim != 0) { - kjt = getArrayTypeAndEnsureExistence(kjt.getSort(), dim); - final JavaInfo javaInfo = services.getJavaInfo(); - } - v = new LogicVariable(new ProgramElementName(id.getText()), kjt.getSort()); - } -; diff --git a/system/de/uka/ilkd/key/parser/keyparser.g b/system/de/uka/ilkd/key/parser/keyparser.g index a789338eecc..c9ee4d0a20e 100644 --- a/system/de/uka/ilkd/key/parser/keyparser.g +++ b/system/de/uka/ilkd/key/parser/keyparser.g @@ -36,16 +36,17 @@ header { import de.uka.ilkd.key.proof.*; import de.uka.ilkd.key.proof.init.*; - import de.uka.ilkd.key.proof.mgt.*; - import de.uka.ilkd.key.rule.*; import de.uka.ilkd.key.rule.conditions.*; import de.uka.ilkd.key.rule.metaconstruct.*; + + import de.uka.ilkd.key.speclang.SetAsListOfOperationContract; + import de.uka.ilkd.key.speclang.SetOfOperationContract; + import de.uka.ilkd.key.speclang.dl.translation.DLSpecFactory; import de.uka.ilkd.key.util.*; - import de.uka.ilkd.key.jml.*; import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.JavaReader; @@ -139,7 +140,7 @@ options { private ProgramMethod pm = null; private SetOfTaclet taclets = SetAsListOfTaclet.EMPTY_SET; - private ContractSet contracts = new ContractSet(); + private SetOfOperationContract contracts = SetAsListOfOperationContract.EMPTY_SET; private ParserConfig schemaConfig; private ParserConfig normalConfig; @@ -417,7 +418,7 @@ options { return taclets; } - public ContractSet getContracts(){ + public SetOfOperationContract getContracts(){ return contracts; } @@ -728,11 +729,6 @@ options { "you use an array or object type in a .key-file with missing " + "\\javaSource section."); } - result = getServices().getImplementation2SpecMap(). - lookupModelField(prefixKJT, attributeName); - if(result != null){ - return result; - } // WATCHOUT why not in DECLARATION MODE if(!isDeclParser()) { if (prefixSort == Sort.NULL) { @@ -952,7 +948,7 @@ options { private HashSet progVars(JavaBlock jb) { if(isGlobalDeclTermParser()) { ProgramVariableCollector pvc - = new ProgramVariableCollector(jb.program()); + = new ProgramVariableCollector(jb.program(), getServices()); pvc.start(); return pvc.result(); }else @@ -961,7 +957,7 @@ options { return new HashSet(); } DeclarationProgramVariableCollector pvc - = new DeclarationProgramVariableCollector(jb.program()); + = new DeclarationProgramVariableCollector(jb.program(), getServices()); pvc.start(); return pvc.result(); } @@ -1194,21 +1190,8 @@ options { break; } } - if(!result) { - JMLClassSpec cs = getServices().getImplementation2SpecMap().getSpecForClass(kjt); - if(cs != null){ - try { - cs.lookupModelMethod(new Name(LT(n+2).getText())); - result = true; - }catch(AmbigiousModelElementException e){ - result = false; - } - } - } } - }else{ - result = false; - } + } } catch (antlr.TokenStreamException tse) { // System.out.println("an exception occured"+tse); result = false; @@ -2904,25 +2887,8 @@ query [Term prefix] returns [Term result = null] if (argsWithBoundVars != null) { args = argsWithBoundVars.getTerms(); } - try{ - result = getServices().getJavaInfo().getProgramMethodTerm + result = getServices().getJavaInfo().getProgramMethodTerm (prefix, mid.getText(), args, classRef); - }catch(java.lang.IllegalArgumentException e){ - ProgramMethod pm = - getServices().getImplementation2SpecMap(). - lookupModelMethod( - getServices().getJavaInfo().getKeYJavaType(prefix.sort()), - new Name(mid.getText())); - if(pm == null){ - throw e; - } - Term[] argTerms = new Term[args.length + 1]; - argTerms[0] = prefix; - for(int i = 0; i= 0; - } - - - private String extractTypeName(String fullyQualifiedName) { - return fullyQualifiedName.substring(0, - fullyQualifiedName.indexOf("::")); - } - - - private String extractPropertyName(String fullyQualifiedName) { - return fullyQualifiedName.substring(fullyQualifiedName.indexOf("::")+2); - } - - - public OCLEntity resolve(OCLEntity receiver, - String name, - OCLParameters parameters) throws OCLTranslationError { - if(parameters == null || !parameters.getDeclaredVars().isEmpty()) { - return null; - } - - String containingName; - if(isFullyQualified(name)) { - containingName = extractTypeName(name); - name = extractPropertyName(name); - } else { - KeYJavaType containingType - = javaInfo.getKeYJavaType(receiver.getSort()); - if(containingType == null) { - return null; - } - containingName = containingType.getFullName(); - } - - Term[] args - = fbc.convertFormulasToBool(parameters.getEntities()).toArray(); - - Term recTerm = receiver.getTerm(); - KeYJavaType recType = receiver.getType(); - OCLCollection recCollection = receiver.getCollection(); - try { - if(recTerm != null || recType != null) { - - Term methodTerm = javaInfo.getProgramMethodTerm( - receiver.getTerm(), - name, - args, - containingName); - - return new OCLEntity(methodTerm); - } else if(recCollection != null) { - Term recVarTerm = recCollection.getPredVarAsTerm(); - Term methodTerm = javaInfo.getProgramMethodTerm( - recVarTerm, - name, - args, - containingName); - OCLCollection newCollection - = recCollection.collect(services, methodTerm); - return new OCLEntity(newCollection); - } - } catch(Exception e) { - if (e instanceof OCLTranslationError) { - throw (OCLTranslationError) e; - } - } - - return null; - } - - - public boolean needVarDeclaration(String propertyName) { - return false; - } -} diff --git a/system/de/uka/ilkd/key/parser/ocl/OCLEntity.java b/system/de/uka/ilkd/key/parser/ocl/OCLEntity.java deleted file mode 100644 index 0aa812b230f..00000000000 --- a/system/de/uka/ilkd/key/parser/ocl/OCLEntity.java +++ /dev/null @@ -1,124 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.parser.ocl; - -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.util.Debug; - - -/** - * A Term, a KeYJavaType, or an OCLCollection. - */ -class OCLEntity { - private final Term term; - private final KeYJavaType type; - private final OCLCollection collection; - - - public OCLEntity(Term term) { - Debug.assertTrue(term != null); - this.term = term; - this.type = null; - this.collection = null; - } - - - public OCLEntity(KeYJavaType type) { - Debug.assertTrue(type != null); - this.term = null; - this.type = type; - this.collection = null; - } - - - public OCLEntity(OCLCollection collection) { - Debug.assertTrue(collection != null); - this.term = null; - this.type = null; - this.collection = collection; - } - - - public boolean isTerm() { - return term != null; - } - - - public boolean isType() { - return type != null; - } - - - public boolean isCollection() { - return collection != null; - } - - - /** - * returns a collection containing only the element which is represented - * by the Term of this entity - * @throws OCLTranslationError - */ - public OCLEntity asCollection() throws OCLTranslationError { - return this.term != null ? new OCLEntity(new OCLCollection(this.term)) : null; - } - - - public Term getTerm() { - return term; - } - - - public KeYJavaType getType() { - return type; - } - - - public OCLCollection getCollection() { - return collection; - } - - - /** - * For types and terms, this method returns the corresponding sort. - * For collections it returns the sort of the elements, the collection - * contains. - * - * @return non-collection-sort of this entity - */ - public Sort getSort() { - Sort result; - - if(isType()) { - result = type.getSort(); - } else if(isTerm()) { - result = term.sort(); - } else { - result = collection.getElementSort(); - } - - return result; - } - - - public String toString() { - if(isTerm()) { - return term.toString(); - } else if(isType()) { - return type.toString(); - } else { - return collection.toString(); - } - } - -} diff --git a/system/de/uka/ilkd/key/parser/ocl/OCLTranslationError.java b/system/de/uka/ilkd/key/parser/ocl/OCLTranslationError.java deleted file mode 100644 index 86ecd9ab7a7..00000000000 --- a/system/de/uka/ilkd/key/parser/ocl/OCLTranslationError.java +++ /dev/null @@ -1,29 +0,0 @@ -package de.uka.ilkd.key.parser.ocl; - -import de.uka.ilkd.key.speclang.SLTranslationError; - -public class OCLTranslationError extends antlr.RecognitionException { - - String message = ""; - - - public OCLTranslationError(String msg) { - super(msg); - this.message = msg; - } - - public OCLTranslationError(String msg, int line, int col) { - super(msg, "", line, col); - this.message = msg; - } - - public String getMessage() { - return this.message; - } - - public SLTranslationError getSLTranslationError() { - SLTranslationError result = new SLTranslationError(message, getLine(), getColumn()); - result.setStackTrace(getStackTrace()); - return result; - } -} diff --git a/system/de/uka/ilkd/key/parser/ocl/PropertyManager.java b/system/de/uka/ilkd/key/parser/ocl/PropertyManager.java deleted file mode 100644 index c53312400d0..00000000000 --- a/system/de/uka/ilkd/key/parser/ocl/PropertyManager.java +++ /dev/null @@ -1,216 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.parser.ocl; - -import de.uka.ilkd.key.java.JavaInfo; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.IteratorOfLogicVariable; -import de.uka.ilkd.key.logic.op.IteratorOfParsableVariable; -import de.uka.ilkd.key.logic.op.ListOfLogicVariable; -import de.uka.ilkd.key.logic.op.ListOfParsableVariable; -import de.uka.ilkd.key.logic.op.ParsableVariable; -import de.uka.ilkd.key.logic.sort.ObjectSort; - - -/** - * Resolves property calls of any kind. - * Keeps a stack of namespaces to deal with several levels of local variables - * (e.g. "self", or iterator variables in forall() or select() subtrees). - */ -class PropertyManager { - - private static final TermBuilder tb = TermBuilder.DF; - - private final JavaInfo javaInfo; - private final ListOfPropertyResolver resolvers; - - private ListOfNamespace /*ParsableVariable*/ - localVariablesNamespaces = SLListOfNamespace.EMPTY_LIST; - - - public PropertyManager(Services services, FormulaBoolConverter fbc, ParsableVariable excVar) { - this.javaInfo = services.getJavaInfo(); - ListOfPropertyResolver list = SLListOfPropertyResolver.EMPTY_LIST; - list = list.prepend(new AssociationResolver(services)); - list = list.prepend(new BuiltInPropertyResolver(services, excVar)); - list = list.prepend(new MethodResolver(services, fbc)); - list = list.prepend(new AttributeResolver(services)); - resolvers = list; - } - - - /** - * Tries to resolve a name as a property call on an explicit receiver. - * @throws OCLTranslationError - */ - private OCLEntity resolveExplicit(OCLEntity receiver, - String name, - OCLParameters parameters) throws OCLTranslationError { - IteratorOfPropertyResolver it = resolvers.iterator(); - while(it.hasNext()) { - OCLEntity result = it.next().resolve(receiver, name, parameters); - if(result != null) { - return result; - } - } - return null; - } - - - /** - * Tries to resolve a name as a type. - */ - private OCLEntity resolveType(String name) { - try { - KeYJavaType kjt = javaInfo.getTypeByClassName(name); - if(kjt != null) { - return new OCLEntity(kjt); - } - } catch(RuntimeException e) { - // do nothing - } - return null; - } - - - /** - * Tries to resolve a name as a local variable. - */ - private OCLEntity resolveLocal(String name) { - Name n = new Name(name); - IteratorOfNamespace it = localVariablesNamespaces.iterator(); - while(it.hasNext()) { - ParsableVariable localVar = (ParsableVariable) it.next().lookup(n); - if(localVar != null) { - Term varTerm = tb.var(localVar); - return new OCLEntity(varTerm); - } - } - - return null; - } - - - /** - * Tries to resolve a name as a property call on any available implicit - * receiver. - * @throws OCLTranslationError - */ - private OCLEntity resolveImplicit(String name, OCLParameters parameters) throws OCLTranslationError { - IteratorOfNamespace it = localVariablesNamespaces.iterator(); - while(it.hasNext()) { - Namespace ns = it.next(); - ListOfNamed elements = ns.elements(); - - IteratorOfNamed it2 = elements.iterator(); - while(it2.hasNext()) { - ParsableVariable localVar = (ParsableVariable) it2.next(); - if(localVar.sort() instanceof ObjectSort) { - Term recTerm = tb.var(localVar); - OCLEntity result - = resolveExplicit(new OCLEntity(recTerm), - name, - parameters); - if(result != null) { - return result; - } - } - } - } - - return null; - } - - - /** - * Pushes a new, empty namespace onto the stack. - */ - public void pushLocalVariablesNamespace() { - Namespace ns = new Namespace(); - localVariablesNamespaces = localVariablesNamespaces.prepend(ns); - } - - - /** - * Puts a local variable into the topmost namespace on the stack - */ - public void putIntoTopLocalVariablesNamespace(ParsableVariable pv) { - localVariablesNamespaces.head().addSafely(pv); - } - - - /** - * Puts a list of local variables into the topmost namespace on the stack. - */ - public void putIntoTopLocalVariablesNamespace(ListOfLogicVariable pvs) { - IteratorOfLogicVariable it = pvs.iterator(); - while(it.hasNext()) { - localVariablesNamespaces.head().addSafely(it.next()); - } - } - - - /** - * Throws away the topmost namespace on the stack. - */ - public void popLocalVariablesNamespace() { - localVariablesNamespaces = localVariablesNamespaces.tail(); - } - - - /** - * Determines whether a variable has to be put into localVariableNamespace - * @param propertyName name of the propertyCall - * @return true, if propertyName needs a variable to be put into - * localVariableNamespace - */ - public boolean needVarDeclaration(String propertyName) { - IteratorOfPropertyResolver it = resolvers.iterator(); - while(it.hasNext()) { - if (it.next().needVarDeclaration(propertyName)) { - return true; - } - } - return false; - } - - - /** - * Resolves arbitrary property calls. - * @param receiver the specified explicit receiver, or null - * @param name name of the property - * @param parameters actual parameters of the property call, or null - * @return corresponding term, type or collection if successful, null - * otherwise - * @throws OCLTranslationError - */ - public OCLEntity resolve(OCLEntity receiver, - String name, - OCLParameters parameters) throws OCLTranslationError { - OCLEntity result = null; - - if(receiver != null) { - result = resolveExplicit(receiver, name, parameters); - } else { - result = resolveType(name); - if(result == null) { - result = resolveLocal(name); - if(result == null) { - result = resolveImplicit(name, parameters); - } - } - } - - return result; - } -} diff --git a/system/de/uka/ilkd/key/parser/ocl/PropertyResolver.java b/system/de/uka/ilkd/key/parser/ocl/PropertyResolver.java deleted file mode 100644 index 87c8bb088fe..00000000000 --- a/system/de/uka/ilkd/key/parser/ocl/PropertyResolver.java +++ /dev/null @@ -1,36 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.parser.ocl; - - - - -interface PropertyResolver { - - /** - * Resolves property calls on explicit receivers. - * @param receiver receiver (may *not* be null) - * @param name name of the property - * @param parameters the actual parameters, or null if not applicable - * @return a suitable term or collection if successful, null otherwise - */ - public OCLEntity resolve(OCLEntity receiver, - String name, - OCLParameters parameters) throws OCLTranslationError; - - /** - * Determines whether a propertyCall needs a declaration of a variable - * @param propertyName name of the propertyCall - * @return true, if propertyName needs a variable to be declarated - */ - public boolean needVarDeclaration(String propertyName); - -} diff --git a/system/de/uka/ilkd/key/parser/schemajava/SchemaJavaParser.jj b/system/de/uka/ilkd/key/parser/schemajava/SchemaJavaParser.jj index a0e83a3cc1d..193ad1a19f0 100644 --- a/system/de/uka/ilkd/key/parser/schemajava/SchemaJavaParser.jj +++ b/system/de/uka/ilkd/key/parser/schemajava/SchemaJavaParser.jj @@ -474,6 +474,7 @@ TOKEN : | < FINALLY: "finally" > | < FLOAT: "float" > | < FOR: "for" > + | < GHOST: "ghost" > | < GOTO: "goto" > | < IF: "if" > | < IMPLEMENTS: "implements" > @@ -513,6 +514,7 @@ TOKEN : | < TYPEOF: "#typeof" > | < SWITCHTOIF: "#switch-to-if" > | < UNPACK: "#unpack" > + | < SET: "#set" > } /* LITERALS */ @@ -3098,24 +3100,24 @@ Statement BlockStatement() : { (LOOKAHEAD([ "final" ] "(" ")") result = SVLocalVariableDeclaration() ";" - | LOOKAHEAD([ "final" ] ";" , + | LOOKAHEAD([ "final" | "ghost" ] ";" , { - isLocalVariable((getToken(1).kind == FINAL ? getToken(3) : getToken(2)).toString()) + isLocalVariable((getToken(1).kind == FINAL || getToken(1).kind == GHOST ? getToken(3) : getToken(2)).toString()) }) result = SVLocalVariableDeclaration() ";" - | LOOKAHEAD([ "final" ] "=" , + | LOOKAHEAD([ "final" | "ghost" ] "=" , { - isLocalVariable((getToken(1).kind == FINAL ? getToken(3) : getToken(2)).toString()) + isLocalVariable((getToken(1).kind == FINAL || getToken(1).kind == GHOST ? getToken(3) : getToken(2)).toString()) }) result = SVLocalVariableDeclaration() ";" - | LOOKAHEAD([ "final" ] Type() ";" , + | LOOKAHEAD([ "final" | "ghost" ] Type() ";" , { - isLocalVariable((getToken(1).kind == FINAL ? getToken(3) : getToken(2)).toString()) + isLocalVariable((getToken(1).kind == FINAL || getToken(1).kind == GHOST ? getToken(3) : getToken(2)).toString()) }) result = SVLocalVariableDeclaration() ";" - | LOOKAHEAD([ "final" ] Type() "=" , + | LOOKAHEAD([ "final" | "ghost" ] Type() "=" , { - isLocalVariable((getToken(1).kind == FINAL ? getToken(3) : getToken(2)).toString()) + isLocalVariable((getToken(1).kind == FINAL || getToken(1).kind == GHOST ? getToken(3) : getToken(2)).toString()) }) result = SVLocalVariableDeclaration() ";" | @@ -3182,6 +3184,13 @@ LocalVariableDeclaration SVLocalVariableDeclaration() : Final fi = factory.createFinal(); setPrefixInfo(fi); result.setModifiers(new ModifierArrayList(fi)); + } + | + "ghost" + { + Ghost g = new Ghost(); + setPrefixInfo(g); + result.setModifiers(new ModifierArrayList(g)); } ] (tr = TypeMC() | tr = TypeSV() | tr = Type() ) @@ -3249,6 +3258,17 @@ Expression StatementExpression() : ) ] ) + | ( + "#set" + result = PrimaryExpression() + "=" + expr = Expression() + { + op = new SetAssignment(result, expr); + testLeftHandSide(result); + result = op; + } + ) ) { checkConstruction(result); @@ -3463,7 +3483,20 @@ RKeYMetaConstruct KeYMetaConstructStatement() : return result; } ) - | + | +( "#for-to-while" "(" innerLabel = JumpLabelSV() "," outerLabel = JumpLabelSV() "," + ( stat = Statement() + ) ")" + { + result = factory.createRKeYMetaConstruct(); + setPrefixInfo(result); + result.setChild(stat); + result.addSV(innerLabel); + result.addSV(outerLabel); + result.setName("#for-to-while"); + return result; + } +) | "(" stat = Statement() ")" { result = factory.createRKeYMetaConstruct(); diff --git a/system/de/uka/ilkd/key/pp/LogicPrinter.java b/system/de/uka/ilkd/key/pp/LogicPrinter.java index 751d6d91799..96f0251a93c 100644 --- a/system/de/uka/ilkd/key/pp/LogicPrinter.java +++ b/system/de/uka/ilkd/key/pp/LogicPrinter.java @@ -62,19 +62,19 @@ public class LogicPrinter { public static final int DEFAULT_LINE_WIDTH = 55; /** The max. number of characters to put in one line */ - private int lineWidth = DEFAULT_LINE_WIDTH; + protected int lineWidth = DEFAULT_LINE_WIDTH; /** * The ProgramPrinter used to pretty-print Java blocks in * formulae. */ - private ProgramPrinter prgPrinter; + protected ProgramPrinter prgPrinter; /** Contains information on the concrete syntax of operators. */ private final NotationInfo notationInfo; /** the services object */ - private final Services services; + protected final Services services; /** The sequent we are pretty-printing */ //private Sequent seq; @@ -84,7 +84,7 @@ public class LogicPrinter { protected Layouter layouter; /** The backend layouter will write to. */ - private Backend backend; + protected Backend backend; /** The constraint used for metavariable instantiations of the * current formula */ @@ -100,7 +100,7 @@ public class LogicPrinter { are pretty-printed the right way. */ private boolean oclPrettyPrinting = false; - static Logger logger = Logger.getLogger(LogicPrinter.class.getName()); + protected static Logger logger = Logger.getLogger(LogicPrinter.class.getName()); public static String quickPrintLocationDescriptors( @@ -116,6 +116,20 @@ public static String quickPrintLocationDescriptors( } return p.result().toString(); } + + + public static String quickPrintTerm(Term t, Services services) { + LogicPrinter p = new LogicPrinter(null, + NotationInfo.createInstance(), + services); + try { + p.printTerm(t); + } catch (IOException ioe) { + return t.toString(); + } + return p.result().toString(); + } + /** * Creates a LogicPrinter. Sets the sequent to be printed, as @@ -933,10 +947,10 @@ public void printTerm(Term t) } /** - * Pretty-prints a list of terms. + * Pretty-prints a set of terms. * @param terms the terms to be printed */ - public void printTerm(ListOfTerm terms) + public void printTerm(SetOfTerm terms) throws IOException { getLayouter().print("{"); IteratorOfTerm it = terms.iterator(); @@ -1298,7 +1312,7 @@ private void printUpdateQuantification (Term t, } } - private void printVariables (ArrayOfQuantifiableVariable vars) + protected void printVariables (ArrayOfQuantifiableVariable vars) throws IOException { int size = vars.size (); if(size != 1) diff --git a/system/de/uka/ilkd/key/pp/Notation.java b/system/de/uka/ilkd/key/pp/Notation.java index 101499edc0b..2350cbbd4ad 100644 --- a/system/de/uka/ilkd/key/pp/Notation.java +++ b/system/de/uka/ilkd/key/pp/Notation.java @@ -320,7 +320,7 @@ public void print(Term t, LogicPrinter sp) throws IOException { /** * The standard concrete syntax for function and predicate terms. */ - static class Function extends Notation { + public static class Function extends Notation { public Function() { super(130); @@ -339,7 +339,7 @@ public void print(Term t, LogicPrinter sp) throws IOException { * The standard concrete syntax for a non rigid function with explicit * known dependencies. */ - static class NRFunctionWithDependenciesNotation extends Notation { + public static class NRFunctionWithDependenciesNotation extends Notation { public NRFunctionWithDependenciesNotation() { super(130); @@ -436,11 +436,36 @@ public void print(Term t, LogicPrinter sp) throws IOException { } } } + + //implemented by mbender for jmltest + public static class JMLProgramMethod extends Notation { + private final int ass; + + public JMLProgramMethod(int ass) { + super(130); + this.ass = ass; + } + + public void print(Term t, LogicPrinter sp) throws IOException { + if (sp.getNotationInfo().getAbbrevMap().isEnabled(t)) { + sp.printTerm(t); + } else if (((de.uka.ilkd.key.logic.op.ProgramMethod) t.op()) + .isStatic()) { + + sp.printFunctionTerm(t.op().name().toString().replaceAll("::", + "."), t); + } else { + final ProgramElementName name = (ProgramElementName) t.op() + .name(); + sp.printQueryTerm(name.getProgramName(), t, ass); + } + } + } /** * The standard concrete syntax for attribute terms o.a. */ - static class Attribute extends Notation { + public static class Attribute extends Notation { private int associativity; @@ -493,7 +518,7 @@ public void print(Term t, LogicPrinter sp) throws IOException { /** * The standard concrete syntax for attribute terms o.a. */ - static class ShadowAttribute extends Notation { + public static class ShadowAttribute extends Notation { private int associativity; @@ -517,7 +542,7 @@ public void print(Term t, LogicPrinter sp) throws IOException { * The standard concrete syntax for conditional terms * if (phi) (t1) (t2). */ - static class IfThenElse extends Notation { + public static class IfThenElse extends Notation { private final String keyword; @@ -538,7 +563,7 @@ public void print(Term t, LogicPrinter sp) throws IOException { /** * The standard concrete syntax for all kinds of variables. */ - static class VariableNotation extends Notation { + public static class VariableNotation extends Notation { public VariableNotation() { super(1000); } @@ -555,7 +580,7 @@ public void print(Term t, LogicPrinter sp) throws IOException { } } - static class SortedSchemaVariableNotation extends VariableNotation { + public static class SortedSchemaVariableNotation extends VariableNotation { static Logger logger = Logger.getLogger(Notation.class.getName()); public void print(Term t, LogicPrinter sp) throws IOException { @@ -600,7 +625,7 @@ public void print(Term t, LogicPrinter sp) throws IOException { } } - static class MetavariableNotation extends Notation { + public static class MetavariableNotation extends Notation { public MetavariableNotation() { super(1000); } diff --git a/system/de/uka/ilkd/key/pp/NotationInfo.java b/system/de/uka/ilkd/key/pp/NotationInfo.java index 06576334613..fd1fb517a83 100644 --- a/system/de/uka/ilkd/key/pp/NotationInfo.java +++ b/system/de/uka/ilkd/key/pp/NotationInfo.java @@ -111,12 +111,12 @@ public static final NotationInfo createInstance() { * a Notation registered. Otherwise, we see if there is one for the * class of the operator. */ - private HashMap tbl; + protected HashMap tbl; /** * Maps terms to abbreviations and reverse. */ - private AbbrevMap scm; + protected AbbrevMap scm; /** Create a new NotationInfo. Do not call this constructor @@ -135,7 +135,7 @@ public void setBackToDefault() { * abbreviations, and a set of Notations for the built-in operators * which corresponds to the parser syntax. */ - private void createDefaultNotationTable() { + protected void createDefaultNotationTable() { tbl=new HashMap(); createDefaultOpNotation(); createDefaultTermSymbolNotation(); @@ -146,7 +146,7 @@ private void createDefaultNotationTable() { * Registers notations for the built-in operators. The priorities * and associativities correspond to the parser syntax. */ - private void createDefaultOpNotation() { + protected void createDefaultOpNotation() { tbl.put(Op.TRUE ,new Notation.Constant("true", 130)); tbl.put(Op.FALSE,new Notation.Constant("false", 130)); tbl.put(Op.NOT,new Notation.Prefix("!" ,60,60)); @@ -185,7 +185,7 @@ private void createDefaultOpNotation() { * Register notations for standard classes of operators. This * includes Function operators, all kinds of variables, etc. */ - private void createDefaultTermSymbolNotation() { + protected void createDefaultTermSymbolNotation() { tbl.put(Function.class, new Notation.Function()); tbl.put(LogicVariable.class, new Notation.VariableNotation()); //tbl.put(SchemaVariable.class, new Notation.Variable()); diff --git a/system/de/uka/ilkd/key/pp/ProgramPrinter.java b/system/de/uka/ilkd/key/pp/ProgramPrinter.java index bbadfb0f1e5..0a97378d327 100644 --- a/system/de/uka/ilkd/key/pp/ProgramPrinter.java +++ b/system/de/uka/ilkd/key/pp/ProgramPrinter.java @@ -17,31 +17,28 @@ import de.uka.ilkd.key.java.PrettyPrinter; import de.uka.ilkd.key.rule.inst.SVInstantiations; - public class ProgramPrinter extends PrettyPrinter { - /** creates the program printer - * @param writer the Writer to print in, may be null. - */ - public ProgramPrinter(Writer writer) { - super(writer); - } - - public ProgramPrinter(Writer writer, SVInstantiations svi) { - super(writer, svi); - } - - public ProgramPrinter() { - super(null); - } + /** + * creates the program printer + * + * @param writer + * the Writer to print in, may be null. + */ + public ProgramPrinter(Writer writer) { + super(writer); + } + + public ProgramPrinter(Writer writer, SVInstantiations svi) { + super(writer, svi); + } + + public ProgramPrinter() { + super(null); + } + + public ProgramPrinter(Writer w, boolean b, + SVInstantiations instantiations) { + super(w,b,instantiations); + } } - - - - - - - - - - diff --git a/system/de/uka/ilkd/key/proof/AtPreFactory.java b/system/de/uka/ilkd/key/proof/AtPreFactory.java new file mode 100644 index 00000000000..2d45d22d566 --- /dev/null +++ b/system/de/uka/ilkd/key/proof/AtPreFactory.java @@ -0,0 +1,255 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.proof; + +import java.util.Iterator; +import java.util.Map; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.NamespaceSet; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.TermFactory; +import de.uka.ilkd.key.logic.UpdateFactory; +import de.uka.ilkd.key.logic.op.AccessOp; +import de.uka.ilkd.key.logic.op.ArrayOfQuantifiableVariable; +import de.uka.ilkd.key.logic.op.ArrayOp; +import de.uka.ilkd.key.logic.op.AttributeOp; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.logic.op.LogicVariable; +import de.uka.ilkd.key.logic.op.NonRigidFunctionLocation; +import de.uka.ilkd.key.logic.op.Operator; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.logic.sort.ArrayOfSort; +import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.rule.UpdateSimplifier; +import de.uka.ilkd.key.rule.updatesimplifier.Update; + + + +public class AtPreFactory { + + private static final TermBuilder TB = TermBuilder.DF; + + public static final AtPreFactory INSTANCE = new AtPreFactory(); + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + private AtPreFactory() { + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + /** + * Returns an available name constructed by affixing a counter to the passed + * base name. + */ + private String getNewName(String baseName, Services services) { + NamespaceSet namespaces = services.getNamespaces(); + + int i = 0; + String result; + do { + result = baseName + "_" + i++; + } while(namespaces.lookup(new Name(result)) != null); + + return result; + } + + + /** + * Returns the sort of the passed operator. + */ + private Sort getSort(Operator op) { + return op.sort(null); + } + + + /** + * Returns the argument sorts of the passed operator + * (why is that so complicated?). + */ + private ArrayOfSort getArgSorts(Operator op, Services services) { + if(op instanceof Function) { + return ((Function)op).argSort(); + } else if(op instanceof AttributeOp) { + AttributeOp aop = (AttributeOp) op; + + //HACK: Oddly, the length attribute is contained in a kjt "(SuperArray, null)", + //i.e. its argument does not have a sort. Therefore, we have to treat this case + //separately. + if(aop.attribute().equals(services.getJavaInfo() + .getArrayLength())) { + Sort objectSort + = services.getJavaInfo().getJavaLangObjectAsSort(); + return new ArrayOfSort(new Sort[]{objectSort}); + } + + Sort selfSort = aop.getContainerType().getSort(); + assert selfSort != null; + Sort[] argSorts = new Sort[] {selfSort}; + return new ArrayOfSort(argSorts); + } else if(op instanceof ArrayOp) { + ArrayOp aop = (ArrayOp) op; + Sort[] argSorts = new Sort[] {aop.arraySort(), + services.getTypeConverter() + .getIntLDT() + .targetSort()}; + return new ArrayOfSort(argSorts); + } else if(op instanceof ProgramVariable && op.arity() == 0) { + return new ArrayOfSort(); + } else { + assert false : "unexpected operator: " + op.name() + + " (" + op.getClass() + ")"; + return null; + } + } + + + /** + * Helper for buildAtPreDefinition(). + */ + private Term[] getTerms(ArrayOfQuantifiableVariable vars) { + int numVars = vars.size(); + Term[] result = new Term[numVars]; + + for(int i = 0; i < numVars; i++) { + LogicVariable var + = (LogicVariable)(vars.getQuantifiableVariable(i)); + result[i] = TB.var(var); + } + + return result; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + /** + * Creates an atPre-function for the passed operator, i.e., a new function + * symbol with the same signature. + */ + public Function createAtPreFunction(Operator normalOp, Services services) { + String atPreName = normalOp.name().toString() + "AtPre"; + if(atPreName.startsWith(".")) { + atPreName = atPreName.substring(1); + } + + Function result + = new NonRigidFunctionLocation(new Name(getNewName(atPreName, + services)), + getSort(normalOp), + getArgSorts(normalOp, + services)); + return result; + } + + + /** + * Creates atPre-functions for all relevant operators in the passed term. + */ + public void createAtPreFunctionsForTerm( + Term term, + /*inout*/ Map /*Operator (normal) + -> Function (atPre)*/ atPreFunctions, + Services services) { + int arity = term.arity(); + Sort[] subSorts = new Sort[arity]; + for(int i = 0; i < arity; i++) { + Term subTerm = term.sub(i); + createAtPreFunctionsForTerm(subTerm, atPreFunctions, services); + subSorts[i] = subTerm.sort(); + } + + if(term.op() instanceof AccessOp + || term.op() instanceof ProgramVariable + || term.op() instanceof ProgramMethod) { + Function atPreFunc = (Function)(atPreFunctions.get(term.op())); + if(atPreFunc == null) { + atPreFunc = AtPreFactory.INSTANCE.createAtPreFunction(term.op(), + services); + atPreFunctions.put(term.op(), atPreFunc); + } + } + } + + + /** + * Creates a definition for an atPre function. + */ + public Update createAtPreDefinition(Operator normalOp, + Function atPreFunc, + Services services) { + assert normalOp != null; + assert atPreFunc != null; + + int arity = normalOp.arity(); + assert arity == atPreFunc.arity(); + LogicVariable[] args = new LogicVariable[arity]; + if(arity == 1) { + args[0] = new LogicVariable(new Name("x"), atPreFunc.argSort(0)); + } else { + for(int i = 0; i < arity; i++) { + args[i] = new LogicVariable(new Name("x" + i), atPreFunc.argSort(i)); + } + } + + Term[] argTerms = getTerms(new ArrayOfQuantifiableVariable(args)); + Term atPreTerm = TB.func(atPreFunc, argTerms); + Term normalTerm = TermFactory.DEFAULT.createTerm( + normalOp, + argTerms, + (ArrayOfQuantifiableVariable)null, + null); + + UpdateFactory uf = new UpdateFactory(services, new UpdateSimplifier()); + Update result = uf.quantify(args, + uf.elementaryUpdate(atPreTerm, normalTerm)); + + return result; + } + + + /** + * Creates definitions for a set of atPre functions. + */ + public Update createAtPreDefinitions( + /*in*/ Map /*Operator (normal) -> Function (atPre)*/ atPreFunctions, + Services services) { + assert atPreFunctions != null; + + UpdateFactory uf = new UpdateFactory(services, new UpdateSimplifier()); + Update result = uf.skip(); + + Iterator it = atPreFunctions.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + Operator normalOp = (Operator) entry.getKey(); + Function atPreFunc = (Function) entry.getValue(); + Update def = createAtPreDefinition(normalOp, atPreFunc, services); + result = uf.parallel(result, def); + } + + return result; + } +} diff --git a/system/de/uka/ilkd/key/proof/BuiltInRuleAppIndex.java b/system/de/uka/ilkd/key/proof/BuiltInRuleAppIndex.java index b7680cdf772..5dd4d6f1adb 100644 --- a/system/de/uka/ilkd/key/proof/BuiltInRuleAppIndex.java +++ b/system/de/uka/ilkd/key/proof/BuiltInRuleAppIndex.java @@ -50,9 +50,7 @@ public ListOfRuleApp getBuiltInRule(Goal goal, BuiltInRule bir = it.next(); if (bir.isApplicable(goal, pos, userConstraint)) { RuleApp app = new BuiltInRuleApp(bir, pos, userConstraint); - if (goal.proof().mgt().ruleApplicable(app, goal)) { - result = result.prepend(app); - } + result = result.prepend(app); } } @@ -147,10 +145,8 @@ private void scanSimplificationRule ( BuiltInRule rule, final PosInOccurrence pos = new PosInOccurrence ( cfma, PosInTerm.TOP_LEVEL, antec ); if (rule.isApplicable ( goal, pos, userConstraint ) ) { - BuiltInRuleApp app = new BuiltInRuleApp(rule, pos, userConstraint ); - if (goal.proof().mgt().ruleApplicable(app, goal) ) { - listener.ruleAdded ( app, pos ); - } + BuiltInRuleApp app = new BuiltInRuleApp(rule, pos, userConstraint ); + listener.ruleAdded ( app, pos ); } } diff --git a/system/de/uka/ilkd/key/proof/Goal.java b/system/de/uka/ilkd/key/proof/Goal.java index 9fd872599e8..5fc0a228ff1 100644 --- a/system/de/uka/ilkd/key/proof/Goal.java +++ b/system/de/uka/ilkd/key/proof/Goal.java @@ -398,7 +398,8 @@ public void addNoPosTacletApp(NoPosTacletApp app) { */ public void addTaclet(Taclet rule, SVInstantiations insts, - Constraint constraint ) { + Constraint constraint, + boolean isAxiom) { NoPosTacletApp tacletApp = NoPosTacletApp.createFixedNoPosTacletApp(rule, insts, constraint); if (tacletApp != null) { @@ -406,7 +407,7 @@ public void addTaclet(Taclet rule, if (proof().env()!=null) { // do not break everything // because of ProofMgt proof().env().registerRuleIntroducedAtNode(tacletApp, - node.parent()); + node.parent(), isAxiom); } } } @@ -633,12 +634,7 @@ public ListOfGoal apply( RuleApp p_ruleApp ) { //System.err.println(Thread.currentThread()); final Proof proof = proof(); - - // TODO: this is maybe not the right place for this check - assert proof.mgt ().ruleApplicable ( p_ruleApp, this ) : - "Someone tried to apply the rule " + p_ruleApp + - " that is not justified"; - + final NodeChangeJournal journal = new NodeChangeJournal(proof, this); addGoalListener(journal); @@ -700,9 +696,7 @@ public void applyUpdateSimplifier (boolean antec) { BuiltInRuleApp app = new BuiltInRuleApp ( rule, pos, userConstraint ); - if (proof().mgt().ruleApplicable(app, this)) { - apply(app); - } + apply(app); } } } diff --git a/system/de/uka/ilkd/key/proof/LoopInvariantProposer.java b/system/de/uka/ilkd/key/proof/LoopInvariantProposer.java index 4bf0e3cb3b9..a777373aa1a 100644 --- a/system/de/uka/ilkd/key/proof/LoopInvariantProposer.java +++ b/system/de/uka/ilkd/key/proof/LoopInvariantProposer.java @@ -11,21 +11,30 @@ package de.uka.ilkd.key.proof; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; import de.uka.ilkd.key.collection.ListOfString; -import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.annotation.Annotation; -import de.uka.ilkd.key.java.annotation.LoopInvariantAnnotation; -import de.uka.ilkd.key.java.reference.*; +import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.SourceElement; +import de.uka.ilkd.key.java.StatementContainer; +import de.uka.ilkd.key.java.reference.ExecutionContext; +import de.uka.ilkd.key.java.reference.ReferencePrefix; +import de.uka.ilkd.key.java.reference.TypeReference; import de.uka.ilkd.key.java.statement.LoopStatement; import de.uka.ilkd.key.java.statement.MethodFrame; import de.uka.ilkd.key.java.visitor.JavaASTVisitor; import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.pp.*; -import de.uka.ilkd.key.rule.*; +import de.uka.ilkd.key.logic.op.IUpdateOperator; +import de.uka.ilkd.key.logic.op.SchemaVariable; +import de.uka.ilkd.key.pp.LogicPrinter; +import de.uka.ilkd.key.pp.NotationInfo; +import de.uka.ilkd.key.pp.ProgramPrinter; +import de.uka.ilkd.key.rule.IteratorOfRuleSet; +import de.uka.ilkd.key.rule.PosTacletApp; +import de.uka.ilkd.key.rule.Taclet; +import de.uka.ilkd.key.rule.TacletApp; +import de.uka.ilkd.key.speclang.LoopInvariant; + public class LoopInvariantProposer implements InstantiationProposer { @@ -33,104 +42,112 @@ public class LoopInvariantProposer implements InstantiationProposer { * An instance of LoopInvariantProposer */ public static final LoopInvariantProposer DEFAULT = new LoopInvariantProposer(); + + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + private LoopInvariantProposer() { + } + - /** - * Returns a proposal for the instantiation of var - * iff app is a TacletApp for a loop invariant taclet - * and var is the SchemaVariable representing the invariant - * and the loop on which the taclet matches contains a loop invariant - * annotation. Otherwise null is returned. - */ - public String getProposal(TacletApp app, - SchemaVariable var, - Services services, - Node undoAnchor, - ListOfString previousProposals){ - - final Object inst = tryToInstantiate(app, var, services); - final LogicPrinter lp = new LogicPrinter(new ProgramPrinter(null), - NotationInfo.createInstance(), - services); - String proposal; - try { - if (inst instanceof Term){ - lp.printTerm((Term) inst); - proposal = lp.toString(); - } else if (inst instanceof ListOfTerm){ - lp.printTerm((ListOfTerm) inst); - proposal = lp.toString(); - } else if (inst instanceof SetOfLocationDescriptor) { - lp.printLocationDescriptors((SetOfLocationDescriptor) inst); - proposal = lp.toString(); - } else if (var.name().toString().equals("#modifies")) { - lp.printLocationDescriptors( - SetAsListOfLocationDescriptor.EMPTY_SET - .add(EverythingLocationDescriptor.INSTANCE)); - proposal = lp.toString(); - } else { - proposal = null; - } - } catch (IOException e){ - proposal = null; - } - - return proposal; + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private LoopStatement getLoopHelp(ProgramElement pe){ + if(pe instanceof LoopStatement){ + return (LoopStatement) pe; + } else if(pe instanceof StatementContainer){ + return getLoopHelp(((StatementContainer) pe).getStatementAt(0)); + } else { + assert false; + return null; + } } + + + private LoopStatement getFirstLoopStatement(Term t){ + while(t.op() instanceof IUpdateOperator){ + t = ( (IUpdateOperator)t.op () ).target ( t ); + } + return getLoopHelp(t.javaBlock().program()); + } + + + private LoopInvariant getLoopInvariant(Term t, Services services) { + LoopStatement loop = getFirstLoopStatement(t); + return services.getSpecificationRepository().getLoopInvariant(loop); + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- /** * returns true if the rulesets contain the rule set loop invariant */ - public static boolean inLoopInvariantRuleSet(IteratorOfRuleSet ruleSets) { - while (ruleSets.hasNext()) { - if (ruleSets.next().name().toString().equals("loop_invariant_proposal")) { + public boolean inLoopInvariantRuleSet(Taclet taclet) { + if(taclet == null) { + return true; + } + IteratorOfRuleSet it = taclet.ruleSets(); + while(it.hasNext()) { + if(it.next().name().toString().equals("loop_invariant_proposal")) { return true; } } return false; } - - private static Term getSelfTerm(Term term, Services services) { - final Services serv = services; + /** + * Returns the receiver term of the innermost method frame of + * the java block of the passed term, or null if the innermost + * frame is that of a static method. + * @param term A term of the form "{u}[p]psi" + * @param services The services object. + */ + public Term getInnermostSelfTerm(Term term, Services services) { + //ignore updates + while(term.op() instanceof IUpdateOperator) { + term = term.sub(((IUpdateOperator)term.op()).targetPos()); + } - //ignore updates - while(term.op() instanceof IUpdateOperator) { - term = term.sub(((IUpdateOperator)term.op()).targetPos()); - } - - //the remaining term should contain a program - //(because this method is only called for apps of taclets - //in "loop_invariant_proposal") - final ProgramElement pe = term.javaBlock().program(); - - //fetch "self" from innermost non-static method-frame - Term result = new JavaASTVisitor(pe) { - private Term result; - protected void doAction(ProgramElement node) { - node.visit(this); - } - protected void doDefaultAction(SourceElement node) { - if(node instanceof MethodFrame && result == null) { - MethodFrame mf = (MethodFrame) node; - ExecutionContext ec - = (ExecutionContext) mf.getExecutionContext(); - ReferencePrefix rp = ec.getRuntimeInstance(); - if(!(rp instanceof TypeReference) && rp !=null) { - result = serv.getTypeConverter().convertToLogicElement(rp); + //the remaining term should have a Java block + final ProgramElement pe = term.javaBlock().program(); + + //fetch "self" from innermost method-frame + Term result = new JavaASTVisitor(pe, services) { + private Term result; + private boolean done = false; + protected void doDefaultAction(SourceElement node) { + if(node instanceof MethodFrame && !done) { + done = true; + MethodFrame mf = (MethodFrame) node; + ExecutionContext ec + = (ExecutionContext) mf.getExecutionContext(); + ReferencePrefix rp = ec.getRuntimeInstance(); + if(!(rp instanceof TypeReference) && rp != null) { + result = services.getTypeConverter() + .convertToLogicElement(rp); } - } - } - public Term run() { - walk(pe); - return result; - } - }.run(); - - return result; + } + } + public Term run() { + walk(pe); + return result; + } + }.run(); + + return result; } - + /** * Returns an instantiation of var * iff app is a TacletApp for a loop invariant taclet @@ -140,82 +157,80 @@ public Term run() { * Depending if the var looked for is a list schemavariable or a normal sv * a list of terms or a term is returned */ - public Object tryToInstantiate(TacletApp app, SchemaVariable var, Services services){ + public Object tryToInstantiate(TacletApp app, + SchemaVariable var, + Services services) { Object inst = null; - if (app instanceof PosTacletApp && - inLoopInvariantRuleSet(app.taclet().ruleSets())) { - final PosInOccurrence pos = ((PosTacletApp) app).posInOccurrence(); - final LoopInvariantAnnotation firstLoopInvAnnot = - getFirstLoopInvariantAnnotation(pos.subTerm()); - if(firstLoopInvAnnot == null) { - return null; - } - - //prepare replacing the loop invariant's "self"-variable - //by the current "self" term - final Term selfTerm = getSelfTerm(pos.subTerm(), services); - Map map = new HashMap(); - map.put(TermBuilder.DF.var(firstLoopInvAnnot.getSelfVar()), - selfTerm); - OpReplacer or = new OpReplacer(map); - - //determine instantiation + if (app instanceof PosTacletApp + && inLoopInvariantRuleSet(app.taclet())) { + final PosInOccurrence pos = ((PosTacletApp) app).posInOccurrence(); + final LoopInvariant inv = getLoopInvariant(pos.subTerm(), services); + if(inv == null) { + return null; + } + + //determine instantiation + final Term selfTerm = getInnermostSelfTerm(pos.subTerm(), services); final String varName = var.name().toString(); - if (varName.equals("inv") - && firstLoopInvAnnot.invariant() != null) { - inst = or.replace(firstLoopInvAnnot.invariant()); - } else if(varName.equals("#modifies") - && firstLoopInvAnnot.assignable() != null) { - inst = or.replace(firstLoopInvAnnot.assignable()); - } else if(var.name().toString().equals("post") - && firstLoopInvAnnot.post() != null) { - inst = or.replace(firstLoopInvAnnot.post()); - } else if(varName.equals("variant") - && firstLoopInvAnnot.variant() != null) { - inst = or.replace(firstLoopInvAnnot.variant()); - } else if(varName.equals("#old")) { - inst = convertToListOfTerm(firstLoopInvAnnot.olds()); - } - } - - return inst; - } - - - private LoopInvariantAnnotation getFirstLoopInvariantAnnotation(Term t) { - final Annotation[] a = getFirstLoopStatement(t).getAnnotations(); - - for(int i = 0; i=0; i--) { - result = result.prepend(array.getTerm(i)); - } - return result; - } - - private LoopStatement getFirstLoopStatement(Term t){ - while(t.op() instanceof IUpdateOperator){ - t = ( (IUpdateOperator)t.op () ).target ( t ); - } - return getLoopHelp(t.javaBlock().program()); - } - - private LoopStatement getLoopHelp(ProgramElement pe){ - if(pe instanceof LoopStatement){ - return (LoopStatement) pe; - } - if(pe instanceof StatementContainer){ - return getLoopHelp(((StatementContainer) pe).getStatementAt(0)); + + /** + * Returns a proposal for the instantiation of var + * iff app is a TacletApp for a loop invariant taclet + * and var is the SchemaVariable representing the invariant + * and the loop on which the taclet matches contains a loop invariant + * annotation. Otherwise null is returned. + */ + public String getProposal(TacletApp app, + SchemaVariable var, + Services services, + Node undoAnchor, + ListOfString previousProposals){ + + final Object inst = tryToInstantiate(app, + var, + services); + final LogicPrinter lp = new LogicPrinter(new ProgramPrinter(null), + NotationInfo.createInstance(), + services); + + String proposal; + try { + if (inst instanceof Term){ + lp.printTerm((Term) inst); + proposal = lp.toString(); + } else if (inst instanceof SetOfTerm){ + lp.printTerm((SetOfTerm) inst); + proposal = lp.toString(); + } else if (inst instanceof SetOfLocationDescriptor) { + lp.printLocationDescriptors((SetOfLocationDescriptor) inst); + proposal = lp.toString(); + } else { + proposal = null; + } + } catch (IOException e){ + proposal = null; } - //shouldn't happen. - return null; + + return proposal; } } diff --git a/system/de/uka/ilkd/key/proof/OpReplacer.java b/system/de/uka/ilkd/key/proof/OpReplacer.java index 64fb8f0f8e8..ec8ad7c1fa7 100644 --- a/system/de/uka/ilkd/key/proof/OpReplacer.java +++ b/system/de/uka/ilkd/key/proof/OpReplacer.java @@ -10,22 +10,30 @@ package de.uka.ilkd.key.proof; +import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import de.uka.ilkd.key.logic.BasicLocationDescriptor; +import de.uka.ilkd.key.logic.EverythingLocationDescriptor; import de.uka.ilkd.key.logic.IteratorOfLocationDescriptor; +import de.uka.ilkd.key.logic.IteratorOfTerm; import de.uka.ilkd.key.logic.LocationDescriptor; import de.uka.ilkd.key.logic.SetAsListOfLocationDescriptor; +import de.uka.ilkd.key.logic.SetAsListOfTerm; import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.logic.SetOfTerm; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.TermFactory; import de.uka.ilkd.key.logic.op.ArrayOfQuantifiableVariable; import de.uka.ilkd.key.logic.op.Operator; +import de.uka.ilkd.key.speclang.FormulaWithAxioms; /** * Replaces operators in a term by other operators with the same signature, - * or subterms of the term by other terms with the same sort. + * or subterms of the term by other terms with the same sort. Does not + * replace in java blocks. */ public class OpReplacer { private static final TermFactory TF = TermFactory.DEFAULT; @@ -43,19 +51,33 @@ public OpReplacer(Map /*Operator -> Operator, Term -> Term*/ map) { } + /** + * Replaces in an operator. + */ + public Operator replace(Operator op) { + Operator newOp = (Operator) map.get(op); + if(newOp != null) { + return newOp; + } else { + return op; + } + } + + /** * Replaces in a term. */ public Term replace(Term term) { + if(term == null) { + return null; + } + Term newTerm = (Term) map.get(term); if(newTerm != null) { return newTerm; } - - Operator newOp = (Operator) map.get(term.op()); - if(newOp == null) { - newOp = term.op(); - } + + Operator newOp = replace(term.op()); int arity = term.arity(); Term newSubTerms[] = new Term[arity]; @@ -85,16 +107,33 @@ public Term replace(Term term) { return result; } + + /** + * Replaces in a set of terms. + */ + public SetOfTerm replace(SetOfTerm terms) { + SetOfTerm result = SetAsListOfTerm.EMPTY_SET; + IteratorOfTerm it = terms.iterator(); + while(it.hasNext()) { + result = result.add(replace(it.next())); + } + return result; + } + + /** * Replaces in a location descriptor. */ public LocationDescriptor replace(LocationDescriptor loc) { - if(loc instanceof BasicLocationDescriptor) { + if(loc == null) { + return null; + } else if(loc instanceof BasicLocationDescriptor) { BasicLocationDescriptor bloc = (BasicLocationDescriptor) loc; return new BasicLocationDescriptor(replace(bloc.getFormula()), replace(bloc.getLocTerm())); } else { + assert loc instanceof EverythingLocationDescriptor; return loc; } } @@ -112,4 +151,32 @@ public SetOfLocationDescriptor replace(SetOfLocationDescriptor locs) { } return result; } + + + /** + * Replaces in a map from Operator to Term. + */ + public Map /*Operator -> Term*/ replace( + /*in*/ Map /*Operator -> Term */ map) { + Map result = new HashMap(); + + Iterator it = map.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + Operator op = (Operator) entry.getKey(); + Term term = (Term) entry.getValue(); + result.put(replace(op), replace(term)); + } + + return result; + } + + + /** + * Replaces in a FormulaWithAxioms. + */ + public FormulaWithAxioms replace(FormulaWithAxioms fwa) { + return new FormulaWithAxioms(replace(fwa.getFormula()), + replace(fwa.getAxioms())); + } } diff --git a/system/de/uka/ilkd/key/proof/ProblemLoader.java b/system/de/uka/ilkd/key/proof/ProblemLoader.java index a101fd8a553..ed17008f940 100644 --- a/system/de/uka/ilkd/key/proof/ProblemLoader.java +++ b/system/de/uka/ilkd/key/proof/ProblemLoader.java @@ -29,8 +29,13 @@ import de.uka.ilkd.key.pp.AbbrevMap; import de.uka.ilkd.key.pp.PresentationFeatures; import de.uka.ilkd.key.proof.init.*; -import de.uka.ilkd.key.proof.mgt.OldOperationContract; +import de.uka.ilkd.key.proof.mgt.ContractWithInvs; +import de.uka.ilkd.key.proof.mgt.SpecificationRepository; import de.uka.ilkd.key.rule.*; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.SLEnvInput; +import de.uka.ilkd.key.speclang.SetAsListOfClassInvariant; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; import de.uka.ilkd.key.util.ExceptionHandlerException; import de.uka.ilkd.key.util.KeYExceptionHandler; import de.uka.ilkd.key.proof.decproc.DecisionProcedureSmtAuflia; @@ -50,7 +55,7 @@ public class ProblemLoader implements Runnable { String currTacletName = null; int currFormula = 0; PosInTerm currPosInTerm = PosInTerm.TOP_LEVEL; - OldOperationContract currContract = null; + ContractWithInvs currContract = null; Stack stack = new Stack(); LinkedList loadedInsts = null; ListOfIfFormulaInstantiation ifSeqFormulaList = @@ -135,29 +140,25 @@ public void finished() { * @throws IllegalArgumentException if the user has selected a file with an unsupported extension * an exception is thrown to indicate this */ - protected KeYUserProblemFile createProblemFile(File file) + protected EnvInput createEnvInput(File file) throws FileNotFoundException { final String filename = file.getName(); if (filename.endsWith(".java")){ - // java file, probably enriched by JML specifications - return new KeYJMLInput(filename, file, - profile instanceof JavaTestGenerationProfile, - main.getProgressMonitor()); + // java file, probably enriched by specifications + return new SLEnvInput(file.getParentFile().getAbsolutePath()); } else if (filename.endsWith(".key") || filename.endsWith(".proof")) { // KeY problem specification or saved proof return new KeYUserProblemFile(filename, file, - main.getProgressMonitor(), Main.jmlSpecs); + main.getProgressMonitor(), Main.enableSpecs); } else if (file.isDirectory()){ - // directory containing JML-enriched java sources - // prompt the - return new JavaInputWithJMLSpecBrowser(file.getPath(), file, - profile instanceof JavaTestGenerationProfile, - main.getProgressMonitor()); + // directory containing java sources, probably enriched + // by specifications + return new SLEnvInput(file.getPath()); } else { if (filename.lastIndexOf('.') != -1) { throw new IllegalArgumentException @@ -175,13 +176,30 @@ protected KeYUserProblemFile createProblemFile(File file) private Object doWork() { String status = ""; - KeYUserProblemFile problemFile = null; + ProofOblInput po = null; try{ try{ if (!keepProblem) { - problemFile = createProblemFile(file); - init = new ProblemInitializer(main); - init.startProver(problemFile, problemFile); + EnvInput envInput = createEnvInput(file); + init = new ProblemInitializer(main); + InitConfig initConfig = init.prepare(envInput); + + if(envInput instanceof ProofOblInput + && !(envInput instanceof KeYFile + && ((KeYFile) envInput).chooseContract())) { + po = (ProofOblInput) envInput; + } else { + if(envInput instanceof KeYFile) { + initConfig.setOriginalKeYFileName(envInput.name()); + } + POBrowser poBrowser = new POBrowser(initConfig); + po = poBrowser.getPO(); + if(po == null) { + return "Aborted."; + } + } + + init.startProver(initConfig, po); } proof = mediator.getSelectedProof(); mediator.stopInterface(true); // first stop (above) is not enough @@ -191,7 +209,7 @@ private Object doWork() { children = currNode.childrenIterator(); // --"-- iconfig = proof.env().getInitConfig(); if (!keepProblem) { - init.tryReadProof(this, problemFile); + init.tryReadProof(this, po); } else { main.setStatusLine("Loading proof", (int)file.length()); CountingBufferedInputStream cinp = @@ -226,8 +244,8 @@ private Object doWork() { status = ex.toString(); } finally { - if (problemFile != null && problemFile instanceof KeYUserProblemFile){ - ((KeYUserProblemFile) problemFile).close(); + if (po != null && po instanceof KeYUserProblemFile){ + ((KeYUserProblemFile) po).close(); } } return status; @@ -315,8 +333,10 @@ public void beginExpr(char id, String s) { currPosInTerm = PosInTerm.TOP_LEVEL; break; case 'c' : //contract - currContract = (OldOperationContract) proof.getServices() - .getSpecificationRepository().getContractByName(s); + currContract = new ContractWithInvs(s, proof.getServices()); + if(currContract == null) { + throw new RuntimeException("Error loading proof: contract \"" + s + "\" not found."); + } break; } } @@ -396,8 +416,9 @@ private BuiltInRuleApp constructBuiltinApp() .getConstraint(); if (currContract!=null) { - ourApp = new MethodContractRuleApp(UseMethodContractRule.INSTANCE, - pos, userConstraint, currContract); + ourApp = new UseOperationContractRuleApp(pos, + userConstraint, + currContract); currContract=null; return ourApp; } @@ -410,7 +431,7 @@ private BuiltInRuleApp constructBuiltinApp() throw new BuiltInConstructionException (currTacletName + " is missing. Most probably the binary "+ - "for this built-in rule ist not in your path or " + + "for this built-in rule is not in your path or " + "you do not have the permission to execute it."); } else { throw new BuiltInConstructionException diff --git a/system/de/uka/ilkd/key/proof/ProgVarReplacer.java b/system/de/uka/ilkd/key/proof/ProgVarReplacer.java index 411c90954fe..d6a72fda05c 100644 --- a/system/de/uka/ilkd/key/proof/ProgVarReplacer.java +++ b/system/de/uka/ilkd/key/proof/ProgVarReplacer.java @@ -22,6 +22,7 @@ import de.uka.ilkd.key.java.ArrayOfProgramElement; import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.Statement; import de.uka.ilkd.key.java.StatementBlock; import de.uka.ilkd.key.java.visitor.ProgVarReplaceVisitor; @@ -40,15 +41,22 @@ public class ProgVarReplacer { /** * map specifying the replacements to be done */ - protected final Map map; + private final Map map; + + + /** + * The services object + */ + private final Services services; /** * creates a ProgVarReplacer that replaces program variables as specified * by the map parameter */ - public ProgVarReplacer(Map m) { - map = m; + public ProgVarReplacer(Map map, Services services) { + this.map = map; + this.services = services; } @@ -398,7 +406,10 @@ public LocationDescriptor replace(LocationDescriptor loc) { * replaces in a statement */ public ProgramElement replace(ProgramElement pe) { - ProgVarReplaceVisitor pvrv = new ProgVarReplaceVisitor(pe, map, false); + ProgVarReplaceVisitor pvrv = new ProgVarReplaceVisitor(pe, + map, + false, + services); pvrv.start(); return pvrv.result(); } diff --git a/system/de/uka/ilkd/key/proof/Proof.java b/system/de/uka/ilkd/key/proof/Proof.java index b5dee38b92a..82b42b15464 100644 --- a/system/de/uka/ilkd/key/proof/Proof.java +++ b/system/de/uka/ilkd/key/proof/Proof.java @@ -21,9 +21,11 @@ import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.*; +import de.uka.ilkd.key.logic.op.ProgramMethod; import de.uka.ilkd.key.pp.AbbrevMap; import de.uka.ilkd.key.proof.init.InitConfig; import de.uka.ilkd.key.proof.init.Profile; +import de.uka.ilkd.key.proof.init.SpecExtPO; import de.uka.ilkd.key.proof.mgt.BasicTask; import de.uka.ilkd.key.proof.mgt.DefaultProofCorrectnessMgt; import de.uka.ilkd.key.proof.mgt.ProofCorrectnessMgt; @@ -110,12 +112,14 @@ public class Proof implements Named { private Strategy activeStrategy; +// implemented by mbender for jmltest + private SpecExtPO specExtPO; /** constructs a new empty proof with name */ private Proof(Name name, Services services, ProofSettings settings) { - this.name = name; + this.name = name; assert services != null : "Tried to create proof without valid services."; - this.services = services.copyProofSpecific(); + this.services = services.copyProofSpecific(this); this.settings = settings; metavariableDeliverer = new MetavariableDeliverer ( this ); @@ -791,11 +795,6 @@ public void setRuleAppIndexToInteractiveMode () { } } - public void addRuleSource(RuleSource src) { - problemHeader += src.getInclusionString()+"\n"; - } - - /** * retrieves number of branches @@ -823,5 +822,26 @@ public String toString() { return result.toString(); } + // implemented by mbender for jmltest + + /** + * This method is just used for jmltest + * + * @param specExtPO + * The Specification Extraction Proof Obligation to be set + */ + public void setPO(SpecExtPO specExtPO) { + this.specExtPO = specExtPO; + } + + /** + * This method is just used for jmltest + * + * @return The Specification Extraction Proof Obligation used for this proof + */ + public SpecExtPO getPO() { + return specExtPO; + } + } diff --git a/system/de/uka/ilkd/key/proof/ProofSaver.java b/system/de/uka/ilkd/key/proof/ProofSaver.java index 4413d649957..cbd29466270 100644 --- a/system/de/uka/ilkd/key/proof/ProofSaver.java +++ b/system/de/uka/ilkd/key/proof/ProofSaver.java @@ -29,6 +29,7 @@ import de.uka.ilkd.key.pp.NotationInfo; import de.uka.ilkd.key.pp.PresentationFeatures; import de.uka.ilkd.key.pp.ProgramPrinter; +import de.uka.ilkd.key.proof.mgt.RuleJustificationBySpec; import de.uka.ilkd.key.rule.*; import de.uka.ilkd.key.rule.inst.*; @@ -163,12 +164,19 @@ private void printSingleNode(Node node, String prefix, StringBuffer tree) { tree.append("\""); tree.append(posInOccurrence2Proof(node.sequent(), appliedRuleApp.posInOccurrence())); - if (appliedRuleApp instanceof MethodContractRuleApp) { + + if (appliedRuleApp.rule() instanceof UseOperationContractRule) { + RuleJustificationBySpec ruleJusti = (RuleJustificationBySpec) + proof.env().getJustifInfo() + .getJustification(appliedRuleApp, + proof.getServices()); + tree.append(" (contract \""); - tree.append(((MethodContractRuleApp)appliedRuleApp).getMethodContract().getName()); + tree.append(ruleJusti.getSpec().toString()); tree.append("\")"); } - tree.append(")\n"); + + tree.append(")\n"); } } diff --git a/system/de/uka/ilkd/key/proof/RuleTreeModel.java b/system/de/uka/ilkd/key/proof/RuleTreeModel.java index a8ec3588bba..0139c15410b 100644 --- a/system/de/uka/ilkd/key/proof/RuleTreeModel.java +++ b/system/de/uka/ilkd/key/proof/RuleTreeModel.java @@ -6,15 +6,6 @@ // The KeY system is protected by the GNU General Public License. // See LICENSE.TXT for details. // -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2004 Universitaet Karlsruhe, Germany -//Universitaet Koblenz-Landau, Germany -//Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// package de.uka.ilkd.key.proof; @@ -25,37 +16,26 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.MutableTreeNode; -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.proof.mgt.Contract; import de.uka.ilkd.key.proof.mgt.ProofCorrectnessMgt; import de.uka.ilkd.key.proof.mgt.RuleJustification; -import de.uka.ilkd.key.proof.mgt.RuleJustificationBySpec; import de.uka.ilkd.key.rule.*; public class RuleTreeModel extends DefaultTreeModel { protected Goal goal; - protected MutableTreeNode axiomTacletRoot - = new DefaultMutableTreeNode("Taclet Base"); protected MutableTreeNode builtInRoot = new DefaultMutableTreeNode("Built-In"); - protected MutableTreeNode lemmaRoot = new DefaultMutableTreeNode("Lemmas"); - protected MutableTreeNode methcontrRoot - = new DefaultMutableTreeNode("Method Contracts"); - protected MutableTreeNode contrRoot - = new DefaultMutableTreeNode("DL Contracts"); + protected MutableTreeNode axiomTacletRoot + = new DefaultMutableTreeNode("Taclet Base"); protected MutableTreeNode proveableTacletsRoot - = new DefaultMutableTreeNode("Auxiliary Taclets"); + = new DefaultMutableTreeNode("Lemmas"); public RuleTreeModel(Goal g) { super(new DefaultMutableTreeNode("Rule Base")); this.goal = g; insertAsLast(builtInRoot, (MutableTreeNode) getRoot()); insertAsLast(axiomTacletRoot, (MutableTreeNode) getRoot()); - insertAsLast(lemmaRoot, (MutableTreeNode) getRoot()); - insertAsLast(proveableTacletsRoot, lemmaRoot); - insertAsLast(methcontrRoot, lemmaRoot); - insertAsLast(contrRoot, lemmaRoot); + insertAsLast(proveableTacletsRoot, (MutableTreeNode) getRoot()); if (g!=null) rulesForGoal(g); } @@ -110,24 +90,11 @@ private void rulesForGoal(Goal g) { RuleJustification just = mgt().getJustification(app); if (just==null) continue; // do not break system because of this if (just.isAxiomJustification()) { - insertAndGroup(new DefaultMutableTreeNode - (app.taclet()), - axiomTacletRoot); - } else if (just instanceof RuleJustificationBySpec) { - RuleJustificationBySpec specJust - = (RuleJustificationBySpec) just; - Contract ct = specJust.getContract(); - if (ct.getObjectOfContract() instanceof ModelMethod) { - insertMethodNodeInto((ModelMethod) - ct.getObjectOfContract(), ct); - } else if (ct.getObjectOfContract() instanceof NoPosTacletApp) { - insertAndGroup - (new DefaultMutableTreeNode(app.taclet()), - proveableTacletsRoot); - } else { - insertAsLast - (new DefaultMutableTreeNode(ct), contrRoot); - } + insertAndGroup(new DefaultMutableTreeNode(app.taclet()), + axiomTacletRoot); + } else { + insertAndGroup(new DefaultMutableTreeNode(app.taclet()), + proveableTacletsRoot); } } } @@ -149,21 +116,6 @@ public int compare(Object o1, Object o2) { return l; } - private void insertMethodNodeInto(ModelMethod meth, Contract ct) { - MutableTreeNode methNode = null; - for (int i=0; i Term*/ axioms = new LinkedHashMap(); + private String header; + private ProofAggregate proofAggregate; - private final String name; - protected final ModelClass modelClass; + protected Term[] poTerms; + protected String[] poNames; + protected SetOfTaclet[] poTaclets; - protected InitConfig initConfig = null; - protected Services services = null; - protected JavaInfo javaInfo = null; - - private Map /*Operator -> Term*/ axioms = new HashMap(); - private String header = null; - private ProofAggregate proofAggregate = null; - - protected Term[] poTerms = null; - protected String[] poNames = null; - protected SetOfTaclet[] poTaclets = null; //------------------------------------------------------------------------- //constructors //------------------------------------------------------------------------- - public AbstractPO(String name, - ModelClass modelClass) { + public AbstractPO(InitConfig initConfig, String name, KeYJavaType selfKJT) { + this.initConfig = initConfig; + this.services = initConfig.getServices(); + this.javaInfo = initConfig.getServices().getJavaInfo(); + this.specRepos = initConfig.getServices().getSpecificationRepository(); + this.uf = new UpdateFactory(services, new UpdateSimplifier()); this.name = name; - this.modelClass = modelClass; + this.selfKJT = selfKJT; } //------------------------------------------------------------------------- @@ -70,34 +96,30 @@ public AbstractPO(String name, //------------------------------------------------------------------------- protected ProgramVariable buildSelfVarAsProgVar() { - String className = modelClass.getFullClassName(); - KeYJavaType classType = javaInfo.getTypeByClassName(className); - ProgramElementName classPEN = new ProgramElementName("self"); - - return new LocationVariable(classPEN, classType); + ProgramVariable result = new LocationVariable(classPEN, selfKJT); + return result; } protected LogicVariable buildSelfVarAsLogicVar() { - String className = modelClass.getFullClassName(); - KeYJavaType classType = javaInfo.getTypeByClassName(className); - ProgramElementName classPEN = new ProgramElementName("self"); - return new LogicVariable(classPEN, classType.getSort()); + LogicVariable result = new LogicVariable(classPEN, selfKJT.getSort()); + return result; } - protected ListOfProgramVariable buildParamVars(ModelMethod modelMethod) { - int numPars = modelMethod.getNumParameters(); + protected ListOfProgramVariable buildParamVars(ProgramMethod programMethod) { + int numPars = programMethod.getParameterDeclarationCount(); ListOfProgramVariable result = SLListOfProgramVariable.EMPTY_LIST; for(int i = 0; i < numPars; i++) { - KeYJavaType parType - = javaInfo.getTypeByClassName(modelMethod.getParameterTypeAt(i)); + KeYJavaType parType = programMethod.getParameterType(i); assert parType != null; - ProgramElementName parPEN - = new ProgramElementName(modelMethod.getParameterNameAt(i)); + String parName = programMethod.getParameterDeclarationAt(i) + .getVariableSpecification() + .getName(); + ProgramElementName parPEN = new ProgramElementName(parName); result = result.append(new LocationVariable(parPEN, parType)); } @@ -105,15 +127,13 @@ protected ListOfProgramVariable buildParamVars(ModelMethod modelMethod) { } - protected ProgramVariable buildResultVar(ModelMethod modelMethod) { + protected ProgramVariable buildResultVar(ProgramMethod programMethod) { ProgramVariable result = null; - if(!modelMethod.isVoid()) { - KeYJavaType resultType - = javaInfo.getTypeByClassName(modelMethod.getResultType()); - assert resultType != null; + KeYJavaType resultKJT = programMethod.getKeYJavaType(); + if(resultKJT != null) { ProgramElementName resultPEN = new ProgramElementName("result"); - result = new LocationVariable(resultPEN, resultType); + result = new LocationVariable(resultPEN, resultKJT); } return result; @@ -121,20 +141,20 @@ protected ProgramVariable buildResultVar(ModelMethod modelMethod) { protected ProgramVariable buildExcVar() { - KeYJavaType excType - = javaInfo.getTypeByClassName("java.lang.Throwable"); + KeYJavaType excType + = javaInfo.getTypeByClassName("java.lang.Exception"); ProgramElementName excPEN = new ProgramElementName("exc"); return new LocationVariable(excPEN, excType); } /** - * Translates a precondition out of an operation contract. - * @throws SLTranslationError + * Translates a precondition out of an operation contract. */ protected Term translatePre(OperationContract contract, ParsableVariable selfVar, - ListOfParsableVariable paramVars) throws SLTranslationError { + ListOfParsableVariable paramVars) + throws ProofInputException { FormulaWithAxioms fwa = contract.getPre(selfVar, paramVars, services); axioms.putAll(fwa.getAxioms()); return fwa.getFormula(); @@ -142,18 +162,21 @@ protected Term translatePre(OperationContract contract, /** - * Translates a postcondition out of an operation contract. - * @throws SLTranslationError + * Translates a postcondition out of an operation contract. */ protected Term translatePost(OperationContract contract, ParsableVariable selfVar, ListOfParsableVariable paramVars, ParsableVariable resultVar, - ParsableVariable excVar) throws SLTranslationError { + ParsableVariable excVar, + /*inout*/ Map /*operator (normal) + -> function (atPre)*/ atPreFunctions) + throws ProofInputException { FormulaWithAxioms fwa = contract.getPost(selfVar, paramVars, resultVar, excVar, + atPreFunctions, services); axioms.putAll(fwa.getAxioms()); return fwa.getFormula(); @@ -166,66 +189,66 @@ protected Term translatePost(OperationContract contract, protected Term translateModifies(OperationContract contract, Term targetTerm, ParsableVariable selfVar, - ListOfParsableVariable paramVars) throws SLTranslationError{ - final SetOfLocationDescriptor locations = - contract.getModifies(selfVar, paramVars, services); - - final UpdateFactory uf = new UpdateFactory(services, new UpdateSimplifier()); - final AnonymisingUpdateFactory auf = new AnonymisingUpdateFactory(uf); - return auf.createAnonymisingUpdateTerm(locations, - targetTerm, - services); + ListOfParsableVariable paramVars) + throws ProofInputException { + SetOfLocationDescriptor locations = contract.getModifies(selfVar, + paramVars, + services); + + UpdateFactory uf = new UpdateFactory(services, new UpdateSimplifier()); + AnonymisingUpdateFactory auf = new AnonymisingUpdateFactory(uf); + Term result = auf.createAnonymisingUpdateTerm(locations, + targetTerm, + services); + return result; } /** - * Translates a class invariant. - * @throws SLTranslationError + * Translates a class invariant. */ - protected Term translateInv(ClassInvariant inv) throws SLTranslationError { - final FormulaWithAxioms fwa = inv.getInv(services); + protected Term translateInv(ClassInvariant inv) + throws ProofInputException { + FormulaWithAxioms fwa = inv.getClosedInv(services); axioms.putAll(fwa.getAxioms()); return fwa.getFormula(); } /** - * Translates a list of class invariants. - * @throws SLTranslationError + * Translates a list of class invariants. */ - protected Term translateInvs(ListOfClassInvariant invs) throws SLTranslationError { - Term result = tb.tt(); - + protected Term translateInvs(SetOfClassInvariant invs) + throws ProofInputException { + Term result = TB.tt(); IteratorOfClassInvariant it = invs.iterator(); while(it.hasNext()) { - result = tb.and(result, translateInv(it.next())); + result = TB.and(result, translateInv(it.next())); } - return result; } /** - * Translates a class invariant as an open formula. - * @throws SLTranslationError + * Translates a class invariant as an open formula. */ protected Term translateInvOpen(ClassInvariant inv, - ParsableVariable selfVar) throws SLTranslationError { - FormulaWithAxioms fwa = inv.getOpenInv(selfVar, services); - axioms.putAll(fwa.getAxioms()); - return fwa.getFormula(); + ParsableVariable selfVar) + throws ProofInputException { + FormulaWithAxioms fwa = inv.getOpenInv(selfVar, services); + axioms.putAll(fwa.getAxioms()); + return fwa.getFormula(); } - protected Term translateInvsOpen(ListOfClassInvariant invs, - ParsableVariable selfVar) throws SLTranslationError { - Term result = tb.tt(); - + protected Term translateInvsOpen(SetOfClassInvariant invs, + ParsableVariable selfVar) + throws ProofInputException { + Term result = TB.tt(); IteratorOfClassInvariant it = invs.iterator(); while(it.hasNext()) { - result = tb.and(result, translateInvOpen(it.next(), selfVar)); + result = TB.and(result, translateInvOpen(it.next(), selfVar)); } - return result; } @@ -249,95 +272,6 @@ protected Term replaceOps(Map /*Operator -> Operator*/ map, Term term) { } - /** - * Creates atPre-functions for all relevant operators in the passed term. - */ - public static void createAtPreFunctionsForTerm( - Term term, - /*inout*/Map /*Operator -> Function*/atPreFunctions) { - int arity = term.arity(); - Sort[] subSorts = new Sort[arity]; - for(int i = 0; i < arity; i++) { - Term subTerm = term.sub(i); - createAtPreFunctionsForTerm(subTerm, atPreFunctions); - subSorts[i] = subTerm.sort(); - } - - if(term.op() instanceof AccessOp - || term.op() instanceof ProgramVariable - || term.op() instanceof ProgramMethod) { - Function atPreFunc = (Function)(atPreFunctions.get(term.op())); - if(atPreFunc == null) { - String atPreName = term.op().name().toString() + "@pre"; - if(atPreName.startsWith(".")) { - atPreName = atPreName.substring(1); - } - atPreFunc = new RigidFunction(new Name(atPreName), - term.sort(), - subSorts); - atPreFunctions.put(term.op(), atPreFunc); - } - } - } - - /** - * Helper for buildAtPreDefinitions(). - */ - private static Term[] getTerms(ArrayOfQuantifiableVariable vars) { - int numVars = vars.size(); - Term[] result = new Term[numVars]; - - for(int i = 0; i < numVars; i++) { - LogicVariable var - = (LogicVariable)(vars.getQuantifiableVariable(i)); - result[i] = tb.var(var); - } - - return result; - } - - - /** - * Creates the necessary definitions for the passed @pre-functions. - */ - public static Term buildAtPreDefinitions( - /*in*/ Map /*Operator -> Function */atPreFunctions) { - Term result = tb.tt(); - - Iterator it = atPreFunctions.entrySet().iterator(); - while(it.hasNext()) { - Map.Entry entry = (Map.Entry)(it.next()); - Operator f1 = (Operator)(entry.getKey()); - Function f2 = (Function)(entry.getValue()); - - int arity = f1.arity(); - assert arity == f2.arity(); - LogicVariable[] args = new LogicVariable[arity]; - for(int i = 0; i < arity; i++) { - args[i] = new LogicVariable(new Name("x" + i), f2.argSort(i)); - } - - Term[] argTerms = getTerms(new ArrayOfQuantifiableVariable(args)); - - Term f1Term = tf.createTerm(f1, - argTerms, - (ArrayOfQuantifiableVariable)null, - null); - Term f2Term = tb.func(f2, argTerms); - Term equalsTerm = tf.createJunctorTerm(Op.EQUALS, f1Term, f2Term); - Term quantifTerm; - if(arity > 0) { - quantifTerm = tb.all(args, equalsTerm); - } else { - quantifTerm = equalsTerm; - } - result = tb.and(result, quantifTerm); - } - - return result; - } - - protected void registerInNamespaces(ProgramVariable pv) { if(pv != null) { initConfig.progVarNS().add(pv); @@ -375,59 +309,26 @@ public boolean askUserForEnvironment() { return false; } - - public void setInitConfig(InitConfig initConfig) { - this.initConfig = initConfig; - this.services = initConfig.getServices(); - this.javaInfo = initConfig.getServices().getJavaInfo(); - } - - + public void readActivatedChoices() throws ProofInputException { initConfig.setActivatedChoices(SetAsListOfChoice.EMPTY_SET); } - - - /** - * Computes the method specifications and stores the results in the - * SpecificationRepository which belongs to the ProofEnvironment of InitCfg. - */ - public void readSpecs(){ - // specifications from model - Vector reprMethods = null; - Iterator reprMethodsIter = null; - UMLModelClass reprClass = null; - Set allClasses = modelClass.getAllClasses(); - Iterator allClassesIter = allClasses.iterator(); - while (allClassesIter.hasNext()){ - reprClass = (UMLModelClass) allClassesIter.next(); - reprMethods = reprClass.getOps(); - reprMethodsIter = reprMethods.iterator(); - while(reprMethodsIter.hasNext()){ - ListOfOperationContract l - = ((ModelMethod)reprMethodsIter.next()).getMyOperationContracts(); - IteratorOfOperationContract it = l.iterator(); - /*TODO - while (it.hasNext()) { - initConfig.getProofEnv().addMethodContract(it.next()); - }*/ - } - } - } - /** * Creates declarations necessary to save/load proof in textual form * (helper for createProof()). */ - private String createProofHeader(String javaPath) { + private void createProofHeader(String javaPath) { if(header != null) { - return header; + return; + } + + if(initConfig.getOriginalKeYFileName() == null) { + header = "\\javaSource \""+javaPath+"\";\n\n"; + } else { + header = "\\include \"./" + initConfig.getOriginalKeYFileName() + "\";"; } - - String s; - s = "\\javaSource \""+javaPath+"\";\n\n"; IteratorOfNamed it; @@ -447,25 +348,22 @@ private String createProofHeader(String javaPath) { } s+="} */ - s += "\n\n\\programVariables {\n"; + header += "\n\n\\programVariables {\n"; it = initConfig.progVarNS().allElements().iterator(); while(it.hasNext()) - s = s+((ProgramVariable)(it.next())).proofToString(); + header += ((ProgramVariable)(it.next())).proofToString(); - s += "}\n\n\\functions {\n"; + header += "}\n\n\\functions {\n"; it = initConfig.funcNS().allElements().iterator(); while(it.hasNext()) { Function f = (Function)it.next(); - // only declare @pre-functions, others will be generated automat. - if(f.name().toString().indexOf("@pre")!=-1) { - s += f.proofToString(); + // only declare @pre-functions, others will be generated automat. (hack) + if(f.name().toString().indexOf("AtPre")!=-1) { + header += f.proofToString(); } } - s += "}\n\n"; - - header = s; - return s; + header += "}\n\n"; } @@ -473,9 +371,9 @@ private String createProofHeader(String javaPath) { * Creates a Proof (helper for getPO()). */ private Proof createProof(String name, Term poTerm) { - if(header == null) { - header = createProofHeader(modelClass.getRootDirectory()); - } + createProofHeader(initConfig.getProofEnv() + .getJavaModel() + .getModelDir()); return new Proof(name, poTerm, header, @@ -490,21 +388,21 @@ private Proof createProof(String name, Term poTerm) { * the passed term (helper for getPO()). */ private Term getRequiredAxioms(Term t) { - Term result = tb.tt(); + Term result = TB.tt(); Set axiomSet = getRequiredAxiomsAsSet(t); Iterator it = axiomSet.iterator(); while(it.hasNext()) { - result = tb.and(result,(Term)it.next()); + result = TB.and(result,(Term)it.next()); } /* if(axioms.containsKey(t.op())) { - result = tb.and(result, (Term)axioms.get(t.op())); + result = TB.and(result, (Term)axioms.get(t.op())); } for(int i = 0; i < t.arity(); i++) { - result = tb.and(result, getRequiredAxioms(t.sub(i))); + result = TB.and(result, getRequiredAxioms(t.sub(i))); } */ return result; @@ -516,7 +414,7 @@ private Term getRequiredAxioms(Term t) { * the passed term (helper for getRequiredAxioms(Term t)). */ private Set getRequiredAxiomsAsSet(Term t) { - Set result = new HashSet(); + Set result = new LinkedHashSet(); if (axioms.containsKey(t.op())) { result.add(axioms.get(t.op())); @@ -541,9 +439,12 @@ public ProofAggregate getPO() { Proof[] proofs = new Proof[poTerms.length]; for(int i = 0; i < proofs.length; i++) { - proofs[i] = createProof(poNames != null ? poNames[i] : name, - tb.imp(getRequiredAxioms(poTerms[i]), - poTerms[i])); + Term axioms = getRequiredAxioms(poTerms[i]); + proofs[i] = createProof(poNames != null ? poNames[i] : name, + poTerms[i].op() == Op.IMP + ? TB.imp(TB.and(axioms, poTerms[i].sub(0)), + poTerms[i].sub(1)) + : TB.imp(axioms, poTerms[i])); if(poTaclets != null) { proofs[i].getGoal(proofs[i].root()).indexOfTaclets() diff --git a/system/de/uka/ilkd/key/proof/init/AssignableCheckProofOblInput.java b/system/de/uka/ilkd/key/proof/init/AssignableCheckProofOblInput.java deleted file mode 100644 index 7cdd14e2804..00000000000 --- a/system/de/uka/ilkd/key/proof/init/AssignableCheckProofOblInput.java +++ /dev/null @@ -1,174 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// -package de.uka.ilkd.key.proof.init; - -import java.util.Vector; -import java.util.HashMap; - -import de.uka.ilkd.key.java.declaration.ArrayOfParameterDeclaration; -import de.uka.ilkd.key.java.declaration.MethodDeclaration; -import de.uka.ilkd.key.jml.JMLMethodSpec; -import de.uka.ilkd.key.jml.JMLSpec; -import de.uka.ilkd.key.jml.UsefulTools; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.Op; -import de.uka.ilkd.key.logic.op.ProgramVariable; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; -import de.uka.ilkd.key.util.Debug; - -/** Represents a proof obligation for the assignable clause of a certain - * (jml) method specification case. - * @deprecated Replaced by RespectsModifiesPO. - */ -public class AssignableCheckProofOblInput extends ModifiesCheckProofOblInput - implements JMLProofOblInput{ - - private JMLMethodSpec spec; - private String javaPath; - - private boolean allInv = false; - - public AssignableCheckProofOblInput(JMLMethodSpec spec, String javaPath){ - super("Assignable PO for: "+spec, null); - this.javaPath = javaPath; - this.spec = spec; - location2descriptor = new HashMap(); - } - - public void setAllInvariants(boolean allInv){ - this.allInv = allInv; - } - - public JMLSpec getSpec() { - return spec; - } - - private void createModifiesElements(){ - modifiesElements = SetAsListOfTerm.EMPTY_SET; - SetOfLocationDescriptor locs = spec.replaceModelFieldsInAssignable(); - IteratorOfLocationDescriptor it = locs.iterator(); - while(it.hasNext()) { - BasicLocationDescriptor bloc = (BasicLocationDescriptor) it.next(); - // Debug.assertTrue(bloc.getFormula().equals(tf.createJunctorTerm(Op.TRUE))); - // Debug.assertTrue(bloc.getLocTerm().freeVars().size() == 0); - location2descriptor.put(bloc.getLocTerm(), bloc); - modifiesElements = modifiesElements.add(bloc.getLocTerm()); - } - } - - public void readProblem(ModStrategy mod){ - createModifiesElements(); - MethodDeclaration md = spec.getMethodDeclaration(); - initConfig.progVarNS().add(UsefulTools.buildParamNamespace(md)); - initConfig.progVarNS().add(spec.getProgramVariableNS().allElements()); - if(spec.getMethodDeclaration().isStatic()){ - self = null; - }else{ - self = (ProgramVariable) spec.getPrefix(); - } - javaInfo = initConfig.getServices().getJavaInfo(); - createModifiesElements(); - pvVector = new Vector(md.getParameterDeclarationCount()); - ArrayOfParameterDeclaration ap = md.getParameters(); - for(int i=0; i = FALSE" ProgramVariable erroneousField = javaInfo.getAttribute(ImplicitFieldAdder.IMPLICIT_CLASS_ERRONEOUS, - classType); - Term result = tb.equals(tb.var(erroneousField), tb.FALSE(services)); + classKJT); + if(erroneousField != null) { + result = TB.and(result, + TB.equals(TB.var(erroneousField), + TB.FALSE(services))); + } //add "C. = FALSE" ProgramVariable initField = javaInfo.getAttribute( ImplicitFieldAdder.IMPLICIT_CLASS_INIT_IN_PROGRESS, - classType); - Term initFalseTerm = tb.equals(tb.var(initField), tb.FALSE(services)); - result = tb.and(result, initFalseTerm); + classKJT); + if(initField != null) { + Term initFalseTerm = TB.equals(TB.var(initField), TB.FALSE(services)); + result = TB.and(result, initFalseTerm); + } - //add explicit invariants - ListOfClassInvariant invs = modelClass.getMyClassInvariants(); - invs = invs.append(modelClass.getMyThroughoutClassInvariants()); - Term invTerm = translateInvs(invs); - result = tb.and(result, invTerm); - return result; } /** - * (helper for buildAssumedInvs()) - * @throws SLTranslationError + * (helper for buildAssumedInvs()) */ - private void buildInvariantTacletsForClass(ModelClass modelClass) throws SLTranslationError { - Term invTerm = buildInvariantsForClass(modelClass); + private void buildInvariantTacletsForClass(KeYJavaType classKJT) + throws ProofInputException { + assert classKJT.getJavaType() instanceof ClassType; + + Term invTerm = buildImplicitInvariantsForClass(classKJT); ConstrainedFormula cf = new ConstrainedFormula(invTerm); Semisequent ante = Semisequent.EMPTY_SEMISEQUENT.insertLast(cf).semisequent(); @@ -172,8 +156,8 @@ private void buildInvariantTacletsForClass(ModelClass modelClass) throws SLTrans SLListOfTaclet.EMPTY_LIST); NoFindTacletBuilder tacletBuilder = new NoFindTacletBuilder(); - String name = "Insert invariants of " + modelClass.getClassName(); - tacletBuilder.setName(new Name(name)); + String s = "Insert implicit invariants of " + classKJT.getName(); + tacletBuilder.setName(new Name(s)); tacletBuilder.addTacletGoalTemplate(template); Taclet taclet = tacletBuilder.getNoFindTaclet(); invTaclets = invTaclets.add(taclet); @@ -182,33 +166,23 @@ private void buildInvariantTacletsForClass(ModelClass modelClass) throws SLTrans } - private Term buildAssumedInvs() throws SLTranslationError { - Debug.assertTrue(invStrategy != null); - String ownFullName = modelClass.getFullClassName(); - String ownPackageName = modelClass.getContainingPackage(); - if(ownPackageName == null) { - ownPackageName = ""; - } - + private Term buildAssumedInvs() throws ProofInputException { //inReachableState - Term result = tb.func(javaInfo.getInReachableState()); + Term result = TB.func(javaInfo.getInReachableState()); - //collect all translated invariants of all classes - Set allClasses = modelClass.getAllClasses(); - Iterator it = allClasses.iterator(); + //assumed invariants + IteratorOfClassInvariant it = assumedInvs.iterator(); while(it.hasNext()) { - ModelClass mc = (ModelClass)(it.next()); - - //display only those designated by the invariant display strategy - if(invStrategy.preselectAll() - || (invStrategy.preselectPackage() - && ownPackageName.equals(mc.getContainingPackage())) - || (invStrategy.preselectClass() - && ownFullName.equals(mc.getFullClassName()))) { - Term classInvTerm = buildInvariantsForClass(mc); - result = tb.and(result, classInvTerm); - } else { - buildInvariantTacletsForClass(mc); + result = TB.and(result, translateInv(it.next())); + } + + //implicit invariants as taclets + Set allKJTs = javaInfo.getAllKeYJavaTypes(); + Iterator it2 = allKJTs.iterator(); + while(it2.hasNext()) { + KeYJavaType kjt = (KeYJavaType) it2.next(); + if(kjt.getJavaType() instanceof ClassType) { + buildInvariantTacletsForClass(kjt); } } @@ -217,11 +191,11 @@ private Term buildAssumedInvs() throws SLTranslationError { /** - * Builds the "general assumption" for a set of assumed invariants. - * @throws SLTranslationError + * Builds the "general assumption" for a set of assumed invariants. */ private Term buildGeneralAssumption(ProgramVariable selfVar, - ListOfProgramVariable paramVars) throws SLTranslationError { + ListOfProgramVariable paramVars) + throws ProofInputException { Term result = null; //build conjunction of invariants @@ -230,53 +204,52 @@ private Term buildGeneralAssumption(ProgramVariable selfVar, //build disjunction of preconditions if(!skipPreconditions) { - Term anyPreTerm = tb.ff(); - ListOfOperationContract contracts - = modelMethod.getMyOperationContracts(); + Term anyPreTerm = TB.ff(); + SetOfOperationContract contracts + = specRepos.getOperationContracts(programMethod); IteratorOfOperationContract it = contracts.iterator(); while(it.hasNext()) { OperationContract contract = it.next(); Term term = translatePre(contract, selfVar, toPV(paramVars)); - anyPreTerm = tb.or(anyPreTerm, term); + anyPreTerm = TB.or(anyPreTerm, term); } - result = tb.and(result, anyPreTerm); + result = TB.and(result, anyPreTerm); } //build "self. = TRUE & self != null" if(selfVar != null) { Term selfCreatedAndNotNullTerm = createdFactory.createCreatedAndNotNullTerm(services, - tb.var(selfVar)); - result = tb.and(result, selfCreatedAndNotNullTerm); + TB.var(selfVar)); + result = TB.and(result, selfCreatedAndNotNullTerm); } //build conjunction of... //- "p_i. = TRUE | p_i = null" for object parameters, and //- "inBounds(p_i)" for integer parameters - Term paramsLegalTerm = tb.tt(); + Term paramsLegalTerm = TB.tt(); IteratorOfProgramVariable it2 = paramVars.iterator(); while(it2.hasNext()) { ProgramVariable paramVar = it2.next(); - Term paramLegalTerm = tb.tt(); + Term paramLegalTerm = TB.tt(); if(paramVar.sort() instanceof ObjectSort) { paramLegalTerm = createdFactory.createCreatedOrNullTerm(services, - tb.var(paramVar)); + TB.var(paramVar)); } else { - LDT ldt - = services.getTypeConverter().getModelFor(paramVar.sort()); - if(ldt instanceof AbstractIntegerLDT) { - Function inBoundsPredicate - = ((AbstractIntegerLDT)ldt).getInBoundsPredicate(); - if(inBoundsPredicate != null) { - paramLegalTerm = tb.func(inBoundsPredicate, - tb.var(paramVar)); - } - } + Type paramType = paramVar.getKeYJavaType().getJavaType(); + LDT ldt = services.getTypeConverter().getModelFor(paramType); + + if(ldt instanceof AbstractIntegerLDT) { + Function inBoundsPred + = ((AbstractIntegerLDT) ldt).getInBounds(); + paramLegalTerm = TB.func(inBoundsPred, TB.var(paramVar)); + } } - paramsLegalTerm = tb.and(paramsLegalTerm, paramLegalTerm); + paramsLegalTerm = TB.and(paramsLegalTerm, paramLegalTerm); } - result = tb.and(result, paramsLegalTerm); + result = TB.and(result, paramsLegalTerm); + return result; } @@ -340,10 +313,10 @@ private Term buildProgramTerm(ProgramVariable[] parVars, //create formal parameters ProgramVariable[] formalParVars = new ProgramVariable[parVars.length]; for(int i = 0; i < parVars.length; i++) { - ProgramElementName name + ProgramElementName pen = new ProgramElementName("_" + parVars[i].name()); formalParVars[i] - = new LocationVariable(name, parVars[i].getKeYJavaType()); + = new LocationVariable(pen, parVars[i].getKeYJavaType()); registerInNamespaces(formalParVars[i]); } @@ -355,16 +328,16 @@ private Term buildProgramTerm(ProgramVariable[] parVars, exceptionVar); //create program term - Term programTerm = tf.createProgramTerm(modality, jb, postTerm); + Term programTerm = TF.createProgramTerm(modality, jb, postTerm); //add updates Term[] locs = new Term[parVars.length]; Term[] values = new Term[parVars.length]; for(int i = 0; i < parVars.length; i++) { - locs[i] = tb.var(formalParVars[i]); - values[i] = tb.var(parVars[i]); + locs[i] = TB.var(formalParVars[i]); + values[i] = TB.var(parVars[i]); } - Term updateTerm = tf.createUpdateTerm(locs, values, programTerm); + Term updateTerm = TF.createUpdateTerm(locs, values, programTerm); return updateTerm; } @@ -372,69 +345,57 @@ private Term buildProgramTerm(ProgramVariable[] parVars, //------------------------------------------------------------------------- - //methods of ProofOblInput interface + //public interface //------------------------------------------------------------------------- public void readProblem(ModStrategy mod) throws ProofInputException { - //make sure initConfig has been set - if(initConfig == null) { - throw new IllegalStateException("InitConfig not set."); - } - //prepare variables, program method and container for @pre-functions - ListOfProgramVariable paramVars = buildParamVars(modelMethod); - ProgramMethod programMethod = getProgramMethod(paramVars); + ListOfProgramVariable paramVars = buildParamVars(programMethod); ProgramVariable selfVar = null; if(programMethod != null && !programMethod.isStatic()) { selfVar = buildSelfVarAsProgVar(); } - ProgramVariable resultVar = buildResultVar(modelMethod); + ProgramVariable resultVar = buildResultVar(programMethod); ProgramVariable exceptionVar = buildExcVar(); - Map atPreFunctions = new HashMap(); + Map atPreFunctions = new LinkedHashMap(); - try { - //build general assumption - Term gaTerm = buildGeneralAssumption(selfVar, paramVars); - - //get precondition defined by subclass - Term preTerm = getPreTerm(selfVar, - paramVars, - resultVar, - exceptionVar, - atPreFunctions); - - //get postcondition defined by subclass - Term postTerm = getPostTerm(selfVar, - paramVars, - resultVar, - exceptionVar, - atPreFunctions); - - //build program term - Term programTerm = buildProgramTerm(paramVars.toArray(), - programMethod, - selfVar, - resultVar, - exceptionVar, - postTerm); + //build general assumption + Term gaTerm = buildGeneralAssumption(selfVar, paramVars); + + //get precondition defined by subclass + Term preTerm = getPreTerm(selfVar, + paramVars, + resultVar, + exceptionVar, + atPreFunctions); + + //get postcondition defined by subclass + Term postTerm = getPostTerm(selfVar, + paramVars, + resultVar, + exceptionVar, + atPreFunctions); + + //build program term + Term programTerm = buildProgramTerm(paramVars.toArray(), + programMethod, + selfVar, + resultVar, + exceptionVar, + postTerm); + + //build definitions for @pre-functions + Update atPreDefinitions = APF.createAtPreDefinitions(atPreFunctions, + services); + + //put everything together + Term result = TB.imp(TB.and(gaTerm, preTerm), + uf.apply(atPreDefinitions, programTerm)); + + //save in field + poTerms = new Term[]{result}; + poTaclets = new SetOfTaclet[]{invTaclets}; - //build definitions for @pre-functions - Term atPreDefinitionsTerm = buildAtPreDefinitions(atPreFunctions); - - //put everything together - Term result = tb.and(atPreDefinitionsTerm, gaTerm); - result = tb.and(result, preTerm); - result = tb.imp(result, programTerm); - - - //save in field - poTerms = new Term[]{result}; - poTaclets = new SetOfTaclet[]{invTaclets}; - - } catch (SLTranslationError e) { - throw new ProofInputException(e); - } - //register everything in namespaces registerInNamespaces(selfVar); registerInNamespaces(paramVars); @@ -442,26 +403,27 @@ public void readProblem(ModStrategy mod) throws ProofInputException { registerInNamespaces(exceptionVar); registerInNamespaces(atPreFunctions); } - - - public Contractable[] getObjectOfContract() { - return new Contractable[] { modelMethod }; + + + public ProgramMethod getProgramMethod() { + return programMethod; } - - public boolean initContract(Contract ct) { - if(!(ct instanceof OldOperationContract)) { - return false; - } - - OldOperationContract mct = (OldOperationContract)ct; - - if(! (mct.getModelMethod().equals(modelMethod) - && mct.getModality().equals(modality))) { + + public boolean equals(Object o) { + if(!(o instanceof EnsuresPO)) { return false; } - - ct.addCompoundProof(getPO()); - return true; + EnsuresPO po = (EnsuresPO) o; + return programMethod.equals(po.programMethod) + && modality.equals(po.modality) + && assumedInvs.equals(po.assumedInvs); + } + + + public int hashCode() { + return programMethod.hashCode() + + modality.hashCode() + + assumedInvs.hashCode(); } } diff --git a/system/de/uka/ilkd/key/proof/init/EnsuresPostPO.java b/system/de/uka/ilkd/key/proof/init/EnsuresPostPO.java index 509f453d891..9bc6076d1ec 100644 --- a/system/de/uka/ilkd/key/proof/init/EnsuresPostPO.java +++ b/system/de/uka/ilkd/key/proof/init/EnsuresPostPO.java @@ -16,11 +16,10 @@ import de.uka.ilkd.key.logic.ldt.LDT; import de.uka.ilkd.key.logic.op.Function; import de.uka.ilkd.key.logic.op.ListOfProgramVariable; -import de.uka.ilkd.key.logic.op.Modality; import de.uka.ilkd.key.logic.op.ProgramVariable; import de.uka.ilkd.key.logic.sort.ObjectSort; import de.uka.ilkd.key.speclang.OperationContract; -import de.uka.ilkd.key.speclang.SLTranslationError; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; /** @@ -30,24 +29,36 @@ public class EnsuresPostPO extends EnsuresPO { private final OperationContract contract; - public EnsuresPostPO(OperationContract contract, - Modality modality, - InvariantSelectionStrategy invStrategy) { - super("EnsuresPost of " + contract.getModelMethod(), - contract.getModelMethod(), - modality, - invStrategy, + public EnsuresPostPO(InitConfig initConfig, + String name, + OperationContract contract, + SetOfClassInvariant assumedInvs) { + super(initConfig, + name, + contract.getProgramMethod(), + contract.getModality(), + assumedInvs, true); this.contract = contract; } + + + public EnsuresPostPO(InitConfig initConfig, OperationContract contract, + SetOfClassInvariant assumedInvs) { + this(initConfig, + "EnsuresPost", + contract, + assumedInvs); + } protected Term getPreTerm(ProgramVariable selfVar, ListOfProgramVariable paramVars, ProgramVariable resultVar, ProgramVariable exceptionVar, - Map atPreFunctions) throws SLTranslationError { - return translatePre(contract, selfVar, toPV(paramVars)); + Map atPreFunctions) throws ProofInputException { + Term result = translatePre(contract, selfVar, toPV(paramVars)); + return result; } @@ -55,20 +66,22 @@ protected Term getPostTerm(ProgramVariable selfVar, ListOfProgramVariable paramVars, ProgramVariable resultVar, ProgramVariable exceptionVar, - Map atPreFunctions) throws SLTranslationError { + Map atPreFunctions) throws ProofInputException { Term result = translatePost(contract, selfVar, toPV(paramVars), resultVar, - exceptionVar); + exceptionVar, + atPreFunctions); - //add implicit postcondition - Term implicitPostTerm = tb.tt(); + //add implicit postcondition (see discussion for Bug #789) + /* + Term implicitPostTerm = TB.tt(); if(resultVar != null) { if(resultVar.sort() instanceof ObjectSort) { implicitPostTerm = createdFactory.createCreatedOrNullTerm(services, - tb.var(resultVar)); + TB.var(resultVar)); } else { LDT ldt = services.getTypeConverter().getModelFor(resultVar.sort()); @@ -76,17 +89,33 @@ protected Term getPostTerm(ProgramVariable selfVar, Function inBoundsPredicate = ((AbstractIntegerLDT)ldt).getInBoundsPredicate(); if(inBoundsPredicate != null) { - implicitPostTerm = tb.func(inBoundsPredicate, - tb.var(resultVar)); + implicitPostTerm = TB.func(inBoundsPredicate, + TB.var(resultVar)); } } } } - final Term excNotNullTerm = tb.not(tb.equals(tb.var(exceptionVar), - tb.NULL(services))); - implicitPostTerm = tb.or(implicitPostTerm, excNotNullTerm); - result = tb.and(result, implicitPostTerm); + Term excNotNullTerm = TB.not(TB.equals(TB.var(exceptionVar), + TB.NULL(services))); + implicitPostTerm = TB.or(implicitPostTerm, excNotNullTerm); + result = TB.and(result, implicitPostTerm); + */ return result; } + + + public boolean equals(Object o) { + if(!(o instanceof EnsuresPostPO)) { + return false; + } + EnsuresPostPO po = (EnsuresPostPO) o; + return super.equals(po) + && contract.equals(po.contract); + } + + + public int hashCode() { + return super.hashCode() + contract.hashCode(); + } } diff --git a/system/de/uka/ilkd/key/proof/init/EnvInput.java b/system/de/uka/ilkd/key/proof/init/EnvInput.java index 764fc761f37..86f4d7e0a68 100644 --- a/system/de/uka/ilkd/key/proof/init/EnvInput.java +++ b/system/de/uka/ilkd/key/proof/init/EnvInput.java @@ -12,7 +12,8 @@ import de.uka.ilkd.key.gui.configuration.LibrariesSettings; -/** Represents an entity read to produce an environment to read a proof +/** + * Represents an entity read to produce an environment to read a proof * obligation. Environment means the initial configuration of a prover * containing namespaces and Java model. */ @@ -22,7 +23,7 @@ public interface EnvInput { * Returns the name of this input. */ String name(); - + /** * Returns the total numbers of chars that can be read in this input. */ @@ -34,19 +35,23 @@ public interface EnvInput { */ void setInitConfig(InitConfig initConfig); - /** reads the include section and returns an Includes object. + /** + * Reads the include section and returns an Includes object. */ Includes readIncludes() throws ProofInputException; - /** reads the libraries settings + /** + * Reads the libraries settings. */ LibrariesSettings readLibrariesSettings() throws ProofInputException; - /** reads the Java path. + /** + * Reads the Java path. */ String readJavaPath() throws ProofInputException; - /** reads the input using the given modification strategy, i.e., + /** + * Reads the input using the given modification strategy, i.e., * parts of the input do not modify the initial configuration while * others do. */ diff --git a/system/de/uka/ilkd/key/proof/init/Includes.java b/system/de/uka/ilkd/key/proof/init/Includes.java index 3901645ef98..2ba0c02cc1a 100644 --- a/system/de/uka/ilkd/key/proof/init/Includes.java +++ b/system/de/uka/ilkd/key/proof/init/Includes.java @@ -11,6 +11,7 @@ package de.uka.ilkd.key.proof.init; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -35,7 +36,7 @@ public class Includes{ public Includes(){ includes = new LinkedList(); ldtIncludes = new LinkedList(); - name2Source = new HashMap(); + name2Source = new LinkedHashMap(); } private void put(String name, RuleSource source, List list){ diff --git a/system/de/uka/ilkd/key/proof/init/InitConfig.java b/system/de/uka/ilkd/key/proof/init/InitConfig.java index b606c8ae7b6..97114c0428f 100644 --- a/system/de/uka/ilkd/key/proof/init/InitConfig.java +++ b/system/de/uka/ilkd/key/proof/init/InitConfig.java @@ -11,6 +11,7 @@ import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.NoSuchElementException; import java.util.Map.Entry; @@ -53,7 +54,7 @@ public class InitConfig { * maps categories to their default choice (both represented as Strings), * which is used if no other choice is specified in the problemfile */ - private HashMap category2DefaultChoice = new HashMap(); + private HashMap category2DefaultChoice = new LinkedHashMap(); /** * maps taclets to their TacletBuilders. This information is needed when @@ -62,7 +63,7 @@ public class InitConfig { * GoalTemplates whose options are activated and those who don't belong * to any specific option. */ - private HashMap taclet2Builder = new HashMap(); + private HashMap taclet2Builder = new LinkedHashMap(); /** * Set of the rule options activated for the current proof. The rule options @@ -74,6 +75,8 @@ public class InitConfig { /** HashMap for quick lookups taclet name->taclet */ private HashMapFromNameToNamed quickTacletMap; + private String originalKeYFileName; + //------------------------------------------------------------------------- @@ -374,6 +377,7 @@ public ProofSettings mergedProofSettings() { try { someProof = ((ProofAggregate)getProofEnv().getProofs().iterator().next()); }catch(NoSuchElementException ne){ + throw new RuntimeException(ne); } if (someProof!=null) { return defaultSettings.setChoiceSettings( @@ -394,6 +398,16 @@ public void add(NamespaceSet ns, ModStrategy mod) { if (mod.modifyHeuristics()) ruleSetNS().add(ns.ruleSets()); if (mod.modifyChoices()) choiceNS().add(ns.choices()); } + + + public void setOriginalKeYFileName(String name) { + originalKeYFileName = name; + } + + + public String getOriginalKeYFileName() { + return originalKeYFileName; + } @@ -408,6 +422,7 @@ public InitConfig copy() { ic.category2DefaultChoice = ((HashMap) category2DefaultChoice.clone()); ic.setTaclet2Builder((HashMap) taclet2Builder.clone()); ic.setTaclets(taclets); + ic.originalKeYFileName = originalKeYFileName; return ic; } diff --git a/system/de/uka/ilkd/key/proof/init/InvariantSelectionStrategy.java b/system/de/uka/ilkd/key/proof/init/InvariantSelectionStrategy.java deleted file mode 100644 index 15dcbf69356..00000000000 --- a/system/de/uka/ilkd/key/proof/init/InvariantSelectionStrategy.java +++ /dev/null @@ -1,96 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.proof.init; - - -/** - * Describes which invariants are to be preselected (i.e. assumed by default), - * and for which ones an insertion rule is created which allows the user to - * select them when needed. - */ -public abstract class InvariantSelectionStrategy { - - /** - * A strategy which preselects all invariants. - */ - public final static InvariantSelectionStrategy PRESELECT_ALL - = new InvariantSelectionStrategy() { - public boolean preselectAll() { - return true; - } - public boolean preselectPackage() { - return true; - } - public boolean preselectClass() { - return true; - } - }; - - - /** - * A strategy which preselects the invariants of the own package only. - */ - public final static InvariantSelectionStrategy PRESELECT_PACKAGE - = new InvariantSelectionStrategy() { - public boolean preselectAll() { - return false; - } - public boolean preselectPackage() { - return true; - } - public boolean preselectClass() { - return true; - } - }; - - - /** - * A strategy which preselects the invariants of the own class only. - */ - public final static InvariantSelectionStrategy PRESELECT_CLASS - = new InvariantSelectionStrategy() { - public boolean preselectAll() { - return false; - } - public boolean preselectPackage() { - return false; - } - public boolean preselectClass() { - return true; - } - }; - - - /** - * A strategy which preselects no invariants at all. - */ - public final static InvariantSelectionStrategy PRESELECT_NONE - = new InvariantSelectionStrategy() { - public boolean preselectAll() { - return false; - } - public boolean preselectPackage() { - return false; - } - public boolean preselectClass() { - return false; - } - }; - - - public abstract boolean preselectAll(); - - - public abstract boolean preselectPackage(); - - - public abstract boolean preselectClass(); -} diff --git a/system/de/uka/ilkd/key/proof/init/JMLInvPO.java b/system/de/uka/ilkd/key/proof/init/JMLInvPO.java deleted file mode 100644 index 004da35fe73..00000000000 --- a/system/de/uka/ilkd/key/proof/init/JMLInvPO.java +++ /dev/null @@ -1,72 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// -package de.uka.ilkd.key.proof.init; - -import de.uka.ilkd.key.jml.JMLClassSpec; -import de.uka.ilkd.key.jml.UsefulTools; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.op.ProgramMethod; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.mgt.Contract; - -/** the proofobligation for invariants and historyconstraints*/ -public class JMLInvPO extends JMLProofOblInputImpl{ - - private Term po = null; - - public JMLInvPO(JMLClassSpec spec, ProgramMethod pm, - String javaPath, boolean allInv){ - super(spec, javaPath, allInv); - this.pm = pm; - } - - public ProofAggregate getPO(){ - return ProofAggregate.createProofAggregate( - new Proof(name(), - po, - createProblemHeader(), - initConfig.createTacletIndex(), - initConfig.createBuiltInRuleIndex(), - initConfig.getServices()), name()); - } - - public void readProblem(ModStrategy mod) throws ProofInputException{ - initConfig.progVarNS().add(UsefulTools.buildParamNamespace(pm.getMethodDeclaration())); - po = ((JMLClassSpec) spec).getPreservesInvariantBehavior(pm, allInv); - initConfig.progVarNS().add(spec.getProgramVariableNS().allElements()); - if(allInv){ - initConfig.progVarNS().add(initConfig.getServices(). - getImplementation2SpecMap(). - getAllInvPVNS().allElements()); - } - } - - public boolean initContract(Contract ct){ - return false; - } - - public String name(){ - return "Invariant "+(allInv ? "(including all invariants)" : - "(only invariants for "+ - ((JMLClassSpec) spec). - getClassDeclaration().getName()+")")+ - " and History Constraint PO for "+ - pm.getMethodDeclaration().getName(); - } - - public boolean checkPurity(){ - return po != null ? - (UsefulTools.purityCheck(po, initConfig.getServices(). - getImplementation2SpecMap()) == null): - true; - } - -} diff --git a/system/de/uka/ilkd/key/proof/init/JMLPostAndInvPO.java b/system/de/uka/ilkd/key/proof/init/JMLPostAndInvPO.java deleted file mode 100644 index ed17f64d216..00000000000 --- a/system/de/uka/ilkd/key/proof/init/JMLPostAndInvPO.java +++ /dev/null @@ -1,95 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2003 Universitaet Karlsruhe, Germany -// and Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.proof.init; - -import de.uka.ilkd.key.jml.JMLMethodSpec; -import de.uka.ilkd.key.jml.UsefulTools; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; -import de.uka.ilkd.key.proof.mgt.JMLMethodContract; -import de.uka.ilkd.key.proof.mgt.JavaModelMethod; - -public class JMLPostAndInvPO extends JMLProofOblInputImpl{ - - private Term po = null; - private JavaModelMethod jmm = null; - private ProofAggregate result; - - public JMLPostAndInvPO(JMLMethodSpec spec, String javaPath, boolean allInv){ - super(spec, javaPath, allInv); - pm = spec.getProgramMethod(); - jmm = new JavaModelMethod(spec.getProgramMethod(), javaPath, null); //TODO - } - - public ProofAggregate getPO(){ - if (result!=null) return result; - return result = ProofAggregate.createProofAggregate( - new Proof(name(), - po, - createProblemHeader(), - initConfig.createTacletIndex(), - initConfig.createBuiltInRuleIndex(), - initConfig.getServices()), name()); - } - - public void readProblem(ModStrategy mod) throws ProofInputException{ - initConfig.progVarNS(). - add(UsefulTools.buildParamNamespace(pm.getMethodDeclaration())); - po = ((JMLMethodSpec) spec).createDLFormula(true, allInv); - initConfig.progVarNS().add(spec.getProgramVariableNS().allElements()); - if(allInv){ - initConfig.progVarNS().add(initConfig.getServices(). - getImplementation2SpecMap(). - getAllInvPVNS().allElements()); - } - } - - public boolean initContract(Contract ct) { - if (!(ct instanceof JMLMethodContract) || allInv!=JMLMethodContract.allInvariants) { - return false; - } - if (((JMLMethodContract) ct).getSpec() != spec) { - return false; - } - ct.addCompoundProof(getPO()); - return true; - } - - public boolean checkPurity(){ - return po != null ? - (UsefulTools.purityCheck(po, initConfig.getServices(). - getImplementation2SpecMap()) == null): - true; - } - - public Contractable[] getObjectOfContract(){ - return new Contractable[]{jmm}; - } - - public String name(){ - return "Post, Invariant "+(allInv ? "(including all invariants)" : - "(only invariants for "+ - ((JMLMethodSpec) spec). - getClassDeclaration().getName()+")")+ - " and Constraint PO for spec:\n "+ - spec.toString(); - } - -} diff --git a/system/de/uka/ilkd/key/proof/init/JMLPostPO.java b/system/de/uka/ilkd/key/proof/init/JMLPostPO.java deleted file mode 100644 index d547efe1251..00000000000 --- a/system/de/uka/ilkd/key/proof/init/JMLPostPO.java +++ /dev/null @@ -1,63 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// -package de.uka.ilkd.key.proof.init; - -import de.uka.ilkd.key.jml.JMLMethodSpec; -import de.uka.ilkd.key.jml.UsefulTools; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofAggregate; - -public class JMLPostPO extends JMLProofOblInputImpl{ - - private Term po = null; - - public JMLPostPO(JMLMethodSpec spec, String javaPath, boolean allInv){ - super(spec, javaPath, allInv); - pm = spec.getProgramMethod(); - } - - public ProofAggregate getPO(){ - return ProofAggregate.createProofAggregate( - new Proof(name(), - po, - createProblemHeader(), - initConfig.createTacletIndex(), - initConfig.createBuiltInRuleIndex(), - initConfig.getServices()), name()); - } - - public void readProblem(ModStrategy mod) throws ProofInputException{ - initConfig.progVarNS().add(UsefulTools.buildParamNamespace(pm.getMethodDeclaration())); - - po = ((JMLMethodSpec) spec).createDLFormula(false, allInv); - - initConfig.progVarNS().add(spec.getProgramVariableNS().allElements()); - if(allInv){ - initConfig.progVarNS().add(initConfig.getServices(). - getImplementation2SpecMap(). - getAllInvPVNS().allElements()); - } - } - - public boolean checkPurity(){ - return UsefulTools.purityCheck((JMLMethodSpec) spec, - initConfig.getServices(). - getImplementation2SpecMap()) == null; - } - - public String name(){ - return "Ensures Post Condition PO (using "+ - (allInv ? "all invariants" : "only invariants from "+ - ((JMLMethodSpec) spec).getClassDeclaration().getName())+ - " for the precondition) Condition PO for:\n "+spec.toString(); - } - -} diff --git a/system/de/uka/ilkd/key/proof/init/JMLProofOblInput.java b/system/de/uka/ilkd/key/proof/init/JMLProofOblInput.java deleted file mode 100644 index 42f3345f6b2..00000000000 --- a/system/de/uka/ilkd/key/proof/init/JMLProofOblInput.java +++ /dev/null @@ -1,36 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// -package de.uka.ilkd.key.proof.init; - -public interface JMLProofOblInput extends ProofOblInput { - - /** - * Checks if the methods used in the specification that underlies this - * JMLProofOblInput are declared with the modifier pure. - */ - boolean checkPurity(); - - /** - * Creates program variables section for the problem header. - */ - String createProgramVarsSection(); - - /** - * Creates java section for the problem header. - */ - String createJavaSection(); - - /** - * Creates the problem header. - */ - String createProblemHeader(); -} - - diff --git a/system/de/uka/ilkd/key/proof/init/JMLProofOblInputImpl.java b/system/de/uka/ilkd/key/proof/init/JMLProofOblInputImpl.java deleted file mode 100644 index fd52802fc2a..00000000000 --- a/system/de/uka/ilkd/key/proof/init/JMLProofOblInputImpl.java +++ /dev/null @@ -1,155 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// -package de.uka.ilkd.key.proof.init; - -import de.uka.ilkd.key.java.abstraction.ArrayType; -import de.uka.ilkd.key.java.abstraction.Type; -import de.uka.ilkd.key.jml.JMLSpec; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.Function; -import de.uka.ilkd.key.logic.op.ProgramMethod; -import de.uka.ilkd.key.logic.op.ProgramVariable; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; -import de.uka.ilkd.key.proof.mgt.JavaModelMethod; -import de.uka.ilkd.key.util.KeYExceptionHandler; - - -public abstract class JMLProofOblInputImpl implements JMLProofOblInput { - - protected JMLSpec spec = null; - protected ProgramMethod pm = null; - protected InitConfig initConfig = null; - protected String javaPath = null; - protected KeYExceptionHandler exceptionHandler = null; - protected boolean allInv = false; - - protected JMLProofOblInputImpl(JMLSpec spec, String javaPath, - boolean allInv){ - this.spec = spec; - this.javaPath = javaPath; - this.allInv = allInv; - } - - /** - * sets the exception handler used to collect occured errors - */ - public void setExceptionHandler(KeYExceptionHandler keh){ - exceptionHandler = keh; - } - - public boolean initContract(Contract ct) { - return false; - } - - public boolean askUserForEnvironment(){ - return false; - } - - /** - * Checks if the methods used in the specification that underlies this - * JMLProofOblInput are declared with the modifier pure. - */ - public abstract boolean checkPurity(); - - public void read(ModStrategy mod) throws ProofInputException{} - - /** - * The Java Model is already initialized; - */ - public String readModel() throws ProofInputException{ - return null; - } - - public void initJavaModelSettings(String path) {} - - /** returns the path to the Java model. - */ - public String getJavaPath(){ - return javaPath; - } - - /** set the initial configuration used to read an input. It may become - * modified during reading depending on the modification strategy used - * for reading. - */ - public void setInitConfig(InitConfig i){ - initConfig = i; - } - - /** Specs have already been read. - */ - public void readSpecs(){ - } - - public void readActivatedChoices() throws ProofInputException{ - //nothing to do - } - - /** reads the include section and returns an Includes object. - */ - public Includes readIncludes() throws ProofInputException{ - return new Includes(); - } - - /** returns the name of the proof obligation input. - */ - public String name(){ - return spec.toString(); - } - - public Contractable[] getObjectOfContract(){ - return new Contractable[] { - new JavaModelMethod(pm, javaPath, initConfig.getServices())}; - } - - public void startProtocol() { - // do nothing - } - - public String createProgramVarsSection(){ - IteratorOfNamed it = initConfig.progVarNS().allElements().iterator(); - String result = "\\programVariables {\n"; - while(it.hasNext()){ - final ProgramVariable pv = (ProgramVariable) it.next(); - final Type javaType = pv.getKeYJavaType().getJavaType(); - if (javaType instanceof ArrayType) { - result += - ((ArrayType)javaType).getAlternativeNameRepresentation()+" "+pv.name()+";\n"; - } else { - result += javaType.getFullName()+" "+pv.name()+";\n"; - } - } - result += "}\n"; - return result; - } - - public String createFunctionSection(){ - IteratorOfNamed it = spec.getFunctionNS().allElements().iterator(); - String result = "\\functions {\n"; - while(it.hasNext()){ - Function f = (Function) it.next(); - result += f.proofToString(); - } - result += "}\n"; - return result; - } - - public String createJavaSection(){ - return "\\javaSource \""+getJavaPath()+"\";\n"; - } - - public String createProblemHeader(){ - return createJavaSection()+"\n"+createProgramVarsSection()+"\n"+ - createFunctionSection()+"\n"; - } -} - - diff --git a/system/de/uka/ilkd/key/proof/init/JUnitTestProfile.java b/system/de/uka/ilkd/key/proof/init/JUnitTestProfile.java index 6e745c4961e..31bb9862fc8 100644 --- a/system/de/uka/ilkd/key/proof/init/JUnitTestProfile.java +++ b/system/de/uka/ilkd/key/proof/init/JUnitTestProfile.java @@ -6,7 +6,7 @@ import de.uka.ilkd.key.rule.ListOfBuiltInRule; import de.uka.ilkd.key.rule.Rule; import de.uka.ilkd.key.rule.UpdateSimplificationRule; -import de.uka.ilkd.key.rule.UseMethodContractRule; +import de.uka.ilkd.key.rule.UseOperationContractRule; import de.uka.ilkd.key.strategy.FOLStrategy; import de.uka.ilkd.key.strategy.JavaCardDLStrategy; import de.uka.ilkd.key.strategy.SetOfStrategyFactory; @@ -35,8 +35,8 @@ protected SetOfStrategyFactory getStrategyFactories() { return set; } - protected UseMethodContractRule getContractRule() { - return UseMethodContractRule.INSTANCE; + protected UseOperationContractRule getContractRule() { + return UseOperationContractRule.INSTANCE; } protected UpdateSimplificationRule getUpdateSimplificationRule() { diff --git a/system/de/uka/ilkd/key/proof/init/JavaInput.java b/system/de/uka/ilkd/key/proof/init/JavaInput.java deleted file mode 100644 index 800afb5e21f..00000000000 --- a/system/de/uka/ilkd/key/proof/init/JavaInput.java +++ /dev/null @@ -1,160 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// -package de.uka.ilkd.key.proof.init; - -import java.io.File; -import java.io.IOException; - -import de.uka.ilkd.key.logic.SetAsListOfChoice; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.TermFactory; -import de.uka.ilkd.key.logic.op.Op; -import de.uka.ilkd.key.proof.ProblemLoader; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; -import de.uka.ilkd.key.util.ProgressMonitor; - - -/** - * This is the input type for JML enriched java source files or such - * source files in a directory tree structure - * @deprecated - */ -public class JavaInput extends KeYUserProblemFile implements ProofOblInput { - - File path = null; - - /** - * @param name - * @param path - * @param monitor - */ - public JavaInput(String name, File path, ProgressMonitor monitor) { - super(name, path, monitor); - this.path = path; - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.ProofOblInput#getPO() - */ - public ProofAggregate getPO() { - - Term dummy = TermFactory.DEFAULT.createJunctorTerm(Op.TRUE); - - - - // create empty dummy proof to ensure the java model was loaded - return ProofAggregate.createProofAggregate( - new Proof("dummy proof", dummy, "", - getInitConfig().createTacletIndex(), - getInitConfig().createBuiltInRuleIndex(), - getInitConfig().getServices()), - "dummy proof"); - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.EnvInput#getNumberOfChars() - */ - public int getNumberOfChars() { - return 0; - } - - /** starts reading the input and modifies the InitConfig of this - * object with respect to the given modification strategy. - * @param mod the modification strategy to use - */ - public void read(ModStrategy mod) throws ProofInputException{ - return; - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.KeYFile#readProblem(de.uka.ilkd.key.proof.init.ModStrategy) - */ - public void readProblem(ModStrategy mod) throws ProofInputException{ - return; - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.ProofOblInput#askUserForEnvironment() - */ - public boolean askUserForEnvironment(){ - return false; - } - - /** returns the path to the Java model. - */ - public String readJavaPath() throws ProofInputException{ - String javaPath = null; - try{ - javaPath = path.getCanonicalFile().getAbsolutePath(); - } catch(IOException ioe) { - throw new ProofInputException(ioe); - } - return javaPath; - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.KeYFile#readActivatedChoices() - */ - public void readActivatedChoices() throws ProofInputException{ - initConfig.setActivatedChoices(SetAsListOfChoice.EMPTY_SET); - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.KeYFile#readIncludes() - */ - public Includes readIncludes() throws ProofInputException{ - return new Includes(); - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.KeYFile#getObjectOfContract() - */ - public Contractable[] getObjectOfContract(){ - return new Contractable[0]; - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.KeYFile#initContract(de.uka.ilkd.key.proof.mgt.Contract) - */ - public boolean initContract(Contract ct){ - return false; - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.KeYFile#readFuncAndPred(de.uka.ilkd.key.proof.init.ModStrategy) - */ - public void readFuncAndPred(ModStrategy mod) throws ProofInputException { - return; - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.KeYFile#readSorts(de.uka.ilkd.key.proof.init.ModStrategy) - */ - public void readSorts(ModStrategy mod) throws ProofInputException { - return; - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.KeYFile#readRulesAndProblem(de.uka.ilkd.key.proof.init.ModStrategy) - */ - public void readRulesAndProblem(ModStrategy mod) throws ProofInputException{ - return; - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.KeYFile#readProof(de.uka.ilkd.key.proof.ProblemLoader) - */ - public void readProof(ProblemLoader prl) throws ProofInputException { - return; - } -} diff --git a/system/de/uka/ilkd/key/proof/init/JavaInputWithJMLSpecBrowser.java b/system/de/uka/ilkd/key/proof/init/JavaInputWithJMLSpecBrowser.java deleted file mode 100644 index d29fae70c5e..00000000000 --- a/system/de/uka/ilkd/key/proof/init/JavaInputWithJMLSpecBrowser.java +++ /dev/null @@ -1,79 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// -package de.uka.ilkd.key.proof.init; - -import java.io.File; - -import javax.swing.JOptionPane; - -import de.uka.ilkd.key.gui.JMLSpecBrowser; -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.util.ProgressMonitor; - -/** - * This class extends the JavaInput by opening the JML Specification Browser - * after loading the java source files and contained JML specifications. - * @deprecated - */ -public class JavaInputWithJMLSpecBrowser extends JavaInput { - - private JMLProofOblInput jmlPO; - - /** - * @param name name of the input, will be the name of the created environment - * @param path path of the java files - * @param monitor ProgressMonitor for showing progress while loading - */ - public JavaInputWithJMLSpecBrowser(String name, File path, - boolean allIntMode, ProgressMonitor monitor) { - super(name, path, monitor); - } - - public void read(ModStrategy mod) throws ProofInputException { - //readProblem(mod); - } - - public void readProblem(ModStrategy mod) throws ProofInputException { - jmlPO = null; - int option = JOptionPane.NO_OPTION; - do { - JMLSpecBrowser sb = - new JMLSpecBrowser(initConfig.getServices(), readJavaPath()); - jmlPO = sb.getPOI(); - if (jmlPO == null) { - option = JOptionPane.showConfirmDialog - (null, "Do you really want to abort loading the proof?", - "Abort Loading", - JOptionPane.YES_NO_OPTION); - } - } while (option == JOptionPane.NO_OPTION && jmlPO == null); - - if (jmlPO == null){ - if (option == JOptionPane.YES_OPTION) { - throw ProofInputException.USER_ABORT_EXCEPTION; - } - throw new ProofInputException("No Proofobligation could be created."); - } else { - jmlPO.setInitConfig(getInitConfig()); - } - try { - jmlPO.readProblem(ModStrategy.NO_GENSORTS); - } catch(ProofInputException e){ - initConfig.getServices().getExceptionHandler().reportException(e); - } - } - - /* (non-Javadoc) - * @see de.uka.ilkd.key.proof.init.ProofOblInput#getPO() - */ - public ProofAggregate getPO() { - return jmlPO.getPO(); - } -} diff --git a/system/de/uka/ilkd/key/proof/init/JavaProfile.java b/system/de/uka/ilkd/key/proof/init/JavaProfile.java index e3af9b721df..f5882ca5fa7 100644 --- a/system/de/uka/ilkd/key/proof/init/JavaProfile.java +++ b/system/de/uka/ilkd/key/proof/init/JavaProfile.java @@ -8,7 +8,7 @@ import de.uka.ilkd.key.rule.ListOfBuiltInRule; import de.uka.ilkd.key.rule.Rule; import de.uka.ilkd.key.rule.UpdateSimplificationRule; -import de.uka.ilkd.key.rule.UseMethodContractRule; +import de.uka.ilkd.key.rule.UseOperationContractRule; import de.uka.ilkd.key.strategy.FOLStrategy; import de.uka.ilkd.key.strategy.JavaCardDLStrategy; import de.uka.ilkd.key.strategy.SetOfStrategyFactory; @@ -48,8 +48,8 @@ protected SetOfStrategyFactory getStrategyFactories() { return set; } - protected UseMethodContractRule getContractRule() { - return UseMethodContractRule.INSTANCE; + protected UseOperationContractRule getContractRule() { + return UseOperationContractRule.INSTANCE; } protected UpdateSimplificationRule getUpdateSimplificationRule() { diff --git a/system/de/uka/ilkd/key/proof/init/JavaTestGenerationProfile.java b/system/de/uka/ilkd/key/proof/init/JavaTestGenerationProfile.java index e4e1b241b6d..5c582cd0d71 100644 --- a/system/de/uka/ilkd/key/proof/init/JavaTestGenerationProfile.java +++ b/system/de/uka/ilkd/key/proof/init/JavaTestGenerationProfile.java @@ -9,11 +9,9 @@ import de.uka.ilkd.key.proof.BalancedGoalChooserBuilder; import de.uka.ilkd.key.proof.DefaultGoalChooserBuilder; import de.uka.ilkd.key.proof.SetAsListOfGoalChooserBuilder; -import de.uka.ilkd.key.rule.UseMethodContractRule; import de.uka.ilkd.key.strategy.SetOfStrategyFactory; import de.uka.ilkd.key.strategy.StrategyFactory; import de.uka.ilkd.key.strategy.VBTStrategy; -import de.uka.ilkd.key.unittest.UseMethodContractRuleForTestGen; public class JavaTestGenerationProfile extends JavaProfile { @@ -32,11 +30,7 @@ protected SetOfStrategyFactory getStrategyFactories() { return super.getStrategyFactories().add(DEFAULT); } - - protected UseMethodContractRule getContractRule() { - return UseMethodContractRuleForTestGen.INSTANCE; - } - + public String name() { return "Java Testcase Generation Profile"; } diff --git a/system/de/uka/ilkd/key/proof/init/KeYFile.java b/system/de/uka/ilkd/key/proof/init/KeYFile.java index 38c548155fa..e5a95ee613e 100644 --- a/system/de/uka/ilkd/key/proof/init/KeYFile.java +++ b/system/de/uka/ilkd/key/proof/init/KeYFile.java @@ -13,157 +13,139 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.util.LinkedHashMap; import de.uka.ilkd.key.collection.ListOfString; import de.uka.ilkd.key.gui.configuration.LibrariesSettings; import de.uka.ilkd.key.gui.configuration.ProofSettings; import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.recoderext.RecoderModelTransformer; import de.uka.ilkd.key.logic.NamespaceSet; import de.uka.ilkd.key.parser.KeYLexer; import de.uka.ilkd.key.parser.KeYParser; import de.uka.ilkd.key.parser.ParserConfig; import de.uka.ilkd.key.parser.ParserMode; import de.uka.ilkd.key.proof.CountingBufferedInputStream; -import de.uka.ilkd.key.proof.ProblemLoader; import de.uka.ilkd.key.proof.RuleSource; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; +import de.uka.ilkd.key.rule.SetOfTaclet; +import de.uka.ilkd.key.speclang.SLEnvInput; import de.uka.ilkd.key.util.Debug; import de.uka.ilkd.key.util.ProgressMonitor; -/** represents an input from a .key file producing an environment. + +/** + * Represents an input from a .key file producing an environment. */ public class KeYFile implements EnvInput { - protected String javaPath; - private boolean javaPathAlreadyParsed=false; - - - /** the RuleSource delivering the input stream for the file. - */ - protected RuleSource file = null; - - /** maps methods to their jml specifications. */ - protected LinkedHashMap method2jmlspecs=null; - + private final String name; - protected InputStream input = null; - - /** the initial configuration to be used (and modified) while reading. + /** the RuleSource delivering the input stream for the file. */ - protected InitConfig initConfig = null; - - private String name; - - protected KeYParser problemParser=null; - - protected ProofSettings settings; - + protected final RuleSource file; + /** the graphical entity to notify on the state of reading. */ - protected ProgressMonitor monitor; + protected final ProgressMonitor monitor; + + /** + * for disabling the parsing of specifications (e.g. when running tests) + */ + private final boolean parseSpecs; + + private String javaPath; + private boolean javaPathAlreadyParsed=false; + private ProofSettings settings; + + private InputStream input; + + protected InitConfig initConfig; + + private boolean chooseContract = false; + + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + /** creates a new representation for a given file by indicating a name - * and a file representing the physical source of the .key file. + * and a RuleSource representing the physical source of the .key file. */ - public KeYFile(String name, File file) { - this(name, RuleSource.initRuleFile(file), null); + public KeYFile(String name, + RuleSource file, + ProgressMonitor monitor, + boolean parseSpecs) { + assert name != null; + assert file != null; + this.name = name; + this.file = file; + this.monitor = monitor; + this.parseSpecs = parseSpecs; } + /** creates a new representation for a given file by indicating a name * and a file representing the physical source of the .key file. - * @param monitor the progress monitor to notify on the state of reading */ - public KeYFile(String name, File file, ProgressMonitor monitor) { - this(name, RuleSource.initRuleFile(file), monitor); - } - - /** creates a new representation for a given file by indicating a name - * and a RuleSource representing the physical source of the .key file. - * @param monitor the progress monitor to notify on the state of reading - */ - public KeYFile(String name, RuleSource file, ProgressMonitor monitor) { - this.file=file; - this.name=name; - this.monitor=monitor; + public KeYFile(String name, + File file, + ProgressMonitor monitor, + boolean parseSpecs) { + this(name, RuleSource.initRuleFile(file), monitor, parseSpecs); } + - /** returns the initial configuration that is used to read and - * that may be modified by reading. - */ - public InitConfig getInitConfig() { - return initConfig; + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private KeYParser createDeclParser() throws FileNotFoundException { + return new KeYParser(ParserMode.DECLARATION, + new KeYLexer(getNewStream(), + initConfig.getServices().getExceptionHandler()), + file.toString(), + initConfig.getServices().copy(), + initConfig.namespaces().copy()); } - /** returns the number of chars in the .key file. - */ - public int getNumberOfChars() { - return file.getNumberOfChars(); - } - - protected InputStream getNewStream() - throws FileNotFoundException { - try { - if (input != null) input.close(); - } catch(IOException ioe) { - System.err.println("WARNING: Cannot close stream "+file+"\n"+ioe); - } + protected InputStream getNewStream() throws FileNotFoundException { + close(); if (!file.isAvailable()) { - throw new FileNotFoundException("File/Resource " + file + " not found."); + throw new FileNotFoundException("File/Resource " + file + " not found."); } input = file.getNewStream(); return input; } - - /** reads the whole .key file and modifies the initial configuration - * assigned to this object according to the given modification strategy. - * Throws an exception if no initial configuration has been set yet. - */ - public void read(ModStrategy mod) throws ProofInputException { - if (initConfig==null) { - throw new IllegalStateException("KeYFile: InitConfig not set."); - } - try { - Debug.out("Reading KeY file", file); - CountingBufferedInputStream cinp = - new CountingBufferedInputStream - (getNewStream(),monitor,getNumberOfChars()/100); - - final NamespaceSet normal = initConfig.namespaces().copy(); - final NamespaceSet schema = setupSchemaNamespace(normal); - - final ParserConfig normalConfig = new ParserConfig - (initConfig.getServices(), normal); - final ParserConfig schemaConfig = new ParserConfig - (initConfig.getServices(), schema); - - problemParser = new KeYParser - (ParserMode.PROBLEM, new KeYLexer(cinp,initConfig.getServices().getExceptionHandler()), file.toString(), schemaConfig, normalConfig, initConfig. - getTaclet2Builder(), initConfig.getTaclets(), initConfig.getActivatedChoices()); - problemParser.problem(); - - - - - initConfig.addCategory2DefaultChoices(problemParser. - getCategory2Default()); - initConfig.setTaclets(problemParser.getTaclets()); - initConfig.add(normalConfig.namespaces(), mod); - if (initConfig.getProofEnv()!=null) { - initConfig.getProofEnv().addMethodContracts - (problemParser.getContracts(), null); - } - Debug.out("Read KeY file ", file); - } catch (antlr.ANTLRException e) { - throw new ProofInputException(e); - } catch (FileNotFoundException fnfe) { - throw new ProofInputException(fnfe); + + protected ProofSettings getPreferences() throws ProofInputException { + if (settings == null) { + if (file.isDirectory()) { + return null; + } + try { + KeYParser problemParser + = new KeYParser(ParserMode.PROBLEM, + new KeYLexer(getNewStream(), null), + file.toString()); + settings = new ProofSettings(ProofSettings.DEFAULT_SETTINGS); + settings.setProfile(ProofSettings.DEFAULT_SETTINGS.getProfile()); + settings.loadSettingsFromString(problemParser.preferences()); + } catch (antlr.ANTLRException e) { + throw new ProofInputException(e); + } catch (FileNotFoundException fnfe) { + throw new ProofInputException(fnfe); + } catch (de.uka.ilkd.key.util.ExceptionHandlerException ehe) { + throw new ProofInputException(ehe.getCause().getMessage()); + } } + return settings; } + /** * when reading in rules modal schema operators and schemavariables are * added to the namespace, but shall not occur in the normal function @@ -182,38 +164,69 @@ protected NamespaceSet setupSchemaNamespace(final NamespaceSet normal) { normal.choices(), normal.programVariables()); } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public String name() { + return name; + } + + + public RecoderModelTransformer getTransformer() { + return null; + } + + + public int getNumberOfChars() { + return file.getNumberOfChars(); + } + + + public void setInitConfig(InitConfig conf) { + this.initConfig=conf; + } + public Includes readIncludes() throws ProofInputException{ - if(file == null) return new Includes(); - try { - final ParserConfig pc = new ParserConfig - (new Services(), new NamespaceSet()); + try { + ParserConfig pc = new ParserConfig + (new Services(), + new NamespaceSet()); // FIXME: there is no exception handler here, thus, when parsing errors are ecountered - // during collection of includes (it is enough to mispell \include) the error - // message is very uninformative - ProofInputException without filename, line and column - // numbers. Somebody please fix that. /Woj - problemParser = new KeYParser - (ParserMode.PROBLEM, - new KeYLexer(getNewStream(),null), file.toString(), - pc, pc, null, null, null); + // during collection of includes (it is enough to mispell \include) the error + // message is very uninformative - ProofInputException without filename, line and column + // numbers. Somebody please fix that. /Woj + KeYParser problemParser = new KeYParser(ParserMode.PROBLEM, + new KeYLexer(getNewStream(), + null), + file.toString(), + pc, + pc, + null, + null, + null); problemParser.parseIncludes(); - return problemParser.getIncludes(); - } catch (antlr.ANTLRException e) { - throw new ProofInputException(e); + return problemParser.getIncludes(); + } catch (antlr.ANTLRException e) { + throw new ProofInputException(e); } catch (FileNotFoundException fnfe) { throw new ProofInputException(fnfe); } catch(de.uka.ilkd.key.util.ExceptionHandlerException ehe){ - throw new ProofInputException(ehe); - } + throw new ProofInputException(ehe); + } } - - + + public LibrariesSettings readLibrariesSettings() throws ProofInputException { - if (initConfig==null) { - throw new IllegalStateException("KeYFile: InitConfig not set."); - } - - if (settings == null) { + if (initConfig==null) { + throw new IllegalStateException("KeYFile: InitConfig not set."); + } + + if (settings == null) { getPreferences(); } @@ -227,16 +240,119 @@ public LibrariesSettings readLibrariesSettings() throws ProofInputException { return result; } + + public String readJavaPath() throws ProofInputException { + if (javaPathAlreadyParsed) { + return javaPath; + } + try { + KeYParser problemParser = new KeYParser(ParserMode.PROBLEM, + new KeYLexer(getNewStream(), + null), + file.toString()); + + problemParser.preferences(); // skip preferences + + ListOfString javaPaths = problemParser.javaSource(); + + if (javaPaths == null) { + // no java model at all + javaPath = null; + javaPathAlreadyParsed=true; + return null; + } + javaPath = (javaPaths.size() == 0 ? "" : javaPaths.head()); + + if(javaPaths.size() > 1) + Debug.fail("Don't know what to do with multiple Java paths."); + + javaPathAlreadyParsed=true; + + if (javaPath.length() != 0) { + File cfile = new File(javaPath); + if (!cfile.isAbsolute()) { // test relative pathname + File parent=file.file().getParentFile(); + cfile = new File(parent,javaPath). + getCanonicalFile().getAbsoluteFile(); + javaPath = cfile.getAbsolutePath(); + } + if (!cfile.exists()) { + throw new ProofInputException("Declared Java source " + + javaPath + " not found."); + } + } + return javaPath; + } catch (antlr.ANTLRException e) { + throw new ProofInputException(e); + } catch (IOException ioe) { + throw new ProofInputException(ioe); + } catch(de.uka.ilkd.key.util.ExceptionHandlerException ehe){ + ehe.printStackTrace(); + System.out.println(ehe.getCause().getMessage()); + throw new ProofInputException(ehe.getCause().getMessage()); + } + } + - private KeYParser createDeclParser() throws FileNotFoundException { - return new KeYParser(ParserMode.DECLARATION, - new KeYLexer(getNewStream(), - initConfig.getServices().getExceptionHandler()), - file.toString(), - initConfig.getServices().copy(), - initConfig.namespaces().copy()); + public void read(ModStrategy mod) throws ProofInputException { + if (initConfig==null) { + throw new IllegalStateException("KeYFile: InitConfig not set."); + } + + //read .key file + try { + Debug.out("Reading KeY file", file); + CountingBufferedInputStream cinp = + new CountingBufferedInputStream + (getNewStream(),monitor,getNumberOfChars()/100); + + final NamespaceSet normal = initConfig.namespaces().copy(); + final NamespaceSet schema = setupSchemaNamespace(normal); + + final ParserConfig normalConfig + = new ParserConfig(initConfig.getServices(), normal); + final ParserConfig schemaConfig + = new ParserConfig(initConfig.getServices(), schema); + + KeYParser problemParser + = new KeYParser(ParserMode.PROBLEM, + new KeYLexer(cinp, + initConfig.getServices() + .getExceptionHandler()), + file.toString(), + schemaConfig, + normalConfig, + initConfig.getTaclet2Builder(), + initConfig.getTaclets(), + initConfig.getActivatedChoices()); + problemParser.problem(); + initConfig.addCategory2DefaultChoices(problemParser. + getCategory2Default()); + SetOfTaclet st = problemParser.getTaclets(); + initConfig.setTaclets(st); + initConfig.add(normalConfig.namespaces(), mod); + + initConfig.getServices() + .getSpecificationRepository() + .addOperationContracts(problemParser.getContracts()); + chooseContract = problemParser.getChooseContract(); + Debug.out("Read KeY file ", file); + } catch (antlr.ANTLRException e) { + throw new ProofInputException(e); + } catch (FileNotFoundException fnfe) { + throw new ProofInputException(fnfe); + } + + //read JML specs + readJavaPath(); + if(parseSpecs && javaPath != null) { + SLEnvInput slEnvInput = new SLEnvInput(javaPath); + slEnvInput.setInitConfig(initConfig); + slEnvInput.read(mod); + } } + /** reads the sorts declaration of the .key file only, * modifying the sort namespace * of the initial configuration if allowed in the given @@ -255,6 +371,7 @@ public void readSorts(ModStrategy mod) throws ProofInputException { } } + /** reads the functions and predicates declared in the .key file only, * modifying the function namespaces of the respective taclet options. */ @@ -271,40 +388,36 @@ public void readFuncAndPred(ModStrategy mod) throws ProofInputException { } } + /** reads the rules and problems declared in the .key file only, * modifying the set of rules * of the initial configuration if allowed in the given * modification strategy. */ - public void readRulesAndProblem(ModStrategy mod) - throws ProofInputException { - - /* - two namespace sets which share all namespace except the - variable and function namespace - */ + public void readRulesAndProblem(ModStrategy mod) + throws ProofInputException { final NamespaceSet normal = initConfig.namespaces().copy(); final NamespaceSet schema = setupSchemaNamespace(normal); - final ParserConfig schemaConfig = new ParserConfig(initConfig.getServices(), schema); - final ParserConfig normalConfig = new ParserConfig(initConfig.getServices(), normal); + try { final CountingBufferedInputStream cinp = new CountingBufferedInputStream (getNewStream(),monitor,getNumberOfChars()/100); - problemParser = new KeYParser(ParserMode.PROBLEM, - new KeYLexer(cinp, - initConfig.getServices(). - getExceptionHandler()), - file.toString(), - schemaConfig, - normalConfig, - initConfig.getTaclet2Builder(), - initConfig.getTaclets(), - initConfig.getActivatedChoices()); + KeYParser problemParser + = new KeYParser(ParserMode.PROBLEM, + new KeYLexer(cinp, + initConfig.getServices() + .getExceptionHandler()), + file.toString(), + schemaConfig, + normalConfig, + initConfig.getTaclet2Builder(), + initConfig.getTaclets(), + initConfig.getActivatedChoices()); problemParser.parseTacletsAndProblem(); initConfig.add(normalConfig.namespaces(), mod); initConfig.setTaclets(problemParser.getTaclets()); @@ -315,53 +428,6 @@ public void readRulesAndProblem(ModStrategy mod) } } - - public void readProblem(ModStrategy mod) throws ProofInputException { - readRulesAndProblem(mod); - } - - - public void setInitConfig(InitConfig conf) { - this.initConfig=conf; - } - - - /** reads a saved proof of a .key file - */ - public void readProof(ProblemLoader prl) throws ProofInputException { - try { - problemParser.proof(prl); - } catch(antlr.ANTLRException e) { - throw new ProofInputException(e); - } - } - - public ProofSettings getPreferences() throws ProofInputException { - if (settings == null) { - if (file.isDirectory()) return null; - try { - problemParser = new KeYParser(ParserMode.PROBLEM, - new KeYLexer(getNewStream(),null), file.toString()); - settings = new ProofSettings(ProofSettings.DEFAULT_SETTINGS); - settings.setProfile(ProofSettings.DEFAULT_SETTINGS.getProfile()); - settings.loadSettingsFromString(problemParser.preferences()); - } catch (antlr.ANTLRException e) { - throw new ProofInputException(e); - } catch (FileNotFoundException fnfe) { - throw new ProofInputException(fnfe); - } catch (de.uka.ilkd.key.util.ExceptionHandlerException ehe) { - throw new ProofInputException(ehe.getCause().getMessage()); - } - } - return settings; - } - - /** returns the name of the .key file - */ - public String name() { - return name; - } - public void close() { try { if (input != null) { @@ -371,84 +437,33 @@ public void close() { System.err.println("WARNING: Cannot close stream "+file+"\n"+ioe); } } + + + public boolean chooseContract() { + return chooseContract; + } + public String toString() { return name()+" "+file.toString(); } + public boolean equals(Object o){ - if(!(o instanceof KeYFile)) return false; + if(!(o instanceof KeYFile)) { + return false; + } KeYFile kf = (KeYFile) o; - if(file != null && kf.file != null){ - return kf.file.getExternalForm(). - equals(file.getExternalForm()); - } - return false; + return kf.file.getExternalForm().equals(file.getExternalForm()); + } + public int hashCode(){ final String externalForm = file.getExternalForm(); - if (externalForm == null) + if (externalForm == null) { return -1; + } return externalForm.hashCode(); } - - public Contractable[] getObjectOfContract() { - return new Contractable[0]; - } - - public boolean initContract(Contract ct) { - return false; - } - - - public String readJavaPath() throws ProofInputException { - if (javaPathAlreadyParsed) return javaPath; - try { - problemParser = new KeYParser(ParserMode.PROBLEM, - new KeYLexer(getNewStream(),null), - file.toString()); - - problemParser.preferences(); // skip preferences - - ListOfString javaPaths = problemParser.javaSource(); - - - if (javaPaths == null) { - // no java model at all - javaPath = null; - javaPathAlreadyParsed=true; - return null; - } - javaPath = (javaPaths.size() == 0 ? "" : javaPaths.head()); - - if(javaPaths.size() > 1) - Debug.fail("Don't know what to do with multiple Java paths."); - - javaPathAlreadyParsed=true; - - if (javaPath.length() != 0) { - File cfile = new File(javaPath); - if (!cfile.isAbsolute()) { // test relative pathname - File parent=file.file().getParentFile(); - cfile = new File(parent,javaPath). - getCanonicalFile().getAbsoluteFile(); - javaPath = cfile.getAbsolutePath(); - } - if (!cfile.exists()) { - throw new ProofInputException("Declared Java source " - + javaPath + " not found."); - } - } - return javaPath; - } catch (antlr.ANTLRException e) { - throw new ProofInputException(e); - } catch (IOException ioe) { - throw new ProofInputException(ioe); - } catch(de.uka.ilkd.key.util.ExceptionHandlerException ehe){ - ehe.printStackTrace(); - System.out.println(ehe.getCause().getMessage()); - throw new ProofInputException(ehe.getCause().getMessage()); - } - } } diff --git a/system/de/uka/ilkd/key/proof/init/KeYFileForTests.java b/system/de/uka/ilkd/key/proof/init/KeYFileForTests.java index fdf824093b7..e292923802f 100644 --- a/system/de/uka/ilkd/key/proof/init/KeYFileForTests.java +++ b/system/de/uka/ilkd/key/proof/init/KeYFileForTests.java @@ -29,7 +29,7 @@ public class KeYFileForTests extends KeYFile { * and a file representing the physical source of the .key file. */ public KeYFileForTests(String name, File file) { - super(name, file, null); + super(name, file, null, false); } /** reads the whole .key file and modifies the initial configuration @@ -47,7 +47,7 @@ public void read(ModStrategy mod) throws ProofInputException { final ParserConfig pc = new ParserConfig(initConfig.getServices().copy(), initConfig.namespaces().copy()); - problemParser = new KeYParser + KeYParser problemParser = new KeYParser (ParserMode.PROBLEM,new KeYLexer(cinp,null), file.toString(), pc, pc,initConfig. getTaclet2Builder(), initConfig.getTaclets(),initConfig.getActivatedChoices()); problemParser.problem(); diff --git a/system/de/uka/ilkd/key/proof/init/KeYJMLInput.java b/system/de/uka/ilkd/key/proof/init/KeYJMLInput.java deleted file mode 100644 index fcfc8b21656..00000000000 --- a/system/de/uka/ilkd/key/proof/init/KeYJMLInput.java +++ /dev/null @@ -1,78 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2003 Universitaet Karlsruhe, Germany -// and Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.proof.init; - -import java.io.File; - -import de.uka.ilkd.key.gui.configuration.ProofSettings; -import de.uka.ilkd.key.java.CompilationUnit; -import de.uka.ilkd.key.java.ConvertException; -import de.uka.ilkd.key.util.ProgressMonitor; - - -/** - * sub-class of JavaInputWithJMLSpecBrowser which is used to parse just a - * single JML-enriched java source file. - * @deprecated - */ -public class KeYJMLInput extends JavaInputWithJMLSpecBrowser { - - public KeYJMLInput(String name, File file, boolean allIntMode, - ProgressMonitor monitor){ - super(name, file, allIntMode, monitor); - } - - public ProofSettings getPreferences() { - settings = ProofSettings.DEFAULT_SETTINGS; - return settings; - } - - public String readJavaPath() throws ProofInputException { - assert path != null; - if(path.getParentFile() != null) { - return path.getParentFile().getAbsolutePath(); - } else { - return "./"; - } - } - - - public void readJML(CompilationUnit[] compUnits) throws ProofInputException { - try { - parseJMLSpecs(getTypesWithJMLSpecs(compUnits)); - // initConfig.getServices().getImplementation2SpecMap().setProgVarNS( - // initConfig.progVarNS()); - } catch (ConvertException ce) { - throw new ProofInputException(ce); - } - } - - /* - public String readModel() throws ProofInputException{ - try { - parseJMLSpecs(getTypesWithJMLSpecs( - getKeYJavaASTConverter(). - readCompilationUnitsAsFiles( - new String[]{path.getPath()}))); - // initConfig.getServices().getImplementation2SpecMap().setProgVarNS( - // initConfig.progVarNS()); - } catch (ConvertException ce) { - throw new ProofInputException(ce); - } - return null; - }*/ -} diff --git a/system/de/uka/ilkd/key/proof/init/KeYUserProblemFile.java b/system/de/uka/ilkd/key/proof/init/KeYUserProblemFile.java index 55b7195bd6b..ea7b56c69f3 100644 --- a/system/de/uka/ilkd/key/proof/init/KeYUserProblemFile.java +++ b/system/de/uka/ilkd/key/proof/init/KeYUserProblemFile.java @@ -11,461 +11,184 @@ import java.io.File; import java.io.FileNotFoundException; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Set; -import de.uka.ilkd.key.gui.Main; -import de.uka.ilkd.key.gui.UsedMethodContractsList; -import de.uka.ilkd.key.java.CompilationUnit; -import de.uka.ilkd.key.java.JavaInfo; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.IteratorOfType; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.abstraction.ListOfType; -import de.uka.ilkd.key.java.abstraction.SLListOfType; -import de.uka.ilkd.key.java.declaration.ArrayOfTypeDeclaration; -import de.uka.ilkd.key.java.declaration.ClassDeclaration; -import de.uka.ilkd.key.java.declaration.InterfaceDeclaration; -import de.uka.ilkd.key.java.declaration.TypeDeclaration; -import de.uka.ilkd.key.jml.IteratorOfJMLMethodSpec; -import de.uka.ilkd.key.jml.JMLMethodSpec; -import de.uka.ilkd.key.jml.SetOfJMLMethodSpec; -import de.uka.ilkd.key.logic.Choice; +import de.uka.ilkd.key.gui.configuration.ProofSettings; import de.uka.ilkd.key.logic.NamespaceSet; import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.parser.*; -import de.uka.ilkd.key.parser.jml.JMLSpecBuilder; import de.uka.ilkd.key.proof.CountingBufferedInputStream; +import de.uka.ilkd.key.proof.ProblemLoader; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.mgt.*; import de.uka.ilkd.key.util.ProgressMonitor; -/** represents an input from a .key user problem file producing environment - * as well as a proof obligation. + +/** + * Represents an input from a .key user problem file producing an environment + * as well as a proof obligation. */ public class KeYUserProblemFile extends KeYFile implements ProofOblInput{ private Term problemTerm = null; private String problemHeader = ""; - - // if false only the specifications of Object and Datagroup are read. - // The parsing of javacode and specifications of nonlibrary classes - // is not affected by this flag. - public static boolean parseLibSpecs = false; - // for disabling the parsing of java classes and their - // jmlspecs when running tests - private boolean parseJMLSpecs; - - - private boolean chooseDLContract = false; - protected boolean tacletFile = false; - - /** creates a new representation of a KeYUserFile with the given name, + + private KeYParser lastParser; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + /** + * Creates a new representation of a KeYUserFile with the given name, * a rule source representing the physical source of the input, and * a graphical representation to call back in order to report the progress * while reading. */ - public KeYUserProblemFile(String name, File file, - ProgressMonitor monitor) { - this(name, file, monitor, true); + public KeYUserProblemFile(String name, + File file, + ProgressMonitor monitor, + boolean parseJMLSpecs) { + super(name, file, monitor, parseJMLSpecs); } - - public KeYUserProblemFile(String name, File file, - ProgressMonitor monitor, boolean parseJMLSpecs) { - super(name, file, monitor); - this.parseJMLSpecs = parseJMLSpecs; + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public boolean askUserForEnvironment() { + return true; } - public void readHelp(ModStrategy mod, boolean problemOnly) - throws ProofInputException { - if(file == null) return; - if (initConfig==null) { - throw new IllegalStateException("KeYFile: InitConfig not set."); - } - try { - final CountingBufferedInputStream cinp = - new CountingBufferedInputStream - (getNewStream(),monitor,getNumberOfChars()/100); - final DeclPicker lexer = new DeclPicker(new KeYLexer(cinp,initConfig.getServices().getExceptionHandler())); + + public void readActivatedChoices() throws ProofInputException{ + if (initConfig==null) { + throw new IllegalStateException("KeYFile: InitConfig not set."); + } + try { + ProofSettings settings = getPreferences(); + + ParserConfig pc = new ParserConfig + (initConfig.getServices(), + initConfig.namespaces()); + KeYParser problemParser = new KeYParser + (ParserMode.PROBLEM, new KeYLexer(getNewStream(), + initConfig.getServices().getExceptionHandler()), + file.toString(), pc, pc, null, null, null); + problemParser.parseWith(); + + settings.getChoiceSettings(). + updateWith(problemParser.getActivatedChoices()); + + initConfig.setActivatedChoices(settings.getChoiceSettings(). + getDefaultChoicesAsSet()); + + } catch (antlr.ANTLRException e) { + throw new ProofInputException(e); + } catch (FileNotFoundException fnfe) { + throw new ProofInputException(fnfe); + } + } - /* - two namespace sets which share all namespace except the - variable namespace - */ - final NamespaceSet normal = initConfig.namespaces().copy(); - final NamespaceSet schema = setupSchemaNamespace(normal); - final ParserConfig normalConfig - = new ParserConfig(initConfig.getServices(), normal); - final ParserConfig schemaConfig - = new ParserConfig(initConfig.getServices(), schema); - problemParser = new KeYParser(ParserMode.PROBLEM, lexer, - file.toString(), - schemaConfig, - normalConfig, - initConfig.getTaclet2Builder(), - initConfig.getTaclets(), - initConfig.getActivatedChoices()); - if (problemOnly) { - problemTerm = problemParser.parseProblem(); - } else { - problemTerm = problemParser.problem(); - } - String searchS = "\\problem"; - + public void readProblem(ModStrategy mod) throws ProofInputException { + if (initConfig==null) { + throw new IllegalStateException("KeYUserProblemFile: InitConfig not set."); + } + + try { + CountingBufferedInputStream cinp = + new CountingBufferedInputStream + (getNewStream(),monitor,getNumberOfChars()/100); + DeclPicker lexer = new DeclPicker(new KeYLexer(cinp,initConfig.getServices().getExceptionHandler())); + + final NamespaceSet normal = initConfig.namespaces().copy(); + final NamespaceSet schema = setupSchemaNamespace(normal); + + final ParserConfig normalConfig + = new ParserConfig(initConfig.getServices(), normal); + final ParserConfig schemaConfig + = new ParserConfig(initConfig.getServices(), schema); + + KeYParser problemParser + = new KeYParser(ParserMode.PROBLEM, + lexer, + file.toString(), + schemaConfig, + normalConfig, + initConfig.getTaclet2Builder(), + initConfig.getTaclets(), + initConfig.getActivatedChoices()); + problemTerm = problemParser.parseProblem(); + String searchS = "\\problem"; + if(problemTerm == null) { - chooseDLContract = problemParser.getChooseContract(); + boolean chooseDLContract = problemParser.getChooseContract(); if(chooseDLContract) searchS = "\\chooseContract"; else { - if(!tacletFile) { - throw new ProofInputException("No \\problem or \\chooseContract in the input file!"); - } + throw new ProofInputException("No \\problem or \\chooseContract in the input file!"); } } + problemHeader = lexer.getText(); if(problemHeader != null && - problemHeader.lastIndexOf(searchS) != -1){ - problemHeader = problemHeader.substring( - 0, problemHeader.lastIndexOf(searchS)); - } - initConfig.setTaclets(problemParser.getTaclets()); - initConfig.add(normalConfig.namespaces(), mod); - - if(!problemOnly) { - initConfig.getProofEnv().addMethodContracts( - problemParser.getContracts(), problemHeader); - } - } catch (antlr.ANTLRException e) { - throw new ProofInputException(e); + problemHeader.lastIndexOf(searchS) != -1){ + problemHeader = problemHeader.substring( + 0, problemHeader.lastIndexOf(searchS)); + } + initConfig.setTaclets(problemParser.getTaclets()); + initConfig.add(normalConfig.namespaces(), mod); + lastParser = problemParser; + } catch (antlr.ANTLRException e) { + throw new ProofInputException(e); } catch (FileNotFoundException fnfe) { throw new ProofInputException(fnfe); } } - /** reads the whole .key file and modifies the initial configuration - * assigned to this object according to the given modification strategy. - * Throws an exception if no initial configuration has been set yet. - */ - public void read(ModStrategy mod) throws ProofInputException { - readHelp(mod, false); - } - - /** reads the the problem section of the .key file and modifies - * the initial configuration assigned to this object according to - * the given modification strategy. Throws an exception if no - * initial configuration has been set yet. - */ - public void readProblem(ModStrategy mod) throws ProofInputException { - readHelp(mod, true); - } - - public ProofAggregate getPO() { - + + public ProofAggregate getPO() throws ProofInputException { + assert problemTerm != null; String name = name(); - - if(problemTerm == null && chooseDLContract) { - Iterator it = initConfig.getProofEnv().getSpecificationRepository().getSpecs(); - ContractSet contracts = new ContractSet(); - while (it.hasNext()) { - ContractSet c = (ContractSet)it.next(); - contracts.addAll(c); - } - final ContractSet res = new ContractSet(); - it = contracts.iterator(); - while (it.hasNext()) { - Contract c = (Contract)it.next(); - if(c instanceof DLMethodContract) - res.add(c); - } - - UsedMethodContractsList fr = UsedMethodContractsList. - getInstance(Main.getInstance(false).mediator(), res); - fr.setVisible(true); - DLMethodContract c = (DLMethodContract)fr.getContract(); - if(c == null) return null; - // Transform the header - c.setHeader(problemHeader); - problemHeader = c.getHeader(); - DLHoareTriplePO poi = (DLHoareTriplePO)c.getProofOblInput(null); - initConfig.getServices().getNamespaces(). - programVariables().add(c.getProgramVariables()); - if(poi != null) { - problemTerm = poi.getTerm(); - name = poi.name(); - ProofAggregate po = ProofAggregate.createProofAggregate( - new Proof(name, problemTerm, problemHeader, - initConfig.createTacletIndex(), - initConfig.createBuiltInRuleIndex(), - initConfig.getServices(), settings), name); - poi.setPO(po); - poi.initContract(c); - return po; - } - return null; - }else{ - return ProofAggregate.createProofAggregate( - new Proof(name, problemTerm, problemHeader, - initConfig.createTacletIndex(), - initConfig.createBuiltInRuleIndex(), - initConfig.getServices(), settings), name); - } - } - - /** returns the java.io.file file encapsulated by - * the KeYUserProblemFile. - */ - public File getFile(){ - return file.file(); + ProofSettings settings = getPreferences(); + return ProofAggregate.createProofAggregate( + new Proof(name, + problemTerm, + problemHeader, + initConfig.createTacletIndex(), + initConfig.createBuiltInRuleIndex(), + initConfig.getServices(), + settings), + name); } - /** - * @return Returns the problemHeader. - */ - protected String getProblemHeader () { - return problemHeader; - } - - /** returns true, that is the input asks the user which - * environment he prefers if there are multiple possibilities + + /** + * Reads a saved proof of a .key file. */ - public boolean askUserForEnvironment() { - return true; - } - - public void readSpecs(){ - Services serv = initConfig.getServices(); - ProgramMethod meth; - Iterator it; - if(method2jmlspecs != null && !method2jmlspecs.isEmpty()){ - it = method2jmlspecs.keySet().iterator(); - while(it.hasNext()){ - meth = (ProgramMethod) it.next(); - if(method2jmlspecs.get(meth) != null){ - IteratorOfJMLMethodSpec sit = - ((SetOfJMLMethodSpec) - method2jmlspecs.get(meth)). - iterator(); - while(sit.hasNext()){ - JMLMethodSpec jmlspec = sit.next(); - createJMLMethodContract(meth, jmlspec); - } - } - } - } - if(parseJMLSpecs){ - final Set kjts = serv.getJavaInfo().getAllKeYJavaTypes(); - it = kjts.iterator(); - while(it.hasNext()){ - final KeYJavaType kjt = (KeYJavaType) it.next(); - if(!(kjt.getJavaType() instanceof InterfaceDeclaration - || kjt.getJavaType() instanceof ClassDeclaration)){ - continue; - } - ListOfProgramMethod ml = serv.getJavaInfo().getAllProgramMethodsLocallyDeclared(kjt); - IteratorOfProgramMethod mit = ml.iterator(); - IteratorOfJMLMethodSpec sit; - JMLMethodSpec jmlspec; - while(mit.hasNext()){ - meth = mit.next(); - SetOfJMLMethodSpec specs = - serv.getImplementation2SpecMap(). - getSpecsForMethod(meth); - if(specs != null){ - sit = specs.iterator(); - while(sit.hasNext()){ - jmlspec = sit.next(); - createJMLMethodContract(meth, jmlspec); - } - } - sit = serv.getImplementation2SpecMap(). - getInheritedMethodSpecs(meth, kjt).iterator(); - while(sit.hasNext()){ - jmlspec = sit.next(); - createJMLMethodContract(meth, jmlspec); - } - } - } - } - } - - private void createJMLMethodContract(Object meth, JMLMethodSpec jmlspec){ - Modality[] allMod = new Modality[]{Op.DIA, Op.BOX}; - String jp = null; - if(!jmlspec.isValid()) return; - try{ - jp = readJavaPath(); - }catch(ProofInputException e){ - e.printStackTrace(); - } - for (int i=0; i= 0){ - signatureList = signatureList.prepend((Type) parameterTypes. - elementAt(index)); - index = index - 1; - } - return signatureList; - } - - protected void collectOccuringClasses(KeYJavaType type) { - ProgramTypeCollector mCollector = - new ProgramTypeCollector(m, self, type, initConfig.getServices(), - new HashSet()); - mCollector.start(); - occuringClasses = mCollector.getResult(); - - if (type!= null) { - occuringClasses.add(type); - } - - // get the transitive closure of the occuring classes in the - // sense that for each class the type of all its' attributes - // is in the resulting Set - - Set occuringClassesToAdd = (HashSet) ((HashSet) occuringClasses).clone(); - KeYJavaType current = null; - while (!(occuringClassesToAdd.isEmpty())){ - current = (KeYJavaType) occuringClassesToAdd.iterator().next(); - - Type currClassType = current.getJavaType(); - KeYJavaType currentBase = current; - while (currClassType instanceof ArrayDeclaration) { - currentBase = ((ArrayDeclaration) currClassType). - getBaseType().getKeYJavaType(); - currClassType = currentBase.getJavaType(); - } - if (!(currClassType instanceof PrimitiveType || - currClassType instanceof NullType)){ - // get all attributes of the given class - ListOfField allAttributes = - javaInfo.getKeYProgModelInfo().getAllFieldsLocallyDeclaredIn(currentBase); - - IteratorOfField iterateAttributes = allAttributes.iterator(); - - - while (iterateAttributes.hasNext()){ - final ProgramVariable att = - (ProgramVariable) - iterateAttributes.next().getProgramVariable(); - - if (!att.isImplicit()){ - final KeYJavaType addToOccCla = - (KeYJavaType) att.getKeYJavaType(); - if (!(occuringClasses.contains(addToOccCla))){ - occuringClasses.add(addToOccCla); - occuringClassesToAdd.add(addToOccCla); - } - } - } - } - occuringClassesToAdd.remove(current); - } - } - - - protected Term createProof() { - Term formula; - if(self != null){ - formula = tf.createJunctorTermAndSimplify - (Op.IMP, tf.createJunctorTerm - (Op.NOT, tf.createEqualityTerm - (tf.createVariableTerm(self), - tf.createFunctionTerm(Op.NULL))), - createProofStart()); - }else{ - formula = createProofStart(); - } - return formula; - } - - protected Term createProofStart() { - Iterator iterateClasses = occuringClasses.iterator(); - Term accumulateClassFormulas = - tf.createJunctorTerm(Op.TRUE); - KeYJavaType currClass; - while (iterateClasses.hasNext()) { - currClass = (KeYJavaType) iterateClasses.next(); - if(javaInfo.getNullType()!=currClass){ - accumulateClassFormulas = - tf.createJunctorTermAndSimplify - (Op.AND, createClassFormula(currClass), - accumulateClassFormulas); - } - } - return tf.createJunctorTermAndSimplify - (Op.IMP, tf.createFunctionTerm(javaInfo.getInReachableState()), - accumulateClassFormulas); - } - - private Term createClassFormula(KeYJavaType currClass){ - LogicVariable oprime = new LogicVariable - (new Name("o"), - currClass.getSort()); - - // generate formula starting with \forall o': currClass - Term classFormula = tf.createQuantifierTerm - (Op.ALL, - oprime , - createClassSubFormula(currClass, oprime)); - - - return classFormula; - } - - private Term createClassSubFormula(KeYJavaType currClass, - LogicVariable oprime){ - Type currClassType = currClass.getJavaType(); - // stop primitive types from getting checked for attributes, there are - // none anyway - if (currClassType instanceof PrimitiveType) - {return tf.createJunctorTerm(Op.TRUE);} - - Term classSubFormula; - - ListOfField allAttributes; - // get all attributes of the given class - if (currClassType instanceof ClassDeclaration) { - allAttributes = javaInfo.getKeYProgModelInfo().getAllFieldsLocallyDeclaredIn - (javaInfo.getKeYJavaType(currClassType)); - IteratorOfField iterateAttributes = allAttributes.iterator(); - - // initial value is TRUE which is the value of an empty conjunction - // as this formula is a conjunction this is the correct value in - // case there are no elements - Term accumulateAttributeFormulas = - tf.createJunctorTerm(Op.TRUE); - - ProgramVariable currAttribute = null; - - while (iterateAttributes.hasNext()){ - currAttribute = (ProgramVariable) - iterateAttributes.next().getProgramVariable(); - - accumulateAttributeFormulas = - tf.createJunctorTermAndSimplify - (Op.AND, - createAttributeFormula(currAttribute, currClass, oprime), - accumulateAttributeFormulas); - } - - classSubFormula = accumulateAttributeFormulas; - - }else { - // maybe check whether it is an ArrayDeclaration with test below: - // check it; may be artificial nulltype - if (currClassType instanceof ArrayDeclaration) { - classSubFormula = createArrayFormula(currClass, oprime); - } else { - // is this correct? - classSubFormula = tf.createJunctorTerm(Op.TRUE); - } - } - - Term nullTerm = tf.createFunctionTerm(Op.NULL); - Term ov = tf.createVariableTerm(oprime); - Term nn = tf.createJunctorTerm( - Op.NOT, tf.createEqualityTerm(ov, nullTerm)); - - Term eqc = UsefulTools.isCreated(ov, initConfig.getServices()); - ProgramVariable ci = - initConfig.getServices().getJavaInfo(). - getAttribute(ImplicitFieldAdder.IMPLICIT_CLASS_INITIALIZED, - (ObjectSort) oprime.sort()); - - Term eqi = tf.createEqualityTerm( - tf.createVariableTerm(ci), initConfig.getServices(). - getTypeConverter().convertToLogicElement(BooleanLiteral.TRUE)); - eqc = tf.createJunctorTermAndSimplify(Op.AND, eqc, eqi); - classSubFormula = tf.createJunctorTermAndSimplify( - Op.IMP, tf.createJunctorTerm(Op.AND, nn, eqc), classSubFormula); - return classSubFormula; - } - - - private Term createAttributeFormula(ProgramVariable currAttribute, - KeYJavaType currClass, - LogicVariable oprime) { - if (!currAttribute.isImplicit()){ - - // create conjunction of o' != o111, o' != o112, ... for non-static - // create "false" in case of a static attribute which is part of - // the modifies clause and "true" if it not part of the m.c. - - // some initial value - Term ante = tf.createJunctorTerm(Op.TRUE); - - IteratorOfTerm modifiesIterator = modifiesElements.iterator(); - TypeConverter typeConv = - initConfig.getServices().getTypeConverter(); - final Term t_oprime = tf.createVariableTerm(oprime); - - while (modifiesIterator.hasNext()) { - Term modTerm = modifiesIterator.next(); - - if ( (!(modTerm.op() instanceof ProgramVariable) || - ((ProgramVariable)modTerm.op()).isStatic()) && - ! (modTerm.op() instanceof ArrayOp)){ - ante = createModifiesFormulaForAttribute(currAttribute, - currClass, ante, modTerm, typeConv, t_oprime); - } else { - if (modTerm.op() instanceof ProgramVariable) { - // The modifies element has been a single ProgramVariable, - // meaning no dereferencing has happened. In this case there - // is nothing that can be done because this shouldn't happen - // Only attributes can be changed and thus only those are - // relevant in the modifies clause. - // THROW EXCEPTION HERE !!! - System.out.println("Error - Element with no dereferencing "+ - "in the modifies clause: " + modTerm); - } - if (modTerm.op() instanceof ArrayOp) { - // nothing to do here as an array element is not - // relevant for a normal attribute - } - } - } - - // create part after the implication arrow - LogicVariable x = new LogicVariable - (new Name("x"), - currAttribute.getKeYJavaType().getSort()); - - // Create the MethodReference belonging to the method whose modifies - // clause is being checked here. - Expression[] p = new Expression[pvVector.size()]; - for (int i = 0; i < pvVector.size(); i = i+1) { - p[i] = (ProgramVariable) pvVector.elementAt(i); - } - - StatementBlock mBlock = createMethodCall(p); - - - final Term t_x = tf.createVariableTerm(x); - final Term primedAttribute = - tf.createAttributeTerm(currAttribute, t_oprime); - - Term post = tf.createQuantifierTerm - (Op.ALL, x, tf.createJunctorTermAndSimplify - (Op.IMP, tf.createEqualityTerm(t_x, primedAttribute), - tf.createBoxTerm - (JavaBlock.createJavaBlock(mBlock), - tf.createEqualityTerm - (t_x, primedAttribute)))); - - return tf.createJunctorTermAndSimplify(Op.IMP, ante, post); - } - else { - return tf.createJunctorTerm(Op.TRUE); - } - } - - /** - * @param currAttribute - * @param currClass - * @param ante - * @param modProgVar - * @param typeConv - * @param t_oprime - * @return - */ - private Term createModifiesFormulaForAttribute - (ProgramVariable currAttribute, KeYJavaType currClass, - Term ante, Term modTerm, TypeConverter typeConv, final Term t_oprime){ - - // static attribute - if (modTerm.op() instanceof ProgramVariable) { - // Check if the attributes match - if (modTerm.op()==currAttribute){ - // build formula - ante = tf.createJunctorTerm(Op.FALSE); - } - }else { - ProgramVariable modProgAttrib = (ProgramVariable) - ((AttributeOp) modTerm.op()).attribute(); - BasicLocationDescriptor bloc = (BasicLocationDescriptor) - location2descriptor.get(modTerm); - modTerm = modTerm.sub(0); - - KeYJavaType classType = javaInfo.getKeYJavaType(modTerm.sort()); - // Check if the Class Types match - if (classType == currClass) { - // Check if the attributes match - if (modProgAttrib == currAttribute){ - Term anteSub = tf. createJunctorTerm(Op.NOT, - tf.createEqualityTerm - (t_oprime, modTerm)); - anteSub = tf.createJunctorTermAndSimplify(Op.IMP, - bloc.getFormula(), - anteSub); - // quantify free variables in the prefix - if(modTerm.freeVars().size() >0){ - anteSub = tf.createQuantifierTerm - (Op.ALL, new ArrayOfQuantifiableVariable - (modTerm.freeVars().toArray()), anteSub); - } - // build formula - ante = tf.createJunctorTermAndSimplify - (Op.AND, anteSub, ante); - } - } - } - return ante; - - } - - - private Term createArrayFormula(KeYJavaType currClass, - LogicVariable oprime) { - // create conjunction of o' != o111, o' != o112, ... - // all this with a "check" before it for the right array index - - TypeConverter typeConv = - initConfig.getServices().getTypeConverter(); - - LogicVariable lambda = new LogicVariable - (new Name("lambda"), - typeConv.getIntegerLDT().targetSort()); - - // initial value true, as it is the value of an empty conjunction - // and our terms are connected conjunctively - Term ante = - tf.createJunctorTerm(Op.TRUE); - - IteratorOfTerm modifiesIterator = modifiesElements.iterator(); - while (modifiesIterator.hasNext()) { - Term modTerm = modifiesIterator.next(); - // modElm = typeConv.convertToProgramElement(modTerm); - - // modProgVar = modElm; - - //check whether it is appropriate to add this to the ante - // if (modProgVar instanceof ArrayReference){ - if(modTerm.op() instanceof ArrayOp && - javaInfo.getKeYJavaType(modTerm.sub(0).sort())==currClass){ - Term preCond = tf.createJunctorTerm(Op.TRUE); - if(modTerm.sub(1).freeVars().size() == 0){ - preCond = tf.createEqualityTerm - (modTerm.sub(1), tf.createVariableTerm(lambda)); - } - Debug.assertTrue(modTerm.sub(1).freeVars().size() <= 1); - BasicLocationDescriptor bloc = (BasicLocationDescriptor) - location2descriptor.get(modTerm); - HashMap replaceMap = new HashMap(); - replaceMap.put(modTerm.sub(1).freeVars().iterator().next(), - lambda); - OpReplacer or = new OpReplacer(replaceMap); - preCond = - tf.createJunctorTermAndSimplify(Op.AND, preCond, - or.replace(bloc.getFormula())); - // o' != o_ij - Term postCond = tf.createJunctorTerm - (Op.NOT, tf.createEqualityTerm - (tf.createVariableTerm(oprime), modTerm.sub(0))); - - Term cond = - tf.createJunctorTermAndSimplify(Op.IMP, preCond, postCond); - - // quantify free variables in the prefix - if(modTerm.sub(0).freeVars().size() >0){ - cond = tf.createQuantifierTerm - (Op.ALL, new ArrayOfQuantifiableVariable - (modTerm.sub(0).freeVars().toArray()), cond); - } - - // build parts together into the ante formula - ante = tf.createJunctorTermAndSimplify(Op.AND, cond, ante); - } else { - // The modifies element has not been an ArrayReference, - // that means it has nothing to do with the current class/array - // as that is an array and we can thus ignore this element of - // the modifies clause - } - } - - // create part after the outer implication arrow - LogicVariable x = new LogicVariable - (new Name("x"), - ((ArrayDeclaration) currClass.getJavaType()).getBaseType().getKeYJavaType().getSort() - ); - - // Create the MethodReference belonging to the method whose modifies - // clause is being checked here. - Expression[] p = new Expression[pvVector.size()]; - for (int i = 0; i < pvVector.size(); i = i+1) { - p[i] = (ProgramVariable) pvVector.elementAt(i); - } - - StatementBlock mBlock = createMethodCall(p); - - Term equality = tf.createEqualityTerm - (tf.createVariableTerm(x), - tf.createArrayTerm - (ArrayOp.getArrayOp(oprime.sort()), - tf.createVariableTerm(oprime), - tf.createVariableTerm(lambda)) ); - - Term post = tf.createQuantifierTerm - (Op.ALL, x, - tf.createJunctorTermAndSimplify - (Op.IMP, equality, - tf.createBoxTerm - (JavaBlock.createJavaBlock(mBlock), equality))); - - - Term arrayFormula = tf. - createJunctorTermAndSimplify(Op.IMP, ante, post); - - - // helpers for the next block below - final Function leq = typeConv.getIntegerLDT().getLessOrEquals(); - final Function lt = typeConv.getIntegerLDT().getLessThan(); - final Term zero = - typeConv.getIntegerLDT().translateLiteral(new IntLiteral(0)); - final Term validArrayTerm0 = tf.createFunctionTerm - (leq, zero, tf.createVariableTerm(lambda)); - final ProgramVariable lengthPV = (ProgramVariable) - ((ArrayDeclaration) currClass.getJavaType()).length() - .getFieldSpecifications().getFieldSpecification(0) - .getProgramVariable(); - final Term lengthTerm = tf.createAttributeTerm - (lengthPV, tf.createVariableTerm(oprime)); - final Term validArrayTerm1 = tf.createFunctionTerm - (lt, tf.createVariableTerm(lambda), lengthTerm); - - // creates the 0<= lambda /\ lambda < o'.length() -> rest - arrayFormula = tf.createJunctorTermAndSimplify - (Op.IMP, tf.createJunctorTermAndSimplify - (Op.AND, validArrayTerm0, validArrayTerm1), - arrayFormula); - - // generate and return formula starting with \forall \lambda: int - return tf.createQuantifierTerm(Op.ALL, lambda, arrayFormula); - } - - private StatementBlock createMethodCall(Expression[] p){ - if(m.isConstructor()){ - TypeRef prefix = new TypeRef(self.getKeYJavaType()); - New n = new New(p, - prefix, - prefix); - return new StatementBlock(n); - }else{ - ProgramVariable result = null; - if(m.getKeYJavaType() != null){ - result = - new LocationVariable(new ProgramElementName( - "_result" + resultNameCnt++), - m.getKeYJavaType()); - initConfig.namespaces().programVariables().add(result); - } - MethodBodyStatement mBS = new MethodBodyStatement - (m, - self, - result, - new ArrayOfExpression(p)); - return new StatementBlock(mBS); - } - } - - - public ProofAggregate getPO() { - if (proofObl == null) throw - new IllegalStateException("No proofObl term"); - // now a static call since there is no suitable common superclass - String s = OCLProofOblInput.createProofHeader( - initConfig, - methRepr.getContainingClass().getRootDirectory()); - return ProofAggregate.createProofAggregate( - new Proof(name(), proofObl, s, - initConfig.createTacletIndex(), - initConfig.createBuiltInRuleIndex(), - initConfig.getServices()), - name()); - } - - - /** sets the initial configuration that is used to read the OCL - * input and that is used to be modified during reading. - */ - public void setInitConfig(InitConfig conf) { - this.initConfig=conf; - initConfig.sortNS().startProtocol(); - initConfig.funcNS().startProtocol(); - initConfig.progVarNS().startProtocol(); - } - - /** returns the name of the modifies check proof obligation input. - */ - public String name() { - return name; - } - - public void readActivatedChoices() throws ProofInputException { - - } - - /** reads the include section and returns an Includes object. - */ - public Includes readIncludes() throws ProofInputException { - RuleSource standard = RuleSource.initRuleFile("standardRules.key"); - Includes includes = new Includes(); - includes.put("standardRules", standard); - return includes; - } - - public void readSpecs(){ - // nothing here - } - - public Term getPOTerm() { - return proofObl; - } - - - public SetOfTerm getModifiesElements() { - return modifiesElements; - } - - public Contractable[] getObjectOfContract() { - return new Contractable[]{methRepr}; - } - - public boolean initContract(Contract ct) { - return false; //%% - } - - public void startProtocol() { - // do nothing - } - - -} diff --git a/system/de/uka/ilkd/key/proof/init/NonInterferencePO.java b/system/de/uka/ilkd/key/proof/init/NonInterferencePO.java index cca40c5f397..453478d59b7 100644 --- a/system/de/uka/ilkd/key/proof/init/NonInterferencePO.java +++ b/system/de/uka/ilkd/key/proof/init/NonInterferencePO.java @@ -25,8 +25,6 @@ import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.logic.sort.Sort; import de.uka.ilkd.key.proof.*; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; import de.uka.ilkd.key.proof.mgt.ProofEnvironment; import de.uka.ilkd.key.rule.TacletApp; import de.uka.ilkd.key.util.ExtList; @@ -184,7 +182,9 @@ private Term nonInterfCondition(Node a, Node b) { FirstStatementExtractionVisitor v = - new FirstStatementExtractionVisitor(progB, b); + new FirstStatementExtractionVisitor(progB, + b, + initConfig.getServices()); v.start(); JavaBlock p2prime = JavaBlock.createJavaBlock( (StatementBlock)v.result()); @@ -435,14 +435,6 @@ public String name() { return "Non-Interference of ... and ..."; } - public Contractable[] getObjectOfContract() { - return new Contractable[0]; - } - - public boolean initContract(Contract ct) { - return false; - } - public void startProtocol() { // do nothing } @@ -454,8 +446,9 @@ private class FirstStatementExtractionVisitor extends CreatingASTVisitor { private Node node; public FirstStatementExtractionVisitor(ProgramElement root, - Node n) { - super(root, true); + Node n, + Services services) { + super(root, true, services); this.node = n; } diff --git a/system/de/uka/ilkd/key/proof/init/OCLInvSimplPO.java b/system/de/uka/ilkd/key/proof/init/OCLInvSimplPO.java index c7f9ba8df62..5c19214d45e 100644 --- a/system/de/uka/ilkd/key/proof/init/OCLInvSimplPO.java +++ b/system/de/uka/ilkd/key/proof/init/OCLInvSimplPO.java @@ -39,8 +39,6 @@ import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.ProofAggregate; import de.uka.ilkd.key.proof.RuleSource; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; /** * Used for OCL Simplification. @@ -92,13 +90,6 @@ protected void setProofObligation(Term po) { proofObl = po; } - public boolean initContract(Contract contract) { - return false; // was true, but this seemed to be strange /AR - } - - public Contractable[] getObjectOfContract() { - return new Contractable[0]; - } public ModelClass getModelClass() { return aClass; diff --git a/system/de/uka/ilkd/key/proof/init/PreservesGuardPO.java b/system/de/uka/ilkd/key/proof/init/PreservesGuardPO.java index 95f8715dc26..2779a38277e 100644 --- a/system/de/uka/ilkd/key/proof/init/PreservesGuardPO.java +++ b/system/de/uka/ilkd/key/proof/init/PreservesGuardPO.java @@ -11,20 +11,17 @@ import java.util.Map; -import de.uka.ilkd.key.casetool.IteratorOfModelClass; -import de.uka.ilkd.key.casetool.ListOfModelClass; -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.casetool.ModelMethod; import de.uka.ilkd.key.gui.DependsClauseDialog; +import de.uka.ilkd.key.java.abstraction.IteratorOfKeYJavaType; import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.expression.literal.BooleanLiteral; +import de.uka.ilkd.key.java.abstraction.SetOfKeYJavaType; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.logic.sort.Sort; import de.uka.ilkd.key.speclang.ClassInvariant; import de.uka.ilkd.key.speclang.IteratorOfClassInvariant; -import de.uka.ilkd.key.speclang.ListOfClassInvariant; -import de.uka.ilkd.key.speclang.SLTranslationError; +import de.uka.ilkd.key.speclang.SetAsListOfClassInvariant; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; import de.uka.ilkd.key.util.Debug; @@ -33,20 +30,21 @@ */ public class PreservesGuardPO extends EnsuresPO { - private final ListOfClassInvariant guardedInvs; - private final ListOfModelClass guard; + private final SetOfClassInvariant guardedInvs; + private final SetOfKeYJavaType guard; private Term encapsulationFormula = null; private ListOfProofOblInput dependsPOs = SLListOfProofOblInput.EMPTY_LIST; - public PreservesGuardPO(ModelMethod modelMethod, - ListOfClassInvariant guardedInvs, - ListOfModelClass guard, - InvariantSelectionStrategy invStrategy) { - super("PreservesGuard", - modelMethod, + public PreservesGuardPO(InitConfig initConfig, + ProgramMethod programMethod, + SetOfClassInvariant guardedInvs, + SetOfKeYJavaType guard) { + super(initConfig, + "PreservesGuard", + programMethod, Op.BOX, - invStrategy, + SetAsListOfClassInvariant.EMPTY_SET, false); this.guardedInvs = guardedInvs; this.guard = guard; @@ -117,11 +115,9 @@ private SetOfLocationDescriptor filterDependsClause( } if(containingKjt != null) { - IteratorOfModelClass it2 = guard.iterator(); + IteratorOfKeYJavaType it2 = guard.iterator(); while(it2.hasNext()) { - ModelClass guardClass = it2.next(); - KeYJavaType guardKjt - = javaInfo.getKeYJavaType(guardClass.getFullClassName()); + KeYJavaType guardKjt = it2.next(); if(containingKjt.equals(guardKjt)) { clause = clause.remove(loc); } @@ -156,13 +152,13 @@ private boolean equalsModRenaming(SetOfLocationDescriptor locs1, } BasicLocationDescriptor bloc1 = (BasicLocationDescriptor) loc1; - Term predLoc1Term = tf.createFunctionTerm(pred, + Term predLoc1Term = TF.createFunctionTerm(pred, bloc1.getLocTerm()); - Term freeLoc1Term = tf.createJunctorTerm(Op.AND, + Term freeLoc1Term = TF.createJunctorTerm(Op.AND, bloc1.getFormula(), predLoc1Term); Term boundLoc1Term - = tf.createQuantifierTerm(Op.ALL, + = TF.createQuantifierTerm(Op.ALL, freeLoc1Term.freeVars().toArray(), freeLoc1Term); @@ -175,13 +171,13 @@ private boolean equalsModRenaming(SetOfLocationDescriptor locs1, } BasicLocationDescriptor bloc2 = (BasicLocationDescriptor) loc2; - Term predLoc2Term = tf.createFunctionTerm(pred, + Term predLoc2Term = TF.createFunctionTerm(pred, bloc2.getLocTerm()); - Term freeLoc2Term = tf.createJunctorTerm(Op.AND, + Term freeLoc2Term = TF.createJunctorTerm(Op.AND, bloc2.getFormula(), predLoc2Term); Term boundLoc2Term - = tf.createQuantifierTerm(Op.ALL, + = TF.createQuantifierTerm(Op.ALL, freeLoc2Term.freeVars().toArray(), freeLoc2Term); @@ -206,14 +202,11 @@ private boolean equalsModRenaming(SetOfLocationDescriptor locs1, * Determines a depends clause for an invariant * (helper for buildEncapsulationFormula). */ - private SetOfLocationDescriptor getDependsClauseForInv(ClassInvariant inv) { + private SetOfLocationDescriptor getDependsClauseForInv(ClassInvariant inv) + throws ProofInputException { Term invTerm = null; - try { - invTerm = translateInv(inv); - } catch (SLTranslationError e) { - e.printStackTrace(); - } + invTerm = translateInv(inv); SetOfLocationDescriptor extractedClause = extractDependsClauseFromTerm(invTerm); @@ -227,7 +220,9 @@ private SetOfLocationDescriptor getDependsClauseForInv(ClassInvariant inv) { result = dlg.getDependsClause(); if(!equalsModRenaming(result, extractedClause)) { - ProofOblInput dependsPO = new CorrectDependsPO(result, inv); + ProofOblInput dependsPO = new CorrectDependsPO(initConfig, + result, + inv); dependsPOs = dependsPOs.prepend(dependsPO); } } @@ -236,13 +231,11 @@ private SetOfLocationDescriptor getDependsClauseForInv(ClassInvariant inv) { } - private Term createInstanceOf(ModelClass modelClass, Term term) { - Name name = new Name(modelClass.getFullClassName() + "::instance"); - Function instanceFunc = (Function) initConfig.funcNS().lookup(name); - Term instanceTerm = tf.createFunctionTerm(instanceFunc, term); - Term trueLitTerm = services.getTypeConverter() - .convertToLogicElement(BooleanLiteral.TRUE); - return tf.createEqualityTerm(instanceTerm, trueLitTerm); + private Term createInstanceOf(KeYJavaType kjt, Term term) { + Name n = new Name(kjt.getFullName() + "::instance"); + Function instanceFunc = (Function) initConfig.funcNS().lookup(n); + Term instanceTerm = TB.func(instanceFunc, term); + return TB.equals(instanceTerm, TB.TRUE(services)); } @@ -267,7 +260,7 @@ private void buildEncapsulationFormula() throws ProofInputException { } //create the formula - encapsulationFormula = tf.createJunctorTerm(Op.TRUE); + encapsulationFormula = TF.createJunctorTerm(Op.TRUE); IteratorOfLocationDescriptor it2 = dependsClause.iterator(); while(it2.hasNext()) { LocationDescriptor loc = it2.next(); @@ -280,41 +273,41 @@ private void buildEncapsulationFormula() throws ProofInputException { LogicVariable y = new LogicVariable(new Name("y"), javaLangObjectSort); - Term yTerm = tf.createVariableTerm(y); + Term yTerm = TF.createVariableTerm(y); Term dTerm = bloc.getLocTerm().sub(0); Term phiTerm = bloc.getFormula(); //create "Acc(y, d_k') & phi_k" - Term accTerm = tf.createFunctionTerm(accPred, + Term accTerm = TF.createFunctionTerm(accPred, yTerm, dTerm); - Term premiseTerm = tf.createJunctorTermAndSimplify(Op.AND, + Term premiseTerm = TF.createJunctorTermAndSimplify(Op.AND, accTerm, phiTerm); //create disjunction of "C::Instance(y)" for all guards C - Term isGuardTerm = tf.createJunctorTerm(Op.FALSE); - IteratorOfModelClass it3 = guard.iterator(); + Term isGuardTerm = TF.createJunctorTerm(Op.FALSE); + IteratorOfKeYJavaType it3 = guard.iterator(); while(it3.hasNext()) { - ModelClass guardClass = it3.next(); - Term instanceOfTerm = createInstanceOf(guardClass, yTerm); + KeYJavaType guardKJT = it3.next(); + Term instanceOfTerm = createInstanceOf(guardKJT, yTerm); isGuardTerm - = tf.createJunctorTermAndSimplify(Op.OR, + = TF.createJunctorTermAndSimplify(Op.OR, isGuardTerm, instanceOfTerm); } //create "phi_k & y = d_k'" - Term yEqualTerm = tf.createEqualityTerm(yTerm, dTerm); - Term isWithinTerm = tf.createJunctorTermAndSimplify(Op.AND, + Term yEqualTerm = TF.createEqualityTerm(yTerm, dTerm); + Term isWithinTerm = TF.createJunctorTermAndSimplify(Op.AND, phiTerm, yEqualTerm); //create implication Term impTerm - = tf.createJunctorTerm(Op.IMP, + = TF.createJunctorTerm(Op.IMP, premiseTerm, - tf.createJunctorTerm(Op.OR, + TF.createJunctorTerm(Op.OR, isWithinTerm, isGuardTerm)); @@ -330,12 +323,12 @@ private void buildEncapsulationFormula() throws ProofInputException { = bloc.getLocTerm().freeVars(); quantifierTerm = (freeVars.size() == 0 ? quantifierTerm - : tf.createQuantifierTerm(Op.ALL, + : TF.createQuantifierTerm(Op.ALL, freeVars.toArray(), quantifierTerm)); encapsulationFormula - = tf.createJunctorTermAndSimplify(Op.AND, + = TF.createJunctorTermAndSimplify(Op.AND, encapsulationFormula, quantifierTerm); } @@ -350,10 +343,10 @@ private Term createAccessedTerm(ProgramVariable v, Function accPred) { LogicVariable x = new LogicVariable(new Name("x"), javaLangObjectSort); - Term accTerm = tf.createFunctionTerm(accPred, - tf.createVariableTerm(x), - tf.createVariableTerm(v)); - return tf.createQuantifierTerm(Op.EX, x, accTerm); + Term accTerm = TF.createFunctionTerm(accPred, + TF.createVariableTerm(x), + TF.createVariableTerm(v)); + return TF.createQuantifierTerm(Op.EX, x, accTerm); } @@ -362,7 +355,7 @@ protected Term getPreTerm(ProgramVariable selfVar, ProgramVariable resultVar, ProgramVariable exceptionVar, Map atPreFunctions) throws ProofInputException { - Term result = tf.createJunctorTerm(Op.TRUE); + Term result = TF.createJunctorTerm(Op.TRUE); Function accPred = getAccPred(); Sort javaLangObjectSort = javaInfo.getJavaLangObjectAsSort(); @@ -374,7 +367,7 @@ protected Term getPreTerm(ProgramVariable selfVar, Term paramAccTerm = createAccessedTerm(paramVar, javaLangObjectSort, accPred); - result = tf.createJunctorTermAndSimplify(Op.AND, + result = TF.createJunctorTermAndSimplify(Op.AND, result, paramAccTerm); } @@ -384,14 +377,14 @@ protected Term getPreTerm(ProgramVariable selfVar, Term selfAccTerm = createAccessedTerm(selfVar, javaLangObjectSort, accPred); - result = tf.createJunctorTermAndSimplify(Op.AND, + result = TF.createJunctorTermAndSimplify(Op.AND, result, selfAccTerm); } //add main formula buildEncapsulationFormula(); - result = tf.createJunctorTermAndSimplify(Op.AND, + result = TF.createJunctorTermAndSimplify(Op.AND, result, encapsulationFormula); @@ -404,7 +397,7 @@ protected Term getPostTerm(ProgramVariable selfVar, ProgramVariable resultVar, ProgramVariable exceptionVar, Map atPreFunctions) throws ProofInputException { - Term result = tf.createJunctorTerm(Op.TRUE); + Term result = TF.createJunctorTerm(Op.TRUE); Function accPred = getAccPred(); Sort javaLangObjectSort = javaInfo.getJavaLangObjectAsSort(); @@ -415,7 +408,7 @@ protected Term getPostTerm(ProgramVariable selfVar, //add main formula buildEncapsulationFormula(); - result = tf.createJunctorTermAndSimplify(Op.IMP, + result = TF.createJunctorTermAndSimplify(Op.IMP, result, encapsulationFormula); @@ -425,12 +418,11 @@ protected Term getPostTerm(ProgramVariable selfVar, //------------------------------------------------------------------------- - //methods of ProofOblInput interface + //public interface //------------------------------------------------------------------------- public void readProblem(ModStrategy mod) throws ProofInputException { super.readProblem(mod); - setInitConfig(initConfig); Debug.assertTrue(poTerms.length == 1); Debug.assertTrue(poNames == null); @@ -451,13 +443,20 @@ public void readProblem(ModStrategy mod) throws ProofInputException { poNames[i] = dependsPO.name(); } } - - public void setInitConfig(InitConfig conf) { - super.setInitConfig(conf); - IteratorOfProofOblInput it = dependsPOs.iterator(); - while(it.hasNext()) { - it.next().setInitConfig(conf); + + public boolean equals(Object o) { + if(!(o instanceof PreservesGuardPO)) { + return false; } + PreservesGuardPO po = (PreservesGuardPO) o; + return super.equals(po) + && guardedInvs.equals(po.guardedInvs) + && guard.equals(po.guard); + } + + + public int hashCode() { + return super.hashCode() + guardedInvs.hashCode() + guard.hashCode(); } } diff --git a/system/de/uka/ilkd/key/proof/init/PreservesInvPO.java b/system/de/uka/ilkd/key/proof/init/PreservesInvPO.java index dd2f26ac50d..0f64655bcae 100644 --- a/system/de/uka/ilkd/key/proof/init/PreservesInvPO.java +++ b/system/de/uka/ilkd/key/proof/init/PreservesInvPO.java @@ -11,13 +11,12 @@ import java.util.Map; -import de.uka.ilkd.key.casetool.ModelMethod; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.op.ListOfProgramVariable; import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.ProgramMethod; import de.uka.ilkd.key.logic.op.ProgramVariable; -import de.uka.ilkd.key.speclang.ListOfClassInvariant; -import de.uka.ilkd.key.speclang.SLTranslationError; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; /** @@ -25,22 +24,28 @@ */ public class PreservesInvPO extends EnsuresPO { - private final ListOfClassInvariant ensuredInvs; + private final SetOfClassInvariant ensuredInvs; - protected PreservesInvPO(String name, - ModelMethod modelMethod, - InvariantSelectionStrategy invStrategy, - ListOfClassInvariant ensuredInvs) { - super(name, modelMethod, Op.BOX, invStrategy, false); + protected PreservesInvPO(InitConfig initConfig, + String name, + ProgramMethod programMethod, + SetOfClassInvariant assumedInvs, + SetOfClassInvariant ensuredInvs) { + super(initConfig, name, programMethod, Op.BOX, assumedInvs, false); this.ensuredInvs = ensuredInvs; } - public PreservesInvPO(ModelMethod modelMethod, - InvariantSelectionStrategy invStrategy, - ListOfClassInvariant ensuredInvs) { - this("PreservesInv", modelMethod, invStrategy, ensuredInvs); + public PreservesInvPO(InitConfig initConfig, + ProgramMethod programMethod, + SetOfClassInvariant assumedInvs, + SetOfClassInvariant ensuredInvs) { + this(initConfig, + "PreservesInv", + programMethod, + assumedInvs, + ensuredInvs); } @@ -48,8 +53,8 @@ protected Term getPreTerm(ProgramVariable selfVar, ListOfProgramVariable paramVars, ProgramVariable resultVar, ProgramVariable exceptionVar, - Map atPreFunctions) { - return tb.tt(); + Map atPreFunctions) throws ProofInputException { + return TB.tt(); } @@ -57,7 +62,22 @@ protected Term getPostTerm(ProgramVariable selfVar, ListOfProgramVariable paramVars, ProgramVariable resultVar, ProgramVariable exceptionVar, - Map atPreFunctions) throws SLTranslationError { + Map atPreFunctions) throws ProofInputException { return translateInvs(ensuredInvs); } + + + public boolean equals(Object o) { + if(!(o instanceof PreservesInvPO)) { + return false; + } + PreservesInvPO po = (PreservesInvPO) o; + return super.equals(po) + && ensuredInvs.equals(po.ensuredInvs); + } + + + public int hashCode() { + return super.hashCode() + ensuredInvs.hashCode(); + } } diff --git a/system/de/uka/ilkd/key/proof/init/PreservesOwnInvPO.java b/system/de/uka/ilkd/key/proof/init/PreservesOwnInvPO.java index d2553188643..2da6f73021c 100644 --- a/system/de/uka/ilkd/key/proof/init/PreservesOwnInvPO.java +++ b/system/de/uka/ilkd/key/proof/init/PreservesOwnInvPO.java @@ -9,7 +9,7 @@ package de.uka.ilkd.key.proof.init; -import de.uka.ilkd.key.casetool.ModelMethod; +import de.uka.ilkd.key.logic.op.ProgramMethod; /** @@ -17,11 +17,16 @@ */ public class PreservesOwnInvPO extends PreservesInvPO { - public PreservesOwnInvPO(ModelMethod modelMethod, - InvariantSelectionStrategy invStrategy) { - super("PreservesOwnInv", - modelMethod, - invStrategy, - modelMethod.getContainingClass().getMyClassInvariants()); + public PreservesOwnInvPO(InitConfig initConfig, + ProgramMethod programMethod) { + super(initConfig, + "PreservesOwnInv", + programMethod, + initConfig.getServices() + .getSpecificationRepository() + .getClassInvariants(programMethod.getContainerType()), + initConfig.getServices() + .getSpecificationRepository() + .getClassInvariants(programMethod.getContainerType())); } } diff --git a/system/de/uka/ilkd/key/proof/init/PreservesThroughoutPO.java b/system/de/uka/ilkd/key/proof/init/PreservesThroughoutPO.java index de8076d30a0..d8ffbf15264 100644 --- a/system/de/uka/ilkd/key/proof/init/PreservesThroughoutPO.java +++ b/system/de/uka/ilkd/key/proof/init/PreservesThroughoutPO.java @@ -11,13 +11,12 @@ import java.util.Map; -import de.uka.ilkd.key.casetool.ModelMethod; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.op.ListOfProgramVariable; import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.ProgramMethod; import de.uka.ilkd.key.logic.op.ProgramVariable; -import de.uka.ilkd.key.speclang.ListOfClassInvariant; -import de.uka.ilkd.key.speclang.SLTranslationError; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; /** @@ -25,15 +24,16 @@ */ public class PreservesThroughoutPO extends EnsuresPO { - private ListOfClassInvariant invs; + private SetOfClassInvariant invs; - public PreservesThroughoutPO(ModelMethod modelMethod, - ListOfClassInvariant invs, - InvariantSelectionStrategy invStrategy) { - super("PreservesThroughout", - modelMethod, + public PreservesThroughoutPO(InitConfig initConfig, + ProgramMethod programMethod, + SetOfClassInvariant invs) { + super(initConfig, + "PreservesThroughout", + programMethod, Op.TOUT, - invStrategy, + invs, true); this.invs = invs; } @@ -43,8 +43,8 @@ protected Term getPreTerm(ProgramVariable selfVar, ListOfProgramVariable paramVars, ProgramVariable resultVar, ProgramVariable exceptionVar, - Map atPreFunctions) { - return tb.tt(); + Map atPreFunctions) throws ProofInputException { + return TB.tt(); } @@ -52,7 +52,22 @@ protected Term getPostTerm(ProgramVariable selfVar, ListOfProgramVariable paramVars, ProgramVariable resultVar, ProgramVariable exceptionVar, - Map atPreFunctions) throws SLTranslationError { + Map atPreFunctions) throws ProofInputException { return translateInvs(invs); } + + + public boolean equals(Object o) { + if(!(o instanceof PreservesThroughoutPO)) { + return false; + } + PreservesThroughoutPO po = (PreservesThroughoutPO) o; + return super.equals(po) + && invs.equals(po.invs); + } + + + public int hashCode() { + return super.hashCode() + invs.hashCode(); + } } diff --git a/system/de/uka/ilkd/key/proof/init/ProblemInitializer.java b/system/de/uka/ilkd/key/proof/init/ProblemInitializer.java index 8caed95d099..dc0824e760d 100644 --- a/system/de/uka/ilkd/key/proof/init/ProblemInitializer.java +++ b/system/de/uka/ilkd/key/proof/init/ProblemInitializer.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.Vector; import java.util.Map.Entry; @@ -63,7 +64,7 @@ public class ProblemInitializer { private final Services services; private final UpdateSimplifier simplifier; - private final HashSet alreadyParsed = new HashSet(); + private final HashSet alreadyParsed = new LinkedHashSet(); //------------------------------------------------------------------------- @@ -79,10 +80,8 @@ public ProblemInitializer(Main main) { } - /** - * For tests only - */ - public ProblemInitializer(Profile profile) { + public ProblemInitializer(Profile profile) { + assert profile != null; this.main = null; this.profile = profile; this.services = new Services(); @@ -180,8 +179,10 @@ private void readLDTIncludes(Includes in, String name = (String) it.next(); keyFile[i++] = new KeYFile(name, in.get(name), - (main==null) ? null : - main.getProgressMonitor()); + (main == null + ? null + : main.getProgressMonitor()), + false); } LDTInput ldtInp = new LDTInput(keyFile, main); @@ -212,7 +213,8 @@ private void readIncludes(EnvInput envInput, KeYFile keyFile = new KeYFile(fileName, in.get(fileName), (main==null) ? - null : main.getProgressMonitor()); + null : main.getProgressMonitor(), + false); readEnvInput(keyFile, initConfig, readLibraries); } } @@ -240,9 +242,12 @@ private void readLibraries(EnvInput envInput, InitConfig initConfig) throws Proo } else { rs = RuleSource.initRuleFile(fileName); } - KeYFile keyFile = new KeYFile(fileName, rs, - (main == null) ? null : main - .getProgressMonitor()); + KeYFile keyFile = new KeYFile(fileName, + rs, + (main == null + ? null + : main.getProgressMonitor()), + false); readEnvInput(keyFile, initConfig); } } @@ -325,10 +330,9 @@ private void readJava(EnvInput envInput, InitConfig initConfig) reportStatus("Reading Java model"); ProjectSettings settings = initConfig.getServices().getJavaInfo().getKeYProgModelInfo() - .getServConf().getProjectSettings(); + .getServConf().getProjectSettings(); PathList searchPathList = settings.getSearchPathList(); - if(searchPathList.find(javaPath) == null) { searchPathList.add(javaPath); } @@ -339,12 +343,6 @@ private void readJava(EnvInput envInput, InitConfig initConfig) } else { String[] cus = (String[]) getClasses(javaPath).toArray(new String[]{}); CompilationUnit[] compUnits = r2k.readCompilationUnitsAsFiles(cus); - //temporary hack - if(envInput instanceof KeYUserProblemFile) { - KeYUserProblemFile kupf = (KeYUserProblemFile) envInput; - kupf.readActivatedChoices(); - kupf.readJML(compUnits); - } initConfig.getServices().getJavaInfo().setJavaSourcePath(javaPath); //checkin Java model to CVS @@ -436,7 +434,6 @@ private InitConfig determineEnvironment(ProofOblInput po, ProofEnvironment env = initConfig.getProofEnv(); //read activated choices - po.setInitConfig(initConfig); po.readActivatedChoices(); initConfig.createNamespacesForActivatedChoices(); @@ -466,10 +463,6 @@ private InitConfig determineEnvironment(ProofOblInput po, GlobalProofMgt.getInstance().registerProofEnvironment(env); } - //read specs (TODO) - po.setInitConfig(initConfig); - po.readSpecs(); - return initConfig; } @@ -520,9 +513,12 @@ public InitConfig prepare(EnvInput envInput) throws ProofInputException { RuleSource tacletBase = profile.getStandardRules().getTacletBase(); if(tacletBase != null) { KeYFile tacletBaseFile - = new KeYFile("taclet base", - profile.getStandardRules().getTacletBase(), - (main==null) ? null : main.getProgressMonitor()); + = new KeYFile("taclet base", + profile.getStandardRules().getTacletBase(), + (main == null + ? null + : main.getProgressMonitor()), + false); readEnvInput(tacletBaseFile, lastBaseConfig, false); } } @@ -552,13 +548,12 @@ public void startProver(InitConfig initConfig, ProofOblInput po) assert initConfig != null; stopInterface(); - try{ + try { //determine environment initConfig = determineEnvironment(po, initConfig); //read problem reportStatus("Loading problem \""+po.name()+"\""); - po.setInitConfig(initConfig); po.readProblem(ModStrategy.NO_FUNCS); reportReady(); @@ -594,10 +589,10 @@ public void startProver(EnvInput envInput, ProofOblInput po) public void tryReadProof(ProblemLoader prl, ProofOblInput problem) throws ProofInputException { - if (problem instanceof KeYFile) { - KeYFile proof = (KeYFile)problem; - reportStatus("Loading proof", proof.getNumberOfChars()); - proof.readProof(prl); + if(problem instanceof KeYUserProblemFile) { + KeYUserProblemFile kupf = (KeYUserProblemFile)problem; + reportStatus("Loading proof", kupf.getNumberOfChars()); + kupf.readProof(prl); } } } diff --git a/system/de/uka/ilkd/key/proof/init/ProofInputException.java b/system/de/uka/ilkd/key/proof/init/ProofInputException.java index a9d1c64cc3b..6b81a03b6e3 100644 --- a/system/de/uka/ilkd/key/proof/init/ProofInputException.java +++ b/system/de/uka/ilkd/key/proof/init/ProofInputException.java @@ -17,21 +17,20 @@ public class ProofInputException extends Exception { public static final ProofInputException USER_ABORT_EXCEPTION = new ProofInputException("User cancelled problem loading."); - String reason; + private final String message; public ProofInputException(Exception e) { super(e.getMessage()); - reason = e.toString(); + message = e.toString(); initCause(e); } - public ProofInputException(String s) { - super(s); - reason = s; + public ProofInputException(String message) { + super(message); + this.message = message; } public String toString() { - return reason; + return message; } - } diff --git a/system/de/uka/ilkd/key/proof/init/ProofOblInput.java b/system/de/uka/ilkd/key/proof/init/ProofOblInput.java index 45a68695365..f22fbf1740e 100644 --- a/system/de/uka/ilkd/key/proof/init/ProofOblInput.java +++ b/system/de/uka/ilkd/key/proof/init/ProofOblInput.java @@ -10,47 +10,32 @@ package de.uka.ilkd.key.proof.init; import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; /** * Represents something that produces an input proof obligation for the * prover. A .key file or a proof obligation generated from a CASE tool may - * be instances. An instance can be called to set an initial configuration, - * that is modified during reading the input (using setInitConfig), - * to get the read proof - * obligation (using getProblemTerm). During reading the input + * be instances. During reading the input the * given initial configuration may become modified. The modification * can be controlled by a modification strategy. */ public interface ProofOblInput { - /** returns the name of the proof obligation input. + /** + * Returns the name of the proof obligation input. */ String name(); boolean askUserForEnvironment(); - /** Set the initial configuration used to read the input. It may become - * modified during reading depending on the modification strategy used - * for reading. Must be called before calling any of the read* methods. - */ - void setInitConfig(InitConfig i); - void readActivatedChoices() throws ProofInputException; - - void readSpecs(); void readProblem(ModStrategy mod) throws ProofInputException; - /** returns the proof obligation term as result of the proof obligation + /** + * Returns the proof obligation term as result of the proof obligation * input. If there is still no input available because nothing has * been read yet null is returned. */ - ProofAggregate getPO(); - - Contractable[] getObjectOfContract(); - - boolean initContract(Contract ct); + ProofAggregate getPO() throws ProofInputException; } diff --git a/system/de/uka/ilkd/key/proof/init/RespectsModifiesPO.java b/system/de/uka/ilkd/key/proof/init/RespectsModifiesPO.java index 4293fe392ed..b825dec4c72 100644 --- a/system/de/uka/ilkd/key/proof/init/RespectsModifiesPO.java +++ b/system/de/uka/ilkd/key/proof/init/RespectsModifiesPO.java @@ -15,14 +15,14 @@ import de.uka.ilkd.key.java.PositionInfo; import de.uka.ilkd.key.java.StatementBlock; import de.uka.ilkd.key.java.declaration.MethodDeclaration; +import de.uka.ilkd.key.java.declaration.modifier.Static; import de.uka.ilkd.key.java.statement.MethodBodyStatement; import de.uka.ilkd.key.logic.JavaBlock; import de.uka.ilkd.key.logic.ProgramElementName; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.logic.sort.Sort; import de.uka.ilkd.key.speclang.OperationContract; -import de.uka.ilkd.key.speclang.SLTranslationError; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; import de.uka.ilkd.key.util.ExtList; @@ -32,52 +32,54 @@ public class RespectsModifiesPO extends EnsuresPO { private final OperationContract contract; + private Term updateAnonMethodTerm = null; - public RespectsModifiesPO(OperationContract contract, - InvariantSelectionStrategy invStrategy) { - super("RespectsModifies", - contract.getModelMethod(), + public RespectsModifiesPO(InitConfig initConfig, + OperationContract contract, + SetOfClassInvariant assumedInvs) { + super(initConfig, + "RespectsModifies", + contract.getProgramMethod(), Modality.BOX, - invStrategy, + assumedInvs, true); this.contract = contract; } private void buildUpdateAnonMethodTerm(ProgramVariable selfVar, - ListOfProgramVariable paramVars) throws SLTranslationError { + ListOfProgramVariable paramVars) + throws ProofInputException { if(updateAnonMethodTerm != null) { return; } - + //build method declaration ExtList extList = new ExtList(); - ProgramElementName name = new ProgramElementName("anonMethod"); - extList.addLast(name); + ProgramElementName methodName = new ProgramElementName("anonMethod"); + extList.add(methodName); + extList.add(new Static()); MethodDeclaration methodDecl = new MethodDeclaration(extList, false); //build program method ProgramMethod programMethod = new ProgramMethod(methodDecl, javaInfo.getJavaLangObject(), - javaInfo.getJavaLangObject(), + null, PositionInfo.UNDEFINED); //build java block - ProgramVariable pseudoSelfVar - = new LocationVariable(new ProgramElementName("anonObject"), - Sort.NULL); MethodBodyStatement call = new MethodBodyStatement(programMethod, - pseudoSelfVar, + javaInfo.createTypeReference(javaInfo.getJavaLangObject()), null, - new ArrayOfExpression());/*paramVars*/ + new ArrayOfExpression()); StatementBlock sb = new StatementBlock(call); JavaBlock jb = JavaBlock.createJavaBlock(sb); //build program term - Term programTerm = tb.dia(jb, tb.tt()); + Term programTerm = TB.dia(jb, TB.tt()); //add update updateAnonMethodTerm = translateModifies(contract, @@ -91,10 +93,10 @@ protected Term getPreTerm(ProgramVariable selfVar, ListOfProgramVariable paramVars, ProgramVariable resultVar, ProgramVariable exceptionVar, - Map atPreFunctions) throws SLTranslationError { + Map atPreFunctions) throws ProofInputException { buildUpdateAnonMethodTerm(selfVar, paramVars); Term preTerm = translatePre(contract, selfVar, toPV(paramVars)); - Term result = tb.and(preTerm, updateAnonMethodTerm); + Term result = TB.and(preTerm, updateAnonMethodTerm); return result; } @@ -103,10 +105,29 @@ protected Term getPostTerm(ProgramVariable selfVar, ListOfProgramVariable paramVars, ProgramVariable resultVar, ProgramVariable exceptionVar, - Map atPreFunctions) throws SLTranslationError { + Map atPreFunctions) + throws ProofInputException { buildUpdateAnonMethodTerm(selfVar, paramVars); - createAtPreFunctionsForTerm(updateAnonMethodTerm, atPreFunctions); + APF.createAtPreFunctionsForTerm(updateAnonMethodTerm, + atPreFunctions, + services); Term result = replaceOps(atPreFunctions, updateAnonMethodTerm); return result; } + + + + public boolean equals(Object o) { + if(!(o instanceof RespectsModifiesPO)) { + return false; + } + RespectsModifiesPO po = (RespectsModifiesPO) o; + return super.equals(po) + && contract.equals(po.contract); + } + + + public int hashCode() { + return super.hashCode() + contract.hashCode(); + } } diff --git a/system/de/uka/ilkd/key/proof/init/SpecExtPO.java b/system/de/uka/ilkd/key/proof/init/SpecExtPO.java new file mode 100755 index 00000000000..c0bb81b0a19 --- /dev/null +++ b/system/de/uka/ilkd/key/proof/init/SpecExtPO.java @@ -0,0 +1,116 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.proof.init; + +import java.util.Map; + +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.op.ListOfProgramVariable; +import de.uka.ilkd.key.logic.op.LogicVariable; +import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.ProofAggregate; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; + +/** + * This class is needed to use Key for extraction of additional information to + * be used in jmltest + * + * @author mbender@uni-koblenz.de + * + */ +public class SpecExtPO extends EnsuresPostPO { + + private ListOfProgramVariable params; + + private ProgramVariable result; + + private ProgramVariable selfVarAsProgVar; + + private LogicVariable selfVarAsLogicVar; + + private ProgramVariable excVar; + + public SpecExtPO(InitConfig initConfig, OperationContract contract, + SetOfClassInvariant assumedInvs) { + super(initConfig, "ExtractSpec", contract, assumedInvs); + } + + public SpecExtPO(InitConfig initConfig, OperationContract contract, + SetOfClassInvariant assumedInvs, ProgramMethod pm) { + this(initConfig, contract, assumedInvs); + } + + protected Term getPostTerm(ProgramVariable selfVar, + ListOfProgramVariable paramVars, ProgramVariable resultVar, + ProgramVariable exceptionVar, Map atPreFunctions) + throws ProofInputException { + return TermBuilder.DF.tf().createJunctorTerm(Op.COMPUTE_SPEC_OP, + TermBuilder.DF.tf().createJunctorTerm(Op.TRUE)); + } + + public ProofAggregate getPO() { + Proof[] proofs = super.getPO().getProofs(); + for (int i = 0; i < proofs.length; i++) { + if (proofs[i].name().toString().equals( + "ExtractSpec of " + getProgramMethod())) { + proofs[i].setPO(this); + } + + } + return ProofAggregate.createProofAggregate(proofs, name); + } + + protected ListOfProgramVariable buildParamVars(ProgramMethod programMethod) { + return params = super.buildParamVars(programMethod); + } + + protected ProgramVariable buildResultVar(ProgramMethod programMethod) { + return result = super.buildResultVar(programMethod); + } + + protected ProgramVariable buildSelfVarAsProgVar() { + return selfVarAsProgVar = super.buildSelfVarAsProgVar(); + } + + protected LogicVariable buildSelfVarAsLogicVar() { + return selfVarAsLogicVar = super.buildSelfVarAsLogicVar(); + } + + protected ProgramVariable buildExcVar() { + return excVar = super.buildExcVar(); + } + + public ListOfProgramVariable getParams() { + return params; + } + + public ProgramVariable getResult() { + return result; + } + + public ProgramVariable getSelfVarAsProgVar() { + return selfVarAsProgVar; + } + + public LogicVariable getSelfVarAsLogicVar() { + return selfVarAsLogicVar; + } + + public ProgramVariable getExcVar() { + return excVar; + } + +} diff --git a/system/de/uka/ilkd/key/proof/init/StrongOperationContractPO.java b/system/de/uka/ilkd/key/proof/init/StrongOperationContractPO.java index bce88f1fcc6..f066af90582 100644 --- a/system/de/uka/ilkd/key/proof/init/StrongOperationContractPO.java +++ b/system/de/uka/ilkd/key/proof/init/StrongOperationContractPO.java @@ -10,18 +10,16 @@ package de.uka.ilkd.key.proof.init; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; -import de.uka.ilkd.key.casetool.ModelMethod; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.op.ListOfProgramVariable; +import de.uka.ilkd.key.logic.op.ProgramMethod; import de.uka.ilkd.key.logic.op.ProgramVariable; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; -import de.uka.ilkd.key.speclang.ListOfClassInvariant; +import de.uka.ilkd.key.rule.updatesimplifier.Update; import de.uka.ilkd.key.speclang.OperationContract; -import de.uka.ilkd.key.speclang.SLTranslationError; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; /** @@ -30,8 +28,8 @@ public class StrongOperationContractPO extends AbstractPO { private final OperationContract contract; - private final ListOfClassInvariant assumedInvs; - private final ListOfClassInvariant ensuredInvs; + private final SetOfClassInvariant assumedInvs; + private final SetOfClassInvariant ensuredInvs; @@ -39,11 +37,13 @@ public class StrongOperationContractPO extends AbstractPO { //constructors //------------------------------------------------------------------------- - public StrongOperationContractPO(OperationContract contract, - ListOfClassInvariant assumedInvs, - ListOfClassInvariant ensuredInvs) { - super("StrongOperationContract of " + contract.getModelMethod(), - contract.getModelMethod().getContainingClass()); + public StrongOperationContractPO(InitConfig initConfig, + OperationContract contract, + SetOfClassInvariant assumedInvs, + SetOfClassInvariant ensuredInvs) { + super(initConfig, + "StrongOperationContract of " + contract.getProgramMethod(), + contract.getProgramMethod().getContainerType()); this.contract = contract; this.assumedInvs = assumedInvs; this.ensuredInvs = ensuredInvs; @@ -56,57 +56,46 @@ public StrongOperationContractPO(OperationContract contract, //------------------------------------------------------------------------- public void readProblem(ModStrategy mod) throws ProofInputException { - //make sure initConfig has been set - if(initConfig == null) { - throw new IllegalStateException("InitConfig not set."); - } - //prepare variables and container for @pre-functions - ModelMethod modelMethod = contract.getModelMethod(); + ProgramMethod programMethod = contract.getProgramMethod(); ProgramVariable selfVar = buildSelfVarAsProgVar(); - ListOfProgramVariable paramVars = buildParamVars(modelMethod); - ProgramVariable resultVar = buildResultVar(modelMethod); + ListOfProgramVariable paramVars = buildParamVars(programMethod); + ProgramVariable resultVar = buildResultVar(programMethod); ProgramVariable exceptionVar = buildExcVar(); - Map atPreFunctions = new HashMap(); + Map atPreFunctions = new LinkedHashMap(); - try { - //translate precondition - Term preTerm = translatePre(contract, selfVar, toPV(paramVars)); - - //translate and conjoin assumed invariants - Term assumedInvsTerm = translateInvs(assumedInvs); - - //translate postcondition - Term postTerm = translatePost(contract, - selfVar, - toPV(paramVars), - resultVar, - exceptionVar); - - //translate and conjoin ensured invariants - Term ensuredInvsTerm = translateInvs(ensuredInvs); - - //build post implication with updates - Term postImpTerm = tb.imp(postTerm, ensuredInvsTerm); - Term postUpdateTerm = translateModifies(contract, - postImpTerm, - selfVar, - toPV(paramVars)); - - //build definitions for @pre-functions - Term atPreDefinitionsTerm = buildAtPreDefinitions(atPreFunctions); - - //put together @pre-definitions, precondition, and assumed invariants - Term defAndPreAndAssumedInvsTerm = tb.and(atPreDefinitionsTerm, - tb.and(preTerm, - assumedInvsTerm)); - - //build top level implication - Term poTerm = tb.imp(defAndPreAndAssumedInvsTerm, postUpdateTerm); - poTerms = new Term[]{poTerm}; - } catch (SLTranslationError e) { - throw new ProofInputException(e); - } + //translate precondition + Term preTerm = translatePre(contract, selfVar, toPV(paramVars)); + + //translate and conjoin assumed invariants + Term assumedInvsTerm = translateInvs(assumedInvs); + + //translate postcondition + Term postTerm = translatePost(contract, + selfVar, + toPV(paramVars), + resultVar, + exceptionVar, + atPreFunctions); + + //translate and conjoin ensured invariants + Term ensuredInvsTerm = translateInvs(ensuredInvs); + + //build post implication with updates + Term postImpTerm = TB.imp(postTerm, ensuredInvsTerm); + Term postUpdateTerm = translateModifies(contract, + postImpTerm, + selfVar, + toPV(paramVars)); + + //build definitions for @pre-functions + Update atPreDefinitions + = APF.createAtPreDefinitions(atPreFunctions, services); + + //put everyhing together + Term poTerm = TB.imp(TB.and(preTerm, assumedInvsTerm), + uf.apply(atPreDefinitions, postUpdateTerm)); + poTerms = new Term[]{poTerm}; //register everything in namespaces registerInNamespaces(selfVar); @@ -115,14 +104,4 @@ public void readProblem(ModStrategy mod) throws ProofInputException { registerInNamespaces(exceptionVar); registerInNamespaces(atPreFunctions); } - - - public Contractable[] getObjectOfContract() { - return new Contractable[0]; - } - - - public boolean initContract(Contract ct) { - return false; - } } diff --git a/system/de/uka/ilkd/key/proof/init/TacletSoundnessPO.java b/system/de/uka/ilkd/key/proof/init/TacletSoundnessPO.java index 097c172a1a7..2e5c05b9185 100644 --- a/system/de/uka/ilkd/key/proof/init/TacletSoundnessPO.java +++ b/system/de/uka/ilkd/key/proof/init/TacletSoundnessPO.java @@ -20,7 +20,6 @@ import de.uka.ilkd.key.logic.op.ProgramVariable; import de.uka.ilkd.key.proof.Proof; import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.SingleProof; import de.uka.ilkd.key.proof.mgt.*; import de.uka.ilkd.key.rule.*; import de.uka.ilkd.key.rule.soundness.POBuilder; @@ -41,8 +40,7 @@ public boolean askUserForEnvironment () { public TacletSoundnessPO (String name, File file, ProgressMonitor monitor) { - super ( name, file, monitor ); - this.tacletFile = true; + super ( name, file, monitor, true ); } /** returns the proof obligation term as result of the proof obligation @@ -62,7 +60,7 @@ public NoPosTacletApp[] getTaclets () { * strategy. */ public void readProblem(ModStrategy mod) throws ProofInputException { - + assert initConfig != null; final InitConfig old = initConfig; initConfig = old.copy (); @@ -106,6 +104,13 @@ public void readProblem(ModStrategy mod) throws ProofInputException { for (int i=0; i RuleJustificationBySpec*/ app2Just + = new LinkedHashMap(); - public ComplexRuleJustificationBySpec() {} - - public void add(Contract ct, RuleJustificationBySpec just) { - contract2Just.put(ct, just); - } - - public RuleJustification getSpecificJustification(RuleApp app, Services services) { - if (app instanceof MethodContractRuleApp) { - return (RuleJustification) - contract2Just.get(((MethodContractRuleApp)app).getMethodContract()); - } else if (app instanceof BuiltInRuleApp){ - return (RuleJustification) contract2Just.get - (UseMethodContractRule.INSTANCE.selectExistingContract - (services, app.posInOccurrence(), - AutomatedContractConfigurator.INSTANCE)); - } else { - Debug.fail(); // should never be the case - return null; - } - } - - public DepAnalysis dependsOn(Proof p) { - // TODO Auto-generated method stub - return null; - } - + public boolean isAxiomJustification() { return false; } - - public List getProofList() { - return new LinkedList(); + + + public RuleJustification getSpecificJustification(RuleApp app, + Services services) { + RuleJustification result = (RuleJustification) app2Just.get(app); + return result == null ? this : result; + } + + + public void add(RuleApp ruleApp, RuleJustificationBySpec just) { + app2Just.put(ruleApp, just); } - } diff --git a/system/de/uka/ilkd/key/proof/mgt/Contract.java b/system/de/uka/ilkd/key/proof/mgt/Contract.java deleted file mode 100644 index 66a6663d61f..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/Contract.java +++ /dev/null @@ -1,46 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.proof.mgt; - -import java.util.List; - -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.init.ProofOblInput; - -/** - * @deprecated - */ -public interface Contract { - - void addCompoundProof(ProofAggregate pl); - - void removeCompoundProof(ProofAggregate pl); - - List getProofs(); - - Object getObjectOfContract(); - - void setProofEnv(ProofEnvironment env); - - ProofEnvironment getProofEnv(); - - ProofOblInput getProofOblInput(Proof proof); - - /** Sets the textual header needed to later load the proof of this contract. - * This header is usually copied from the problem, in which the contract - * is defined/used. - */ - void setHeader(String s); - - String getName(); - -} diff --git a/system/de/uka/ilkd/key/proof/mgt/ContractSet.java b/system/de/uka/ilkd/key/proof/mgt/ContractSet.java deleted file mode 100644 index 959b5182484..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/ContractSet.java +++ /dev/null @@ -1,81 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.proof.mgt; - - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import de.uka.ilkd.key.logic.op.Modality; -import de.uka.ilkd.key.proof.ProofAggregate; - -/** represents a set of contracts (@link{Contract}}) with attached proofs.*/ -public class ContractSet { - - private List contracts = new LinkedList(); - - public Contract add(Contract ct) { - Iterator it = contracts.iterator(); - while (it.hasNext()) { - Contract c = (Contract) it.next(); - if (c.equals(ct)) { - return c; - } - } - contracts.add(ct); - return ct; - } - - public void addAll(ContractSet cs) { - if (cs==null) return; - Iterator it = cs.iterator(); - while (it.hasNext()) { - add((Contract)it.next()); - } - } - - public Iterator iterator() { - return contracts.iterator(); - } - - public void removeProofList(ProofAggregate pl) { - for (final Iterator it=iterator(); it.hasNext();) { - ((Contract)it.next()).removeCompoundProof(pl); - } - } - - public int size() { - return contracts.size(); - } - - public Contract[] toArray() { - return (Contract[]) contracts.toArray(new Contract[contracts.size()]); - } - - /** returns a set of contracts with the argument as identifying - * contracted object and the matching modality - */ - public ContractSet getMethodContracts(Modality modality) { - ContractSet result = new ContractSet(); - Iterator it = iterator(); - while (it.hasNext()) { - Contract ct = (Contract) it.next(); - if (ct instanceof OldOperationContract - && ((OldOperationContract)ct).applicableForModality(modality)) { - result.add(ct); - } - } - return result; - } - - -} diff --git a/system/de/uka/ilkd/key/proof/mgt/ContractUtil.java b/system/de/uka/ilkd/key/proof/mgt/ContractUtil.java deleted file mode 100644 index d32b7725d26..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/ContractUtil.java +++ /dev/null @@ -1,85 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.proof.mgt; - -import de.uka.ilkd.key.casetool.ModelMethod; - -public class ContractUtil { - - private ContractUtil() {} - - public static PrePostPair getPreInvPost(ModelMethod m) { - String pre = "(" + normalizeConstraint(m.getMyPreCond()) - + ")" + " and " + "(" - + normalizeConstraint(m.getContainingClass().getMyInv()) + ")"; - String post = normalizeConstraint(m.getMyPostCond()); - return new PrePostPair(pre, post); - } - - public static PrePostPair getPrePost(ModelMethod m) { - String pre = "(" + normalizeConstraint(m.getMyPreCond()) - + ")"; - String post = normalizeConstraint(m.getMyPostCond()); - pre=pre.trim(); - post=post.trim(); - return new PrePostPair(pre, post); - } - - public static PrePostPair getPreInvPostInv(ModelMethod m) { - String inv = normalizeConstraint(m.getContainingClass().getMyInv()); - String pre = "(" + normalizeConstraint(m.getMyPreCond()) - + ")" + " and " + "(" - + inv + ")"; - String post = "(" + normalizeConstraint(m.getMyPostCond()) +")" - + " and " + "(" + inv + ")"; - return new PrePostPair(pre, post); - } - - public static PrePostPair getPreInvInv(ModelMethod m) { - String inv = normalizeConstraint(m.getContainingClass().getMyInv()); - String pre = "(" + normalizeConstraint(m.getMyPreCond()) - + ")" + " and " + "(" - + inv + ")"; - return new PrePostPair(pre, inv); - } - - public static PrePostPair getPreInvTout(ModelMethod m) { - String poToutText; - if (m.getContainingClassName().equals(m.getName())){ - poToutText=""; - } else { - poToutText= "("+normalizeConstraint(m.getMyPreCond())+")" - + " and " + "(" - + normalizeConstraint(m.getContainingClass().getMyInv()) + ")" - + " and " + "(" - +normalizeConstraint - (m.getContainingClass().getMyThroughout())+")"; - } - return new PrePostPair - (poToutText, normalizeConstraint - (m.getContainingClass().getMyThroughout())); - } - - - /** - * Converts an empty string to "true" and keeps it unchanged otherwise. - */ - public static String normalizeConstraint(String aText) { - if (aText.equals("")){ - return "true"; - } else { - return aText; - } - } - - - -} diff --git a/system/de/uka/ilkd/key/proof/mgt/ContractWithInvs.java b/system/de/uka/ilkd/key/proof/mgt/ContractWithInvs.java new file mode 100644 index 00000000000..26396728edd --- /dev/null +++ b/system/de/uka/ilkd/key/proof/mgt/ContractWithInvs.java @@ -0,0 +1,155 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.proof.mgt; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.speclang.ClassInvariant; +import de.uka.ilkd.key.speclang.IteratorOfClassInvariant; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.SetAsListOfClassInvariant; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; + + +public class ContractWithInvs { + + public final OperationContract contract; + public final SetOfClassInvariant assumedInvs; + public final SetOfClassInvariant ensuredInvs; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public ContractWithInvs(OperationContract contract, + SetOfClassInvariant assumedInvs, + SetOfClassInvariant ensuredInvs) { + assert contract != null; + assert assumedInvs != null; + assert ensuredInvs != null; + this.contract = contract; + this.assumedInvs = assumedInvs; + this.ensuredInvs = ensuredInvs; + } + + + /** + * Creates a ContractWithInvs from a string originating from + * ContractWithInvs.toString(). + */ + public ContractWithInvs(String s, Services services) { + String[] split = s.split(";", 3); + assert split.length == 3; + String contractName = split[0]; + String[] assumedInvNames = split[1].split(","); + String[] ensuredInvNames = split[2].split(","); + SpecificationRepository specRepos + = services.getSpecificationRepository(); + + contract = specRepos.getOperationContractByName(contractName); + assert contract != null; + + SetOfClassInvariant tempAssumedInvs + = SetAsListOfClassInvariant.EMPTY_SET; + for(int i = 0; i < assumedInvNames.length; i++) { + if(!assumedInvNames[i].equals("")) { + ClassInvariant inv + = specRepos.getClassInvariantByName(assumedInvNames[i]); + assert inv != null; + tempAssumedInvs = tempAssumedInvs.add(inv); + } + } + assumedInvs = tempAssumedInvs; + + SetOfClassInvariant tempEnsuredInvs + = SetAsListOfClassInvariant.EMPTY_SET; + for(int i = 0; i < ensuredInvNames.length; i++) { + if(!ensuredInvNames[i].equals("")) { + ClassInvariant inv + = specRepos.getClassInvariantByName(ensuredInvNames[i]); + assert inv != null; + tempEnsuredInvs = tempEnsuredInvs.add(inv); + } + } + ensuredInvs = tempEnsuredInvs; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public String getHTMLText(Services services) { + StringBuffer assumedSB = new StringBuffer(); + IteratorOfClassInvariant it = assumedInvs.iterator(); + while(it.hasNext()) { + assumedSB.append("
" + it.next().getHTMLText(services) + .replaceAll("", "")); + } + + StringBuffer ensuredSB = new StringBuffer(); + it = ensuredInvs.iterator(); + while(it.hasNext()) { + ensuredSB.append("
" + it.next().getHTMLText(services) + .replaceAll("", "")); + } + + return "" + + contract.getHTMLText(services).replaceAll("", "") + + (assumedInvs.size() > 0 + ? "
Assumed invariants:" + assumedSB.toString() + : "") + + (ensuredInvs.size() > 0 + ? "Ensured invariants:" + ensuredSB.toString() + : "") + + ""; + } + + + + public String toString() { + StringBuffer assumedSB = new StringBuffer(); + IteratorOfClassInvariant it = assumedInvs.iterator(); + while(it.hasNext()) { + assumedSB.append(it.next().getName() + ","); + } + + StringBuffer ensuredSB = new StringBuffer(); + it = ensuredInvs.iterator(); + while(it.hasNext()) { + assumedSB.append(it.next().getName() + ","); + } + + return contract.getName() + ";" + + assumedSB.toString() + ";" + + ensuredSB.toString(); + } + + + + public boolean equals(Object o) { + if(!(o instanceof ContractWithInvs)) { + return false; + } + ContractWithInvs cwi = (ContractWithInvs) o; + return contract.equals(cwi.contract) + && assumedInvs.equals(cwi.assumedInvs) + && ensuredInvs.equals(cwi.ensuredInvs); + } + + + public int hashCode() { + return contract.hashCode() + + assumedInvs.hashCode() + + ensuredInvs.hashCode(); + } +} diff --git a/system/de/uka/ilkd/key/proof/mgt/Contractable.java b/system/de/uka/ilkd/key/proof/mgt/Contractable.java deleted file mode 100644 index a0543fd3688..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/Contractable.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Created on 27.04.2005 - * - */ -package de.uka.ilkd.key.proof.mgt; - -/** - * @author andreas - * - */ -public interface Contractable { - - boolean equalContractable(Contractable c); - -} diff --git a/system/de/uka/ilkd/key/proof/mgt/DLHoareTriplePO.java b/system/de/uka/ilkd/key/proof/mgt/DLHoareTriplePO.java deleted file mode 100644 index 2f44400ce2d..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/DLHoareTriplePO.java +++ /dev/null @@ -1,190 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.proof.mgt; - -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.Statement; -import de.uka.ilkd.key.java.StatementBlock; -import de.uka.ilkd.key.java.statement.Desugarable; -import de.uka.ilkd.key.java.statement.MethodBodyStatement; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.Modality; -import de.uka.ilkd.key.logic.op.Op; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.init.*; -import de.uka.ilkd.key.util.KeYExceptionHandler; - -/** - * represents a proof obligation input to the prover for a DLMethodContract - */ -public class DLHoareTriplePO implements ProofOblInput { - - private ProofAggregate res; - private Term term; - private InitConfig initConfig; - private String name; - private Contractable[] contractable; - private String header; // needed to loaded the proof later - DLMethodContract ct; - - public DLHoareTriplePO(Term t, Modality mod, String header, - String name, Services services, DLMethodContract ct) { - this.ct = ct; - this.term = desugar(t, mod); - this.name = name; - this.header = header; - Statement pe = (Statement) t.sub(1).javaBlock().program(); - Statement unwrapped = DLMethodContract.unwrapBlocks(pe, false); - if (unwrapped instanceof MethodBodyStatement) { - contractable = new Contractable[]{ - ((MethodBodyStatement)unwrapped). - getProgramMethod(services)}; - } else if (unwrapped instanceof Contractable){ - contractable = new Contractable[]{(Contractable)unwrapped}; - } else { - throw new IllegalStateException("DL Hoare Triple Contract defined " - +"on illegal statement "+unwrapped); - } - } - - private static Term desugar(Term fma, Modality mod) { - TermFactory tf = TermFactory.DEFAULT; - StatementBlock sta = (StatementBlock)fma.sub(1).javaBlock().program(); - Statement unwrapped = DLMethodContract.unwrapBlocks(sta,true); - if (unwrapped instanceof Desugarable) { - sta = (StatementBlock)((Desugarable)unwrapped).desugar(); - } - Term result = tf.createJunctorTerm - (Op.IMP, fma.sub(0), - tf.createProgramTerm(mod, - JavaBlock.createJavaBlock(sta), - fma.sub(1).sub(0))); - - return result.equals(fma) ? fma : result; - } - - /** returns the proof obligation term as result of the proof obligation - * input. If there is still no input available because nothing has - * been read yet null is returned. - */ - public ProofAggregate getPO() { - return res; - } - -// public void setSettings(ProofSettings settings) { -// this.settings = settings; -// } - - /** starts reading the input and modifies the InitConfig of this - * object with respect to the given modification - * strategy. - */ - public void readProblem(ModStrategy mod) throws ProofInputException { - initConfig.getServices().getNamespaces(). - programVariables().add(ct.getProgramVariables()); - - Proof p = new Proof(name(), term, header, - initConfig.createTacletIndex(), - initConfig.createBuiltInRuleIndex(), - initConfig.getServices(), - initConfig.mergedProofSettings()); - res = ProofAggregate.createProofAggregate(p, name()); - - } - - public void setExceptionHandler(KeYExceptionHandler keh){ - } - - public boolean askUserForEnvironment() { - return false; - } - - /** reads the Java model that belongs to this input. - */ - public String readModel() throws ProofInputException { - return ""; - } - - /** returns the path to the Java model. - */ - public String getJavaPath() { - return ""; - } - - /** set the initial configuration used to read an input. It may become - * modified during reading depending on the modification strategy used - * for reading. - */ - public void setInitConfig(InitConfig i) { - this.initConfig = i; - } - - public void readSpecs(){ - } - - public void readActivatedChoices() throws ProofInputException { - //nothing to do - } - - public SetOfChoice getActivatedChoices() throws ProofInputException { - return initConfig.getActivatedChoices(); - } - - /** reads the include section and returns an Includes object. - */ - public Includes readIncludes() throws ProofInputException { - return null; - } - - /** returns the name of the proof obligation input. - */ - public String name() { - return name; - } - - /** - * returns the object for which this proof obligation proves a contract on. - * In this case we assume that the first program element of the second - * subterm of the - * proof obligation is a method body statement of which the according program - * method is returned. - */ - public Contractable[] getObjectOfContract() { - return contractable; - } - - /** - * initialises the contract, that is, it adds the proof created by this PO input - * to the contract if the given contract is the same as that of the PO. Then true - * is returned. Otherwise nothing is done and false is returned. - */ - public boolean initContract(Contract ct) { - if (ct==this.ct) { - ct.addCompoundProof(getPO()); - return true; - } else { - return false; - } - } - - public void startProtocol() { - // do nothing - } - - public Term getTerm() { - return term; - } - - public void setPO(ProofAggregate po) { - res = po; - } -} diff --git a/system/de/uka/ilkd/key/proof/mgt/DLMethodContract.java b/system/de/uka/ilkd/key/proof/mgt/DLMethodContract.java deleted file mode 100644 index d75b2800e0d..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/DLMethodContract.java +++ /dev/null @@ -1,552 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.proof.mgt; - -import java.util.*; - -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.abstraction.ArrayType; -import de.uka.ilkd.key.java.abstraction.Type; -import de.uka.ilkd.key.java.statement.Catch; -import de.uka.ilkd.key.java.statement.CatchAllStatement; -import de.uka.ilkd.key.java.statement.MethodBodyStatement; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.logic.sort.AbstractSort; -import de.uka.ilkd.key.pp.LogicPrinter; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofSaver; -import de.uka.ilkd.key.proof.VariableNameProposer; -import de.uka.ilkd.key.proof.init.ProofOblInput; -import de.uka.ilkd.key.util.Debug; - -/** - * represents a contract on the DynamicLogic level, that is pre-condition, - * program, post-condition, and modifies clause. It is the starting point to - * create both proof obligation (to ensure that the contract is valid) as well - * as a taclet (that allows to use the contract in a proof). DLMethodContracts - * are created from UserKeYProblemFiles using the \contract section. Moreover - * they are created when a contract of another input like JML or OCL is - * configured. - * @deprecated - * - */ -public class DLMethodContract extends DefaultOperationContract { - - private Term pre; - private Term atPreAxioms; - private Collection atPreFunctions; - private Modality modality; - private ModelMethod modelMethod; - private Statement stmt; - private Term post; - private SetOfLocationDescriptor modifies; - private NamespaceSet namespaces; - private String displayName; - private String name; - private Services services; - - - private static Statement extractStatement(Term fma) { - JavaProgramElement pe = fma.javaBlock().program(); - return (Statement) ((NonTerminalProgramElement) pe).getChildAt(0); - } - - static Statement unwrapBlocks(Statement s, boolean stopAtCatchAll) { - while (s instanceof StatementBlock - || (s instanceof CatchAllStatement && !stopAtCatchAll) - || s instanceof Catch) { - s = ((StatementContainer) s).getStatementAt(0); - } - return s; - } - - /** - * Creates a DLMethodContract with one implication formula of the form - * pre -> \ post and a modifies clause - * - * @param fma - * the implication formula - * @param modifies - * a set of location descriptors defining the modifies clause for - * this DLMethodContract - * @param name - * a unique identifying name for a contract in the proof - * @param displayName - * the name displayed for this contract - * @param services - * the services object - * @param namespaces - * the namespaces for looking up atpre functions - */ - public DLMethodContract(Term fma, SetOfLocationDescriptor modifies, - String name, String displayName, Services services, - NamespaceSet namespaces) { - - this(fma.sub(0), fma.sub(1).sub(0), null, null, extractStatement(fma - .sub(1)), modifies, (Modality) fma.sub(1).op(), name, - displayName, services, namespaces.copy()); - - setupAtPreFunctions(fma, namespaces); - } - - /** - * Creates a DLMethodContract with separate parts and possible additional - * preconditions which are not to be proven in the precondition branch of - * the created proof. - * - * @param pre - * the precondition of the contract - * @param post - * the postcondition of the contract - * @param extraPre - * the additional preconditions - * @param atPreFunctions - * a Collection with all functions used to model @pre for function symbols - * @param mbs - * the statement of the proof, either this is a method body - * statement or a catch all statement - * @param modifies - * a set of location descriptors defining the modifies clause for - * this DLMethodContract - * @param name - * a unique identifying name for a contract in the proof - * @param displayName - * the name displayed for this contract - * @param services - * the services object - * @param namespaces - * the namespaces for looking up atpre functions - */ - public DLMethodContract(Term pre, Term post, Term extraPre, - Collection atPreFunctions, Statement mbs, - SetOfLocationDescriptor modifies, Modality modality, String name, - String displayName, Services services, NamespaceSet namespaces) { - - assert pre != null && post != null; - - this.pre = pre; - this.post = post; - this.atPreAxioms = extraPre; - this.atPreFunctions = atPreFunctions == null ? new HashSet() - : atPreFunctions; - this.stmt = mbs; - this.modifies = modifies; - this.modality = modality; - this.name = name; - this.displayName = displayName; - this.services = services; - this.namespaces = namespaces; - this.modelMethod = new JavaModelMethod(getProgramMethod(), services - .getJavaInfo().getJavaSourcePath(), services); - } - - /** - * @param namespaces - * @param map - */ - private void addAtPreFunctions(Namespace namespace, Map map) { - if (namespace instanceof AtPreNamespace) { - final Map atPreMapping = ((AtPreNamespace) namespace) - .getAtPreMapping(); - map.putAll(atPreMapping); - atPreFunctions.addAll(atPreMapping.values()); - } - } - - public void addPost(Term t) { - post = TermBuilder.DF.and(t, post); - } - - public void addPre(Term t) { - pre = TermBuilder.DF.and(t, pre); - } - - public boolean applicableForModality(Modality mod) { - return getModality().equals(ModalityClass.getNormReprModality(mod)); - } - - private ProgramVariable clone(ProgramVariable pv, Services services) { - final ProgramElementName name = services.getVariableNamer() - .getTemporaryNameProposal(pv.name().toString()); - return new LocationVariable(name, pv.getKeYJavaType()); - } - - private RigidFunction clone(RigidFunction rf) { - String basename = rf.name().toString().replaceAll("@pre", "AtPre"); - final String name = VariableNameProposer.DEFAULT.getNameProposal(basename, services, null); - return new RigidFunction(new Name(name), rf.sort(), rf.argSort()); - } - - public DLMethodContract copy() { - return new DLMethodContract(pre, post, atPreAxioms, - getAtPreFunctions(), stmt, modifies, modality, name, - displayName, services, namespaces); - } - - public DLMethodContract createDLMethodContract(Proof proof) { - final DLMethodContract c = copy(); - c.displayName = c.displayName + " (derived)"; - return c; - } - - private Term createImplication() { - final TermBuilder tb = TermBuilder.DF; - final Term modalityTerm = tb.tf().createProgramTerm(modality, - JavaBlock.createJavaBlock(new StatementBlock(getStatement())), - getPost()); - return tb.imp(tb.and(getAdditionalAxioms(), getPre()), modalityTerm); - } - - public String createProgramVarsSection() { - final IteratorOfNamed it = namespaces.programVariables().allElements() - .iterator(); - String result = "\n\n\\programVariables {\n"; - while (it.hasNext()) { - ProgramVariable pv = (ProgramVariable) it.next(); - final Type javaType = pv.getKeYJavaType().getJavaType(); - - final String typeName = javaType instanceof ArrayType ? ((ArrayType) javaType) - .getAlternativeNameRepresentation() - : javaType.getFullName(); - - result += " " + typeName + " " + pv.name() + ";\n"; - } - result += "}\n"; - return result; - } - - public boolean equals(Object cmp) { - if (!(cmp instanceof OldOperationContract)) { - return false; - } - if (!(cmp instanceof DLMethodContract)) { - return cmp.equals(this); - } - DLMethodContract cmpHoare = (DLMethodContract) cmp; - // TODO: This does not work if functions for @pre are introduced - boolean b = cmpHoare.modelMethod.equals(modelMethod) - && cmpHoare.atPreAxioms.equalsModRenaming(atPreAxioms) - && cmpHoare.post.equalsModRenaming(post) - && cmpHoare.pre.equalsModRenaming(pre) - && cmpHoare.modality.equals(modality); - if (!b || cmpHoare.modifies.size() != modifies.size()) - return false; - return modifies.equals(cmpHoare.modifies); - } - - protected Term getAdditionalAxioms() { - return atPreAxioms; - } - - private Collection getAtPreFunctions() { - return atPreFunctions; - } - - public CatchAllStatement getCatchAllStatement() { - Statement s = unwrapBlocks(getStatement(), true); - return (s instanceof CatchAllStatement) ? (CatchAllStatement) s : null; - } - - public String getHTMLText() { - return "pre: " - + getPreText() - + "
post: " - + getPostText() - + "
modifies: " - + getModifiesText() - + "
termination: " - + (getModality() == Op.DIA ? "total" : getModality().toString()) - + ""; - } - - public MethodBodyStatement getMethodBodyStatement() { - return (MethodBodyStatement) unwrapBlocks(getStatement(), false); - } - - public Modality getModality() { - return ModalityClass.getNormReprModality(modality); - } - - public ModelMethod getModelMethod() { - return modelMethod; - } - - public SetOfLocationDescriptor getModifies() { - return modifies; - } - - public String getModifiesText() { - return LogicPrinter.quickPrintLocationDescriptors(getModifies(), services); - } - - public String getName() { - return name; - } - - /** - * returns the object on which this contract is, in this case it is the - * program statement of the contract; or in case that this is a method body - * statement the according program method is returned. - */ - public Object getObjectOfContract() { - return getProgramMethod(); - } - - public Term getPost() { - return post; - } - - public String getPostText() { - return ProofSaver.printTerm(getPost(), services).toString(); - } - - public Term getPre() { - return pre; - } - - public String getPreText() { - return ProofSaver.printTerm(getPre(), services).toString(); - } - - public ProgramMethod getProgramMethod() { - Object o = unwrapBlocks(getStatement(), false); - if (o instanceof MethodBodyStatement) { - return ((MethodBodyStatement) o).getProgramMethod(services); - } - Debug.fail(); - return null; - } - - /** - * returns a proof obligation input needed to show the corretcness of this - * contract. - * - */ - public ProofOblInput getProofOblInput(Proof proof) { - return new DLHoareTriplePO(createImplication(), getModality(), header, - getName(), services, this); - } - - public Statement getStatement() { - return stmt; - } - - public int hashCode() { - int result = 0; - result = 37 * result + modelMethod.hashCode(); - result = 37 * result + modality.hashCode(); - result = 37 * result + atPreAxioms.hashCode(); - result = 37 * result + post.hashCode(); - result = 37 * result + pre.hashCode(); - result = 37 * result + modifies.hashCode(); - return result; - } - - /** - * @param replacementMap - * @param localFunctions - * @param localProgramVariables - */ - protected void instantiateAtPreSymbols(Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables) { - final Iterator it = getAtPreFunctions().iterator(); - while (it.hasNext()) { - final RigidFunction rf = (RigidFunction) it.next(); - final RigidFunction newRf = clone(rf); - localFunctions.addSafely(newRf); - replacementMap.put(rf, newRf); - } - } - - protected void instantiateAuxiliarySymbols(Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables, Services services) { - instantiateDLContractPV(replacementMap, localProgramVariables); - } - - private void instantiateDLContractPV(Map replacementMap, - Namespace programVariables) { - final IteratorOfNamed it = namespaces.programVariables().elements() - .iterator(); - while (it.hasNext()) { - final ProgramVariable pv = (ProgramVariable) it.next(); - assert !pv.isMember(); - if (!replacementMap.containsKey(pv)) { - final ProgramVariable newPV = clone(pv, services); - programVariables.addSafely(newPV); - replacementMap.put(pv, newPV); - } - } - } - - /** - * @param insts - * @param replacementMap - * @param localProgramVariables - * @param localFunctions - */ - protected void instantiateMethodParameters( - MethodContractInstantiation insts, final Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables) { - for (int i = 0, methodParameterSize = insts.getArgumentCount(); i < methodParameterSize; i++) { - replacementMap.put(getMethodBodyStatement().getArguments() - .getExpression(i), insts.getArgumentAt(i)); - } - } - - /** - * @param insts - * @param replacementMap - * @param localProgramVariables - * @param localFunctions - */ - protected void instantiateMethodReceiver(MethodContractInstantiation insts, - final Map replacementMap, Namespace localFunctions, - Namespace localProgramVariables) { - if (!getMethodBodyStatement().isStatic(services)) { - // this can be a field reference for instance - Term rec = services.getTypeConverter().convertToLogicElement( - insts.getReceiver()); - Sort recSort = rec.sort(); - MethodBodyStatement mbs = null; - if(stmt instanceof CatchAllStatement) { - mbs = (MethodBodyStatement)((StatementBlock)((CatchAllStatement)stmt).getBody()).getBody().getStatement(0); - }else{ - mbs = (MethodBodyStatement)stmt; - } - Sort actSort = mbs.getBodySource().getSort(); - if(!recSort.equals(actSort)) { - rec = TermFactory.DEFAULT.createFunctionTerm(((AbstractSort)actSort).getCastSymbol(), rec); - } - replacementMap.put(getMethodBodyStatement().getDesignatedContext(), - rec); - } - } - - /** - * @param insts - * @param replacementMap - * @param localProgramVariables - * @param localFunctions - */ - protected void instantiateMethodReturnVariable( - MethodContractInstantiation insts, final Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables) { - replacementMap.put(getMethodBodyStatement().getResultVariable(), insts - .getResult()); - } - - public void setHeader(String s) { - if (s == null) - return; - // 1. Check if there is a \programVariables section (I can - // imagine an unlikely situation where it's actually missing), - // if so, replace it with a "fresh" one - int start = s.indexOf("\\programVariables"); - int end = -1; - if (start != -1) { - end = s.indexOf("}", start); - header = s.substring(0, start) + createProgramVarsSection() - + s.substring(end + 1); - } else { - // 2. No? Then put it somewhere "on top" - start = s.indexOf("\\withOptions"); - if (start != -1) { - // Put it after \withOptions - start = s.indexOf(";", start) + 1; - } else { - // Put it after \javaSource - start = s.indexOf("\\javaSource"); - if (start != -1) { - start = s.indexOf(";", start) + 1; - } else { - Debug - .fail("Your .key file is missing vital sections as far as this situation is concerned."); - } - } - header = s.substring(0, start) + createProgramVarsSection() - + s.substring(start + 1); - } - } - - public String getHeader() { - return header; - } - - private void setupAtPreFunctions(Term fma, NamespaceSet namespaces) { - final TermBuilder tb = TermBuilder.DF; - final Map map = new TreeMap(new NameComparator()); - atPreFunctions = new HashSet(); - - addAtPreFunctions(namespaces.programVariables(), map); - addAtPreFunctions(namespaces.functions(), map); - - Term conj = tb.tt(); - - final Iterator it = map.entrySet().iterator(); - - while (it.hasNext()) { - Map.Entry e = (Map.Entry) it.next(); - TermSymbol atPost = (TermSymbol) e.getKey(); - Function atPre = (Function) e.getValue(); - LogicVariable[] vars = new LogicVariable[atPost.arity()]; - - if (atPost instanceof ProgramVariable - && ((ProgramVariable) atPost).isMember() - && !((ProgramVariable) atPost).isStatic()) { - vars = new LogicVariable[] { new LogicVariable(new Name("x"), - atPre.argSort(0)) }; - } else { - for (int i = 0; i < vars.length; i++) { - vars[i] = new LogicVariable(new Name("x" + i), - ((Function) atPost).argSort(i)); - } - } - - final Term[] varTerms = new Term[vars.length]; - for (int i = 0; i < vars.length; i++) { - varTerms[i] = tb.var(vars[i]); - } - - final Term atPostTerm; - if ((atPost instanceof ProgramVariable) - && ((ProgramVariable) atPost).isMember() - && !((ProgramVariable) atPost).isStatic()) { - atPostTerm = tb.dot(varTerms[0], (ProgramVariable) atPost); - } else { - atPostTerm = tb.func(atPost, varTerms); - } - - final Term atPreTerm = tb.func(atPre, varTerms); - conj = tb.and(conj, tb.all(vars, tb.equals(atPreTerm, atPostTerm))); - } - - atPreAxioms = conj; - - } - - public Namespace getProgramVariables() { - return namespaces.programVariables(); - } - - public String toString() { - return "[DL Hoare Triple Contract] " + getName(); - } - - private class NameComparator implements Comparator { - public int compare(Object o1, Object o2) { - return ((Named)o1).name().compareTo(((Named)o2).name()); - } - } - -} diff --git a/system/de/uka/ilkd/key/proof/mgt/DefaultOperationContract.java b/system/de/uka/ilkd/key/proof/mgt/DefaultOperationContract.java deleted file mode 100644 index 3c011cb222b..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/DefaultOperationContract.java +++ /dev/null @@ -1,122 +0,0 @@ -package de.uka.ilkd.key.proof.mgt; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.statement.CatchAllStatement; -import de.uka.ilkd.key.logic.Namespace; -import de.uka.ilkd.key.logic.ProgramElementName; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.op.LocationVariable; -import de.uka.ilkd.key.logic.op.ProgramVariable; -import de.uka.ilkd.key.proof.Proof; - -/** - * @deprecated - */ -public abstract class DefaultOperationContract extends AbstractContract - implements OldOperationContract, HoareTripleContract { - - protected abstract Term getAdditionalAxioms(); - - public InstantiatedMethodContract instantiate(MethodContractInstantiation insts, - Proof proof) { - - final Services services = proof.getServices(); - - final Namespace localFunctions = new Namespace(); - final Namespace localProgramVariables = new Namespace(); - final Map replacementMap = new HashMap(); - - instantiateMethodParameters(insts, replacementMap, - localFunctions, localProgramVariables); - - instantiateMethodReceiver(insts, replacementMap, - localFunctions, localProgramVariables); - - instantiateMethodReturnVariable(insts, replacementMap, - localFunctions, localProgramVariables); - - final ProgramVariable excVar = - instantiateCatchAllStatement(getCatchAllStatement(), - replacementMap, localFunctions, localProgramVariables, services); - - instantiateAtPreSymbols(replacementMap, localFunctions, localProgramVariables); - - instantiateAuxiliarySymbols(replacementMap, localFunctions, localProgramVariables, proof.getServices()); - return InstantiatedMethodContract.create - (replacementMap, getPre(), getPost(), getAdditionalAxioms(), - getModifies(), insts.getModality(), excVar, - localFunctions, localProgramVariables); - } - - public abstract CatchAllStatement getCatchAllStatement(); - - - protected abstract void instantiateAuxiliarySymbols(Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables, Services services); - - /** - * @param insts - * @param replacementMap - * @param localProgramVariables - * @param localFunctions - */ - protected abstract void instantiateMethodReturnVariable( - MethodContractInstantiation insts, Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables); - - /** - * @param localProgramVariables - * @param replacementMap - * @param ca - * @return - */ - protected ProgramVariable instantiateCatchAllStatement(CatchAllStatement ca, - Map replacementMap, Namespace localFunctions, - Namespace localProgramVariables, Services services) { - - ProgramVariable excVar = null; - if (ca != null) { - final ProgramVariable paramPV = (ProgramVariable) ca - .getParameterDeclaration().getVariableSpecification() - .getProgramVariable(); - - final ProgramElementName catchAllInstantiadParameterName = services - .getVariableNamer().getTemporaryNameProposal( - paramPV.name().toString()); - - excVar = new LocationVariable(catchAllInstantiadParameterName, - paramPV.getKeYJavaType()); - replacementMap.put(paramPV, excVar); - localProgramVariables.add(excVar); - } - return excVar; - } - - /** - * @param insts - * @param replacementMap - * @param localProgramVariables - * @param localFunctions - */ - protected abstract void instantiateMethodReceiver( - MethodContractInstantiation insts, Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables); - - /** - * @param insts - * @param replacementMap - * @param localProgramVariables - * @param localFunctions - */ - protected abstract void instantiateMethodParameters( - MethodContractInstantiation insts, Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables); - - protected abstract void instantiateAtPreSymbols(Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables); - -} diff --git a/system/de/uka/ilkd/key/proof/mgt/DefaultProofCorrectnessMgt.java b/system/de/uka/ilkd/key/proof/mgt/DefaultProofCorrectnessMgt.java index 3629da969e6..afee60bf3de 100644 --- a/system/de/uka/ilkd/key/proof/mgt/DefaultProofCorrectnessMgt.java +++ b/system/de/uka/ilkd/key/proof/mgt/DefaultProofCorrectnessMgt.java @@ -6,136 +6,179 @@ // The KeY system is protected by the GNU General Public License. // See LICENSE.TXT for details. // -package de.uka.ilkd.key.proof.mgt; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +package de.uka.ilkd.key.proof.mgt; import de.uka.ilkd.key.gui.KeYMediator; import de.uka.ilkd.key.gui.RuleAppListener; +import de.uka.ilkd.key.logic.op.ProgramMethod; import de.uka.ilkd.key.proof.*; +import de.uka.ilkd.key.proof.init.EnsuresPostPO; +import de.uka.ilkd.key.proof.init.InitConfig; +import de.uka.ilkd.key.proof.init.PreservesInvPO; +import de.uka.ilkd.key.proof.init.ProofOblInput; +import de.uka.ilkd.key.proof.init.RespectsModifiesPO; +import de.uka.ilkd.key.rule.IteratorOfRuleApp; import de.uka.ilkd.key.rule.RuleApp; +import de.uka.ilkd.key.rule.SetAsListOfRuleApp; +import de.uka.ilkd.key.rule.SetOfRuleApp; -public class DefaultProofCorrectnessMgt implements ProofCorrectnessMgt{ +public class DefaultProofCorrectnessMgt implements ProofCorrectnessMgt { - private Proof proof; - private Set cachedAppliedRules = new HashSet(); - private KeYMediator mediator; - private DefaultMgtProofListener proofListener + private final Proof proof; + private final SpecificationRepository specRepos; + private final DefaultMgtProofListener proofListener = new DefaultMgtProofListener(); - private DefaultMgtProofTreeListener proofTreeListener + private final DefaultMgtProofTreeListener proofTreeListener = new DefaultMgtProofTreeListener(); - + + private KeYMediator mediator; + private SetOfRuleApp cachedRuleApps = SetAsListOfRuleApp.EMPTY_SET; private ProofStatus proofStatus = null; - - private DepAnalysis lastAnalysisInfo; - + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + public DefaultProofCorrectnessMgt(Proof p) { - this.proof=p; + this.proof = p; + this.specRepos = p.getServices().getSpecificationRepository(); proof.addProofTreeListener(proofTreeListener); } + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private boolean atLeastOneClosed(SetOfProof proofs) { + IteratorOfProof it = proofs.iterator(); + while(it.hasNext()) { + Proof proof = it.next(); + proof.mgt().updateProofStatus(); + if(proof.mgt().getStatus().getProofClosed()) { + return true; + } + } + return false; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + public RuleJustification getJustification(RuleApp r) { return proof.env().getJustifInfo().getJustification(r, proof.getServices()); } - public boolean ruleApplicable(RuleApp r, Goal g) { - final RuleJustification just = getJustification(r); - if (just==null) { - System.err.println("Warning: No justification for rule " + - r.rule().name() +" found"); - return true; - } - lastAnalysisInfo = just.dependsOn(proof); - return !lastAnalysisInfo.depExists(); - } - - - public String getLastAnalysisInfo() { - return lastAnalysisInfo == null ? "" : lastAnalysisInfo.toString(); + + /** + * Tells whether a contract for the passed operation may be applied + * in the passed goal without creating circular dependencies. + */ + public boolean contractApplicableFor(ProgramMethod pm, Goal g) { + //get the method which is being verified in the passed goal + ProgramMethod pmUnderVerification + = specRepos.getOperationForProof(g.proof()); + if(pmUnderVerification == null) { + return true; + } + + //collect all proofs on which the specification of the + //passed operation may depend + SetOfProof proofs = specRepos.getProofs(pm); + SetOfProof newProofs = proofs; + while(newProofs.size() > 0) { + IteratorOfProof it = newProofs.iterator(); + newProofs = SetAsListOfProof.EMPTY_SET; + + while(it.hasNext()) { + Proof proof = it.next(); + IteratorOfRuleApp cachedRuleAppsIt + = proof.mgt().getNonAxiomApps().iterator(); + while(cachedRuleAppsIt.hasNext()) { + RuleApp ruleApp = cachedRuleAppsIt.next(); + RuleJustification ruleJusti = getJustification(ruleApp); + if(ruleJusti instanceof RuleJustificationBySpec) { + ContractWithInvs cwi + = ((RuleJustificationBySpec) ruleJusti).getSpec(); + SetOfProof proofsForPm + = specRepos.getProofs(cwi.contract + .getProgramMethod()); + newProofs = newProofs.union(proofsForPm); + proofs = proofs.union(proofsForPm); + } + } + } + } + + //is one of those proofs about the operation under verification? + IteratorOfProof it = proofs.iterator(); + while(it.hasNext()) { + ProgramMethod pm2 = specRepos.getOperationForProof(it.next()); + if(pm2.equals(pmUnderVerification)) { + return false; + } + } + + return true; } + public void updateProofStatus() { - boolean closed = false; - boolean closedButLemmasLeft = false; - boolean open = false; + //proof open? + if(proof.openGoals().size() > 0) { + proofStatus = ProofStatus.OPEN; + return; + } - if (proof.openGoals().size() == 0){ - // either closed or closedButLemmasLeft - Iterator cachedAppliedRulesIt = cachedAppliedRules.iterator(); - - RuleApp rule = null; - RuleJustification ruleJusti = null; - List list = null; - Iterator listIterator = null; - ProofAggregate pl = null; - int size = 0; - Proof p = null; - - boolean allRulesClosed = true; - while (cachedAppliedRulesIt.hasNext()) { - // every rule must be proven correct - rule = (RuleApp) cachedAppliedRulesIt.next(); - ruleJusti = getJustification(rule); - list = ruleJusti.getProofList(); - listIterator = list.iterator(); - boolean oneClosed = false; - while (listIterator.hasNext()) { - // one of these must be closed - pl = (ProofAggregate) listIterator.next(); - boolean allClosed = true; - Proof[] proofs = pl.getProofs(); - size = proofs.length; - for (int i = 0; i < size; i++) { - // all of these must be closed - p = proofs[i]; - p.mgt().updateProofStatus(); - if (p.mgt().getStatus().getProofClosed()) { - // This proof is closed so it is possible - // that all proofs are closed. - } - else { - // There is a proof which is not closed, - // so not all proofs can be closed! - allClosed = false; - } - } - if (allClosed) { - // all proofs in the ProofList are closed, meaning - // that this proof is closed - oneClosed = true; - } - else { - // Nothing to do here because this proof wasn't closed. - } - } - if (oneClosed) { - // This rule is closed so it is still possible all rules are - // closed and thus no need to change allRulesClosed here. - } - else { - allRulesClosed = false; - } - } - if (allRulesClosed) { - closed = true; - } - else { - closedButLemmasLeft = true; - } - } - else { - open = true; - } - proofStatus = new ProofStatus(closed, closedButLemmasLeft, open); - } - - private void cacheAppliedRule(RuleApp r) { - cachedAppliedRules.add(r); + //used, but yet unproven specifications? + IteratorOfRuleApp cachedRuleAppsIt = cachedRuleApps.iterator(); + while(cachedRuleAppsIt.hasNext()) { + RuleApp ruleApp = cachedRuleAppsIt.next(); + RuleJustification ruleJusti = getJustification(ruleApp); + if(ruleJusti instanceof RuleJustificationBySpec) { + ContractWithInvs cwi + = ((RuleJustificationBySpec) ruleJusti).getSpec(); + InitConfig initConfig = proof.env().getInitConfig(); + ProofOblInput ensuresPostPO + = new EnsuresPostPO(initConfig, + cwi.contract, + cwi.assumedInvs); + SetOfProof ensuresPostProofs + = specRepos.getProofs(ensuresPostPO); + ProofOblInput preservesInvPO + = new PreservesInvPO(initConfig, + cwi.contract.getProgramMethod(), + cwi.assumedInvs, + cwi.ensuredInvs); + SetOfProof preservesInvProofs + = specRepos.getProofs(preservesInvPO); + ProofOblInput respectsModifiesPO + = new RespectsModifiesPO(initConfig, + cwi.contract, + cwi.assumedInvs); + SetOfProof respectsModifiesProofs + = specRepos.getProofs(respectsModifiesPO); + + if(!(atLeastOneClosed(ensuresPostProofs) + && atLeastOneClosed(preservesInvProofs) + && atLeastOneClosed(respectsModifiesProofs))) { + proofStatus = ProofStatus.CLOSED_BUT_LEMMAS_LEFT; + return; + } + } + } + + //no -> proof is closed + proofStatus = ProofStatus.CLOSED; } + public void ruleApplied(RuleApp r) { RuleJustification rj = getJustification(r); if (rj==null) { @@ -143,21 +186,25 @@ public void ruleApplied(RuleApp r) { return; } if (!rj.isAxiomJustification()) { - cacheAppliedRule(r); + cachedRuleApps = cachedRuleApps.add(r); } } + public void ruleUnApplied(RuleApp r) { - boolean success = cachedAppliedRules.remove(r); - if (success) { + int oldSize = cachedRuleApps.size(); + cachedRuleApps = cachedRuleApps.remove(r); + if(oldSize != cachedRuleApps.size()) { updateProofStatus(); } } - public Iterator getAppliedNonAxioms() { - return cachedAppliedRules.iterator(); + + public SetOfRuleApp getNonAxiomApps() { + return cachedRuleApps; } + public void setMediator ( KeYMediator p_mediator ) { if ( mediator != null ) mediator.removeRuleAppListener ( proofListener ); @@ -168,22 +215,29 @@ public void setMediator ( KeYMediator p_mediator ) { mediator.addRuleAppListener ( proofListener ); } + public Proof getProof() { return proof; } + public boolean proofSimilarTo(Proof p) { return p.name().equals(getProof().name()); //%%% } + public ProofStatus getStatus() { if (proofStatus == null) updateProofStatus(); return proofStatus; } - class DefaultMgtProofListener implements RuleAppListener { - - /** invoked when a rule has been applied */ + + + //------------------------------------------------------------------------- + //inner classes + //------------------------------------------------------------------------- + + private class DefaultMgtProofListener implements RuleAppListener { public void ruleApplied(ProofEvent e) { if (DefaultProofCorrectnessMgt.this.getProof()==e.getSource()) { //%% actually I only want to listen to events of one proof @@ -193,24 +247,11 @@ public void ruleApplied(ProofEvent e) { } } - class DefaultMgtProofTreeListener extends ProofTreeAdapter { + + private class DefaultMgtProofTreeListener extends ProofTreeAdapter { public void proofClosed(ProofTreeEvent e) { ProofEnvironment pEnv = proof.env(); pEnv.updateProofStatus(); } - - public void proofPruned(ProofTreeEvent e) { - - } - - public void proofGoalsAdded(ProofTreeEvent e) { - - } - - public void proofStructureChanged(ProofTreeEvent e) { - - } } - - } diff --git a/system/de/uka/ilkd/key/proof/mgt/DepAnalysis.java b/system/de/uka/ilkd/key/proof/mgt/DepAnalysis.java deleted file mode 100644 index a65061ca946..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/DepAnalysis.java +++ /dev/null @@ -1,68 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -package de.uka.ilkd.key.proof.mgt; - -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.rule.Rule; - -public class DepAnalysis { - - private final boolean depExists; - private final Rule r; - private final Proof p; - private final String info; - - private static final DepAnalysis noDepInstance - = new DepAnalysis(false, "No Dependency"); - - public static DepAnalysis getInstance(boolean depExists, Rule r, - Proof p, String info) { - if (!depExists) { - return noDepInstance; - } else { - return new DepAnalysis(depExists, r, p, info); - } - } - - public static DepAnalysis getInstance(boolean depExists, Rule r, - Proof p) { - return getInstance(depExists, r, p, ""); - } - - public static DepAnalysis getInstance(boolean depExists, String info) { - return getInstance(depExists, null, null, info); - } - - - private DepAnalysis(boolean depExists, Rule r, Proof p, String info) { - this.depExists=depExists; - this.r=r; - this.p=p; - this.info=info; - } - - public DepAnalysis(boolean depExists, String info) { - this(depExists, null, null, info); - } - - public String toString() { - StringBuffer res = null; - if (r!=null && p!=null) { - res = new StringBuffer("Rule "+r.name()+" is "); - if (depExists) res.append("not "); - res.append("used in proof "+p.name()+". "); - } - return (res!=null) ? res+info : info; - } - - public boolean depExists() { - return depExists; - } - -} diff --git a/system/de/uka/ilkd/key/proof/mgt/InstantiatedMethodContract.java b/system/de/uka/ilkd/key/proof/mgt/InstantiatedMethodContract.java deleted file mode 100644 index 0b61fffcd49..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/InstantiatedMethodContract.java +++ /dev/null @@ -1,117 +0,0 @@ -package de.uka.ilkd.key.proof.mgt; - -import java.util.Map; - -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.Modality; -import de.uka.ilkd.key.logic.op.ProgramVariable; -import de.uka.ilkd.key.proof.SymbolReplacer; - -/** - * @deprecated - */ -public class InstantiatedMethodContract { - - private Term pre; - private Term post; - private Term atPreAxioms; - private SetOfLocationDescriptor modifies; - private Modality modality; - private ProgramVariable exc; - private Namespace functions; - private Namespace programVariables; - - public static InstantiatedMethodContract create(Map m, Term pre, Term post, - Term atPreAxioms, - SetOfLocationDescriptor mods, - Modality modality, - ProgramVariable exc, - Namespace functions, - Namespace programVariables) { - assert modality != null; - - final SymbolReplacer pvr = new SymbolReplacer(m); - return new InstantiatedMethodContract(replace(pvr, pre), - replace(pvr, post), - replace(pvr, atPreAxioms), - replace(pvr, mods), - modality, exc, - functions, programVariables); - } - - /** - * replaces the template locations in term t by the concrete ones - * contained in the instantiation map of pvr - * @param pvr the SymbolReplacer - * @param t the Term whose location templates are instantiated - * @return the instantiated term t - */ - private static Term replace(SymbolReplacer pvr, Term t) { - return pvr.replace(t); - } - - /** - * used to replace the template locations used in LocationDescriptor by the one - * in the replacement map of pvr - * @param pvr the SymbolReplacer - * @param mods the SetOfLocationDescriptor to be instantiated - * @return the instantiated set of location descriptors - */ - private static SetOfLocationDescriptor replace(SymbolReplacer pvr, - SetOfLocationDescriptor mods) { - SetOfLocationDescriptor result = SetAsListOfLocationDescriptor.EMPTY_SET; - final IteratorOfLocationDescriptor it = mods.iterator(); - while ( it.hasNext() ) { - result = result.add(pvr.replace(it.next())); - } - return result; - } - - - private InstantiatedMethodContract(Term pre, Term post, Term atPreAxioms, - SetOfLocationDescriptor mods, - Modality modality, ProgramVariable exc, - Namespace functions, Namespace programVariables) { - this.pre = pre; - this.atPreAxioms = atPreAxioms; - this.post = post; - this.modifies = mods; - this.modality = modality; - this.exc = exc; - this.functions = functions; - this.programVariables = programVariables; - } - - public Term getPre() { - return pre; - } - - public Term getPost() { - return post; - } - - public Term getAtPreAxioms() { - return atPreAxioms; - } - - public SetOfLocationDescriptor getModifies() { - return modifies; - } - - public Modality getModality() { - return modality; - } - - public ProgramVariable getExceptionVariable() { - return exc; - } - - public Namespace getAdditionalProgramVariables() { - return programVariables; - } - - public Namespace getAdditionalFunctions() { - return functions; - } - -} diff --git a/system/de/uka/ilkd/key/proof/mgt/JMLMethodContract.java b/system/de/uka/ilkd/key/proof/mgt/JMLMethodContract.java deleted file mode 100644 index 066f55b4018..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/JMLMethodContract.java +++ /dev/null @@ -1,285 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - - -package de.uka.ilkd.key.proof.mgt; - -import java.util.List; -import java.util.Map; - -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.Statement; -import de.uka.ilkd.key.java.statement.CatchAllStatement; -import de.uka.ilkd.key.jml.JMLLemmaMethodSpec; -import de.uka.ilkd.key.jml.JMLMethodSpec; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.pp.LogicPrinter; -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.proof.ProofSaver; -import de.uka.ilkd.key.proof.init.JMLPostAndInvPO; -import de.uka.ilkd.key.proof.init.ProofOblInput; - -/** - * @deprecated - */ -public class JMLMethodContract extends DefaultOperationContract { - - //iff true all existing invariants are added to the pre- and postcondition - //of the method contract, iff false only the invariants of the containing - //type and the instance invariants (if meth is not static) for the - //corresponding object are added. History constraints of the current type - //are always added. - public static final boolean allInvariants = true; - private ModelMethod meth; - private Modality modality; - - private JMLMethodSpec spec; - - public JMLMethodContract(ModelMethod meth, JMLMethodSpec spec, - Modality modality) { - this.meth = meth; - this.spec = spec; - this.modality = modality; - } - - public void addCompoundProof(ProofAggregate pl) { - proofs.add(pl); - } - - public boolean applicableForModality(Modality mod) { - return getModality().equals(ModalityClass.getNormReprModality(mod)); - } - - public DLMethodContract createDLMethodContract(Proof proof) { - return new DLMethodContract(getPre(), getPost(), - spec.getPi1Functional(), spec.introducedConstants(), - (Statement) spec.getProofStatement(), - spec.getAssignable(), - modality, - "Derived JML Method Contract", - "Derived JML Method Contract", - spec.getServices(), spec.getNamespaces()); - } - - public boolean equals(Object cmp) { - if (!(cmp instanceof JMLMethodContract)) return false; - final JMLMethodContract mc = (JMLMethodContract)cmp; - return meth.equals(getObjectOfContract()) && - getModality() == mc.getModality() && - getSpec().equals(mc.getSpec()); - } - - protected Term getAdditionalAxioms() { - return spec.getPi1Functional(); - } - - public CatchAllStatement getCatchAllStatement() { - return spec.getCatchAllStatement(); - } - - public String getHTMLText() { - return "pre: "+getPreText()+"
post: " - +getPostText()+"
modifies: " - +getModifiesText()+"
termination: " - +(getModality()==Op.DIA ? "total" : getModality().toString()) - +""; - } - - public Modality getModality() { - return ModalityClass.getNormReprModality(modality); - } - - public ModelMethod getModelMethod() { - return meth; - } - - public SetOfLocationDescriptor getModifies() { - return spec.getAssignable(); - } - - public String getModifiesText() { - return LogicPrinter.quickPrintLocationDescriptors(getModifies(), spec.getServices()); - } - - public String getName() { - return "JML Method Contract: "+spec.getMethodDeclaration().getFullName()+" (spec id:" +spec.id() +")"; - } - - public Object getObjectOfContract() { - return spec.getProgramMethod(); - } - - public Term getPost() { - return spec.getCompletePostFunctional(false, false); - } - - public String getPostText() { - return ProofSaver.printTerm(getPost(), spec.getServices()).toString(); - } - - public Term getPre() { - return spec.getCompletePre(false, false, modality == Op.DIA); - } - - public String getPreText() { - return ProofSaver.printTerm(getPre(), spec.getServices()).toString(); - } - - - public ProofEnvironment getProofEnv() { - return env; - } - - - public ProofOblInput getProofOblInput(Proof proof) { - return new JMLPostAndInvPO(spec, env.getJavaModel().getModelDir(), - allInvariants); //TODO - } - - public List getProofs() { - return proofs; - } - - public JMLMethodSpec getSpec(){ - return spec; - } - - public Statement getStatement() { - return (Statement) spec.getProofStatement(); - } - - public int hashCode() { - int result = 0; - result = 37 * result + meth.hashCode(); - result = 37 * result + getModality().hashCode(); - result = 37 * result + getSpec().hashCode(); - return result; - } - - - private static Name getNewName(Services services, Name baseName) { - NamespaceSet namespaces = services.getNamespaces(); - - int i = 0; - Name name; - do { - name = new Name(baseName + "_" + i++); - } while(namespaces.lookup(name) != null); - - return name; - } - - - protected void instantiateAtPreSymbols(Map replacementMap, Namespace localFunctions, - Namespace localProgramVariables) {} - - protected void instantiateAuxiliarySymbols(Map replacementMap, - Namespace localFunctions, Namespace localProgramVariables, Services services) { - IteratorOfQuantifierPrefixEntry it = spec.getOldLVs().iterator(); - while(it.hasNext()) { - LogicVariable lv = (LogicVariable) it.next().getVariable(); - - RigidFunction rf = (RigidFunction) spec.getLv2Const().get(lv); - if(rf != null) { - Name name = getNewName(services, rf.name()); - RigidFunction newRf = new RigidFunction(name, - rf.sort(), - rf.argSort()); - localFunctions.add(newRf); - replacementMap.put(rf, newRf); - } - } - IteratorOfOperator ito = spec.getOldFuncSymbols().iterator(); - while(ito.hasNext()) { - Operator op = ito.next(); - Name name = getNewName(services, op.name()); - Operator newOp; - if(op instanceof RigidFunction){ - RigidFunction rf = (RigidFunction) op; - newOp = new RigidFunction(name, rf.sort(), rf.argSort()); - }else{ - LocationVariable lv = (LocationVariable) op; - newOp = new LocationVariable(new ProgramElementName( - name.toString()), - lv.getKeYJavaType()); - } - localFunctions.add(newOp); - replacementMap.put(op, newOp); - } - } - - /** - * adds programvariables used as instantiations for the method parameters - * to the corresponding map - * @param insts the {@link MethodContractInstantiation} with the concrete instantiation - * of the method body statement - * @param replacementMap the Map with all instantiations - */ - protected void instantiateMethodParameters(MethodContractInstantiation insts, - Map replacementMap, Namespace localFunctions, Namespace localProgramVariables) { - for (int i=0; i=0) { - return classname.substring(0, classname.lastIndexOf(".")); - } else { - return null; - } - } - - // return the invariant of the parent if any, else "" - public String getParentInv(){ - return "";//%% - - } - - // return the classname of the parent if any, else "" - public String getParentClassName(){ - - return "";//%% - } - - - // returns true if class has a parent - public boolean hasOrigParent(){ - return false; - } - - - // calls getOpNames on parent if any, else returns null - public Vector getParentOpNames(){ - return null; - } - - - // calls getOps on parent if any, else returns null - public Vector getParentOps(){ - return null; - } - - // calls getOpNames on parent if any, else returns null - public Vector getInheritedOpNames(){ - return null; - } - - - // calls getOps on parent if any, else returns null - public Vector getInheritedOps(){ - return null; - } - - - public Vector getOpNames(){ - return null; - - } - - // returns ReprModelMethod - public Vector getOps(){ - - return null; - } - - public void getAssociations(HashMapOfClassifier classifiers){ - - } - - public String getText(){ - return "";//%% - } - - public String[] getClassesInPackage(){ - return new String[0]; - } - - public String getRootDirectory(){ - return rootDir; - } - - public Set getAllClasses(){ - Set allKJTs = services.getJavaInfo().getAllKeYJavaTypes(); - Iterator it = allKJTs.iterator(); - Set result = new HashSet(); - while (it.hasNext()) { - result.add(new JavaModelClass((KeYJavaType)it.next(), - rootDir, services)); - } - return result; - } - - public String getActXmifile() { - return ""; - } - - public int hashCode() { - int result = 7; - result = 13*result + getKeYJavaType().hashCode(); - result = 13*result + getRootDirectory().hashCode(); - return result; - } - - public boolean equals(Object o) { - if (!(o instanceof JavaModelClass)) { - return false; - } - JavaModelClass cmp = (JavaModelClass) o; - return kjt.equals(cmp.getKeYJavaType()) && - getRootDirectory().equals(cmp.getRootDirectory()); - } - - public ListOfClassInvariant getMyClassInvariants() { - return services.getSpecificationRepository().getAllInvariantsForType(getKeYJavaType()); - } - - public ListOfClassInvariant getMyThroughoutClassInvariants() { - return SLListOfClassInvariant.EMPTY_LIST;//%% - } - - public ListOfModelClass getMyParents() { - return SLListOfModelClass.EMPTY_LIST;//% - } - - public UMLInfo createUMLInfo(Services services) { - return new UMLInfo(services, SLListOfAssociation.EMPTY_LIST);//% - } - - public String toString() { - return getKeYJavaType()+","+getRootDirectory(); - } -} diff --git a/system/de/uka/ilkd/key/proof/mgt/JavaModelMethod.java b/system/de/uka/ilkd/key/proof/mgt/JavaModelMethod.java deleted file mode 100644 index 64dfadf8fcc..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/JavaModelMethod.java +++ /dev/null @@ -1,264 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.proof.mgt; - -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.java.Comment; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.declaration.ConstructorDeclaration; -import de.uka.ilkd.key.java.declaration.MethodDeclaration; -import de.uka.ilkd.key.logic.op.ProgramMethod; -import de.uka.ilkd.key.speclang.ListOfOperationContract; -import de.uka.ilkd.key.speclang.SLListOfOperationContract; - -public class JavaModelMethod implements ModelMethod, Contractable { - - private ProgramMethod method; - private String preCond=null; - private String postCond=null; - private String modifies=null; - private JavaModelClass contClass; - - public JavaModelMethod(ProgramMethod pm, String rootDir, Services services) { - this.method = pm; - contClass = new JavaModelClass(pm.getContainerType(), rootDir, services); - } - - public ModelClass getContainingClass() { - return contClass; - } - - public ProgramMethod getProgramMethod() { - return method; - } - - public String getContainingClassName() { - return method.getContainerType().getName(); - } - - public String getContainingPackage() { - return contClass.getContainingPackage(); - } - - // return signature of form name(arg1: type1; arg2: type2 ...) - // and translates Java types to OCL types - public String getCallSignature() { - return getCallSignature(true); - } - - public int getNumParameters() { - return 0;//%%% - } - - public String getParameterNameAt(int i){ - return "";//%%% - } - - public String getParameterTypeAt(int i){ - return "";//%%% - } - - public String getResultType() { - return "";//%%% - } - - private String toOCL(String s, boolean doit) { - if (!doit) { - return s; - } else { - return transformTypeJava2OCL(s); - } - } - - public static String transformTypeJava2OCL(String aJavaType){ - if ("int".equals(aJavaType) || - "byte".equals(aJavaType) || - "char".equals(aJavaType) || - "short".equals(aJavaType) || - "long".equals(aJavaType)){ - return "Integer"; - } - else if ("boolean".equals(aJavaType)) {return "Boolean";} - else if (aJavaType.endsWith("[]")) { - String base = transformTypeJava2OCL(aJavaType.substring - (0,aJavaType.length()-2)); - return "KeYArrayOf"+base; - - } - else { - return aJavaType; - } - } - - - // return signature of form name(arg1: type1; arg2: type2 ...) - public String getCallSignature(boolean translateJavaType2OCLTypes){ - StringBuffer res = new StringBuffer(getName()+"("); - MethodDeclaration md = method.getMethodDeclaration(); - for (int i=0; i=0) { - int end = s.indexOf("@", start+1); - int end2 = s.indexOf("\n", start+1); - if (end2>=0 && end2method is a model method. - */ - public boolean isModel() { - return method.isModel(); - } - - // set modifies clause - public void setMyModifClause(String modifClause) { - modifies=modifClause; - } - - public boolean isQuery() { - return "".equals(getMyModifClause()); - } - - // set precondition - public void setMyPreCond(String precond) { - preCond=precond; - } - - // returns precondition of parent if any, else "" - public String getParentPreCond() { - return "";//%% - } - - public ModelMethod getParentMethod(){ - return null;//%% - } - - public String getMyPostCond() { - if (postCond==null) { - postCond=getTagContent("@postconditions"); - if (postCond==null) postCond=""; - } - return postCond; - } - - public void setMyPostCond(String postcond) { - postCond=postcond; - } - - public String getParentPostCond() { - return "";//%% - } - - // set/get GF abstract syntax representation of pre-/postconditions - public String getMyGFAbs() { - return "";//%% - } - - public void setMyGFAbs(String abs) { - return;//%% - } - - public boolean hasOrigParent() { - return false;//%% - } - - public String getActXmifile(){ - return null; - } - - public String toString() { - return getContainingClass().getClassName() + "::" + getCallSignature(); - } - - public int hashCode() { - return getProgramMethod().hashCode()*13+getContainingClass().hashCode(); - } - - public boolean equals(Object o) { - if (!(o instanceof JavaModelMethod)) { - return false; - } - JavaModelMethod jmm = (JavaModelMethod)o; - return getProgramMethod().equals(jmm.getProgramMethod()) && - getContainingClass().equals(jmm.getContainingClass()); - } - - public ListOfOperationContract getMyOperationContracts() { - return SLListOfOperationContract.EMPTY_LIST;//%% - } - - public boolean equalContractable(Contractable c) { - return equals(c); - } -} diff --git a/system/de/uka/ilkd/key/proof/mgt/LemmaRuleJustification.java b/system/de/uka/ilkd/key/proof/mgt/LemmaRuleJustification.java deleted file mode 100644 index e1625981181..00000000000 --- a/system/de/uka/ilkd/key/proof/mgt/LemmaRuleJustification.java +++ /dev/null @@ -1,76 +0,0 @@ -// This file is part of KeY - Integrated Deductive Software Design -// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -// The KeY system is protected by the GNU General Public License. -// See LICENSE.TXT for details. -// - -package de.uka.ilkd.key.proof.mgt; - -import java.util.Iterator; -import java.util.List; - -import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.ProofAggregate; -import de.uka.ilkd.key.rule.RuleApp; - -public abstract class LemmaRuleJustification implements RuleJustification{ - - private RuleJustification getJustification(RuleApp r, ProofEnvironment env) { - return env.getJustifInfo().getJustification(r, env.getInitialServices()); - } - - public DepAnalysis dependsOn(Proof p) { - List list = getProofList(); - Iterator it = list.iterator(); - if (!it.hasNext()) { - return DepAnalysis.getInstance(false, "No Proof available " - +"for method contract"); - } - while (it.hasNext()) { - ProofAggregate pl=(ProofAggregate)it.next(); - if (pl==null) { - return new DepAnalysis(false, "No proof in proof list "+ - "for method contract"); - } - Proof[] proofs = pl.getProofs(); - for (int i=0; i SetOfOperationContract*/ contracts + = new LinkedHashMap(); + private final Map /*String -> OperationContract*/ contractsByName + = new LinkedHashMap(); + private final Map /*KeYJavaType -> SetOfClassInvariant*/ invs + = new LinkedHashMap(); + private final Map /*String -> ClassInvariant*/ invsByName + = new LinkedHashMap(); + private final Map /*KeYJavaType -> SetOfClassInvariant*/ throughoutInvs + = new LinkedHashMap(); + private final Map /*String -> ClassInvariant*/ throughoutInvsByName + = new LinkedHashMap(); + private final Map /*EnsuresPO -> SetOfProof*/ proofs + = new LinkedHashMap(); + private final Map /*LoopStatement -> LoopInvariant*/ loopInvs + = new LinkedHashMap(); + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public SetOfOperationContract getOperationContracts(ProgramMethod pm) { + SetOfOperationContract result + = (SetOfOperationContract) contracts.get(pm); + return result == null ? SetAsListOfOperationContract.EMPTY_SET : result; } - // TODO: ensure fixed order (?) - private void createClassInvariants() { - final SortedSet allClassesSorted = - new TreeSet(new KeYJavaType.LexicographicalKeYJavaTypeOrder()); - allClassesSorted.addAll(services.getJavaInfo().getAllKeYJavaTypes()); - - final Iterator it = allClassesSorted.iterator(); - invariants = new LinkedHashMap(); - while (it.hasNext()) { - final KeYJavaType kjt = (KeYJavaType) it.next(); - final JMLClassSpec jmlcs = services.getImplementation2SpecMap().getSpecForClass(kjt); - if (jmlcs!=null) { - SetOfTerm terms = jmlcs.getAllQuantifiedInvariants(); - IteratorOfTerm it2 = terms.iterator(); - while (it2.hasNext()) { - Term t = it2.next(); - if (t!=null) { - ClassInvariant inv = new TranslatedClassInvariant( - new JavaModelClass(kjt, - services.getJavaInfo().getJavaSourcePath(), - services), t, services); - ListOfClassInvariant invs = (ListOfClassInvariant) invariants.get(kjt); - if (invs==null) { - invs = SLListOfClassInvariant.EMPTY_LIST; - } - invariants.put(kjt, invs.prepend(inv)); - } - } - } - } + + public SetOfOperationContract getOperationContracts(ProgramMethod pm, + Modality modality) { + SetOfOperationContract result = getOperationContracts(pm); + IteratorOfOperationContract it = result.iterator(); + while(it.hasNext()) { + OperationContract contract = it.next(); + if(!contract.getModality().equals(modality)) { + result = result.remove(contract); + } + } + return result; } - /** returns an iterator of specifications ({@link Contract}) - * contained in this repository. Modifications to the underlying - * set are not allowed. - */ - public Iterator getSpecs() { - return contracts.values().iterator(); + + public OperationContract getOperationContractByName(String name) { + return (OperationContract) contractsByName.get(name); + } + + + public SetOfClassInvariant getClassInvariants(KeYJavaType kjt) { + SetOfClassInvariant result = (SetOfClassInvariant) invs.get(kjt); + return result == null ? SetAsListOfClassInvariant.EMPTY_SET : result; } + - public Contract getContractByName(String name) { - Iterator it = contracts.entrySet().iterator(); - while (it.hasNext()) { - Contract ct = (Contract)((ContractSet) - ((Map.Entry)it.next()).getValue()).iterator().next(); - if (ct.getName().equals(name)) { - return ct; + public ClassInvariant getClassInvariantByName(String name) { + return (ClassInvariant) invsByName.get(name); + } + + + public SetOfClassInvariant getThroughoutClassInvariants(KeYJavaType kjt) { + SetOfClassInvariant result + = (SetOfClassInvariant) throughoutInvs.get(kjt); + return result == null ? SetAsListOfClassInvariant.EMPTY_SET : result; + } + + public ClassInvariant getThroughoutClassInvariantByName(String name) { + return (ClassInvariant) throughoutInvsByName.get(name); + } + + + public SetOfProof getProofs(ProofOblInput po) { + SetOfProof result = (SetOfProof) proofs.get(po); + return result == null ? SetAsListOfProof.EMPTY_SET : result; + } + + + public SetOfProof getProofs(ProgramMethod pm) { + SetOfProof result = SetAsListOfProof.EMPTY_SET; + Iterator it = proofs.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + EnsuresPO po = (EnsuresPO) entry.getKey(); + SetOfProof sop = (SetOfProof) entry.getValue(); + if(po.getProgramMethod().equals(pm)) { + result = result.union(sop); } } - return null; + return result; } - /** returns a set of contracts with the argument as identifying - * contracted object. - */ - public ContractSet getContract(Object objOfContract) { - Object o = objOfContract; - if(objOfContract instanceof ModelMethod) { - o = convertToProgramMethod((ModelMethod)objOfContract); - } - return (ContractSet) contracts.get(o); - } - - /** returns a set of contracts with one of the elements in - * the argument list as identifying contracted object. - */ - public ContractSet getContracts(ListOfProgramMethod objsOfContract, - Modality modality) { - ContractSet ctSet = new ContractSet(); - IteratorOfProgramMethod it = objsOfContract.iterator(); - while (it.hasNext()) { - ContractSet cs = getContract(it.next()); - if (cs!=null) { - ctSet.addAll(cs.getMethodContracts(modality)); + + public ProgramMethod getOperationForProof(Proof proof) { + Iterator it = proofs.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + EnsuresPO po = (EnsuresPO) entry.getKey(); + SetOfProof sop = (SetOfProof) entry.getValue(); + if(sop.contains(proof)) { + return po.getProgramMethod(); } } - return ctSet; + return null; } - /** returns a set of contracts with the argument as identifying - * contracted object. - */ - public ContractSet getContract(Object objOfContract, Modality modality) { - ContractSet ctSet = getContract(objOfContract); - if (ctSet==null) { - return new ContractSet(); - } - ctSet = ctSet.getMethodContracts(modality); - if (ctSet==null) { - return new ContractSet(); - } - return ctSet; + + public LoopInvariant getLoopInvariant(LoopStatement loop) { + return (LoopInvariant) loopInvs.get(loop); } + + public void addOperationContract(OperationContract contract) { + ProgramMethod pm = contract.getProgramMethod(); + String name = contract.getName(); + assert contractsByName.get(name) == null + : "Tried to add a contract with a non-unique name!"; + contracts.put(pm, getOperationContracts(pm).add(contract)); + contractsByName.put(name, contract); + } - /** adds a contract to this specification repository. - */ - public Contract add(Contract ct) { - Object o = ct.getObjectOfContract(); - if (o instanceof ModelMethod) { - o = convertToProgramMethod((ModelMethod)o); - } - ContractSet cs =(ContractSet) contracts.get(o); - if (cs==null) { - cs = new ContractSet(); - contracts.put(o, cs); - } - return cs.add(ct); - } - - public void removeProofList(ProofAggregate pl) { - Iterator it = getSpecs(); - while (it.hasNext()) { - Object o = it.next(); - ((ContractSet) o).removeProofList(pl); - } + + public void addOperationContracts(SetOfOperationContract contracts) { + IteratorOfOperationContract it = contracts.iterator(); + while(it.hasNext()) { + addOperationContract(it.next()); + } } - public ListOfClassInvariant getAllInvariantsForType(KeYJavaType kjt) { - if (invariants == null) { - createClassInvariants(); + + public void addClassInvariant(ClassInvariant inv) { + KeYJavaType kjt = inv.getKJT(); + String name = inv.getName(); + assert invsByName.get(name) == null + : "Tried to add an invariant with a non-unique name!"; + invs.put(kjt, getClassInvariants(kjt).add(inv)); + invsByName.put(name, inv); + } + + + public void addClassInvariants(SetOfClassInvariant invs) { + IteratorOfClassInvariant it = invs.iterator(); + while(it.hasNext()) { + addClassInvariant(it.next()); } - return invariants.containsKey(kjt) ? (ListOfClassInvariant) invariants.get(kjt) - : SLListOfClassInvariant.EMPTY_LIST; } - - public SpecificationRepository copy(Services s) { - final SpecificationRepository res = new SpecificationRepository(s); - res.contracts = this.contracts; //TODO deepcopy - res.invariants = this.invariants; //TODO - return res; + + + public void addThroughoutClassInvariant(ClassInvariant inv) { + KeYJavaType kjt = inv.getKJT(); + String name = inv.getName(); + assert throughoutInvsByName.get(name) == null + : "Tried to add an invariant with a non-unique name!"; + throughoutInvs.put(kjt, getThroughoutClassInvariants(kjt).add(inv)); + throughoutInvsByName.put(name, inv); } - -//------------------------ Helper methods -----------------------------// - private ProgramMethod convertToProgramMethod(ModelMethod m) { - JavaInfo javaInfo = services.getJavaInfo(); - KeYJavaType containingClass = javaInfo.getKeYJavaTypeByClassName(m.getContainingClassName()); - String name = m.getName(); - - ListOfKeYJavaType signature = SLListOfKeYJavaType.EMPTY_LIST; - for(int i=0;i0) { - result = (OldOperationContract) ctSet.iterator().next(); - return; - } - result = null; - } - - public OldOperationContract getMethodContract() { - return result; - } - - public ListOfClassInvariant getPreInvariants() { - return SLListOfClassInvariant.EMPTY_LIST; - } - - public ListOfClassInvariant getPostInvariants() { - return SLListOfClassInvariant.EMPTY_LIST; - } - - public void setProgramMethods(ListOfProgramMethod pm) { - this.programMethods = pm; - } - - public void setModality(Modality modality) { - this.modality = modality; - } - - public boolean wasSuccessful() { - return (result!=null); - } - - public void clear() { - result=null; - } - - public void allowConfiguration(boolean allowConfig) { - // no effect currently, we do not configure anyway - } - -} diff --git a/system/de/uka/ilkd/key/rule/BuiltInRuleApp.java b/system/de/uka/ilkd/key/rule/BuiltInRuleApp.java index 096dc17acb6..cdaf4e1f562 100644 --- a/system/de/uka/ilkd/key/rule/BuiltInRuleApp.java +++ b/system/de/uka/ilkd/key/rule/BuiltInRuleApp.java @@ -35,7 +35,7 @@ public BuiltInRuleApp(BuiltInRule builtInRule, Constraint userConstraint) { this.builtInRule = builtInRule; this.pio = pio; - this.userConstraint = userConstraint; + this.userConstraint = userConstraint; } /** diff --git a/system/de/uka/ilkd/key/rule/CheckPrgTransfSoundness.java b/system/de/uka/ilkd/key/rule/CheckPrgTransfSoundness.java index a95b568db7d..e9cf0fc1474 100644 --- a/system/de/uka/ilkd/key/rule/CheckPrgTransfSoundness.java +++ b/system/de/uka/ilkd/key/rule/CheckPrgTransfSoundness.java @@ -10,13 +10,11 @@ import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.proof.ProofAggregate; import de.uka.ilkd.key.proof.init.EnvInput; import de.uka.ilkd.key.proof.init.InitConfig; import de.uka.ilkd.key.proof.init.JavaProfile; import de.uka.ilkd.key.proof.init.KeYFileForTests; import de.uka.ilkd.key.proof.init.ProblemInitializer; -import de.uka.ilkd.key.proof.init.ProofOblInput; import de.uka.ilkd.key.util.KeYResourceManager; diff --git a/system/de/uka/ilkd/key/rule/ContractConfigurator.java b/system/de/uka/ilkd/key/rule/ContractConfigurator.java deleted file mode 100644 index 675c60ab77e..00000000000 --- a/system/de/uka/ilkd/key/rule/ContractConfigurator.java +++ /dev/null @@ -1,30 +0,0 @@ -package de.uka.ilkd.key.rule; - -import de.uka.ilkd.key.logic.op.ListOfProgramMethod; -import de.uka.ilkd.key.logic.op.Modality; -import de.uka.ilkd.key.proof.mgt.OldOperationContract; -import de.uka.ilkd.key.proof.mgt.SpecificationRepository; -import de.uka.ilkd.key.speclang.ListOfClassInvariant; - -public interface ContractConfigurator { - - void setSpecification(SpecificationRepository repos); - - void start(); - - OldOperationContract getMethodContract(); - - ListOfClassInvariant getPreInvariants(); - - ListOfClassInvariant getPostInvariants(); - - void setProgramMethods(ListOfProgramMethod pm); - - void setModality(Modality modality); - - boolean wasSuccessful(); - - void clear(); - - void allowConfiguration(boolean allowConfig); -} diff --git a/system/de/uka/ilkd/key/rule/MethodContractRuleApp.java b/system/de/uka/ilkd/key/rule/MethodContractRuleApp.java deleted file mode 100644 index d01979de74a..00000000000 --- a/system/de/uka/ilkd/key/rule/MethodContractRuleApp.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.uka.ilkd.key.rule; - -import de.uka.ilkd.key.logic.Constraint; -import de.uka.ilkd.key.logic.PosInOccurrence; -import de.uka.ilkd.key.proof.mgt.OldOperationContract; - -public class MethodContractRuleApp extends BuiltInRuleApp { - - private OldOperationContract contract; - - public MethodContractRuleApp(UseMethodContractRule builtInRule, - PosInOccurrence pio, - Constraint userConstraint, - OldOperationContract contract) { - super(builtInRule, pio, userConstraint); - this.contract = contract; - } - - public OldOperationContract getMethodContract() { - return contract; - } - - -} diff --git a/system/de/uka/ilkd/key/rule/NoPosTacletApp.java b/system/de/uka/ilkd/key/rule/NoPosTacletApp.java index d593fd8b257..d5c5b2899e6 100644 --- a/system/de/uka/ilkd/key/rule/NoPosTacletApp.java +++ b/system/de/uka/ilkd/key/rule/NoPosTacletApp.java @@ -17,7 +17,6 @@ import de.uka.ilkd.key.logic.RenameTable; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.proof.mgt.Contractable; import de.uka.ilkd.key.rule.inst.SVInstantiations; import de.uka.ilkd.key.util.Debug; @@ -35,7 +34,7 @@ * * */ -public class NoPosTacletApp extends TacletApp implements Contractable { +public class NoPosTacletApp extends TacletApp { /** creates a NoPosTacletApp for the given taclet and no instantiation * information and CHECKS variable conditions as well as it resolves @@ -473,9 +472,5 @@ public boolean equals(Object o) { public int hashCode() { return super.hashCode(); - } - - public boolean equalContractable(Contractable c) { - return equals(c); - } + } } diff --git a/system/de/uka/ilkd/key/rule/Taclet.java b/system/de/uka/ilkd/key/rule/Taclet.java index 1d4b2c8bc99..320b8da9484 100644 --- a/system/de/uka/ilkd/key/rule/Taclet.java +++ b/system/de/uka/ilkd/key/rule/Taclet.java @@ -10,6 +10,8 @@ package de.uka.ilkd.key.rule; +import java.util.HashMap; + import de.uka.ilkd.key.java.ContextStatementBlock; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.SourceData; @@ -1446,7 +1448,7 @@ protected void applyAddrule(ListOfTaclet rules, Goal goal, neededInstances = neededInstances.add ( cit.next () ); } - goal.addTaclet(tacletToAdd, neededInstances, matchCond.getConstraint ()); + goal.addTaclet(tacletToAdd, neededInstances, matchCond.getConstraint (), true); } } @@ -1465,7 +1467,7 @@ protected void applyAddProgVars(SetOfSchemaVariable pvs, Goal goal, final VariableNamer vn = services.getVariableNamer(); inst = vn.rename(inst, goal, posOfFind); final RenamingTable rt = - RenamingTable.getRenamingTable(vn.getRenamingMap()); + RenamingTable.getRenamingTable((HashMap)vn.getRenamingMap()); if (rt != null) { renamings = renamings.append(rt); } diff --git a/system/de/uka/ilkd/key/rule/TacletApp.java b/system/de/uka/ilkd/key/rule/TacletApp.java index 82a8ee2abde..c095eab95de 100644 --- a/system/de/uka/ilkd/key/rule/TacletApp.java +++ b/system/de/uka/ilkd/key/rule/TacletApp.java @@ -591,7 +591,7 @@ public TacletApp tryToInstantiate(Goal goal, Services services) { while (it.hasNext()) { SchemaVariable var = it.next(); - if (LoopInvariantProposer.inLoopInvariantRuleSet(taclet().ruleSets())){ + if (LoopInvariantProposer.DEFAULT.inLoopInvariantRuleSet(taclet())){ Object inv = LoopInvariantProposer.DEFAULT.tryToInstantiate(this, var, services); if (inv instanceof Term){ app = app.addCheckedInstantiation(var, (Term)inv, services, true); diff --git a/system/de/uka/ilkd/key/rule/UseMethodContractRule.java b/system/de/uka/ilkd/key/rule/UseMethodContractRule.java deleted file mode 100644 index 1f2b9fe3f00..00000000000 --- a/system/de/uka/ilkd/key/rule/UseMethodContractRule.java +++ /dev/null @@ -1,626 +0,0 @@ -package de.uka.ilkd.key.rule; - -import java.util.Iterator; - -import javax.swing.JOptionPane; - -import de.uka.ilkd.key.gui.Main; -import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.abstraction.ArrayType; -import de.uka.ilkd.key.java.abstraction.IteratorOfKeYJavaType; -import de.uka.ilkd.key.java.reference.ExecutionContext; -import de.uka.ilkd.key.java.statement.MethodBodyStatement; -import de.uka.ilkd.key.java.statement.MethodFrame; -import de.uka.ilkd.key.java.statement.Throw; -import de.uka.ilkd.key.java.visitor.ProgramContextAdder; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.logic.op.*; -import de.uka.ilkd.key.proof.*; -import de.uka.ilkd.key.proof.mgt.*; -import de.uka.ilkd.key.rule.inst.ContextStatementBlockInstantiation; -import de.uka.ilkd.key.rule.updatesimplifier.Update; -import de.uka.ilkd.key.speclang.IteratorOfClassInvariant; -import de.uka.ilkd.key.speclang.SLTranslationError; - -/** - * implements the rule which inserts method contracts for a method body - * statement - * - * @author andreas - * - */ -public class UseMethodContractRule implements BuiltInRule { - - private final Name name = new Name("Use Method Contract"); - private final TermBuilder tb = TermBuilder.DF; - - - /** The only instance of this rule */ - public static UseMethodContractRule INSTANCE = new UseMethodContractRule(); - - protected UseMethodContractRule() { - } - - /** - * returns true iff this rule is applicable at the given position, that is, - * if there is a contract applicable for a method body statement at that - * position in the specification repository belonging to the proof of the - * given goal. This does not necessarily mean that a rule application will - * change the goal (this decision is made due to performance reasons) - */ - public boolean isApplicable(Goal goal, PosInOccurrence pos, - Constraint userConstraint) { - final Services services = goal.node().proof().getServices(); - final MbsInfo mbsInfo = getMbsInfo(pos); - - return mbsInfo != null && getContracts(mbsInfo.mbs.getProgramMethod(services), - mbsInfo.modality, services, goal.proof(), pos).size() != 0; - } - - /** - * returns the list of all program methods overriden - * by the given method pm inclusive pm - * @param pm the ProgramMethod - * @param services the Services - * @return list of all overridden methods - */ - private ListOfProgramMethod getProgramMethodsInSupertypes - (ProgramMethod pm, Services services) { - final IteratorOfKeYJavaType types = - services.getJavaInfo().getAllSupertypes(pm.getContainerType()).iterator(); - - ListOfProgramMethod allMethods = SLListOfProgramMethod.EMPTY_LIST; - while (types.hasNext()) { - if (!(types instanceof ArrayType)) { - allMethods = allMethods.prepend - (services.getJavaInfo().getAllProgramMethodsLocallyDeclared - (types.next())); - } - } - - final String pmName = pm.getMethodDeclaration().getName(); - - ListOfProgramMethod result = SLListOfProgramMethod.EMPTY_LIST; - final IteratorOfProgramMethod it = allMethods.iterator(); - nextOverriddenMethod: while (it.hasNext()) { - final ProgramMethod p = it.next(); - if (p != pm - && p.getMethodDeclaration().getName().equals(pmName) - && p.getParameterDeclarationCount() == pm - .getParameterDeclarationCount()) { - for (int i = 0; i < p.getParameterDeclarationCount(); i++) { - if (p.getParameterDeclarationAt(i).getTypeReference() - .getKeYJavaType() != pm - .getParameterDeclarationAt(i).getTypeReference() - .getKeYJavaType()) { - continue nextOverriddenMethod; - } - } - result = result.prepend(p); - } - } - return result.prepend(pm); - } - - private static MbsInfo getMbsInfo(PosInOccurrence pio) { - if (pio==null || pio.isInAntec()) { - return null; - } - - Term t = pio.subTerm(); - - while (t.op() instanceof IUpdateOperator) { - pio = pio.down(((IUpdateOperator)t.op()).targetPos()); - t = pio.subTerm(); - } - - if (!(t.op() instanceof Modality)) { - return null; - } - - final Modality modality = (Modality) t.op(); - final ProgramElement pe = t.executableJavaBlock().program(); - - if (pe == null) { // TODO: can this situation occurr? - return null; - } - - PosInProgram res = PosInProgram.TOP; - ProgramElement activeStatement = (Statement) pe; - ExecutionContext ec = null; - - if (activeStatement instanceof ProgramPrefix) { - - ProgramPrefix curPrefix = (ProgramPrefix)activeStatement; - - final ArrayOfProgramPrefix prefix = curPrefix.getPrefixElements(); - final int length = prefix.size(); - - // fail fast check - curPrefix = prefix.getProgramPrefix(length-1);// length -1 >= 0 as prefix array - //contains curPrefix as first element - - activeStatement = curPrefix.getFirstActiveChildPos().getProgram(curPrefix); - - if (!(activeStatement instanceof MethodBodyStatement)) { - return null; - } - - int i = length - 1; - do { - if (ec == null && curPrefix instanceof MethodFrame) { - ec = (ExecutionContext)((MethodFrame)curPrefix).getExecutionContext(); - } - res = curPrefix.getFirstActiveChildPos().append(res); - i--; - if (i >= 0) { - curPrefix = prefix.getProgramPrefix(i); - } - } while (i >= 0); - - } else if (!(activeStatement instanceof MethodBodyStatement)) { - return null; - } - return new MbsInfo(pio, res, ec, (MethodBodyStatement)activeStatement, modality); - } - - - /** - * return the set of all contracts for the given method (including - * the contracts of possible overriden methods) and termination marker - * @param pm the ProgramMethod whose contracts are collected - * @param modality the Modality serving as termination marker - * @param services the Services - * @return all contracts applicable for the given method - */ - private ContractSet getContracts(ProgramMethod pm, - Modality modality, - Services services, - Proof proof, - PosInOccurrence pos) { - - ContractSet ctSet = new ContractSet(); - IteratorOfProgramMethod it = getProgramMethodsInSupertypes(pm, services).iterator(); - while (it.hasNext()) { - ContractSet contracts = services.getSpecificationRepository().getContract(it.next(), modality); - - //prevent application of contracts with "everything" modifier sets - //if metavariables are involved (hackish, see Bug 810) - if(getAllMetavariables(pos.topLevel().subTerm()).size() > 0) { - Iterator it2 = contracts.iterator(); - while(it2.hasNext()) { - OldOperationContract ct = (OldOperationContract) it2.next(); - if(ct.createDLMethodContract(proof).getModifies().contains(EverythingLocationDescriptor.INSTANCE)) { - it2.remove(); - } - } - } - - ctSet.addAll(contracts); - } - return ctSet; - } - - /** - * calls the given contract configurator and returns the selected contract - * or creates a new DLMethodContract from the results of the - * configuration. The selected / configured contract suits to the given - * position. It is added to the proof environment of the given proof. - * - */ - private OldOperationContract selectContract(Services services, - Proof proof, - PosInOccurrence pos, - ContractConfigurator cc, - boolean allowConfiguration) { - final SpecificationRepository repos - = services.getSpecificationRepository(); - MbsInfo mbsPos = getMbsInfo(pos); - MethodBodyStatement mbs = mbsPos.mbs; - Modality modality = mbsPos.modality; - ProgramMethod pm = mbs.getProgramMethod(services); - ContractSet ctSet = getContracts(pm, modality, services, proof, pos); - if (ctSet.size()==0) { - return null; - } - cc.setSpecification(repos); - cc.setProgramMethods(getProgramMethodsInSupertypes(pm, services)); - cc.setModality(modality); - cc.allowConfiguration(allowConfiguration); - cc.start(); - if (!cc.wasSuccessful()) return null; - DLMethodContract dlhResultCt = null; - if (cc.getPreInvariants().isEmpty() - && cc.getPostInvariants().isEmpty()) { - return cc.getMethodContract(); - } else { - dlhResultCt = - cc.getMethodContract().createDLMethodContract(proof); - - IteratorOfClassInvariant it = cc.getPreInvariants().iterator(); - while (it.hasNext()) { - try { - dlhResultCt.addPre(it.next().getInv(services).getFormula()); - } catch (SLTranslationError e) { - // too bad (error in invariant) - // TODO: - // user should be informed about what happend here! - } - } - it = cc.getPostInvariants().iterator(); - while (it.hasNext()) { - try { - dlhResultCt.addPost(it.next().getInv(services).getFormula()); - } catch (SLTranslationError e) { - // too bad (error in invariant) - // TODO: - // user should be informed about what happend here! - } - } - dlhResultCt = (DLMethodContract) proof.env().addMethodContract(dlhResultCt); - } - - - return dlhResultCt; - } - - /** - * calls the given contract configurator and returns the selected contract - * or creates a new DLMethodContract from the results of the - * configuration. The selected / configured contract suits to the given - * position. It is added to the proof environment of the given proof. - * - */ - public OldOperationContract selectContract(Proof proof, PosInOccurrence pos, - ContractConfigurator cc) { - return selectContract(proof.getServices(), proof, pos, cc, true); - } - - /** - * calls the given contract configurator and returns the selected contract - * or creates a new DLMethodContract from the results of the - * configuration. The selected / configured contract suits to the given - * position. It is added to the proof environment of the given proof. - * - */ - public OldOperationContract selectExistingContract(Services services, - PosInOccurrence pos, - ContractConfigurator cc) { - return selectContract(services, null, pos, cc, false); - } - - - private OldOperationContract getSelectedMethodContract(RuleApp ruleApp, Proof proof) { - if (ruleApp instanceof MethodContractRuleApp) { - // selected beforehand - return ((MethodContractRuleApp) ruleApp).getMethodContract(); - } - return selectContract(proof, ruleApp.posInOccurrence(), - AutomatedContractConfigurator.INSTANCE); - } - - private static ProgramElementName getNewName(Services services, String baseName) { - NamespaceSet namespaces = services.getNamespaces(); - - int i = 0; - ProgramElementName name; - do { - name = new ProgramElementName(baseName + "_" + i++); - } while(namespaces.lookup(name) != null); - - return name; - } - - - /** - * the rule is applied based on the information of the given rule application: - * if the given rule application is a - * {@link MethodContractRuleApp} then the contained method contract is applied, - * otherwise a contract is selected based on the - * {@link AutomatedContractConfigurator}. - * @param goal the goal that the rule application should refer to - * @param services the Services with the necessary information about - * the java programs - * @param ruleApp the rule application that is executed. - */ - public ListOfGoal apply(Goal goal, Services services, RuleApp ruleApp) { - OldOperationContract ct = getSelectedMethodContract(ruleApp, goal.node().proof()); - - MbsInfo mbsPos = getMbsInfo(ruleApp.posInOccurrence()); - MethodBodyStatement mbs = mbsPos.mbs; - Modality modality = mbsPos.modality; - - Expression[] insts = new Expression[mbs.getArguments().size()]; - mbs.getArguments().arraycopy(0,insts,0,mbs.getArguments().size()); - Expression receiver = null; - if (mbs.getDesignatedContext() instanceof Expression) { - receiver = (Expression) mbs.getDesignatedContext(); - } - - ProgramVariable resultVar = (ProgramVariable) mbs.getResultVariable(); - ProgramMethod pm = mbs.getProgramMethod(services); - if(resultVar == null && pm.getKeYJavaType() != null) { - //method is non-void, but its result is discarded; we need to create a - //result variable anyway - ProgramElementName pen = getNewName(services, "res"); - resultVar = new LocationVariable(pen, pm.getKeYJavaType()); - services.getNamespaces().programVariables().add(resultVar); - } - - MethodContractInstantiation mci - = new MethodContractInstantiation(receiver, insts, - resultVar, modality); - final InstantiatedMethodContract ctInst = - ct.instantiate(mci, goal.node().proof()); - - if (ctInst == null) { - return SLListOfGoal.EMPTY_LIST.prepend(goal.split(1)); - } - - return applyInstantiatedContract(goal, ruleApp.posInOccurrence(), - ctInst, mbsPos, services); - } - - - - /** - * executes the instantiated method contract and returns the newly created goals - * @param goal the Goal where the method contract rule has been applies - * @param pos the PosInOccurunce describing the rules focus - * @param iCt the InstantiatedMethodContract - * @param mbsPos information about the method body statement on which the rule matched - * @param services the Services - * @return the new goals created by applying the method contract rule - */ - private ListOfGoal applyInstantiatedContract(Goal goal, PosInOccurrence pos, - InstantiatedMethodContract iCt, - MbsInfo mbsPos, Services services) { - - services.getNamespaces().functions().add(iCt.getAdditionalFunctions()); - - final UpdateFactory uf = new UpdateFactory(services, goal.simplifier()); - final Update u = updateToRigid(iCt, uf, services, pos); - - final boolean openExceptionalBranch = iCt.getExceptionVariable() != null; - - final ListOfGoal result = - (openExceptionalBranch ? goal.split(3) : goal.split(2)); - - final IteratorOfGoal goalIt = result.iterator(); - - if (openExceptionalBranch) { - openBranch(pos, iCt, mbsPos, excPostFma(iCt, mbsPos, uf, u, services), - goalIt.next(), getExceptionalLabel(), services); - } - - openBranch(pos, iCt, mbsPos, postFma(iCt, mbsPos, uf, u, services), - goalIt.next(), getPostLabel() ,services); - - - openBranch(pos, iCt, mbsPos, preFma(iCt, mbsPos, uf, u, services), - goalIt.next(), getPreLabel(), services); - return result; - } - - /** - * opens a new branch with branch label branchLabel, replaces - * the formula the rule has in focus (described by mbsPos) by formula - * newFormula - * @param pos the Position of the focus term - * @param iCt the InstantiatedMethodContract - * @param mbsPos position of the method body statement (the one in focus of the rule) - * @param newFormula the Term with the new formula - * @param branchGoal the new Goal where to replace the formula - * @param branchLabel a String labelling the branch - * @param services the Services - */ - private void openBranch(PosInOccurrence pos, InstantiatedMethodContract iCt, - MbsInfo mbsPos, final Term newFormula, final Goal branchGoal, String branchLabel, - Services services) { - branchGoal.node().getNodeInfo().setBranchLabel(branchLabel); - replaceFormula(mbsPos.pio, branchGoal, newFormula); - addAdditionalProgramVariables(iCt, pos, branchGoal, services); - } - - /** - * adds and renames if necessary the newly introduced program variables to - * the given goal - * @param iCt the InstantiatedMethodContract containing a set of all newly added - * program variables - * @param pos the PosInOccurrence of the find focus - * @param goal the Goal - * @param services the Services - */ - private void addAdditionalProgramVariables(InstantiatedMethodContract iCt, - PosInOccurrence pos, Goal goal, Services services) { - final IteratorOfNamed it = - iCt.getAdditionalProgramVariables().allElements().iterator(); - while (it.hasNext()) { - final ProgramVariable next = (ProgramVariable) it.next(); - assert !next.isMember(); - final ProgramVariable renamed = - services.getVariableNamer().rename(next, goal, pos); - goal.addProgramVariable(renamed); - } - } - - /** - * replace the formula at position pio of goal g - * by the new formula fma - * @param pio the PosInOccurrence of the formula to be replaced - * @param g the Goal where to replace the formula - * @param fma the Term that is the new formula - */ - private void replaceFormula(PosInOccurrence pio, Goal g, Term fma) { - final ConstrainedFormula cf = pio.constrainedFormula(); - final ConstrainedFormula newCf = new ConstrainedFormula - (replace(cf.formula(), fma, pio.posInTerm().iterator()), cf.constraint()); - g.changeFormula(newCf, pio); - } - - private Term replace(Term term, Term with, IntIterator it) { - if (it.hasNext()) { - int sub = it.next(); - Term[] subs=new Term[term.arity()]; - final ArrayOfQuantifiableVariable[] vars = - new ArrayOfQuantifiableVariable[term.arity()]; - for (int i=0;i 0) { + ProgramVariable dummySelfVar + = SVF.createSelfVar(services, pm, true); + ListOfParsableVariable dummyParamVars + = SVF.createParamVars(services, pm, true); + IteratorOfOperationContract it = result.iterator(); + while(it.hasNext()) { + OperationContract contract = it.next(); + if(contract.getModifies(dummySelfVar, dummyParamVars, services) + .contains(EverythingLocationDescriptor.INSTANCE)) { + result = result.remove(contract); + } + } + } + + return result; + } + + + /** + * Chooses a contract to be applied together with invariants to be assumed + * and ensured. This is done either automatically or by asking the user. + */ + private ContractWithInvs configureContract(Services services, + ProgramMethod pm, + Modality modality, + PosInOccurrence pio) { + if(Main.getInstance().mediator().autoMode()) { + SetOfOperationContract contracts + = getApplicableContracts(services, pm, modality, pio); + //TODO: Apply *all* contracts here instead of a random one + return new ContractWithInvs(contracts.iterator().next(), + SetAsListOfClassInvariant.EMPTY_SET, + SetAsListOfClassInvariant.EMPTY_SET); + } else { + ContractConfigurator cc + = new ContractConfigurator(Main.getInstance(), + services, + pm, + modality, + true, + true, + true); + if(cc.wasSuccessful()) { + return cc.getContractWithInvs(); + } else { + return null; + } + } + } + + + /** + * Replaces the term at the passed PosInOccurrence with the passed + * replacement in the passed goal. + */ + private void replaceInGoal(Term replacement, Goal goal, PosInOccurrence pio) { + Map replaceMap = new LinkedHashMap(); + replaceMap.put(pio.subTerm(), replacement); + OpReplacer or = new OpReplacer(replaceMap); + + ConstrainedFormula cf = pio.constrainedFormula(); + ConstrainedFormula newCf + = new ConstrainedFormula(or.replace(cf.formula()), + cf.constraint()); + goal.changeFormula(newCf, pio); + } + + + private PosInProgram getPosInProgram(JavaBlock jb) { + ProgramElement pe = jb.program(); + + PosInProgram result = PosInProgram.TOP; + + if (pe instanceof ProgramPrefix) { + ProgramPrefix curPrefix = (ProgramPrefix)pe; + + final ArrayOfProgramPrefix prefix = curPrefix.getPrefixElements(); + final int length = prefix.size(); + + // fail fast check + curPrefix = prefix.getProgramPrefix(length-1);// length -1 >= 0 as prefix array + //contains curPrefix as first element + + pe = curPrefix.getFirstActiveChildPos().getProgram(curPrefix); + + assert pe instanceof MethodBodyStatement; + + int i = length - 1; + do { + result = curPrefix.getFirstActiveChildPos().append(result); + i--; + if (i >= 0) { + curPrefix = prefix.getProgramPrefix(i); + } + } while (i >= 0); + + } else { + assert pe instanceof MethodBodyStatement; + } + return result; + } + + + private StatementBlock replaceStatement(JavaBlock jb, + StatementBlock replacement) { + PosInProgram pos = getPosInProgram(jb); + int lastPos = pos.last(); + ContextStatementBlockInstantiation csbi = + new ContextStatementBlockInstantiation(pos, + pos.up().down(lastPos+1), + null, + jb.program()); + final NonTerminalProgramElement result = + ProgramContextAdder.INSTANCE.start( + (JavaNonTerminalProgramElement)jb.program(), + replacement, + csbi); + return (StatementBlock) result; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public boolean isApplicable(Goal goal, + PosInOccurrence pio, + Constraint userConstraint) { + Services services = goal.node().proof().getServices(); + + //pio must be a modality term in succedent + pio = goBelowUpdates(pio); + if(pio == null + || pio.isInAntec() + || !(pio.subTerm().op() instanceof Modality) + || pio.subTerm().javaBlock().program() == null) { + return false; + } + + //active statement must be method body statement (TODO: constructor calls, see bug 702) + Modality modality = (Modality) pio.subTerm().op(); + SourceElement activeStatement + = getActiveStatement(pio.subTerm().javaBlock()); + if(!(activeStatement instanceof MethodBodyStatement)) { + return false; + } + + //there must be applicable contracts for the operation + MethodBodyStatement mbs = (MethodBodyStatement) activeStatement; + ProgramMethod pm = mbs.getProgramMethod(services); + SetOfOperationContract contracts + = getApplicableContracts(services, pm, modality, pio); + if(contracts.size() == 0) { + return false; + } + + //applying a contract here must not create circular dependencies + //between proofs + if(!goal.proof().mgt().contractApplicableFor(pm, goal)) { + return false; + } + + return true; + } + + + public ListOfGoal apply(Goal goal, Services services, RuleApp ruleApp) { + //collect information about sequent + PosInOccurrence pio = goBelowUpdates(ruleApp.posInOccurrence()); + Modality modality = (Modality) pio.subTerm().op(); + JavaBlock jb = pio.subTerm().javaBlock(); + SourceElement activeStatement = getActiveStatement(jb); + MethodBodyStatement mbs = (MethodBodyStatement) activeStatement; + ProgramMethod pm = mbs.getProgramMethod(services); + Term actualSelf + = (mbs.getDesignatedContext() instanceof Expression + ? services.getTypeConverter() + .convertToLogicElement(mbs.getDesignatedContext()) + : null); + ListOfTerm actualParams = SLListOfTerm.EMPTY_LIST; + ArrayOfExpression args = mbs.getArguments(); + for(int i = 0; i < args.size(); i++) { + actualParams = actualParams.append( + services.getTypeConverter() + .convertToLogicElement(args.getProgramElement(i))); + } + ProgramVariable actualResult + = (ProgramVariable) mbs.getResultVariable(); + + //configure contract and assumed / ensured invariants + ContractWithInvs cwi; + if(ruleApp instanceof UseOperationContractRuleApp) { + //the contract and invariants are already fixed + //(probably because we're in the process of reading in a + //proof from a file) + cwi = ((UseOperationContractRuleApp) ruleApp).getInstantiation(); + } else { + cwi = configureContract(services, pm, modality, pio); + } + if(cwi == null) { + return null; + } + assert cwi.contract.getProgramMethod().equals(pm); + + //create variables for self, parameters, result, exception, and a map + //for atPre-functions + ProgramVariable selfVar + = SVF.createSelfVar(services, pm, true); + ListOfParsableVariable paramVars + = SVF.createParamVars(services, pm, true); + ProgramVariable resultVar + = SVF.createResultVar(services, pm, true); + ProgramVariable excVar + = SVF.createExcVar(services, pm, true); + Map atPreFunctions + = new LinkedHashMap(); + + //translate the contract and the invariants + FormulaWithAxioms pre = cwi.contract.getPre(selfVar, + paramVars, + services); + FormulaWithAxioms post = cwi.contract.getPost(selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions, + services); + SetOfLocationDescriptor modifies = cwi.contract.getModifies(selfVar, + paramVars, + services); + IteratorOfClassInvariant it = cwi.assumedInvs.iterator(); + while(it.hasNext()) { + pre = pre.conjoin(it.next().getClosedInv(services)); + } + it = cwi.ensuredInvs.iterator(); + while(it.hasNext()) { + post = post.conjoin(it.next().getClosedInv(services)); + } + + //split goal into three branches + ListOfGoal result = goal.split(3); + Goal preGoal = result.tail().tail().head(); + preGoal.setBranchLabel("Pre"); + Goal postGoal = result.tail().head(); + postGoal.setBranchLabel("Post"); + Goal excPostGoal = result.head(); + excPostGoal.setBranchLabel("Exceptional Post"); + + //prepare common stuff for the three branches + UpdateFactory uf = new UpdateFactory(services, goal.simplifier()); + AnonymisingUpdateFactory auf = new AnonymisingUpdateFactory(uf); + SetOfMetavariable mvs = getAllMetavariables(pio.topLevel().subTerm()); + Term[] mvTerms = new Term[mvs.size()]; + IteratorOfMetavariable it2 = mvs.iterator(); + for(int i = 0; i < mvTerms.length; i++) { + mvTerms[i] = TermBuilder.DF.func(it2.next()); + } + Update anonUpdate = auf.createAnonymisingUpdate(modifies, + mvTerms, + services); + Update atPreUpdate = APF.createAtPreDefinitions(atPreFunctions, + services); + Update selfParamsUpdate = (selfVar == null + ? uf.skip() + : uf.elementaryUpdate(TB.var(selfVar), + actualSelf)); + IteratorOfParsableVariable paramsIt = paramVars.iterator(); + IteratorOfTerm actualParamsIt = actualParams.iterator(); + while(paramsIt.hasNext()) { + assert actualParamsIt.hasNext(); + selfParamsUpdate + = uf.parallel(selfParamsUpdate, + uf.elementaryUpdate(TB.var(paramsIt.next()), + actualParamsIt.next())); + } + Term excNullTerm = TB.equals(TB.var(excVar), TB.NULL(services)); + + //create "Pre" branch + Term preTerm = uf.apply(selfParamsUpdate, + TB.imp(pre.getAxiomsAsFormula(), + pre.getFormula())); + replaceInGoal(preTerm, preGoal, pio); + + //create "Post" branch + StatementBlock postSB = replaceStatement(jb, new StatementBlock()); + Term postTermWithoutUpdate + = TB.imp(TB.and(new Term[]{excNullTerm, + post.getAxiomsAsFormula(), + post.getFormula()}), + TB.prog(modality, + JavaBlock.createJavaBlock(postSB), + pio.subTerm().sub(0))); + + Update resultUpdate = (actualResult == null + ? uf.skip() + : uf.elementaryUpdate(TB.var(actualResult), + TB.var(resultVar))); + + //case distinction necessary because UpdateFactory is unable + //to deal with update compositions involving both normal and + //anonym*ous* updates; replace by "else" case once this is fixed + Term postTerm; + if(anonUpdate.isAnonymousUpdate()) { + postTerm = uf.apply(resultUpdate, postTermWithoutUpdate); + postTerm = TB.tf().createAnonymousUpdateTerm( + AnonymousUpdate.getNewAnonymousOperator(), + postTerm); + } else { + postTerm = uf.apply(uf.sequential(new Update[]{selfParamsUpdate, + atPreUpdate, + anonUpdate, + resultUpdate}), + postTermWithoutUpdate); + } + + replaceInGoal(postTerm, postGoal, pio); + + //create "Exceptional Post" branch + StatementBlock excPostSB + = replaceStatement(jb, new StatementBlock(new Throw(excVar))); + Term excPostTermWithoutUpdate + = TB.imp(TB.and(new Term[]{TB.not(excNullTerm), + post.getAxiomsAsFormula(), + post.getFormula()}), + TB.prog(modality, + JavaBlock.createJavaBlock(excPostSB), + pio.subTerm().sub(0))); + Term excPostTerm = uf.apply(uf.sequential(new Update[]{selfParamsUpdate, + atPreUpdate, + anonUpdate}), + excPostTermWithoutUpdate); + + replaceInGoal(excPostTerm, excPostGoal, pio); + + //create justification + RuleJustificationBySpec just = new RuleJustificationBySpec(cwi); + ComplexRuleJustificationBySpec cjust + = (ComplexRuleJustificationBySpec) + goal.proof().env().getJustifInfo().getJustification(this); + cjust.add(ruleApp, just); + + return result; + } + + + public Name name() { + return NAME; + } + + + public String displayName() { + return NAME.toString(); + } + + + public String toString() { + return displayName(); + } +} diff --git a/system/de/uka/ilkd/key/rule/UseOperationContractRuleApp.java b/system/de/uka/ilkd/key/rule/UseOperationContractRuleApp.java new file mode 100644 index 00000000000..8dcc846131d --- /dev/null +++ b/system/de/uka/ilkd/key/rule/UseOperationContractRuleApp.java @@ -0,0 +1,38 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.rule; + + +import de.uka.ilkd.key.logic.Constraint; +import de.uka.ilkd.key.logic.PosInOccurrence; +import de.uka.ilkd.key.proof.mgt.ContractWithInvs; + + +/** + * Represents an application of the use contract rule. Currently, this is only + * used for applications read in from a proof file; fresh applications are + * represented as regular BuiltInRuleApps. (yes, I know that this is ugly - BW) + */ +public class UseOperationContractRuleApp extends BuiltInRuleApp { + + private final ContractWithInvs instantiation; + + public UseOperationContractRuleApp(PosInOccurrence pio, + Constraint userConstraint, + ContractWithInvs instantiation) { + super(UseOperationContractRule.INSTANCE, pio, userConstraint); + this.instantiation = instantiation; + } + + public ContractWithInvs getInstantiation() { + return instantiation; + } +} diff --git a/system/de/uka/ilkd/key/rule/conditions/NewJumpLabelCondition.java b/system/de/uka/ilkd/key/rule/conditions/NewJumpLabelCondition.java index 5c487514d76..b802ced74ab 100644 --- a/system/de/uka/ilkd/key/rule/conditions/NewJumpLabelCondition.java +++ b/system/de/uka/ilkd/key/rule/conditions/NewJumpLabelCondition.java @@ -51,7 +51,7 @@ public MatchConditions check(SchemaVariable var, } final LinkedList programs = collect(matchCond.getInstantiations()); programs.add(matchCond.getInstantiations().getContextInstantiation().contextProgram()); - if (!isUnique((Label)instCandidate, programs)) { + if (!isUnique((Label)instCandidate, programs, services)) { return null; } } @@ -73,11 +73,13 @@ private LinkedList collect(SVInstantiations inst) { return result; } - private boolean isUnique(Label label, LinkedList programs) { + private boolean isUnique(Label label, + LinkedList programs, + Services services) { final HashSet result = new HashSet(100); for (final Iterator it = programs.iterator(); it.hasNext();) { final LabelCollector lc = - new LabelCollector((ProgramElement)it.next(), result); + new LabelCollector((ProgramElement)it.next(), result, services); lc.start(); } return !result.contains(label); diff --git a/system/de/uka/ilkd/key/rule/encapsulation/FreeProgramVariableDetector.java b/system/de/uka/ilkd/key/rule/encapsulation/FreeProgramVariableDetector.java index 352215a485d..cd000a7b0b7 100644 --- a/system/de/uka/ilkd/key/rule/encapsulation/FreeProgramVariableDetector.java +++ b/system/de/uka/ilkd/key/rule/encapsulation/FreeProgramVariableDetector.java @@ -11,6 +11,7 @@ package de.uka.ilkd.key.rule.encapsulation; import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.declaration.VariableSpecification; import de.uka.ilkd.key.java.visitor.JavaASTVisitor; @@ -23,13 +24,8 @@ class FreeProgramVariableDetector extends JavaASTVisitor { private SetOfProgramVariable declaredVars; - public FreeProgramVariableDetector(ProgramElement root) { - super(root); - } - - - protected void doAction(ProgramElement node) { - node.visit(this); + public FreeProgramVariableDetector(ProgramElement root, Services services) { + super(root, services); } diff --git a/system/de/uka/ilkd/key/rule/encapsulation/TypeSchemeConstraintExtractor.java b/system/de/uka/ilkd/key/rule/encapsulation/TypeSchemeConstraintExtractor.java index 0d8bd6ee5f5..7922eaea41a 100644 --- a/system/de/uka/ilkd/key/rule/encapsulation/TypeSchemeConstraintExtractor.java +++ b/system/de/uka/ilkd/key/rule/encapsulation/TypeSchemeConstraintExtractor.java @@ -40,6 +40,7 @@ import de.uka.ilkd.key.rule.metaconstruct.ProgramMetaConstruct; import de.uka.ilkd.key.rule.soundness.ProgramSVProxy; import de.uka.ilkd.key.rule.soundness.ProgramSVSkolem; +import de.uka.ilkd.key.speclang.LoopInvariant; import de.uka.ilkd.key.util.Debug; @@ -1048,6 +1049,11 @@ public void performActionOnCopyAssignment(CopyAssignment x) { push(assignmentTerm); } } + + + public void performActionOnSetAssignment(SetAssignment x) { + assert false : "not implemented"; + } public void performActionOnDivideAssignment(DivideAssignment x) { @@ -1593,5 +1599,7 @@ public void performActionOnProgramConstant(ProgramConstant x) { } - + public void performActionOnLoopInvariant(LoopInvariant x) { + //nothing to do + } } diff --git a/system/de/uka/ilkd/key/rule/encapsulation/UniverseAnalyser.java b/system/de/uka/ilkd/key/rule/encapsulation/UniverseAnalyser.java index b066fb97f0f..d9dd701e46d 100644 --- a/system/de/uka/ilkd/key/rule/encapsulation/UniverseAnalyser.java +++ b/system/de/uka/ilkd/key/rule/encapsulation/UniverseAnalyser.java @@ -99,7 +99,8 @@ public boolean analyse(ArrayOfLocation R, //check if pi contains any predefined local reference variables //(not allowed) - FreeProgramVariableDetector fpvd = new FreeProgramVariableDetector(pi); + FreeProgramVariableDetector fpvd + = new FreeProgramVariableDetector(pi, services); if(fpvd.findFreePV()) { verbose("There is a predefined local reference variable in pi. " + "Canceling."); diff --git a/system/de/uka/ilkd/key/rule/export/TacletLoader.java b/system/de/uka/ilkd/key/rule/export/TacletLoader.java index 697e1c31b80..ceabb834d9e 100644 --- a/system/de/uka/ilkd/key/rule/export/TacletLoader.java +++ b/system/de/uka/ilkd/key/rule/export/TacletLoader.java @@ -94,7 +94,7 @@ private void loadLDTIncludes(Includes in, int level, String filename) } while(it.hasNext()){ final String name = (String) it.next(); - keyFile[i] = new KeYFile(name, in.get(name), null); + keyFile[i] = new KeYFile(name, in.get(name), null, false); keyFile[i].setInitConfig(initConfig); Includes includes = keyFile[i].readIncludes(); loadIncludes(includes, level+1, name); @@ -126,7 +126,7 @@ private void loadLDTIncludes(Includes in, int level, String filename) private void loadFile(String filename, RuleSource ruleSource, int level) throws ProofInputException { if (alreadyParsed.add(filename)) { - KeYFile file = new KeYFile(filename, ruleSource, null); + KeYFile file = new KeYFile(filename, ruleSource, null, false); file.setInitConfig(initConfig); diff --git a/system/de/uka/ilkd/key/rule/export/html/HTMLFile.java b/system/de/uka/ilkd/key/rule/export/html/HTMLFile.java index dfd428c71f6..f3cebd2bf56 100644 --- a/system/de/uka/ilkd/key/rule/export/html/HTMLFile.java +++ b/system/de/uka/ilkd/key/rule/export/html/HTMLFile.java @@ -25,8 +25,6 @@ public abstract class HTMLFile extends HTMLContainer { private static final String PRCSVERSION = Main.INTERNAL_VERSION; - - static KeYResourceManager resManager = KeYResourceManager.getManager(); diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/AtPreEquations.java b/system/de/uka/ilkd/key/rule/metaconstruct/AtPreEquations.java index 8e05af1cc30..6e0dd978b1a 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/AtPreEquations.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/AtPreEquations.java @@ -1,12 +1,17 @@ package de.uka.ilkd.key.rule.metaconstruct; -import java.util.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.*; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.TermFactory; import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.proof.init.AbstractPO; +import de.uka.ilkd.key.proof.AtPreFactory; import de.uka.ilkd.key.rule.MatchConditions; import de.uka.ilkd.key.rule.inst.SVInstantiations; @@ -15,17 +20,75 @@ public class AtPreEquations extends AbstractMetaOperator { private static Term updateFormula = null; private static HashMap atPreMapping = null; - public static Map getAtPreFunctions(Term t){ + public static Map getAtPreFunctions(Term t, Services services){ if(t==updateFormula){ // atPre Functions were already calculated for updateFormula return atPreMapping; } updateFormula = t; atPreMapping = new HashMap(); - AbstractPO.createAtPreFunctionsForTerm(t, atPreMapping); + AtPreFactory.INSTANCE.createAtPreFunctionsForTerm(t, atPreMapping, services); return atPreMapping; } + /** + * Helper for buildAtPreDefinitions(). + */ + private static Term[] getTerms(ArrayOfQuantifiableVariable vars) { + int numVars = vars.size(); + Term[] result = new Term[numVars]; + + for(int i = 0; i < numVars; i++) { + LogicVariable var + = (LogicVariable)(vars.getQuantifiableVariable(i)); + result[i] = TermBuilder.DF.var(var); + } + + return result; + } + + /** + * @deprecated: use updates for defining atPre-functions instead. + */ + private static Term buildAtPreDefinitions( + /*in*/ Map /*Operator -> Function */atPreFunctions) { + Term result = TermBuilder.DF.tt(); + + Iterator it = atPreFunctions.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry)(it.next()); + Operator f1 = (Operator)(entry.getKey()); + Function f2 = (Function)(entry.getValue()); + + int arity = f1.arity(); + assert arity == f2.arity(); + LogicVariable[] args = new LogicVariable[arity]; + for(int i = 0; i < arity; i++) { + args[i] = new LogicVariable(new Name("x" + i), f2.argSort(i)); + } + + Term[] argTerms = getTerms(new ArrayOfQuantifiableVariable(args)); + + TermFactory tf = TermBuilder.DF.tf(); + Term f1Term = tf.createTerm(f1, + argTerms, + (ArrayOfQuantifiableVariable)null, + null); + Term f2Term = TermBuilder.DF.func(f2, argTerms); + Term equalsTerm = tf.createJunctorTerm(Op.EQUALS, f1Term, f2Term); + Term quantifTerm; + if(arity > 0) { + quantifTerm = TermBuilder.DF.all(args, equalsTerm); + } else { + quantifTerm = equalsTerm; + } + result = TermBuilder.DF.and(result, quantifTerm); + } + + return result; + } + + public AtPreEquations() { super(new Name("#atPreEqs"), 1); } @@ -34,12 +97,8 @@ public AtPreEquations() { * @see de.uka.ilkd.key.logic.op.MetaOperator#calculate(de.uka.ilkd.key.logic.Term, de.uka.ilkd.key.rule.inst.SVInstantiations, de.uka.ilkd.key.java.Services) */ public Term calculate(Term term, SVInstantiations svInst, Services services) { - Map atPreFunctions = getAtPreFunctions(term.sub(0)); - final Iterator it = atPreFunctions.values().iterator(); - while(it.hasNext()) { - services.getNamespaces().functions().add((Function) it.next()); - } - return AbstractPO.buildAtPreDefinitions(atPreFunctions); + Map atPreFunctions = getAtPreFunctions(term.sub(0), services); + return buildAtPreDefinitions(atPreFunctions); } /* (non-Javadoc) diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/ExpandMethodBody.java b/system/de/uka/ilkd/key/rule/metaconstruct/ExpandMethodBody.java index c3c7f58d677..4a9e4fe9e47 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/ExpandMethodBody.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/ExpandMethodBody.java @@ -82,7 +82,7 @@ public ProgramElement symbolicExecution(ProgramElement pe, argsAsParam.getExpression(i)); } ProgVarReplaceVisitor paramRepl = - new ProgVarReplaceVisitor(result, map); + new ProgVarReplaceVisitor(result, map, services); paramRepl.start(); result = (StatementBlock) paramRepl.result(); diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/ForToWhile.java b/system/de/uka/ilkd/key/rule/metaconstruct/ForToWhile.java new file mode 100644 index 00000000000..acdbb367979 --- /dev/null +++ b/system/de/uka/ilkd/key/rule/metaconstruct/ForToWhile.java @@ -0,0 +1,118 @@ +package de.uka.ilkd.key.rule.metaconstruct; + +import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.Statement; +import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.logic.op.ListOfSchemaVariable; +import de.uka.ilkd.key.logic.op.SLListOfSchemaVariable; +import de.uka.ilkd.key.logic.op.SchemaVariable; +import de.uka.ilkd.key.rule.inst.SVInstantiations; + +/** + * converts a for-loop to a while loop. Invariant and other rules cannot be + * performed on for but only on while loops. + * + * It makes uses of the {@link ForToWhileTransformation} to create a transformed + * loop body which is then put into the corresponding context. + * + *

Example

+ * + *
+ * for (int i = 0; i < 100; i++) {
+ *     if (i == 2)
+ *         continue;
+ *     if (i == 3)
+ *         break;
+ * }
+ * 
+ * + * is translated to + * + *
+ * _label1: {
+ *     int i = 0;
+ *     while (i < 100) {
+ *         _label0: {
+ *             if (i == 2)
+ *                 break _label0;
+ *             if (i == 3)
+ *                 break _label1;
+ *         }
+ *         i++;
+ *     }
+ * }
+ * 
+ * + * @see ForToWhileTransformation + * @author MU + */ + +public class ForToWhile extends ProgramMetaConstruct implements + MetaConstructWithSV { + + /** + * the outer label that is used to leave the while loop ('l1') + */ + private final SchemaVariable outerLabel; + + /** + * the inner label ('l2') + */ + private final SchemaVariable innerLabel; + + /** + * creates an loop to while - ProgramMetaConstruct + * + * @param loop + * the LoopStatement contained by the meta construct + * @param innerLabel + * the label used to handle continue + * @param outerLabel + * the label used to handle break (only needed for + * do-while-loops) + */ + public ForToWhile(SchemaVariable innerLabel, SchemaVariable outerLabel, + Statement loop) { + super("#for-to-while", loop); + this.innerLabel = innerLabel; + this.outerLabel = outerLabel; + + } + + /** + * performs the necessary transformation using a LoopToWhileTransformation + */ + public ProgramElement symbolicExecution(ProgramElement pe, + Services services, SVInstantiations svInst) { + + WhileLoopTransformation w = new ForToWhileTransformation(pe, + (ProgramElementName) svInst.getInstantiation(outerLabel), + (ProgramElementName) svInst.getInstantiation(innerLabel), + services); + + w.start(); + return w.result(); + } + + /** + * return a list of the SV that are relevant to this UnwindLoop + * + * @param originalLoop + * the loop to work upon - ignored + * @param svInst + * the instantiations so far - ignored + * @return a list of 0 to 2 schema variables (outer/inner label) + */ + public ListOfSchemaVariable neededInstantiations(SVInstantiations svInst) { + ListOfSchemaVariable ret = SLListOfSchemaVariable.EMPTY_LIST; + + if (innerLabel != null) + ret = ret.prepend(innerLabel); + + if (outerLabel != null) + ret = ret.prepend(outerLabel); + + return ret; + } +} diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/ForToWhileTransformation.java b/system/de/uka/ilkd/key/rule/metaconstruct/ForToWhileTransformation.java new file mode 100644 index 00000000000..d861d65b8cb --- /dev/null +++ b/system/de/uka/ilkd/key/rule/metaconstruct/ForToWhileTransformation.java @@ -0,0 +1,122 @@ +package de.uka.ilkd.key.rule.metaconstruct; + +import de.uka.ilkd.key.java.ArrayOfStatement; +import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.Statement; +import de.uka.ilkd.key.java.StatementBlock; +import de.uka.ilkd.key.java.expression.ExpressionStatement; +import de.uka.ilkd.key.java.expression.literal.BooleanLiteral; +import de.uka.ilkd.key.java.statement.For; +import de.uka.ilkd.key.java.statement.Guard; +import de.uka.ilkd.key.java.statement.IForUpdates; +import de.uka.ilkd.key.java.statement.ILoopInit; +import de.uka.ilkd.key.java.statement.LabeledStatement; +import de.uka.ilkd.key.java.statement.While; +import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.speclang.LoopInvariant; +import de.uka.ilkd.key.util.ExtList; + +/** + * This transformation is used to transform a for-loop into a while-loop. + * + * This is done because there are some rules (invariant, induction, ...) that + * are only available for while-loops, not for for-loops. + * + * The transformation behaviour is very similar to the superclass' behaviour + * only the outermost for loop is treated silghtly differently. + * + * @see ForToWhile Here is an example + * @author MU + * + */ + +public class ForToWhileTransformation extends WhileLoopTransformation { + + public ForToWhileTransformation(ProgramElement root, + ProgramElementName outerLabel, ProgramElementName innerLabel, + Services services) { + super(root, outerLabel, innerLabel, services); + } + + /** + * change the for-loop to a while loop with inits and updates. + */ + public void performActionOnFor(For x) { + ExtList changeList = (ExtList) stack.peek(); + + if (replaceBreakWithNoLabel == 0) { + // most outer for loop + + if (changeList.getFirst() == CHANGED) + changeList.removeFirst(); + + ILoopInit inits = null; + IForUpdates updates = null; + Guard guard = null; + Statement body = null; + + if (changeList.get(0) instanceof ILoopInit) { + inits = (ILoopInit) changeList.removeFirst(); + } + + if (x.getGuard() != null) { + guard = (Guard) changeList.removeFirst(); + } else { + guard = new Guard(BooleanLiteral.TRUE); + } + + if (changeList.get(0) instanceof IForUpdates) { + updates = (IForUpdates) changeList.removeFirst(); + } + + body = (Statement) changeList.removeFirst(); + + if (innerLabelNeeded() && breakInnerLabel != null) { + body = new LabeledStatement(breakInnerLabel.getLabel(), body); + } + + final int updateSize = (updates == null ? 0 : updates.size()); + Statement innerBlockStatements[] = new Statement[updateSize + 1]; + innerBlockStatements[0] = body; + for (int copyStatements = 0; copyStatements < updateSize; copyStatements++) { + innerBlockStatements[copyStatements + 1] = (ExpressionStatement) updates + .getExpressionAt(copyStatements); + } + + final int initSize = (inits == null ? 0 : inits.size()); + Statement outerBlockStatements[] = new Statement[initSize + 1]; + + for (int copyStatements = 0; copyStatements < initSize; copyStatements++) { + outerBlockStatements[copyStatements] = inits.getInits() + .getLoopInitializer(copyStatements); + } + + outerBlockStatements[initSize] = new While(guard.getExpression(), + new StatementBlock(new ArrayOfStatement( + innerBlockStatements)), null); + + Statement outerBlock = new StatementBlock(new ArrayOfStatement( + outerBlockStatements)); + + if (outerLabelNeeded() && breakOuterLabel != null) { + outerBlock = new LabeledStatement(breakOuterLabel.getLabel(), + outerBlock); + } + + // copy loop invariant to the created while loop + LoopInvariant li + = services.getSpecificationRepository().getLoopInvariant(x); + if(li != null) { + li = li.setLoop((While)outerBlockStatements[initSize]); + services.getSpecificationRepository().setLoopInvariant(li); + } + + addChild(outerBlock); + changed(); + } else { + super.performActionOnFor(x); + } + } + +} diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/IntroAtPreDefsOp.java b/system/de/uka/ilkd/key/rule/metaconstruct/IntroAtPreDefsOp.java new file mode 100644 index 00000000000..8e783901cbd --- /dev/null +++ b/system/de/uka/ilkd/key/rule/metaconstruct/IntroAtPreDefsOp.java @@ -0,0 +1,85 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// + +package de.uka.ilkd.key.rule.metaconstruct; + +import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.SourceElement; +import de.uka.ilkd.key.java.statement.IteratorOfLoopStatement; +import de.uka.ilkd.key.java.statement.LoopStatement; +import de.uka.ilkd.key.java.statement.MethodFrame; +import de.uka.ilkd.key.java.statement.SetAsListOfLoopStatement; +import de.uka.ilkd.key.java.statement.SetOfLoopStatement; +import de.uka.ilkd.key.java.visitor.JavaASTVisitor; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.UpdateFactory; +import de.uka.ilkd.key.logic.op.AbstractMetaOperator; +import de.uka.ilkd.key.proof.AtPreFactory; +import de.uka.ilkd.key.rule.inst.SVInstantiations; +import de.uka.ilkd.key.rule.updatesimplifier.Update; +import de.uka.ilkd.key.speclang.LoopInvariant; + + +/** + * Creates an anonymising update for a modifies clause. + */ +public class IntroAtPreDefsOp extends AbstractMetaOperator { + + private static final AtPreFactory APF = AtPreFactory.INSTANCE; + + public IntroAtPreDefsOp() { + super(new Name("#introAtPreDefs"), 1); + } + + + public Term calculate(Term term, SVInstantiations svInst, Services services) { + Term target = term.sub(0); + + //the target term should have a Java block + ProgramElement pe = target.javaBlock().program(); + assert pe != null; + + //collect all loops in the innermost method frame + SetOfLoopStatement loops = new JavaASTVisitor(pe, services) { + private SetOfLoopStatement result = SetAsListOfLoopStatement.EMPTY_SET; + private boolean done = false; + protected void doDefaultAction(SourceElement node) { + if(node instanceof MethodFrame) { + done = true; + } else if(node instanceof LoopStatement && !done) { + result = result.add((LoopStatement) node); + } + } + public SetOfLoopStatement run() { + walk(root()); + return result; + } + }.run(); + + //create update defining all atPre symbols used in these loops + UpdateFactory uf = new UpdateFactory(services, + services.getProof().simplifier()); + Update atPreUpdate = uf.skip(); + IteratorOfLoopStatement it = loops.iterator(); + while(it.hasNext()) { + LoopStatement loop = it.next(); + LoopInvariant inv = services.getSpecificationRepository() + .getLoopInvariant(loop); + if(inv != null) { + Update u = APF.createAtPreDefinitions(inv.getAtPreFunctions(), + services); + atPreUpdate = uf.parallel(atPreUpdate, u); + } + } + + return uf.apply(atPreUpdate, target); + } +} diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/LocationDependentFunction.java b/system/de/uka/ilkd/key/rule/metaconstruct/LocationDependentFunction.java index eba7d670d25..a8765aea076 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/LocationDependentFunction.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/LocationDependentFunction.java @@ -21,15 +21,14 @@ public class LocationDependentFunction extends AbstractMetaOperator { private static Term updTerm = null; private static Term heapDepFuncTerm = null; - public static Term getHeapDepFuncTermFor(Term term, Services services){ + private static Term getHeapDepFuncTermFor(Term term, Services services){ if(term.sub(0)==updTerm){ return heapDepFuncTerm; } updTerm = term.sub(0); - ListOfProgramVariable pvs = collectRelevantPVs(term); - Term hdf = createHeapDependentFunctionTerm(pvs); - services.getNamespaces().functions().add(hdf.op()); - Map map = AtPreEquations.getAtPreFunctions(updTerm); + ListOfProgramVariable pvs = collectRelevantPVs(term, services); + Term hdf = createHeapDependentFunctionTerm(pvs, services); + Map map = AtPreEquations.getAtPreFunctions(updTerm, services); OpReplacer or = new OpReplacer(map); Term preUpdTerm = or.replace(updTerm); if ( !( updTerm.op () instanceof IUpdateOperator ) ) return hdf; @@ -51,7 +50,20 @@ public Term calculate(Term term, SVInstantiations svInst, Services services) { return getHeapDepFuncTermFor(term, services); } - private static Term createHeapDependentFunctionTerm(ListOfProgramVariable l){ + private static Name getNewName(Services services, Name baseName) { + NamespaceSet namespaces = services.getNamespaces(); + + int i = 0; + Name name; + do { + name = new Name(baseName + "_" + i++); + } while(namespaces.lookup(name) != null); + + return name; + } + + private static Term createHeapDependentFunctionTerm(ListOfProgramVariable l, + Services services){ Term[] subs = new Term[l.size()]; Sort[] subSorts = new Sort[l.size()]; int i=0; @@ -63,13 +75,16 @@ private static Term createHeapDependentFunctionTerm(ListOfProgramVariable l){ subSorts[i++] = pv.sort(); } ArrayOfSort aos = new ArrayOfSort(subSorts); - Function anon = new NonRigidHeapDependentFunction(new Name("anon"), Sort.FORMULA, aos); + Name anonName = getNewName(services, new Name("anon")); + Function anon = new NonRigidHeapDependentFunction(anonName, Sort.FORMULA, aos); + services.getNamespaces().functions().add(anon); return tf.createFunctionTerm(anon, subs); } - private static ListOfProgramVariable collectRelevantPVs(Term t){ + private static ListOfProgramVariable collectRelevantPVs(Term t, + Services services){ LoopStatement loop = getLoop(t.sub(1).javaBlock().program()); - FreePVCollector pc = new FreePVCollector(loop); + FreePVCollector pc = new FreePVCollector(loop, services); pc.start(); return pc.result(); } @@ -128,11 +143,8 @@ private static class FreePVCollector extends JavaASTVisitor { = SLListOfProgramVariable.EMPTY_LIST; private ListOfProgramVariable freePVs = SLListOfProgramVariable.EMPTY_LIST; - public FreePVCollector(ProgramElement root) { - super(root); - } - protected void doAction(ProgramElement node) { - node.visit(this); + public FreePVCollector(ProgramElement root, Services services) { + super(root, services); } protected void doDefaultAction(SourceElement node) { if(node instanceof ProgramVariable) { diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/MetaConstructWithSV.java b/system/de/uka/ilkd/key/rule/metaconstruct/MetaConstructWithSV.java new file mode 100644 index 00000000000..71ff917aeb3 --- /dev/null +++ b/system/de/uka/ilkd/key/rule/metaconstruct/MetaConstructWithSV.java @@ -0,0 +1,35 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.rule.metaconstruct; + +import de.uka.ilkd.key.logic.op.ListOfSchemaVariable; +import de.uka.ilkd.key.rule.inst.SVInstantiations; + +/** + * This interface can be used to indicate that a program meta construct needs + * the instantiation of certain schema variables. These are then taken into + * consideration by the ProgramSVCollector. + * + * @author MU + * + */ +public interface MetaConstructWithSV { + + /** + * get a list of schema variables that are needed by this entity when + * working given a SV instantiation set. + * + * @param svInst + * the instatiations of SV so far. + * @return a list of schema variables relevant for this entity; + */ + public ListOfSchemaVariable neededInstantiations(SVInstantiations svInst); +} diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/MethodCall.java b/system/de/uka/ilkd/key/rule/metaconstruct/MethodCall.java index 4b2eb204ff2..740ecde6452 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/MethodCall.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/MethodCall.java @@ -259,10 +259,6 @@ public ProgramElement symbolicExecution(ProgramElement pe, services.getJavaInfo().getKeYProgModelInfo().findImplementations (staticPrefixType, methRef.getName(), getTypes(arguments)); - if (imps == SLListOfKeYJavaType.EMPTY_LIST) { - imps = services.getImplementation2SpecMap(). - findSpecifications(methRef.getName(), staticPrefixType); - } if (imps.isEmpty()) { Type staticPrefix = staticPrefixType.getJavaType(); if (staticPrefix instanceof ClassType && diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/ReplaceWhileLoop.java b/system/de/uka/ilkd/key/rule/metaconstruct/ReplaceWhileLoop.java index a2bd81f7885..fade137387a 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/ReplaceWhileLoop.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/ReplaceWhileLoop.java @@ -13,6 +13,7 @@ package de.uka.ilkd.key.rule.metaconstruct; import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.Statement; import de.uka.ilkd.key.java.StatementBlock; import de.uka.ilkd.key.java.abstraction.KeYJavaType; @@ -61,8 +62,10 @@ public class ReplaceWhileLoop extends CreatingASTVisitor { * @param innerLabel * the ProgramElementName of the inner label */ - public ReplaceWhileLoop(ProgramElement root, StatementBlock toInsert) { - super(root, true); + public ReplaceWhileLoop(ProgramElement root, + StatementBlock toInsert, + Services services) { + super(root, true, services); this.toInsert = toInsert; firstWhileFound = false; } @@ -76,8 +79,8 @@ public ReplaceWhileLoop(ProgramElement root, StatementBlock toInsert) { * the SVInstantiations if available */ public ReplaceWhileLoop(ProgramElement root, SVInstantiations inst, - StatementBlock toInsert) { - super(root, true); + StatementBlock toInsert, Services services) { + super(root, true, services); this.toInsert = toInsert; firstWhileFound = false; instantiations = (inst == null ? diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/TestProgramMetaConstructs.java b/system/de/uka/ilkd/key/rule/metaconstruct/TestProgramMetaConstructs.java index 124b4347518..57e715aaf9b 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/TestProgramMetaConstructs.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/TestProgramMetaConstructs.java @@ -74,7 +74,8 @@ public void xtestASTWalker() { WhileLoopTransformation trans = new WhileLoopTransformation(block2, new ProgramElementName("l1"), - new ProgramElementName("l2")); + new ProgramElementName("l2"), + new Services()); trans.start(); System.out.println("Result:"+trans); } diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/UnwindLoop.java b/system/de/uka/ilkd/key/rule/metaconstruct/UnwindLoop.java index 38d50d323f6..731603ea49e 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/UnwindLoop.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/UnwindLoop.java @@ -13,6 +13,8 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.statement.LoopStatement; import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.logic.op.ListOfSchemaVariable; +import de.uka.ilkd.key.logic.op.SLListOfSchemaVariable; import de.uka.ilkd.key.logic.op.SchemaVariable; import de.uka.ilkd.key.rule.inst.SVInstantiations; @@ -36,7 +38,7 @@ * }} * becomes */ -public class UnwindLoop extends ProgramMetaConstruct { +public class UnwindLoop extends ProgramMetaConstruct implements MetaConstructWithSV { /** the outer label that is used to leave the while loop ('l1') */ private final SchemaVariable outerLabel; @@ -74,16 +76,37 @@ public ProgramElement symbolicExecution(ProgramElement pe, (ProgramElementName) svInst.getInstantiation(outerLabel), (ProgramElementName) - svInst.getInstantiation(innerLabel)); + svInst.getInstantiation(innerLabel), + services); w.start(); return w.result(); } + /** @deprecated */ public SchemaVariable getInnerLabelSV() { return innerLabel; } + /** @deprecated */ public SchemaVariable getOuterLabelSV() { return outerLabel; - } + } + + /** + * return a list of the SV that are relevant to this UnwindLoop + * @param originalLoop the loop to work upon - ignored + * @param svInst the instantiations so far - ignored + * @return a list of 0 to 2 schema variables (outer/inner label) + */ + public ListOfSchemaVariable neededInstantiations(SVInstantiations svInst) { + ListOfSchemaVariable ret = SLListOfSchemaVariable.EMPTY_LIST; + + if(innerLabel != null) + ret = ret.prepend(innerLabel); + + if(outerLabel != null) + ret = ret.prepend(outerLabel); + + return ret; + } } diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvRule.java b/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvRule.java index c77f04be5d1..87a67de6602 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvRule.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvRule.java @@ -101,7 +101,7 @@ private void init(Term term, Services services) { modality = (Modality)term.sub(0).op(); ReplaceWhileLoop removeWhile = - new ReplaceWhileLoop(root, null); + new ReplaceWhileLoop(root, null, services); removeWhile.start(); body = removeWhile.getTheLoop(); @@ -309,7 +309,11 @@ public Term calculate(Term term, SVInstantiations svInst, Services services) { public ListOfSchemaVariable neededInstantiations(ProgramElement originalLoop, SVInstantiations svInst) { WhileInvariantTransformation w = - new WhileInvariantTransformation(originalLoop, svInst); + new WhileInvariantTransformation(originalLoop, + svInst, + javaInfo == null + ? null + : javaInfo.getServices()); w.start(); instantiations = SLListOfSchemaVariable.EMPTY_LIST; if (w.innerLabelNeeded()) { @@ -459,7 +463,7 @@ private Term throwCase(ProgramVariable excFlag, protected JavaBlock addContext(JavaNonTerminalProgramElement root, StatementBlock block) { ReplaceWhileLoop replaceWhile = - new ReplaceWhileLoop(root, block); + new ReplaceWhileLoop(root, block, javaInfo.getServices()); replaceWhile.start(); return JavaBlock.createJavaBlock((StatementBlock)replaceWhile.result()); diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvRuleWrapper.java b/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvRuleWrapper.java index f50f51713de..7ad9509d27e 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvRuleWrapper.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvRuleWrapper.java @@ -9,11 +9,14 @@ // package de.uka.ilkd.key.rule.metaconstruct; +import de.uka.ilkd.key.java.JavaProgramElement; import de.uka.ilkd.key.java.statement.While; import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.op.ListOfSchemaVariable; +import de.uka.ilkd.key.rule.inst.SVInstantiations; -public class WhileInvRuleWrapper extends While { +public class WhileInvRuleWrapper extends While implements MetaConstructWithSV { private Term wrappedElement; @@ -27,4 +30,12 @@ public Term unwrap() { return wrappedElement; } + + public ListOfSchemaVariable neededInstantiations(SVInstantiations svInst) { + Term t = unwrap(); + JavaProgramElement jpe = t.sub(0).javaBlock().program(); + WhileInvRule wir = (WhileInvRule) t.op(); + return wir.neededInstantiations(jpe, svInst); + } + } diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvariantTransformation.java b/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvariantTransformation.java index af8d0524247..b193115acc0 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvariantTransformation.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/WhileInvariantTransformation.java @@ -16,7 +16,6 @@ import java.util.ListIterator; import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.expression.literal.BooleanLiteral; import de.uka.ilkd.key.java.statement.*; import de.uka.ilkd.key.logic.ProgramElementName; @@ -32,7 +31,6 @@ */ public class WhileInvariantTransformation extends WhileLoopTransformation { - private Services services = null; private JavaInfo javaInfo = null; private ProgramVariable cont = null; @@ -67,8 +65,7 @@ public WhileInvariantTransformation(ProgramElement root, LinkedList breakList, Services services) { - super(root, outerLabel, innerLabel); - this.services = services; + super(root, outerLabel, innerLabel, services); this.cont = cont; this.exc = exc; this.excParam = excParam; @@ -86,8 +83,9 @@ public WhileInvariantTransformation(ProgramElement root, * @param inst the SVInstantiations if available */ public WhileInvariantTransformation(ProgramElement root, - SVInstantiations inst) { - super(root, inst); + SVInstantiations inst, + Services services) { + super(root, inst, services); this.breakList = new LinkedList(); } @@ -152,9 +150,6 @@ public void performActionOnReturn(Return x) { doDefaultAction(x); } - protected void performActionOnAnnotationArray(Annotation[] a){ - //do nothing; - } public void performActionOnContinue(Continue x) { if (replaceJumpStatement(x) || @@ -264,8 +259,7 @@ public void performActionOnWhile(While x) { Statement body = (Statement) (changeList.isEmpty() ? null : changeList.removeFirst()); - addChild(new While(guard, body, x.getPositionInfo(), - x.getAnnotations())); + addChild(new While(guard, body, x.getPositionInfo())); changed(); } else { doDefaultAction(x); diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/WhileLoopTransformation.java b/system/de/uka/ilkd/key/rule/metaconstruct/WhileLoopTransformation.java index 364e7e6f2ac..818257214ec 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/WhileLoopTransformation.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/WhileLoopTransformation.java @@ -15,10 +15,10 @@ import java.util.Stack; import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.declaration.LocalVariableDeclaration; import de.uka.ilkd.key.java.expression.ExpressionStatement; import de.uka.ilkd.key.java.expression.operator.CopyAssignment; +import de.uka.ilkd.key.java.expression.operator.SetAssignment; import de.uka.ilkd.key.java.reference.IExecutionContext; import de.uka.ilkd.key.java.statement.*; import de.uka.ilkd.key.java.visitor.JavaASTVisitor; @@ -96,8 +96,9 @@ public class WhileLoopTransformation extends JavaASTVisitor { */ public WhileLoopTransformation(ProgramElement root, ProgramElementName outerLabel, - ProgramElementName innerLabel) { - super(root); + ProgramElementName innerLabel, + Services services) { + super(root, services); breakOuterLabel = (outerLabel == null ? null : new Break(outerLabel)); breakInnerLabel = (innerLabel == null ? null : new Break(innerLabel)); replaceBreakWithNoLabel = 0; @@ -108,8 +109,10 @@ public WhileLoopTransformation(ProgramElement root, * @param root the ProgramElement where to begin * @param inst the SVInstantiations if available */ - public WhileLoopTransformation(ProgramElement root, SVInstantiations inst) { - super(root); + public WhileLoopTransformation(ProgramElement root, + SVInstantiations inst, + Services services) { + super(root, services); instantiations = (inst == null ? SVInstantiations.EMPTY_SVINSTANTIATIONS : inst); @@ -273,6 +276,7 @@ public void performActionOnBreak(Break x) { if (runMode == CHECK) { needOuterLabel = true; } else { + needOuterLabel = true; addChild(breakOuterLabel); changed(); } @@ -286,6 +290,7 @@ public void performActionOnContinue(Continue x) { if (runMode == CHECK) { needInnerLabel = true; } else { + needInnerLabel = true; addChild(breakInnerLabel); changed(); } @@ -294,6 +299,7 @@ public void performActionOnContinue(Continue x) { if (runMode == CHECK) { needInnerLabel = true; } else if (runMode == TRANSFORMATION) { + needInnerLabel = true; addChild(new Break(breakInnerLabel.getLabel())); changed(); } @@ -484,7 +490,7 @@ public void performActionOnFor(For x) { For remainder = new For(null, x.getGuard(), unchangedUpdates, x.getBody()); - if (breakInnerLabel != null) { + if (innerLabelNeeded() && breakInnerLabel != null) { body = new LabeledStatement(breakInnerLabel.getLabel(), body); } @@ -513,7 +519,7 @@ public void performActionOnFor(For x) { new Then(new StatementBlock(new ArrayOfStatement (innerBlockStatements)))); - if (breakOuterLabel!=null) { + if (outerLabelNeeded() && breakOuterLabel!=null) { addChild(new LabeledStatement (breakOuterLabel.getLabel(), new StatementBlock(new ArrayOfStatement @@ -548,7 +554,7 @@ public void performActionOnWhile(While x) { Statement body = (Statement) (changeList.isEmpty() ? null : changeList.removeFirst()); - if (breakInnerLabel != null) { + if (innerLabelNeeded() && breakInnerLabel != null) { // an unlabeled continue needs to be handled with (replaced) body = new LabeledStatement(breakInnerLabel.getLabel(), body); @@ -557,7 +563,7 @@ public void performActionOnWhile(While x) { StatementBlock block = new StatementBlock (new ArrayOfStatement(new Statement[] {body, (Statement) root()})); - if (breakOuterLabel != null) { + if (outerLabelNeeded() && breakOuterLabel != null) { // an unlabeled break occurs in the // while loop therefore we need a labeled statement then = new Then(new LabeledStatement(breakOuterLabel.getLabel(), @@ -576,8 +582,7 @@ public void performActionOnWhile(While x) { Statement body = (Statement) (changeList.isEmpty() ? null : changeList.removeFirst()); - addChild(new While(guard, body, x.getPositionInfo(), - x.getAnnotations())); + addChild(new While(guard, body, x.getPositionInfo())); changed(); } else { doDefaultAction(x); @@ -597,7 +602,7 @@ public void performActionOnDo(Do x) { changeList.removeFirst()); Expression guard = ((Guard) changeList.removeFirst()).getExpression(); Statement unwindedBody = null; - if (breakInnerLabel != null) { + if (innerLabelNeeded() && breakInnerLabel != null) { // an unlabeled continue needs to be handled with (replaced) unwindedBody = new LabeledStatement(breakInnerLabel.getLabel(), body); @@ -610,10 +615,9 @@ public void performActionOnDo(Do x) { {unwindedBody, new While(guard, x.getBody(), - x.getPositionInfo(), - x.getAnnotations())})); + x.getPositionInfo())})); - if (breakOuterLabel != null) { + if (outerLabelNeeded() && breakOuterLabel != null) { // an unlabeled break occurs in the // body therefore we need a labeled statement resultStatement = new LabeledStatement(breakOuterLabel.getLabel(), @@ -630,8 +634,7 @@ public void performActionOnDo(Do x) { Statement body = (Statement) (changeList.isEmpty() ? null : changeList.removeFirst()); - addChild(new Do(guard, body, x.getPositionInfo(), - x.getAnnotations())); + addChild(new Do(guard, body, x.getPositionInfo())); changed(); } else { doDefaultAction(x); @@ -639,9 +642,6 @@ public void performActionOnDo(Do x) { } } - protected void performActionOnAnnotationArray(Annotation[] a){ - //do nothing; - } public void performActionOnIf(If x) { DefaultAction def=new DefaultAction() { @@ -731,6 +731,15 @@ ProgramElement createNewElement(ExtList changeList) { }; def.doAction(x); } + + public void performActionOnSetAssignment(SetAssignment x) { + DefaultAction def=new DefaultAction() { + ProgramElement createNewElement(ExtList changeList) { + return new SetAssignment(changeList); + } + }; + def.doAction(x); + } public void performActionOnThen(Then x) { DefaultAction def=new DefaultAction() { diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/arith/Monomial.java b/system/de/uka/ilkd/key/rule/metaconstruct/arith/Monomial.java index 9089e9ab75f..0114105e6ac 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/arith/Monomial.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/arith/Monomial.java @@ -197,7 +197,7 @@ private BigInteger cofactor(BigInteger v0, BigInteger v1) { public Term toTerm (Services services) { final TermSymbol mul = - services.getTypeConverter().getIntegerLDT().getArithMultiplication(); + services.getTypeConverter().getIntegerLDT().getMul(); Term res = null; final IteratorOfTerm it = parts.iterator (); @@ -238,9 +238,9 @@ private static class Analyser { public Analyser(final Services services) { this.services = services; - final IntegerLDT intLDT = services.getTypeConverter().getIntegerLDT(); - numbers = intLDT.getNumberSymbol(); - mul = intLDT.getArithMultiplication(); + final IntegerLDT integerLDT = services.getTypeConverter().getIntegerLDT(); + numbers = integerLDT.getNumberSymbol(); + mul = integerLDT.getMul(); } public void analyse(Term monomial) { diff --git a/system/de/uka/ilkd/key/rule/metaconstruct/arith/Polynomial.java b/system/de/uka/ilkd/key/rule/metaconstruct/arith/Polynomial.java index 4badc26142f..7e042fc7590 100644 --- a/system/de/uka/ilkd/key/rule/metaconstruct/arith/Polynomial.java +++ b/system/de/uka/ilkd/key/rule/metaconstruct/arith/Polynomial.java @@ -197,7 +197,7 @@ public boolean sameParts(Polynomial p) { public Term toTerm (Services services) { final TermSymbol add = - services.getTypeConverter().getIntegerLDT().getArithAddition(); + services.getTypeConverter().getIntegerLDT().getAdd(); Term res = null; final IteratorOfMonomial it = parts.iterator (); @@ -241,7 +241,7 @@ public Analyser(final Services services) { this.tc = services.getTypeConverter (); final IntegerLDT intLDT = tc.getIntegerLDT (); numbers = intLDT.getNumberSymbol (); - add = intLDT.getArithAddition (); + add = intLDT.getAdd(); } public void analyse(Term polynomial) { diff --git a/system/de/uka/ilkd/key/rule/soundness/ProgramSVProxy.java b/system/de/uka/ilkd/key/rule/soundness/ProgramSVProxy.java index 8a6b5023095..61350239524 100644 --- a/system/de/uka/ilkd/key/rule/soundness/ProgramSVProxy.java +++ b/system/de/uka/ilkd/key/rule/soundness/ProgramSVProxy.java @@ -15,7 +15,6 @@ import de.uka.ilkd.key.java.*; import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.reference.ExecutionContext; import de.uka.ilkd.key.java.visitor.Visitor; import de.uka.ilkd.key.logic.op.ArrayOfIProgramVariable; @@ -248,18 +247,6 @@ public PositionInfo getPositionInfo () { return PositionInfo.UNDEFINED; } - /** - *@return the annotations. - */ - public Annotation[] getAnnotations(){ - return new Annotation[0]; - } - - public int getAnnotationCount(){ - return 0; - } - - public MatchConditions match(SourceData source, MatchConditions matchCond) { // TODO Auto-generated method stub return null; diff --git a/system/de/uka/ilkd/key/rule/soundness/ProgramSVSkolem.java b/system/de/uka/ilkd/key/rule/soundness/ProgramSVSkolem.java index cd7de8db74f..f0c05db8eee 100644 --- a/system/de/uka/ilkd/key/rule/soundness/ProgramSVSkolem.java +++ b/system/de/uka/ilkd/key/rule/soundness/ProgramSVSkolem.java @@ -16,7 +16,6 @@ import de.uka.ilkd.key.java.*; import de.uka.ilkd.key.java.abstraction.ArrayOfKeYJavaType; import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.annotation.Annotation; import de.uka.ilkd.key.java.statement.JumpStatement; import de.uka.ilkd.key.java.visitor.Visitor; import de.uka.ilkd.key.logic.ProgramElementName; @@ -221,16 +220,4 @@ public void prettyPrint(PrettyPrinter w) throws java.io.IOException { public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { return this == se; } - - /** - *@return the annotations. - */ - public Annotation[] getAnnotations(){ - return new Annotation[0]; - } - - public int getAnnotationCount(){ - return 0; - } - } diff --git a/system/de/uka/ilkd/key/rule/soundness/SVPrefixCollector.java b/system/de/uka/ilkd/key/rule/soundness/SVPrefixCollector.java index 6fc7eb2fc0d..55bfbe1415f 100644 --- a/system/de/uka/ilkd/key/rule/soundness/SVPrefixCollector.java +++ b/system/de/uka/ilkd/key/rule/soundness/SVPrefixCollector.java @@ -109,7 +109,7 @@ private void addSVTypeInfo ( SchemaVariable p_sv, public void subtreeEntered(Term t) { if ( t.op() instanceof Modality ) { ProgramCollector c = new ProgramCollector - ( t.javaBlock ().program () ); + ( t.javaBlock ().program (), services ); c.start (); } else if ( t.op () instanceof SchemaVariable ) { SchemaVariable sv = (SchemaVariable)t.op (); @@ -156,8 +156,8 @@ private class ProgramCollector private int startAtChild; private boolean enter; - public ProgramCollector(ProgramElement root) { - super(root); + public ProgramCollector(ProgramElement root, Services services) { + super(root, services); } private void pushLevelMark () { @@ -265,13 +265,6 @@ protected void walk(ProgramElement node) { popLevelMark (); } - - /** the action that is performed just before leaving the node the - * last time - */ - protected void doAction(ProgramElement node) { - node.visit(this); - } /** starts the walker*/ public void start() { diff --git a/system/de/uka/ilkd/key/rule/soundness/StaticProgramChecker.java b/system/de/uka/ilkd/key/rule/soundness/StaticProgramChecker.java index 62810294696..f06f5c2ed00 100644 --- a/system/de/uka/ilkd/key/rule/soundness/StaticProgramChecker.java +++ b/system/de/uka/ilkd/key/rule/soundness/StaticProgramChecker.java @@ -75,14 +75,11 @@ public class StaticProgramChecker */ private final KeYJavaType LEVEL = new KeYJavaType (); - private final Services services; - private final Logger logger = Logger.getLogger ( "key.taclet_soundness" ); public StaticProgramChecker ( ProgramElement p_root, Services p_services ) { - super(p_root); - services = p_services; + super(p_root, p_services); } /** @@ -159,13 +156,6 @@ private void checkStatement ( NonTerminalProgramElement p_progEl, raiseTypeError (); } - /** the action that is performed just before leaving the node the - * last time - */ - protected void doAction(ProgramElement node) { - node.visit(this); - } - public void doAssignment () { // narrowing of constant expressions is not yet performed final ArrayOfKeYJavaType types = popAndCheckType ( 2, true ); @@ -625,6 +615,10 @@ public void performActionOnContinue(Continue x) { public void performActionOnCopyAssignment(CopyAssignment x) { doAssignment (); } + + public void performActionOnSetAssigment(SetAssignment x) { + doAssignment (); + } public void performActionOnDivide(Divide x) { doNumericPromotion ( x ); diff --git a/system/de/uka/ilkd/key/rule/soundness/TacletPORule.java b/system/de/uka/ilkd/key/rule/soundness/TacletPORule.java index c4efaffc345..7432e522b97 100644 --- a/system/de/uka/ilkd/key/rule/soundness/TacletPORule.java +++ b/system/de/uka/ilkd/key/rule/soundness/TacletPORule.java @@ -105,7 +105,8 @@ private void updateNamespaces ( Goal p_goal, app = it.next (); p_goal.addTaclet ( app.taclet (), app.instantiations (), - app.constraint () ); + app.constraint (), + false); } } } diff --git a/system/de/uka/ilkd/key/rule/soundness/TermProgramVariableCollector.java b/system/de/uka/ilkd/key/rule/soundness/TermProgramVariableCollector.java index 11b4820c067..6f6e24481a8 100644 --- a/system/de/uka/ilkd/key/rule/soundness/TermProgramVariableCollector.java +++ b/system/de/uka/ilkd/key/rule/soundness/TermProgramVariableCollector.java @@ -12,6 +12,7 @@ import java.util.HashSet; +import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.visitor.ProgramVariableCollector; import de.uka.ilkd.key.logic.JavaBlock; import de.uka.ilkd.key.logic.Term; @@ -21,7 +22,14 @@ public class TermProgramVariableCollector extends Visitor { - private HashSet result = new HashSet (); + private final HashSet result = new HashSet (); + private final Services services; + + + public TermProgramVariableCollector(Services services) { + this.services = services; + } + /** is called by the execPostOrder-method of a term * @param Term to checked if it is a program variable and if true the @@ -34,7 +42,7 @@ public void visit(Term t) { if ( t.javaBlock () != JavaBlock.EMPTY_JAVABLOCK ) { ProgramVariableCollector pvc - = new ProgramVariableCollector ( t.javaBlock ().program () ); + = new ProgramVariableCollector ( t.javaBlock ().program (), services ); pvc.start(); result.addAll ( pvc.result () ); } diff --git a/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnAttributeAccess.java b/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnAttributeAccess.java index 27e2de3a296..5f7c1c36c67 100644 --- a/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnAttributeAccess.java +++ b/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnAttributeAccess.java @@ -45,7 +45,8 @@ public ApplyOnAttributeAccess(UpdateSimplifier updateSimplifier) { * attribute operator */ public boolean isApplicable (Update update, Term target) { - return (target.op () instanceof AttributeOp)|| (target.op() instanceof NonRigidFunctionLocation); + return (target.op () instanceof AttributeOp) + || (target.op() instanceof NonRigidFunctionLocation && target.op().arity() > 0); } /** diff --git a/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnLocalVariableOrStaticField.java b/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnLocalVariableOrStaticField.java index 8aedae10cf9..e409e662c44 100644 --- a/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnLocalVariableOrStaticField.java +++ b/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnLocalVariableOrStaticField.java @@ -10,7 +10,9 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.op.Location; import de.uka.ilkd.key.logic.op.LocationVariable; +import de.uka.ilkd.key.logic.op.NonRigidFunctionLocation; import de.uka.ilkd.key.logic.op.SetAsListOfQuantifiableVariable; import de.uka.ilkd.key.logic.op.SetOfQuantifiableVariable; import de.uka.ilkd.key.rule.AbstractUpdateRule; @@ -41,7 +43,9 @@ public ApplyOnLocalVariableOrStaticField(UpdateSimplifier us) { * variable */ public boolean isApplicable(Update update, Term target) { - return target.op() instanceof LocationVariable; + return target.op() instanceof LocationVariable + || target.op() instanceof NonRigidFunctionLocation + && target.op().arity() == 0; } /** @@ -60,7 +64,7 @@ public Term apply(Update update, Term target, Services services) { private PVIfExCascade createCascade (Update update, Term target) { return new PVIfExCascade ( update.getAssignmentPairs - ( (LocationVariable)target.op () ) ); + ( (Location)target.op () ) ); } private static class PVIfExCascade extends IterateAssignmentPairsIfExCascade { diff --git a/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnModality.java b/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnModality.java index 67e151ed184..555aad38d12 100644 --- a/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnModality.java +++ b/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnModality.java @@ -70,7 +70,7 @@ public boolean isApplicable(Update update, Term target) { public Term apply(Update update, Term target, Services services) { final ArrayOfAssignmentPair pairs = deletionEnabled ? new ArrayOfAssignmentPair( - remove(update, target)) + remove(update, target, services)) : update.getAllAssignmentPairs(); return pairs.size() == 0 ? target : UpdateSimplifierTermFactory.DEFAULT @@ -82,9 +82,10 @@ public Term apply(Update update, Term target, Services services) { * used in the tail of the formula * @author bubel */ - public AssignmentPair[] remove(Update up, Term target) { + public AssignmentPair[] remove(Update up, Term target, Services services) { final ArrayOfAssignmentPair pairs = up.getAllAssignmentPairs(); - final HashSet protectedProgVars = collectProgramVariables(target); + final HashSet protectedProgVars = collectProgramVariables(target, + services); final List result = new ArrayList(pairs.size()); for (int i = 0, size=pairs.size(); i"))); + loc.name().equals(new ProgramElementName(""))); } @@ -129,7 +130,7 @@ private boolean isHeapLocation(Location loc) { * @param target * @return */ - private HashSet collectProgramVariables(Term target) { + private HashSet collectProgramVariables(Term target, Services services) { if (protectedVarsCache.containsKey(target)) { return (HashSet) protectedVarsCache.get(target); } @@ -150,13 +151,15 @@ private HashSet collectProgramVariables(Term target) { if (target.javaBlock() != JavaBlock.EMPTY_JAVABLOCK) { ProgramVariableCollector pvc = - new ProgramVariableCollector(target.javaBlock().program(), true); + new ProgramVariableCollector(target.javaBlock().program(), + services); pvc.start(); foundProgVars.addAll(pvc.result()); } for (int i = 0; i=1000) { diff --git a/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnUpdate.java b/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnUpdate.java index a9bc2cae30d..fb011fd205f 100644 --- a/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnUpdate.java +++ b/system/de/uka/ilkd/key/rule/updatesimplifier/ApplyOnUpdate.java @@ -21,18 +21,13 @@ * Applies an update on an array using rule ... */ public class ApplyOnUpdate extends AbstractUpdateRule { - - private final UpdateFactory ufac; - + /** * creates an instance of this rule used by the given update * simplifier */ public ApplyOnUpdate(UpdateSimplifier us) { super(us); - // The update factory does not need Services for what we - // are doing with it - ufac = new UpdateFactory (null, us); } /** @@ -61,6 +56,8 @@ public boolean isApplicable(Update update, Term target) { * @return true if the rule can be applied on the update, target pair */ public Term apply (Update update, Term target, Services services) { + final UpdateFactory ufac = new UpdateFactory(services, + updateSimplifier()); final Update targetUpdate = Update.createUpdate ( target ); final Update composedUpdate = ufac.sequential ( update, targetUpdate ); final IUpdateOperator updateOp = (IUpdateOperator)target.op (); diff --git a/system/de/uka/ilkd/key/rule/updatesimplifier/UpdateSimplifierTermFactory.java b/system/de/uka/ilkd/key/rule/updatesimplifier/UpdateSimplifierTermFactory.java index a32d3fb65b8..019b487afe2 100644 --- a/system/de/uka/ilkd/key/rule/updatesimplifier/UpdateSimplifierTermFactory.java +++ b/system/de/uka/ilkd/key/rule/updatesimplifier/UpdateSimplifierTermFactory.java @@ -123,7 +123,7 @@ public Term createUpdateTerm(ArrayOfAssignmentPair assignmentPairs, values [i] = assignmentPair.valueUnsafe(); if (assignmentPair.location() == Update.StarLocation.ALL) { Debug.assertTrue( - assignmentPairs.size() == 1, + i == assignmentPairs.size() - 1, "Special star operator tried to escape. " + "(not allowed as long as no generalized terms)"); return tf.createAnonymousUpdateTerm( diff --git a/system/de/uka/ilkd/key/speclang/AbstractClassInvariant.java b/system/de/uka/ilkd/key/speclang/AbstractClassInvariant.java deleted file mode 100644 index 8bff1bd25e8..00000000000 --- a/system/de/uka/ilkd/key/speclang/AbstractClassInvariant.java +++ /dev/null @@ -1,38 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.speclang; - -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.logic.TermBuilder; - - -public abstract class AbstractClassInvariant implements ClassInvariant { - protected static final TermBuilder tb = TermBuilder.DF; - private final ModelClass modelClass; - - - public AbstractClassInvariant(ModelClass modelClass) { - this.modelClass = modelClass; - } - - - public ModelClass getModelClass() { - return modelClass; - } - - - public KeYJavaType getKJT(Services services) { - return services.getJavaInfo().getTypeByClassName( - modelClass.getFullClassName()); - } -} diff --git a/system/de/uka/ilkd/key/speclang/AbstractOperationContract.java b/system/de/uka/ilkd/key/speclang/AbstractOperationContract.java deleted file mode 100644 index 794eeb8a81b..00000000000 --- a/system/de/uka/ilkd/key/speclang/AbstractOperationContract.java +++ /dev/null @@ -1,65 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.speclang; - -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.java.JavaInfo; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; -import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; -import de.uka.ilkd.key.java.abstraction.SLListOfKeYJavaType; -import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.op.Modality; -import de.uka.ilkd.key.logic.op.ProgramMethod; - - -public abstract class AbstractOperationContract implements OperationContract { - protected static final TermBuilder tb = TermBuilder.DF; - private final ModelMethod modelMethod; - private final Modality modality; - - - public AbstractOperationContract(ModelMethod modelMethod, - Modality modality) { - this.modelMethod = modelMethod; - this.modality = modality; - } - - - public ModelMethod getModelMethod() { - return modelMethod; - } - - - public ProgramMethod getProgramMethod(Services services) { - JavaInfo javaInfo = services.getJavaInfo(); - - String containingClassName = modelMethod.getContainingClassName(); - KeYJavaType containingClass - = javaInfo.getKeYJavaTypeByClassName(containingClassName); - - ListOfKeYJavaType signature = SLListOfKeYJavaType.EMPTY_LIST; - for(int i=0; i < modelMethod.getNumParameters(); i++) { - String parTypeName = modelMethod.getParameterTypeAt(i); - signature = signature.append(javaInfo.getKeYJavaType(parTypeName)); - } - - return javaInfo.getProgramMethod(containingClass, - modelMethod.getName(), - signature, - javaInfo.getJavaLangObject()); - } - - - public Modality getModality() { - return modality; - } -} diff --git a/system/de/uka/ilkd/key/speclang/ClassInvariant.java b/system/de/uka/ilkd/key/speclang/ClassInvariant.java index a544cbd3a7e..89e69478e35 100644 --- a/system/de/uka/ilkd/key/speclang/ClassInvariant.java +++ b/system/de/uka/ilkd/key/speclang/ClassInvariant.java @@ -10,19 +10,47 @@ package de.uka.ilkd.key.speclang; -import de.uka.ilkd.key.casetool.ModelClass; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.logic.op.ParsableVariable; +/** + * A class invariant. + */ public interface ClassInvariant { - public ModelClass getModelClass(); + + /** + * Returns the unique internal name of the invariant. + */ + public String getName(); + + /** + * Returns the displayed name of the invariant. + */ + public String getDisplayName(); - public KeYJavaType getKJT(Services services); + /** + * Returns the KeYJavaType representing the class/interface to which the + * invariant belongs. + */ + public KeYJavaType getKJT(); - public FormulaWithAxioms getInv(Services services) throws SLTranslationError; + /** + * Returns the invariant formula with implicit all-quantification over + * the receiver object. + */ + public FormulaWithAxioms getClosedInv(Services services); - public FormulaWithAxioms getOpenInv(ParsableVariable selfVar, - Services services) throws SLTranslationError; + /** + * Returns the invariant formula without implicit all-quantification over + * the receiver object. + */ + public FormulaWithAxioms getOpenInv(ParsableVariable selfVar, + Services services); + + /** + * Returns the invariant in pretty HTML format. + */ + public String getHTMLText(Services services); } diff --git a/system/de/uka/ilkd/key/speclang/ClassInvariantImpl.java b/system/de/uka/ilkd/key/speclang/ClassInvariantImpl.java new file mode 100644 index 00000000000..9812a82de54 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/ClassInvariantImpl.java @@ -0,0 +1,136 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang; + +import java.util.LinkedHashMap; +import java.util.Map; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.op.LogicVariable; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.pp.LogicPrinter; +import de.uka.ilkd.key.proof.OpReplacer; + + +/** + * Standard implementation of the ClassInvariant interface. + */ +public class ClassInvariantImpl implements ClassInvariant { + + protected static final SignatureVariablesFactory SVN + = SignatureVariablesFactory.INSTANCE; + + private final String name; + private final String displayName; + private final KeYJavaType kjt; + private final FormulaWithAxioms originalInv; + private final ParsableVariable originalSelfVar; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + /** + * Creates a class invariant. + * @param name the unique internal name of the invariant + * @param displayName the displayed name of the invariant + * @param kjt the KeYJavaType to which the invariant belongs + * @param inv the invariant formula itself + * @param selfVar the variable used for the receiver object + */ + public ClassInvariantImpl(String name, + String displayName, + KeYJavaType kjt, + FormulaWithAxioms inv, + ParsableVariable selfVar) { + assert name != null && !name.equals(""); + assert displayName != null && !displayName.equals(""); + assert kjt != null; + assert inv != null; + this.name = name; + this.displayName = displayName; + this.kjt = kjt; + this.originalInv = inv; + this.originalSelfVar = selfVar; + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private Map /*Operator -> Operator*/ getReplaceMap( + ParsableVariable selfVar, + Services services) { + Map result = new LinkedHashMap(); + + if(selfVar != null) { + assert originalSelfVar.sort().equals(selfVar.sort()); + result.put(originalSelfVar, selfVar); + } + + return result; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public String getName() { + return name; + } + + + public String getDisplayName() { + return displayName; + } + + + public KeYJavaType getKJT() { + return kjt; + } + + + public FormulaWithAxioms getClosedInv(Services services) { + Sort sort = getKJT().getSort(); + String name = sort.name().toString().substring(0, 1).toLowerCase(); + LogicVariable selfVar = new LogicVariable(new Name(name), sort); + return getOpenInv(selfVar, services).allClose(services); + } + + + public FormulaWithAxioms getOpenInv(ParsableVariable selfVar, + Services services) { + Map replaceMap = getReplaceMap(selfVar, services); + OpReplacer or = new OpReplacer(replaceMap); + return or.replace(originalInv); + } + + + public String getHTMLText(Services services) { + return "" + + LogicPrinter.quickPrintTerm(originalInv.getFormula(), + services) + + ""; + } + + + public String toString() { + return originalInv.toString(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/DLOperationContract.java b/system/de/uka/ilkd/key/speclang/DLOperationContract.java deleted file mode 100644 index 425826a6645..00000000000 --- a/system/de/uka/ilkd/key/speclang/DLOperationContract.java +++ /dev/null @@ -1,151 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.speclang; - -import java.util.HashMap; -import java.util.Map; - -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.BasicLocationDescriptor; -import de.uka.ilkd.key.logic.EverythingLocationDescriptor; -import de.uka.ilkd.key.logic.IteratorOfLocationDescriptor; -import de.uka.ilkd.key.logic.LocationDescriptor; -import de.uka.ilkd.key.logic.SetAsListOfLocationDescriptor; -import de.uka.ilkd.key.logic.SetOfLocationDescriptor; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.op.IteratorOfParsableVariable; -import de.uka.ilkd.key.logic.op.ListOfParsableVariable; -import de.uka.ilkd.key.logic.op.Modality; -import de.uka.ilkd.key.logic.op.ParsableVariable; -import de.uka.ilkd.key.proof.OpReplacer; - - -public class DLOperationContract extends AbstractOperationContract { - private final Term originalPre; - private final Term originalPost; - private final SetOfLocationDescriptor originalModifies; - private final ParsableVariable originalSelfVar; - private final ListOfParsableVariable originalParamVars; - private final ParsableVariable originalResultVar; - private final ParsableVariable originalExcVar; - private final Map /*Operator -> Term*/ axioms; - - - public DLOperationContract(ModelMethod modelMethod, - Modality modality, - Term originalPre, - Term originalPost, - SetOfLocationDescriptor originalModifies, - ParsableVariable originalSelfVar, - ListOfParsableVariable originalParamVars, - ParsableVariable originalResultVar, - ParsableVariable originalExcVar, - Map /*Operator -> Term*/ axioms) { - super(modelMethod, modality); - this.originalPre = originalPre; - this.originalPost = originalPost; - this.originalModifies = originalModifies; - this.originalSelfVar = originalSelfVar; - this.originalParamVars = originalParamVars; - this.originalResultVar = originalResultVar; - this.originalExcVar = originalExcVar; - this.axioms = axioms; - } - - - private Map /*Operator -> Operator*/ getReplaceMap( - ParsableVariable selfVar, - ListOfParsableVariable paramVars, - ParsableVariable resultVar, - ParsableVariable excVar) { - Map result = new HashMap(); - - if(selfVar != null) { - assert originalSelfVar.sort().equals(selfVar.sort()); - result.put(originalSelfVar, selfVar); - } - - if(paramVars != null) { - assert originalParamVars.size() == paramVars.size(); - IteratorOfParsableVariable it1 = originalParamVars.iterator(); - IteratorOfParsableVariable it2 = paramVars.iterator(); - while(it1.hasNext()) { - ParsableVariable originalParamVar = it1.next(); - ParsableVariable paramVar = it2.next(); - assert originalParamVar.sort().equals(paramVar.sort()); - result.put(originalParamVar, paramVar); - } - } - - if(resultVar != null) { - assert originalResultVar.sort().equals(resultVar.sort()); - result.put(originalResultVar, resultVar); - } - - if(excVar != null) { - assert originalExcVar.sort().equals(excVar.sort()); - result.put(originalExcVar, excVar); - } - - return result; - } - - - public FormulaWithAxioms getPre(ParsableVariable selfVar, - ListOfParsableVariable paramVars, - Services services) { - Map replaceMap = getReplaceMap(selfVar, paramVars, null, null); - OpReplacer or = new OpReplacer(replaceMap); - - return new FormulaWithAxioms(or.replace(originalPre), axioms); - } - - - public FormulaWithAxioms getPost(ParsableVariable selfVar, - ListOfParsableVariable paramVars, - ParsableVariable resultVar, - ParsableVariable excVar, - Services services) { - Map replaceMap = getReplaceMap(selfVar, paramVars, resultVar, excVar); - OpReplacer or = new OpReplacer(replaceMap); - - return new FormulaWithAxioms(or.replace(originalPost), axioms); - } - - - public SetOfLocationDescriptor getModifies(ParsableVariable selfVar, - ListOfParsableVariable paramVars, - Services services) { - Map replaceMap = getReplaceMap(selfVar, paramVars, null, null); - OpReplacer or = new OpReplacer(replaceMap); - - SetOfLocationDescriptor result - = SetAsListOfLocationDescriptor.EMPTY_SET; - IteratorOfLocationDescriptor it = originalModifies.iterator(); - while(it.hasNext()) { - LocationDescriptor loc = it.next(); - if(loc instanceof BasicLocationDescriptor) { - BasicLocationDescriptor bloc = (BasicLocationDescriptor) loc; - Term unifiedFormula = or.replace(bloc.getFormula()); - Term unifiedLocTerm = or.replace(bloc.getLocTerm()); - result - = result.add(new BasicLocationDescriptor(unifiedFormula, - unifiedLocTerm)); - } else { - assert loc instanceof EverythingLocationDescriptor; - result = result.add(loc); - } - } - - return result; - } -} diff --git a/system/de/uka/ilkd/key/speclang/FormulaWithAxioms.java b/system/de/uka/ilkd/key/speclang/FormulaWithAxioms.java index fdc3e572b1f..01b6347e727 100644 --- a/system/de/uka/ilkd/key/speclang/FormulaWithAxioms.java +++ b/system/de/uka/ilkd/key/speclang/FormulaWithAxioms.java @@ -10,28 +10,44 @@ package de.uka.ilkd.key.speclang; -import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; +import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.op.IteratorOfQuantifiableVariable; +import de.uka.ilkd.key.logic.op.LogicVariable; +import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.SetOfQuantifiableVariable; +import de.uka.ilkd.key.proof.init.CreatedAttributeTermFactory; +/** + * Data class containing a formula and a set of axioms about the operators used + * in that formula (e.g. the translation of "sum" from OCL). + */ public class FormulaWithAxioms { + + private static final TermBuilder TB = TermBuilder.DF; + + public static final FormulaWithAxioms TT = new FormulaWithAxioms(TB.tt()); + public static final FormulaWithAxioms FF = new FormulaWithAxioms(TB.ff()); + private final Term formula; private final Map /*Operator -> Term*/ axioms; public FormulaWithAxioms(Term formula, Map /*Operator -> Term*/ axioms) { - assert formula.sort() == Sort.FORMULA; this.formula = formula; - this.axioms = new HashMap(); - this.axioms.putAll(axioms); + this.axioms = new LinkedHashMap(); + this.axioms.putAll(axioms); } public FormulaWithAxioms(Term formula) { - this(formula, new HashMap()); + this(formula, new LinkedHashMap()); } @@ -41,8 +57,88 @@ public Term getFormula() { public Map /*Operator -> Term*/ getAxioms() { - HashMap result = new HashMap(); + Map result = new LinkedHashMap(); result.putAll(axioms); return result; } + + + public Term getAxiomsAsFormula() { + Term result = TB.tt(); + Iterator it = axioms.values().iterator(); + while(it.hasNext()) { + result = TB.and(result, (Term)it.next()); + } + return result; + } + + + public FormulaWithAxioms conjoin(FormulaWithAxioms fwa) { + FormulaWithAxioms result + = new FormulaWithAxioms(TB.and(formula, fwa.formula)); + result.axioms.putAll(axioms); + result.axioms.putAll(fwa.axioms); + return result; + } + + + public FormulaWithAxioms disjoin(FormulaWithAxioms fwa) { + FormulaWithAxioms result + = new FormulaWithAxioms(TB.or(formula, fwa.formula)); + result.axioms.putAll(axioms); + result.axioms.putAll(fwa.axioms); + return result; + } + + + public FormulaWithAxioms imply(FormulaWithAxioms fwa) { + FormulaWithAxioms result + = new FormulaWithAxioms(TB.imp(formula, fwa.formula)); + result.axioms.putAll(axioms); + result.axioms.putAll(fwa.axioms); + return result; + } + + + public FormulaWithAxioms negate() { + return new FormulaWithAxioms(TB.not(formula), axioms); + } + + + public FormulaWithAxioms allClose(Services services) { + SetOfQuantifiableVariable freeVars = formula.freeVars(); + LogicVariable[] freeVarsArray = new LogicVariable[freeVars.size()]; + IteratorOfQuantifiableVariable it = freeVars.iterator(); + for(int i = 0; i < freeVarsArray.length; i++) { + freeVarsArray[i] = (LogicVariable) it.next(); + } + Term closedFormula = + CreatedAttributeTermFactory.INSTANCE + .createCreatedNotNullQuantifierTerm( + services, + Op.ALL, + freeVarsArray, + formula); + + return new FormulaWithAxioms(closedFormula, axioms); + } + + + public boolean equals(Object o) { + if(!(o instanceof FormulaWithAxioms)) { + return false; + } + FormulaWithAxioms fwa = (FormulaWithAxioms) o; + return formula.equals(fwa.formula) && axioms.equals(fwa.axioms); + } + + + public int hashCode() { + return formula.hashCode() + axioms.hashCode(); + } + + + public String toString() { + return getFormula().toString(); + } } diff --git a/system/de/uka/ilkd/key/speclang/LoopInvariant.java b/system/de/uka/ilkd/key/speclang/LoopInvariant.java new file mode 100644 index 00000000000..63cd919f778 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/LoopInvariant.java @@ -0,0 +1,105 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang; + +import java.util.Map; + +import de.uka.ilkd.key.java.statement.LoopStatement; +import de.uka.ilkd.key.java.visitor.Visitor; +import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.logic.SetOfTerm; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.op.ParsableVariable; + + +/** + * A loop invariant, consisting of an invariant formula, a set of loop + * predicates, a modifier set, and a variant term. + */ +public interface LoopInvariant { + + /** + * Returns the loop to which the invariant belongs. + */ + public LoopStatement getLoop(); + + /** + * Returns the invariant formula. + */ + public Term getInvariant(Term selfTerm); + + /** + * Returns the set of loop predicates. + */ + public SetOfTerm getPredicates(Term selfTerm); + + /** + * Returns the modifier set. + */ + public SetOfLocationDescriptor getModifies(Term selfTerm); + + /** + * Returns the variant term. + */ + public Term getVariant(Term selfTerm); + + /** + * Tells whether using heuristics for generating additional loop predicates + * is allowed or not. + */ + public boolean getPredicateHeuristicsAllowed(); + + /** + * Returns the variable used for self. + */ + public ParsableVariable getSelfVar(); + + /** + * Returns the map of atPre-functions. + */ + public /*inout*/ Map /*Operator (normal) + -> Function (atPre)*/ getAtPreFunctions(); + + /** + * Returns a new loop invariant where the loop reference has been + * replaced with the passed one. + */ + public LoopInvariant setLoop(LoopStatement loop); + + /** + * Returns a new loop invariant where the invariant formula has been + * repaced with the passed one. Take care: the variables used for + * the receiver, parameters, and local variables must stay the same! + */ + public LoopInvariant setInvariant(Term invariant, Term selfTerm); + + /** + * Returns a new loop invariant where the loop predicates have been + * replaced with the passed ones. + */ + public LoopInvariant setPredicates(SetOfTerm predicates, Term selfTerm); + + /** + * Returns a new loop invariant where the flag for predicate generation + * heuristics has been set to the passed value. Take care: the variables + * used for the receiver, parameters, and local variables must stay the + * same! + */ + public LoopInvariant setPredicateHeuristicsAllowed( + boolean predicateHeuristicsAllowed); + + /** + * Loop invariants can be visited like source elements: + * This method calls the corresponding method of a visitor in order to + * perform some action/transformation on this element. + */ + public void visit(Visitor v); +} diff --git a/system/de/uka/ilkd/key/speclang/LoopInvariantImpl.java b/system/de/uka/ilkd/key/speclang/LoopInvariantImpl.java new file mode 100644 index 00000000000..7a63a91f1c5 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/LoopInvariantImpl.java @@ -0,0 +1,266 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import de.uka.ilkd.key.java.statement.LoopStatement; +import de.uka.ilkd.key.java.visitor.Visitor; +import de.uka.ilkd.key.logic.SetAsListOfLocationDescriptor; +import de.uka.ilkd.key.logic.SetAsListOfTerm; +import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.logic.SetOfTerm; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.proof.OpReplacer; + + +/** + * Standard implementation of the LoopInvariant interface. + */ +public class LoopInvariantImpl implements LoopInvariant { + + private final LoopStatement loop; + private final Term originalInvariant; + private final SetOfTerm originalPredicates; + private final SetOfLocationDescriptor originalModifies; + private final Term originalVariant; + private final ParsableVariable originalSelfVar; + private final Map /*Operator (normal) -> Function (atPre)*/ + originalAtPreFunctions; + private final boolean predicateHeuristicsAllowed; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + /** + * Creates a loop invariant. + * @param loop the loop to which the invariant belongs + * @param invariant the invariant formula + * @param predicates the loop predicates + * @param modifies the modifier set + * @param variant the variant term + * @param selfVar the variable used for the receiver object + * @param atPreFunctions the functions used for atPre + * @param predicateHeuristicsAllowed whether heuristics for generating + * additional loop predicates are allowed + */ + public LoopInvariantImpl(LoopStatement loop, + Term invariant, + SetOfTerm predicates, + SetOfLocationDescriptor modifies, + Term variant, + ParsableVariable selfVar, + /*inout*/ Map /*Operator (normal) + -> Function (atPre)*/ atPreFunctions, + boolean predicateHeuristicsAllowed) { + assert loop != null; + assert predicates != null; + assert modifies != null; + assert atPreFunctions != null; + this.loop = loop; + this.originalInvariant = invariant; + this.originalPredicates = predicates; + this.originalVariant = variant; + this.originalModifies = modifies; + this.originalSelfVar = selfVar; + this.predicateHeuristicsAllowed = predicateHeuristicsAllowed; + this.originalAtPreFunctions = new LinkedHashMap(); + this.originalAtPreFunctions.putAll(atPreFunctions); + } + + + /** + * Creates an empty, default loop invariant for the passed loop. + */ + public LoopInvariantImpl(LoopStatement loop, ParsableVariable selfVar) { + this(loop, + null, + SetAsListOfTerm.EMPTY_SET, + SetAsListOfLocationDescriptor.EMPTY_SET, + null, + selfVar, + new LinkedHashMap(), + true); + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private Map /*Term -> Term*/ getReplaceMap(Term selfTerm) { + Map result = new LinkedHashMap(); + + //self + if(selfTerm != null) { + assert originalSelfVar.sort().equals(selfTerm.sort()); + result.put(TermBuilder.DF.var(originalSelfVar), selfTerm); + } + + //-parameters and other local variables are always kept up to + // date by the ProgVarReplaceVisitor + //-atPre-functions are kept up to date by the IntroAtPreDefinitionsOp + + return result; + } + + + private Map /*Term -> Term*/ getInverseReplaceMap(Term selfTerm) { + Map result = new LinkedHashMap(); + Map replaceMap = getReplaceMap(selfTerm); + Iterator it = replaceMap.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + result.put(entry.getValue(), entry.getKey()); + } + return result; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public LoopStatement getLoop() { + return loop; + } + + + public Term getInvariant(Term selfTerm) { + assert (selfTerm == null) == (originalSelfVar == null); + Map replaceMap = getReplaceMap(selfTerm); + OpReplacer or = new OpReplacer(replaceMap); + return or.replace(originalInvariant); + } + + + public SetOfTerm getPredicates(Term selfTerm) { + assert (selfTerm == null) == (originalSelfVar == null); + Map replaceMap = getReplaceMap(selfTerm); + OpReplacer or = new OpReplacer(replaceMap); + return or.replace(originalPredicates); + } + + + public SetOfLocationDescriptor getModifies(Term selfTerm) { + assert (selfTerm == null) == (originalSelfVar == null); + Map replaceMap = getReplaceMap(selfTerm); + OpReplacer or = new OpReplacer(replaceMap); + return or.replace(originalModifies); + } + + + public Term getVariant(Term selfTerm) { + assert (selfTerm == null) == (originalSelfVar == null); + Map replaceMap = getReplaceMap(selfTerm); + OpReplacer or = new OpReplacer(replaceMap); + return or.replace(originalVariant); + } + + + public boolean getPredicateHeuristicsAllowed() { + return predicateHeuristicsAllowed; + } + + + + public ParsableVariable getSelfVar() { + return originalSelfVar; + } + + + public /*inout*/ Map /*Operator (normal) + -> Function (atPre)*/ getAtPreFunctions() { + Map result = new LinkedHashMap(); + result.putAll(originalAtPreFunctions); + return result; + } + + + public LoopInvariant setLoop(LoopStatement loop) { + return new LoopInvariantImpl(loop, + originalInvariant, + originalPredicates, + originalModifies, + originalVariant, + originalSelfVar, + originalAtPreFunctions, + predicateHeuristicsAllowed); + } + + + public LoopInvariant setInvariant(Term invariant, Term selfTerm) { + assert (selfTerm == null) == (originalSelfVar == null); + Map inverseReplaceMap = getInverseReplaceMap(selfTerm); + OpReplacer or = new OpReplacer(inverseReplaceMap); + return new LoopInvariantImpl(loop, + or.replace(invariant), + originalPredicates, + originalModifies, + originalVariant, + originalSelfVar, + originalAtPreFunctions, + predicateHeuristicsAllowed); + } + + + public LoopInvariant setPredicates(SetOfTerm predicates, Term selfTerm) { + assert (selfTerm == null) == (originalSelfVar == null); + Map inverseReplaceMap = getInverseReplaceMap(selfTerm); + OpReplacer or = new OpReplacer(inverseReplaceMap); + return new LoopInvariantImpl(loop, + originalInvariant, + or.replace(predicates), + originalModifies, + originalVariant, + originalSelfVar, + originalAtPreFunctions, + predicateHeuristicsAllowed); + } + + + public LoopInvariant setPredicateHeuristicsAllowed( + boolean predicateHeuristicsAllowed) { + return new LoopInvariantImpl(loop, + originalInvariant, + originalPredicates, + originalModifies, + originalVariant, + originalSelfVar, + originalAtPreFunctions, + predicateHeuristicsAllowed); + } + + + public void visit(Visitor v) { + v.performActionOnLoopInvariant(this); + } + + + public String toString() { + return "invariant: " + + originalInvariant + + "; predicates: " + + originalPredicates + + "; modifies: " + + originalModifies + + "; variant: " + + originalVariant; + } +} diff --git a/system/de/uka/ilkd/key/speclang/OperationContract.java b/system/de/uka/ilkd/key/speclang/OperationContract.java index 837200b692c..d21ead6e0ee 100644 --- a/system/de/uka/ilkd/key/speclang/OperationContract.java +++ b/system/de/uka/ilkd/key/speclang/OperationContract.java @@ -10,7 +10,8 @@ package de.uka.ilkd.key.speclang; -import de.uka.ilkd.key.casetool.ModelMethod; +import java.util.Map; + import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.SetOfLocationDescriptor; import de.uka.ilkd.key.logic.op.ListOfParsableVariable; @@ -21,28 +22,62 @@ /** * A contract about an operation, consisting of a precondition, a - * postcondition, a modifies clause, and a modality. + * postcondition, a modifier set, and a modality. */ public interface OperationContract { - public ModelMethod getModelMethod(); - - public ProgramMethod getProgramMethod(Services services); + /** + * Returns the unique internal name of the contract. + */ + public String getName(); + + /** + * Returns the displayed name of the contract. + */ + public String getDisplayName(); + + /** + * Returns the ProgramMethod representing the operation to which the + * contract belongs. + */ + public ProgramMethod getProgramMethod(); + + /** + * Returns the modality of the contract. + */ public Modality getModality(); + /** + * Returns the precondition of the contract. + */ public FormulaWithAxioms getPre(ParsableVariable selfVar, ListOfParsableVariable paramVars, - Services services) throws SLTranslationError; + Services services); - + /** + * Returns the postcondition of the contract. + * @param atPreFunctions map containing functions to use as atPre-functions. + * If the method needs an atPre-function which is not + * in this map, it creates a fresh one and adds it to + * the map. + */ public FormulaWithAxioms getPost(ParsableVariable selfVar, ListOfParsableVariable paramVars, ParsableVariable resultVar, ParsableVariable excVar, - Services services) throws SLTranslationError; + /*inout*/ Map /*Operator (normal) + -> Function (atPre)*/ atPreFunctions, + Services services); - + /** + * Returns the modifier set of the contract. + */ public SetOfLocationDescriptor getModifies(ParsableVariable selfVar, ListOfParsableVariable paramVars, - Services services) throws SLTranslationError; + Services services); + + /** + * Returns the contract in pretty HTML format. + */ + public String getHTMLText(Services services); } diff --git a/system/de/uka/ilkd/key/speclang/OperationContractImpl.java b/system/de/uka/ilkd/key/speclang/OperationContractImpl.java new file mode 100644 index 00000000000..075ffbe323f --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/OperationContractImpl.java @@ -0,0 +1,313 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.logic.op.IteratorOfParsableVariable; +import de.uka.ilkd.key.logic.op.ListOfParsableVariable; +import de.uka.ilkd.key.logic.op.Modality; +import de.uka.ilkd.key.logic.op.Operator; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.pp.LogicPrinter; +import de.uka.ilkd.key.proof.AtPreFactory; +import de.uka.ilkd.key.proof.OpReplacer; + + +/** + * Standard implementation of the OperationContract interface. + */ +public class OperationContractImpl implements OperationContract { + + protected static final SignatureVariablesFactory SVN + = SignatureVariablesFactory.INSTANCE; + + private final String name; + private final String displayName; + private final ProgramMethod programMethod; + private final Modality modality; + private final FormulaWithAxioms originalPre; + private final FormulaWithAxioms originalPost; + private final SetOfLocationDescriptor originalModifies; + private final ParsableVariable originalSelfVar; + private final ListOfParsableVariable originalParamVars; + private final ParsableVariable originalResultVar; + private final ParsableVariable originalExcVar; + private final Map /*Operator (normal) -> Function (atPre)*/ + originalAtPreFunctions; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + /** + * Creates an operation contract. + * @param name the unique internal name of the contract + * @param displayName the displayed name of the contract + * @param programMethod the ProgramMethod to which the contract belongs + * @param modality the modality of the contract + * @param pre the precondition of the contract + * @param post the postcondition of the contract + * @param modifies the modifier set of the contract + * @param selfVar the variable used for the receiver object + * @param paramVars the variables used for the operation parameters + * @param resultVar the variables used for the operation result + * @param excVar the variable used for the thrown exception + * @param atPreFunctions the functions used for atPre + */ + public OperationContractImpl(String name, + String displayName, + ProgramMethod programMethod, + Modality modality, + FormulaWithAxioms pre, + FormulaWithAxioms post, + SetOfLocationDescriptor modifies, + ParsableVariable selfVar, + ListOfParsableVariable paramVars, + ParsableVariable resultVar, + ParsableVariable excVar, + /*inout*/ Map /*Operator (normal) + -> Function (atPre)*/ atPreFunctions) { + assert name != null && !name.equals(""); + assert displayName != null && !displayName.equals(""); + assert programMethod != null; + assert modality != null; + assert pre != null; + assert post != null; + assert modifies != null; + assert (selfVar == null) == programMethod.isStatic(); + assert paramVars != null; + assert paramVars.size() + == programMethod.getParameterDeclarationCount(); + assert (resultVar == null) == (programMethod.sort() == null); + assert excVar != null; + assert atPreFunctions != null; + this.name = name; + this.displayName = displayName; + this.programMethod = programMethod; + this.modality = modality; + this.originalPre = pre; + this.originalPost = post; + this.originalModifies = modifies; + this.originalSelfVar = selfVar; + this.originalParamVars = paramVars; + this.originalResultVar = resultVar; + this.originalExcVar = excVar; + this.originalAtPreFunctions = new LinkedHashMap(); + this.originalAtPreFunctions.putAll(atPreFunctions); + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private Map /*Operator -> Operator*/ getReplaceMap( + ParsableVariable selfVar, + ListOfParsableVariable paramVars, + ParsableVariable resultVar, + ParsableVariable excVar, + /*inout*/ Map /*Operator (normal) + -> Function (atPre)*/ atPreFunctions, + Services services) { + Map result = new LinkedHashMap(); + + //self + if(selfVar != null) { + assert originalSelfVar.sort().equals(selfVar.sort()); + result.put(originalSelfVar, selfVar); + } + + //parameters + if(paramVars != null) { + assert originalParamVars.size() == paramVars.size(); + IteratorOfParsableVariable it1 = originalParamVars.iterator(); + IteratorOfParsableVariable it2 = paramVars.iterator(); + while(it1.hasNext()) { + ParsableVariable originalParamVar = it1.next(); + ParsableVariable paramVar = it2.next(); + assert originalParamVar.sort().equals(paramVar.sort()); + result.put(originalParamVar, paramVar); + } + } + + //result + if(resultVar != null) { + assert originalResultVar.sort().equals(resultVar.sort()); + result.put(originalResultVar, resultVar); + } + + //exception + if(excVar != null) { + assert originalExcVar.sort().equals(excVar.sort()); + result.put(originalExcVar, excVar); + } + + //atPre-functions + if(atPreFunctions != null) { + Iterator it = originalAtPreFunctions.entrySet().iterator(); + while(it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + Operator originalNormalOp = (Operator) entry.getKey(); + Function originalAtPreFunc = (Function) entry.getValue(); + Operator normalOp = (Operator) result.get(originalNormalOp); + if(normalOp == null) { + normalOp = originalNormalOp; + } + Function atPreFunc = (Function) atPreFunctions.get(normalOp); + if(atPreFunc == null) { + atPreFunc + = AtPreFactory.INSTANCE.createAtPreFunction(normalOp, + services); + atPreFunctions.put(normalOp, atPreFunc); + services.getNamespaces().functions().add(atPreFunc); + } + assert originalAtPreFunc.sort().equals(atPreFunc.sort()); + result.put(originalAtPreFunc, atPreFunc); + } + } + + return result; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public String getName() { + return name; + } + + + public String getDisplayName() { + return displayName; + } + + + public ProgramMethod getProgramMethod() { + return programMethod; + } + + + public Modality getModality() { + return modality; + } + + + public FormulaWithAxioms getPre(ParsableVariable selfVar, + ListOfParsableVariable paramVars, + Services services) { + assert (selfVar == null) == (originalSelfVar == null); + assert paramVars != null; + assert paramVars.size() == originalParamVars.size(); + assert services != null; + Map replaceMap = getReplaceMap(selfVar, + paramVars, + null, + null, + null, + services); + OpReplacer or = new OpReplacer(replaceMap); + return or.replace(originalPre); + } + + + public FormulaWithAxioms getPost(ParsableVariable selfVar, + ListOfParsableVariable paramVars, + ParsableVariable resultVar, + ParsableVariable excVar, + /*inout*/ Map /*Operator (normal) + -> Function (atPre)*/ atPreFunctions, + Services services) { + assert (selfVar == null) == (originalSelfVar == null); + assert paramVars != null; + assert paramVars.size() == originalParamVars.size(); + assert (resultVar == null) == (originalResultVar == null); + assert excVar != null; + assert atPreFunctions != null; + assert services != null; + Map replaceMap = getReplaceMap(selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions, + services); + OpReplacer or = new OpReplacer(replaceMap); + return or.replace(originalPost); + } + + + public SetOfLocationDescriptor getModifies(ParsableVariable selfVar, + ListOfParsableVariable paramVars, + Services services) { + assert (selfVar == null) == (originalSelfVar == null); + assert paramVars != null; + assert paramVars.size() == originalParamVars.size(); + assert services != null; + Map replaceMap = getReplaceMap(selfVar, + paramVars, + null, + null, + null, + services); + OpReplacer or = new OpReplacer(replaceMap); + return or.replace(originalModifies); + } + + + public String getHTMLText(Services services) { + return "pre " + + LogicPrinter.quickPrintTerm(originalPre.getFormula(), + services) + + "
post " + + LogicPrinter.quickPrintTerm(originalPost.getFormula(), + services) + + "
modifies " + + LogicPrinter.quickPrintLocationDescriptors(originalModifies, + services) + + "
termination " + + getModality() + + ""; + } + + + public String toString() { + return "pre: " + + originalPre + + "; post: " + + originalPost + + "; modifies: " + + originalModifies + + "; termination: " + + getModality(); + } + + +// mbender + public FormulaWithAxioms getOriginalPre() { + return originalPre; + } + + + public FormulaWithAxioms getOriginalPost() { + return originalPost; + } +} diff --git a/system/de/uka/ilkd/key/speclang/PositionedString.java b/system/de/uka/ilkd/key/speclang/PositionedString.java new file mode 100644 index 00000000000..d0c144b5b80 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/PositionedString.java @@ -0,0 +1,66 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang; + +import de.uka.ilkd.key.java.Position; + + +public class PositionedString { + + public final String text; + public final String fileName; + public final Position pos; + + + public PositionedString(String text, String fileName, Position pos) { + assert text != null; + if(fileName == null) { + fileName = "no file"; + } + if(pos == null) { + pos = Position.UNDEFINED; + } + this.text = text; + this.fileName = fileName; + this.pos = pos; + } + + + public PositionedString(String text, String fileName) { + this(text, null, null); + } + + + public PositionedString(String text) { + this(text, null); + } + + + public String toString() { + return text; + } + + + public boolean equals(Object o) { + if(!(o instanceof PositionedString)) { + return false; + } + PositionedString ps = (PositionedString) o; + return text.equals(ps.text) + && fileName.equals(ps.fileName) + && pos.equals(ps.pos); + } + + + public int hashCode() { + return text.hashCode() + fileName.hashCode() + pos.hashCode(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/SLEnvInput.java b/system/de/uka/ilkd/key/speclang/SLEnvInput.java new file mode 100644 index 00000000000..81280586bd3 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/SLEnvInput.java @@ -0,0 +1,140 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang; + +import java.util.Arrays; +import java.util.Comparator; + +import de.uka.ilkd.key.gui.configuration.ProofSettings; +import de.uka.ilkd.key.java.IteratorOfProgramElement; +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.statement.LoopStatement; +import de.uka.ilkd.key.java.visitor.JavaASTCollector; +import de.uka.ilkd.key.logic.op.IteratorOfProgramMethod; +import de.uka.ilkd.key.logic.op.ListOfProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.proof.init.AbstractEnvInput; +import de.uka.ilkd.key.proof.init.ModStrategy; +import de.uka.ilkd.key.proof.init.ProofInputException; +import de.uka.ilkd.key.proof.mgt.SpecificationRepository; +import de.uka.ilkd.key.speclang.LoopInvariant; +import de.uka.ilkd.key.speclang.jml.JMLSpecExtractor; +import de.uka.ilkd.key.speclang.ocl.OCLSpecExtractor; + + +/** + * EnvInput for standalone specification language front ends. + */ +public class SLEnvInput extends AbstractEnvInput { + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + private static String getLanguage() { + return ProofSettings.DEFAULT_SETTINGS.getGeneralSettings().useJML() + ? "JML" + : "OCL"; + } + + + public SLEnvInput(String javaPath) { + super(getLanguage() + " specifications", javaPath); + assert javaPath != null; + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private Object[] sortKJTs(Object[] kjts) { + Arrays.sort(kjts, new Comparator() { + public int compare(Object o1, Object o2) { + KeYJavaType kjt1 = (KeYJavaType)o1; + KeYJavaType kjt2 = (KeYJavaType)o2; + return kjt1.getFullName().compareTo(kjt2.getFullName()); + } + }); + + return kjts; + } + + + private void createSpecs(SpecExtractor specExtractor) + throws ProofInputException { + JavaInfo javaInfo + = initConfig.getServices().getJavaInfo(); + SpecificationRepository specRepos + = initConfig.getServices().getSpecificationRepository(); + + //sort types alphabetically (necessary for deterministic names) + Object[] kjts = sortKJTs(javaInfo.getAllKeYJavaTypes().toArray()); + + //create specifications for all types + for(int i = 0; i < kjts.length; i++) { + KeYJavaType kjt = (KeYJavaType) kjts[i]; + + //class invariants + specRepos.addClassInvariants( + specExtractor.extractClassInvariants(kjt)); + + //contracts, loop invariants + ListOfProgramMethod pms + = javaInfo.getAllProgramMethodsLocallyDeclared(kjt); + IteratorOfProgramMethod it2 = pms.iterator(); + while(it2.hasNext()) { + final ProgramMethod pm = it2.next(); + + //contracts + specRepos.addOperationContracts( + specExtractor.extractOperationContracts(pm)); + + //loop invariants + JavaASTCollector collector + = new JavaASTCollector(pm.getBody(), LoopStatement.class); + collector.start(); + IteratorOfProgramElement it3 = collector.getNodes().iterator(); + while(it3.hasNext()) { + LoopStatement loop = (LoopStatement) it3.next(); + LoopInvariant inv + = specExtractor.extractLoopInvariant(pm, loop); + if(inv != null) { + specRepos.setLoopInvariant(inv); + } + } + } + } + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public void read(ModStrategy mod) throws ProofInputException { + if(initConfig == null) { + throw new IllegalStateException("InitConfig not set."); + } + + String language = getLanguage(); + if(language.equals("JML")) { + createSpecs(new JMLSpecExtractor(initConfig.getServices())); + } else if(language.equals("OCL")) { + createSpecs(new OCLSpecExtractor(initConfig.getServices())); + } else { + assert false : "An unknown specification language is selected."; + } + } +} diff --git a/system/de/uka/ilkd/key/speclang/SLTranslationError.java b/system/de/uka/ilkd/key/speclang/SLTranslationError.java deleted file mode 100644 index 3317fb45cbf..00000000000 --- a/system/de/uka/ilkd/key/speclang/SLTranslationError.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.uka.ilkd.key.speclang; - -import de.uka.ilkd.key.proof.init.ProofInputException; - -public class SLTranslationError extends java.lang.Exception { - - private String msg = ""; - - private int line = -1; - private int col = -1; - - public SLTranslationError(String msg, int line, int col) { - this.msg = msg; - this.line = line; - this.col = col; - } - - /** - * returns a message describing the problem - */ - public String getMessage() { - return this.msg; - } - - /** - * returns the line number within the parsed specification - * @return - */ - public int getLine() { - return this.line; - } - - /** - * returns the column number within the parsed specification - * @return - */ - public int getColumn() { - return this.col; - } - -} diff --git a/system/de/uka/ilkd/key/speclang/SignatureVariablesFactory.java b/system/de/uka/ilkd/key/speclang/SignatureVariablesFactory.java new file mode 100644 index 00000000000..69bf89f1d57 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/SignatureVariablesFactory.java @@ -0,0 +1,143 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.NamespaceSet; +import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.logic.op.ListOfParsableVariable; +import de.uka.ilkd.key.logic.op.LocationVariable; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.logic.op.SLListOfParsableVariable; + + +/** + * Convenience class for creating variables to represent the + * elements of an operation's signature. + * (Creating such variables is necessary in a number of situations, + * such as when creating or applying an operation contract, or when + * creating a proof obligation) + */ +public class SignatureVariablesFactory { + + public static final SignatureVariablesFactory INSTANCE + = new SignatureVariablesFactory(); + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + private SignatureVariablesFactory() { + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + /** + * Returns an available name constructed by affixing a counter to the passed + * base name. + */ + private ProgramElementName getNewName(Services services, + String baseName, + boolean makeNameUnique) { + if(!makeNameUnique) { + return new ProgramElementName(baseName); + } + + NamespaceSet namespaces = services.getNamespaces(); + + int i = 0; + ProgramElementName name; + do { + name = new ProgramElementName(baseName + "_" + i++); + } while(namespaces.lookup(name) != null); + + return name; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + /** + * Creates a program variable for "self". + */ + public ProgramVariable createSelfVar(Services services, + ProgramMethod pm, + boolean makeNameUnique) { + if(pm.isStatic()) { + return null; + } else { + return new LocationVariable(getNewName(services, + "self", + makeNameUnique), + pm.getContainerType()); + } + } + + + /** + * Creates program variables for the parameters. + */ + public ListOfParsableVariable createParamVars(Services services, + ProgramMethod pm, + boolean makeNamesUnique) { + ListOfParsableVariable result = SLListOfParsableVariable.EMPTY_LIST; + for(int i = 0; i < pm.getParameterDeclarationCount(); i++) { + KeYJavaType parType = pm.getParameterType(i); + String parName = pm.getParameterDeclarationAt(i) + .getVariableSpecification() + .getName(); + ProgramElementName parPEN = getNewName(services, + parName, + makeNamesUnique); + result = result.append(new LocationVariable(parPEN, parType)); + } + return result; + } + + + /** + * Creates a program variable for the result. + */ + public ProgramVariable createResultVar(Services services, + ProgramMethod pm, + boolean makeNameUnique) { + return (pm.getKeYJavaType() == null + ? null + : new LocationVariable(getNewName(services, + "result", + makeNameUnique), + pm.getKeYJavaType())); + } + + + /** + * Creates a program variable for the thrown exception. + */ + public ProgramVariable createExcVar(Services services, + ProgramMethod pm, + boolean makeNameUnique) { + return new LocationVariable(getNewName(services, "exc", makeNameUnique), + services.getJavaInfo().getTypeByClassName( + "java.lang.Exception")); + + } +} + \ No newline at end of file diff --git a/system/de/uka/ilkd/key/speclang/SpecExtractor.java b/system/de/uka/ilkd/key/speclang/SpecExtractor.java new file mode 100644 index 00000000000..5a3102e0ddf --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/SpecExtractor.java @@ -0,0 +1,41 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang; + +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.statement.LoopStatement; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + +/** + * Extracts specifications from comments. + */ +public interface SpecExtractor { + + /** + * Returns the operation contracts for the passed operation. + */ + public SetOfOperationContract extractOperationContracts(ProgramMethod pm) + throws SLTranslationException; + + /** + * Returns the class invariants for the passed type. + */ + public SetOfClassInvariant extractClassInvariants(KeYJavaType kjt) + throws SLTranslationException; + + /** + * Returns the loop invariant for the passed loop (if any). + */ + public LoopInvariant extractLoopInvariant(ProgramMethod pm, + LoopStatement loop) + throws SLTranslationException; +} diff --git a/system/de/uka/ilkd/key/speclang/TranslatedClassInvariant.java b/system/de/uka/ilkd/key/speclang/TranslatedClassInvariant.java deleted file mode 100644 index 9f9b177bd41..00000000000 --- a/system/de/uka/ilkd/key/speclang/TranslatedClassInvariant.java +++ /dev/null @@ -1,58 +0,0 @@ -package de.uka.ilkd.key.speclang; - -import java.io.IOException; - -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.op.ParsableVariable; -import de.uka.ilkd.key.pp.LogicPrinter; -import de.uka.ilkd.key.pp.NotationInfo; -import de.uka.ilkd.key.pp.ProgramPrinter; - -/** - * @deprecated - */ -public class TranslatedClassInvariant extends AbstractClassInvariant { - - private final Term translation; - private final Services services; - - /** - * Creates a class invariant. - * @param modelClass the invariant's model class - * @param inv the invariant in some specification language - * @param translator a suitable translator for expressions of this - * specification language - */ - public TranslatedClassInvariant(ModelClass modelClass, - Term translation, - Services services) { - super(modelClass); - this.translation = translation; - this.services = services; - } - - - public FormulaWithAxioms getInv(Services services) { - return new FormulaWithAxioms(translation); - } - - public FormulaWithAxioms getOpenInv(ParsableVariable selfVar, - Services services) { - //not implemented - assert false; - return null; - } - - - public String toString() { - LogicPrinter p = new LogicPrinter(new ProgramPrinter(), NotationInfo.createInstance(), services); - try { - p.printTerm(translation); - } catch (IOException ioe) { - return translation.toString(); - } - return p.result().toString(); - } -} diff --git a/system/de/uka/ilkd/key/speclang/dl/translation/DLSpecFactory.java b/system/de/uka/ilkd/key/speclang/dl/translation/DLSpecFactory.java new file mode 100644 index 00000000000..1b82439b272 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/dl/translation/DLSpecFactory.java @@ -0,0 +1,279 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.dl.translation; + +import java.util.LinkedHashMap; +import java.util.Map; + +import de.uka.ilkd.key.java.ArrayOfExpression; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.SourceElement; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.statement.CatchAllStatement; +import de.uka.ilkd.key.java.statement.MethodBodyStatement; +import de.uka.ilkd.key.logic.BasicLocationDescriptor; +import de.uka.ilkd.key.logic.IteratorOfLocationDescriptor; +import de.uka.ilkd.key.logic.LocationDescriptor; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.op.AttributeOp; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.logic.op.ListOfParsableVariable; +import de.uka.ilkd.key.logic.op.LocationVariable; +import de.uka.ilkd.key.logic.op.Modality; +import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.Operator; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.logic.op.SLListOfParsableVariable; +import de.uka.ilkd.key.proof.init.ProofInputException; +import de.uka.ilkd.key.speclang.FormulaWithAxioms; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.OperationContractImpl; + + +/** + * A factory for creating class invariants and operation contracts + * from DL specifications. + */ +public class DLSpecFactory { + + private static final TermBuilder TB = TermBuilder.DF; + private final Services services; + + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public DLSpecFactory(Services services) { + assert services != null; + this.services = services; + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private MethodBodyStatement extractMBS(Term fma) { + SourceElement se = fma.sub(1).javaBlock().program().getFirstElement(); + if(se instanceof CatchAllStatement) { + CatchAllStatement cas = (CatchAllStatement) se; + SourceElement body = cas.getBody().getFirstElement(); + return (MethodBodyStatement) body; + } else { + return (MethodBodyStatement) se; + } + } + + + private ProgramMethod extractProgramMethod(MethodBodyStatement mbs) { + return mbs.getProgramMethod(services); + } + + + private Modality extractModality(Term fma) { + return (Modality) fma.sub(1).op(); + } + + + private ParsableVariable extractSelfVar(MethodBodyStatement mbs) { + return mbs.isStatic(services) + ? null + : (ProgramVariable) mbs.getDesignatedContext(); + } + + + private ListOfParsableVariable extractParamVars(MethodBodyStatement mbs) { + ArrayOfExpression args = mbs.getArguments(); + + ListOfParsableVariable result = SLListOfParsableVariable.EMPTY_LIST; + for(int i = args.size() - 1; i >= 0; i--) { + result = result.prepend((ProgramVariable) args.getExpression(i)); + } + + return result; + } + + + private ParsableVariable extractResultVar(MethodBodyStatement mbs) { + return (ProgramVariable) mbs.getResultVariable(); + } + + + private ParsableVariable extractExcVar(Term fma) { + SourceElement se = fma.sub(1).javaBlock().program().getFirstElement(); + if(se instanceof CatchAllStatement) { + CatchAllStatement cas = (CatchAllStatement) se; + return (ProgramVariable) cas.getParameterDeclaration() + .getVariableSpecification() + .getFirstElement(); + } else { + return null; + } + } + + + private FormulaWithAxioms extractPre(Term fma) { + return new FormulaWithAxioms(fma.sub(0)); + } + + + private FormulaWithAxioms extractPost(Term fma) { + return new FormulaWithAxioms(fma.sub(1).sub(0)); + } + + + private Map /*Operator (normal) -> Function (atPre)*/ + extractAtPreFunctions(Term term) { + Map result = new LinkedHashMap(); + + //is the operator of the passed term an atPre function? + Operator op = term.op(); + String nameString = op.name().toString(); + if(nameString.endsWith("@pre")) { + assert op instanceof Function; + + //retrieve operator corresponding to the atPre function + Name normalName + = new Name(nameString.substring(0, nameString.length() - 4)); + Operator normalOp = (Operator) services.getNamespaces() + .lookup(normalName); + if(normalOp == null) { + ProgramVariable attrPV + = services.getJavaInfo() + .getAttribute(normalName.toString()); + assert attrPV != null; + normalOp = AttributeOp.getAttributeOp(attrPV); + } + assert normalOp != null; + + //add pair to map + result.put(normalOp, op); + } + + //recurse to subterms + for(int i = 0; i < term.arity(); i++) { + Map map = extractAtPreFunctions(term.sub(i)); + result.putAll(map); + } + + return result; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + /** + * Creates an operation contract from an implication formula of the form + * pre -> \ post and a modifies clause (which is how + * DL contracts are currently represented in .key files). + */ + public OperationContract createDLOperationContract( + String name, + String displayName, + Term fma, + SetOfLocationDescriptor modifies) + throws ProofInputException { + assert name != null; + if(displayName == null) { + displayName = name; + } + assert fma != null; + assert modifies != null; + + MethodBodyStatement mbs = extractMBS(fma); + ProgramMethod pm = extractProgramMethod(mbs); + Modality modality = extractModality(fma); + FormulaWithAxioms pre = extractPre(fma); + FormulaWithAxioms post = extractPost(fma); + ParsableVariable selfVar = extractSelfVar(mbs); + ListOfParsableVariable paramVars = extractParamVars(mbs); + ParsableVariable resultVar = extractResultVar(mbs); + ParsableVariable excVar = extractExcVar(fma); + Map atPreFunctions = extractAtPreFunctions(post.getFormula()); + + //atPre-functions may not occur in precondition + Map forbiddenAtPreFunctions = extractAtPreFunctions(pre.getFormula()); + if(!forbiddenAtPreFunctions.isEmpty()) { + throw new ProofInputException( + "@pre-function not allowed in precondition: " + + forbiddenAtPreFunctions.values().iterator().next()); + } + + //atPre-functions may not occur in modifier set + IteratorOfLocationDescriptor it = modifies.iterator(); + while(it.hasNext()) { + LocationDescriptor loc = it.next(); + if(loc instanceof BasicLocationDescriptor) { + BasicLocationDescriptor bloc = (BasicLocationDescriptor) loc; + Term formula = bloc.getFormula(); + Term locTerm = bloc.getLocTerm(); + forbiddenAtPreFunctions = new LinkedHashMap(); + forbiddenAtPreFunctions.putAll(extractAtPreFunctions(formula)); + forbiddenAtPreFunctions.putAll(extractAtPreFunctions(locTerm)); + if(!forbiddenAtPreFunctions.isEmpty()) { + throw new ProofInputException( + "@pre-function not allowed in modifier set: " + + forbiddenAtPreFunctions.values().iterator().next()); + } + } + } + + //result variable may be omitted + if(resultVar == null && pm.getKeYJavaType() != null) { + ProgramElementName resultPEN = new ProgramElementName("res"); + resultVar = new LocationVariable(resultPEN, pm.getKeYJavaType()); + } + + //exception variable may be omitted + if(excVar == null) { + KeYJavaType excType + = services.getJavaInfo() + .getTypeByClassName("java.lang.Exception"); + ProgramElementName excPEN = new ProgramElementName("exc"); + excVar = new LocationVariable(excPEN, excType); + Term excNullTerm = TB.equals(TB.var(excVar), TB.NULL(services)); + if(modality == Op.DIA) { + post = post.conjoin(new FormulaWithAxioms(excNullTerm)); + } else if(modality == Op.BOX) { + post = post.disjoin(new FormulaWithAxioms(TB.not(excNullTerm))); + } else { + throw new ProofInputException( + "unknown semantics for exceptional termination: " + + modality + "; please use #catchAll block"); + } + } + + return new OperationContractImpl(name, + displayName, + pm, + modality, + pre, + post, + modifies, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/JMLClassInvariant.java b/system/de/uka/ilkd/key/speclang/jml/JMLClassInvariant.java deleted file mode 100644 index 39855988bc4..00000000000 --- a/system/de/uka/ilkd/key/speclang/jml/JMLClassInvariant.java +++ /dev/null @@ -1,69 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.speclang.jml; - -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.Name; -import de.uka.ilkd.key.logic.op.LogicVariable; -import de.uka.ilkd.key.logic.op.ParsableVariable; -import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.speclang.AbstractClassInvariant; -import de.uka.ilkd.key.speclang.FormulaWithAxioms; - - -public class JMLClassInvariant extends AbstractClassInvariant { - private final String originalInv; - - - public JMLClassInvariant(ModelClass modelClass, - String originalInv) { - super(modelClass); - this.originalInv = originalInv; - } - - - public FormulaWithAxioms getInv(Services services) { - Sort sort = getKJT(services).getSort(); - String name = sort.name().toString().substring(0, 0).toLowerCase(); - LogicVariable selfVar = new LogicVariable(new Name(name), sort); - - FormulaWithAxioms inv - = services.getJMLTranslator().translateInv(originalInv, selfVar); - - return new FormulaWithAxioms(tb.all(selfVar, inv.getFormula()), - inv.getAxioms()); - } - - - public FormulaWithAxioms getOpenInv(ParsableVariable selfVar, - Services services) { - return services.getJMLTranslator().translateInv(originalInv, selfVar); - } - - - public String toString() { - return originalInv; - } - - - public boolean equals(Object o) { - if(!(o instanceof JMLClassInvariant)) { - return false; - } - return originalInv.equals(((JMLClassInvariant)o).originalInv); - } - - - public int hashCode() { - return originalInv.hashCode(); - } -} diff --git a/system/de/uka/ilkd/key/speclang/jml/JMLInfoExtractor.java b/system/de/uka/ilkd/key/speclang/jml/JMLInfoExtractor.java new file mode 100644 index 00000000000..4ec0b64a1af --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/JMLInfoExtractor.java @@ -0,0 +1,235 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml; + +import de.uka.ilkd.key.java.Comment; +import de.uka.ilkd.key.java.IteratorOfComment; +import de.uka.ilkd.key.java.ListOfComment; +import de.uka.ilkd.key.java.SLListOfComment; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.declaration.ArrayOfFieldSpecification; +import de.uka.ilkd.key.java.declaration.ArrayOfMemberDeclaration; +import de.uka.ilkd.key.java.declaration.ArrayOfModifier; +import de.uka.ilkd.key.java.declaration.FieldDeclaration; +import de.uka.ilkd.key.java.declaration.MethodDeclaration; +import de.uka.ilkd.key.java.declaration.ParameterDeclaration; +import de.uka.ilkd.key.java.declaration.TypeDeclaration; +import de.uka.ilkd.key.logic.op.ProgramMethod; + +class JMLInfoExtractor { + + // Information about Fields... + + /** + * Returns true, if containingClass is a reference Type and has a field + * declaration with name fieldName, which is explicitly or implicitly + * declared "nullable" + */ + public static boolean isNullable(String fieldName, + KeYJavaType containingClass) { + + if (!(containingClass.getJavaType() instanceof TypeDeclaration)) { + return false; + } + + TypeDeclaration td = (TypeDeclaration) containingClass.getJavaType(); + ArrayOfMemberDeclaration md = td.getMembers(); + FieldDeclaration fd = null; + int position = 0; + + for (int i = 0; i < md.size(); i++) { + if (md.getMemberDeclaration(i) instanceof FieldDeclaration) { + FieldDeclaration tmp = (FieldDeclaration) md + .getMemberDeclaration(i); + ArrayOfFieldSpecification aofs = tmp.getFieldSpecifications(); + for (int j = 0; j < aofs.size(); j++) { + if (aofs.getFieldSpecification(j).getProgramName().equals( + fieldName)) { + fd = tmp; + position = j; + } + } + } + } + + if (fd == null) { + // Field not found + return false; + } + + ListOfComment comments = SLListOfComment.EMPTY_LIST; + + comments = comments.prepend(fd.getComments()); + comments = comments.prepend(fd.getTypeReference().getComments()); + comments = comments.prepend(fd.getFieldSpecifications() + .getFieldSpecification(position).getComments()); + ArrayOfModifier mods = fd.getModifiers(); + for (int i = 0; i < mods.size(); i++) { + comments = comments.prepend(mods.getModifier(i).getComments()); + } + + boolean non_null = false; + boolean nullable = false; + + for (IteratorOfComment it = comments.iterator(); it.hasNext();) { + Comment c = it.next(); + if (checkFor("non_null", c.getText())) + non_null = true; + if (checkFor("nullable", c.getText())) + nullable = true; + } + + if (!non_null && !nullable) + return isNullableByDefault(containingClass); + + if (nullable) + return true; + else + return false; + } + + + // Information about Methods... + + /** + * Returns true, if the pos-th parameter of the given method is + * declared "nullable" (implicit or explicit). + */ + public static boolean parameterIsNullable(ProgramMethod pm, int pos) { + + MethodDeclaration md = pm.getMethodDeclaration(); + ParameterDeclaration pd = md.getParameterDeclarationAt(pos); + + ListOfComment comments = SLListOfComment.EMPTY_LIST; + comments = comments.prepend(pd.getComments()); + comments = comments.prepend(pd.getTypeReference().getComments()); + comments = comments.prepend(pd.getVariableSpecification().getComments()); + for (int j=0; j < pd.getModifiers().size(); j++) { + comments = comments.prepend(pd.getModifiers().getModifier(j).getComments()); + } + for (IteratorOfComment it = comments.iterator(); it.hasNext(); ) { + Comment c = it.next(); + if (checkFor("nullable",c.getText())) + return true; + else if (checkFor("non_null",c.getText())) { + return false; + } + } + + return isNullableByDefault(pm.getContainerType()); + } + + + public static boolean resultIsNullable(ProgramMethod pm) { + MethodDeclaration md = pm.getMethodDeclaration(); + + ListOfComment comments = SLListOfComment.EMPTY_LIST; + ArrayOfModifier mods = md.getModifiers(); + for (int i=0; i < mods.size(); i++) { + comments = comments.prepend(mods.getModifier(i).getComments()); + } + if (md.getTypeReference() != null) { + comments = comments.prepend(md.getTypeReference().getComments()); + } + + for(IteratorOfComment it = comments.iterator(); it.hasNext(); ) { + Comment c = it.next(); + if(checkFor("nullable", c.getText())) { + return true; + } else if(checkFor("non_null", c.getText())) { + return false; + } + } + + return isNullableByDefault(pm.getContainerType()); + } + + + /** + * Returns true, if the JML modifier "pure" is attached to the given method. + */ + public static boolean isPure(ProgramMethod pm) { + ListOfComment coms = SLListOfComment.EMPTY_LIST; + MethodDeclaration method = pm.getMethodDeclaration(); + + // Either "pure" is attached to a modifier .... + ArrayOfModifier mods = method.getModifiers(); + for (int i=0; i < mods.size(); i++) { + coms = coms.prepend(mods.getModifier(i).getComments()); + } + // .... or to the return type + if (method.getTypeReference() != null) { + coms = coms.prepend(method.getTypeReference().getComments()); + } + + for (IteratorOfComment it = coms.iterator(); it.hasNext(); ) { + if (checkFor("pure", it.next().getText())) + return true; + } + + return false; + } + + + // Information about Types + + /** + * Returns true if the given type is specified as nullable, i.e. all fields + * and method parameters are by default specified "nullable" + * + * If t is not a reference type, false is returned. + */ + public static boolean isNullableByDefault(KeYJavaType t) { + + if (!(t.getJavaType() instanceof TypeDeclaration)) { + return false; + } + + TypeDeclaration td = (TypeDeclaration) t.getJavaType(); + + ListOfComment coms = SLListOfComment.EMPTY_LIST; + coms = coms.prepend(td.getComments()); + coms = coms.prepend(td.getProgramElementName().getComments()); + ArrayOfModifier mods = td.getModifiers(); + for (int i=0; i < mods.size(); i++) { + coms = coms.prepend(mods.getModifier(i).getComments()); + } + + for (IteratorOfComment it = coms.iterator(); it.hasNext(); ) { + if (checkFor("nullable_by_default", it.next().getText())) + return true; + } + + return false; + } + + + //---------------- Helper methods ----------------------// + + private static boolean checkFor(String key, String comment) { + if (comment.length() < key.length() + 3 ) + return false; + + String c; + // Check if it is a JML comment + if (comment.startsWith("/*@")) + c = comment.substring(3); + else + return false; + + // Check for the key + if (c.trim().indexOf(key) >= 0) + return true; + + return false; + } + +} diff --git a/system/de/uka/ilkd/key/speclang/jml/JMLOperationContract.java b/system/de/uka/ilkd/key/speclang/jml/JMLOperationContract.java deleted file mode 100644 index 736b2785b38..00000000000 --- a/system/de/uka/ilkd/key/speclang/jml/JMLOperationContract.java +++ /dev/null @@ -1,124 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.speclang.jml; - -import java.util.Map; - -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.SetOfLocationDescriptor; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.op.ListOfParsableVariable; -import de.uka.ilkd.key.logic.op.LogicVariable; -import de.uka.ilkd.key.logic.op.Modality; -import de.uka.ilkd.key.logic.op.ParsableVariable; -import de.uka.ilkd.key.logic.op.ProgramVariable; -import de.uka.ilkd.key.speclang.AbstractOperationContract; -import de.uka.ilkd.key.speclang.FormulaWithAxioms; - - -public class JMLOperationContract extends AbstractOperationContract { - private final String originalDiverges; - private final boolean terminationCase; - private final String originalRequires; - private final String originalEnsures; - private final String originalSignals; - private final String originalAssignable; - - - public JMLOperationContract(ModelMethod modelMethod, - String originalDiverges, - boolean terminationCase, - String originalRequires, - String originalEnsures, - String originalSignals, - String originalAssignable) { - super(modelMethod, terminationCase ? Modality.DIA : Modality.BOX); - this.originalDiverges = originalDiverges; - this.terminationCase = terminationCase; - this.originalRequires = originalRequires; - this.originalEnsures = originalEnsures; - this.originalSignals = originalSignals; - this.originalAssignable = originalAssignable; - } - - - public FormulaWithAxioms getPre(ParsableVariable selfVar, - ListOfParsableVariable paramVars, - Services services) { - JMLTranslator translator = services.getJMLTranslator(); - - FormulaWithAxioms required - = translator.translateRequires(originalRequires, - selfVar, - paramVars); - Term resultFormula = required.getFormula(); - Map resultAxioms = required.getAxioms(); - resultAxioms.putAll(required.getAxioms()); - - if(terminationCase) { - FormulaWithAxioms diverges - = translator.translateDiverges(originalDiverges, - selfVar, - paramVars); - resultFormula = tb.and(resultFormula, tb.not(diverges.getFormula())); - resultAxioms.putAll(diverges.getAxioms()); - } - - return new FormulaWithAxioms(resultFormula, resultAxioms); - } - - - public FormulaWithAxioms getPost(ParsableVariable selfVar, - ListOfParsableVariable paramVars, - ParsableVariable resultVar, - ParsableVariable excVar, - Services services) { - JMLTranslator translator = services.getJMLTranslator(); - - FormulaWithAxioms ensures - = translator.translateEnsures(originalEnsures, - selfVar, - paramVars, - resultVar, - excVar); - FormulaWithAxioms signals - = translator.translateSignals(originalSignals, - selfVar, - paramVars, - resultVar, - excVar); - - Term excVarTerm; - if(excVar instanceof ProgramVariable) { - excVarTerm = tb.var((ProgramVariable) excVar); - } else { - excVarTerm = tb.var((LogicVariable) excVar); - } - Term excNullTerm = tb.equals(excVarTerm, tb.NULL(services)); - - Term resultFormula = tb.ife(excNullTerm, ensures.getFormula(), signals.getFormula()); - Map resultAxioms = ensures.getAxioms(); - resultAxioms.putAll(signals.getAxioms()); - - return new FormulaWithAxioms(resultFormula, resultAxioms); - } - - - public SetOfLocationDescriptor getModifies(ParsableVariable selfVar, - ListOfParsableVariable paramVars, - Services services) { - return services.getJMLTranslator().translateAssignable( - originalAssignable, - selfVar, - paramVars); - } -} diff --git a/system/de/uka/ilkd/key/speclang/jml/JMLSpecExtractor.java b/system/de/uka/ilkd/key/speclang/jml/JMLSpecExtractor.java new file mode 100644 index 00000000000..c865d234dee --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/JMLSpecExtractor.java @@ -0,0 +1,380 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml; + +import de.uka.ilkd.key.collection.SLListOfString; +import de.uka.ilkd.key.java.Comment; +import de.uka.ilkd.key.java.Position; +import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.Field; +import de.uka.ilkd.key.java.abstraction.IteratorOfField; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.abstraction.ListOfField; +import de.uka.ilkd.key.java.abstraction.Type; +import de.uka.ilkd.key.java.declaration.FieldDeclaration; +import de.uka.ilkd.key.java.declaration.TypeDeclaration; +import de.uka.ilkd.key.java.statement.LoopStatement; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.op.NonRigidHeapDependentFunction; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.sort.ArrayOfSort; +import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.speclang.ClassInvariant; +import de.uka.ilkd.key.speclang.LoopInvariant; +import de.uka.ilkd.key.speclang.PositionedString; +import de.uka.ilkd.key.speclang.SetAsListOfClassInvariant; +import de.uka.ilkd.key.speclang.SetAsListOfOperationContract; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; +import de.uka.ilkd.key.speclang.SetOfOperationContract; +import de.uka.ilkd.key.speclang.SpecExtractor; +import de.uka.ilkd.key.speclang.jml.pretranslation.Behavior; +import de.uka.ilkd.key.speclang.jml.pretranslation.IteratorOfTextualJMLConstruct; +import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLClassInv; +import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLConstruct; +import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLFieldDecl; +import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLLoopSpec; +import de.uka.ilkd.key.speclang.jml.pretranslation.KeYJMLPreParser; +import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLMethodDecl; +import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLSpecCase; +import de.uka.ilkd.key.speclang.jml.pretranslation.ListOfTextualJMLConstruct; +import de.uka.ilkd.key.speclang.jml.translation.JMLSpecFactory; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + + +/** + * Extracts JML class invariants and operation contracts from JML comments. + * This is the public interface to the jml package. + */ +public class JMLSpecExtractor implements SpecExtractor { + + private final Services services; + private final JMLSpecFactory jsf; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public JMLSpecExtractor(Services services) { + this.services = services; + this.jsf = new JMLSpecFactory(services); + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + /** + * Concatenates the passed comments in a position-preserving way. + * (see also JMLTransformer::concatenate(), which does the same thing + * for Recoder ASTs) + */ + private String concatenate(Comment[] comments) { + if(comments.length == 0) { + return ""; + } + StringBuffer sb = new StringBuffer(comments[0].getText()); + + for(int i = 1; i < comments.length; i++) { + Position relativePos = comments[i].getRelativePosition(); + for(int j = 0; j < relativePos.getLine(); j++) { + sb.append("\n"); + } + for(int j = 0; j < relativePos.getColumn(); j++) { + sb.append(" "); + } + sb.append(comments[i].getText()); + } + + return sb.toString(); + } + + + private int getIndexOfMethodDecl(ProgramMethod pm, + TextualJMLConstruct[] constructsArray) { + for(int i = 0; i < constructsArray.length; i++) { + if(constructsArray[i] instanceof TextualJMLMethodDecl) { + TextualJMLMethodDecl methodDecl + = (TextualJMLMethodDecl) constructsArray[i]; + if(methodDecl.getMethodName().equals(pm.getName())) { + return i; + } + } + } + return -1; + } + + + private void transformFieldDecl(TextualJMLFieldDecl decl, + KeYJavaType classKjt) + throws SLTranslationException { + if(!decl.getMods().contains("model")) { + return; + } + + String[] splittedDecl = decl.getDecl().text.split(" "); + if(splittedDecl.length != 2) { + throw new SLTranslationException( + "Unexpected structure of model field declaration!", + decl.getDecl().fileName, + decl.getDecl().pos); + } + String typeName = splittedDecl[0]; + String fieldName = splittedDecl[1].substring(0, + splittedDecl[1].length() + - 1); + + Sort sort = services.getJavaInfo().getTypeByName(typeName).getSort(); + ArrayOfSort argSorts = decl.getMods().contains("static") + ? new ArrayOfSort() + : new ArrayOfSort(classKjt.getSort()); + + NonRigidHeapDependentFunction f + = new NonRigidHeapDependentFunction(new Name(fieldName), + sort, + argSorts); + services.getNamespaces().functions().add(f); + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public SetOfClassInvariant extractClassInvariants(KeYJavaType kjt) + throws SLTranslationException { + SetOfClassInvariant result = SetAsListOfClassInvariant.EMPTY_SET; + + //primitive types have no class invariants + if(!(kjt.getJavaType() instanceof TypeDeclaration)) { + return result; + } + + //get type declaration, file name + TypeDeclaration td = (TypeDeclaration) kjt.getJavaType(); + String fileName = td.getPositionInfo().getFileName(); + + //abort if library class (TODO: delete this) + if(td.isLibraryClass()) { + return result; + } + + //add invariants for non_null fields. + ListOfField fields = td.getAllFields(services); + for (IteratorOfField it = fields.iterator(); it.hasNext(); ) { + Field field = it.next(); + String fieldName = field.getProgramName(); + // add invariant only for fields of reference types + // and not for implicit fields. + // [TODO] is there a better way to check this? + if (services.getTypeConverter().isReferenceType(field.getType()) + && !fieldName.startsWith("<")) { + if (!JMLInfoExtractor.isNullable(fieldName, kjt)) { + PositionedString ps + = new PositionedString(fieldName + " != null", + fileName); + result = result.add(jsf.createJMLClassInvariant(kjt, ps)); + } + } + } + + //iterate over all children + for(int i = 0, n = td.getChildCount(); i < n; i++) { + ProgramElement child = td.getChildAt(i); + Comment[] comments = child.getComments(); + if(comments.length == 0) { + continue; + } + + //skip model and ghost elements + //(their comments are duplicates of other comments) + if((child instanceof FieldDeclaration + && ((FieldDeclaration) child).isGhost()) + || (child instanceof ProgramMethod + && ((ProgramMethod) child).isModel())) { + continue; + } + + //concatenate comments, determine position + String concatenatedComment = concatenate(comments); + Position pos = comments[0].getStartPosition(); + + //call preparser + KeYJMLPreParser preParser + = new KeYJMLPreParser(concatenatedComment, fileName, pos); + ListOfTextualJMLConstruct constructs + = preParser.parseClasslevelComment(); + + //create class invs out of textual constructs, add them to result + for(IteratorOfTextualJMLConstruct it = constructs.iterator(); + it.hasNext(); ) { + TextualJMLConstruct c = it.next(); + if(c instanceof TextualJMLClassInv) { + TextualJMLClassInv textualInv = (TextualJMLClassInv) c; + ClassInvariant inv + = jsf.createJMLClassInvariant(kjt, textualInv); + result = result.add(inv); + } else if(c instanceof TextualJMLFieldDecl) { + transformFieldDecl((TextualJMLFieldDecl)c, kjt); + } + } + } + + return result; + } + + + public SetOfOperationContract extractOperationContracts(ProgramMethod pm) + throws SLTranslationException { + SetOfOperationContract result = SetAsListOfOperationContract.EMPTY_SET; + + //get type declaration, file name + TypeDeclaration td + = (TypeDeclaration) pm.getContainerType().getJavaType(); + String fileName = td.getPositionInfo().getFileName(); + + //abort if library class (TODO: delete this) + if(td.isLibraryClass()) { + return result; + } + + //determine purity + final boolean isPure = JMLInfoExtractor.isPure(pm); + + //get comments + Comment[] comments = pm.getComments(); + if(comments.length == 0) { + return result; + } + + //concatenate comments, determine position + String concatenatedComment = concatenate(comments); + Position pos = comments[0].getStartPosition(); + + //call preparser + KeYJMLPreParser preParser + = new KeYJMLPreParser(concatenatedComment, fileName, pos); + ListOfTextualJMLConstruct constructs + = preParser.parseClasslevelComment(); + + //if pure, add default contract + if(isPure) { + TextualJMLSpecCase sc + = new TextualJMLSpecCase(SLListOfString.EMPTY_LIST, + Behavior.NONE); + constructs = constructs.append(sc); + } + + //create JML contracts out of constructs, add them to result + TextualJMLConstruct[] constructsArray = constructs.toArray(); + int startPos; + if(pm.isModel()) { + startPos = getIndexOfMethodDecl(pm, constructsArray) - 1; + } else { + startPos = constructsArray.length - 1; + } + for(int i = startPos; + i >= 0 && constructsArray[i] instanceof TextualJMLSpecCase; + i--) { + TextualJMLSpecCase specCase + = (TextualJMLSpecCase) constructsArray[i]; + + if (isPure) { + specCase.addDiverges(new PositionedString("false")); + if (!pm.isConstructor()) { + specCase.addAssignable(new PositionedString("\\nothing")); + } else { + specCase.addAssignable(new PositionedString("this.*")); + } + } + + //add non-null preconditions + for (int j = 0, n = pm.getParameterDeclarationCount(); j < n; j++) { + Type t = pm.getParameterDeclarationAt(j). + getTypeReference(). + getKeYJavaType(); + boolean isReferenceType = services.getTypeConverter(). + isReferenceType(t); + // no additional precondition for primitive types! + if (isReferenceType + && !JMLInfoExtractor.parameterIsNullable(pm, j)) { + String param_name = pm. + getParameterDeclarationAt(j). + getVariableSpecification(). + getName(); + String nonNull = param_name + " != null"; + specCase.addRequires(new PositionedString(nonNull)); + } + } + + //add non-null postcondition + KeYJavaType resultType = pm.getKeYJavaType(); + if(resultType != null + && services.getTypeConverter().isReferenceType(resultType) + && !JMLInfoExtractor.resultIsNullable(pm) + && specCase.getBehavior() != Behavior.EXCEPTIONAL_BEHAVIOR) { + String nonNull = "\\result " + " != null"; + specCase.addEnsures(new PositionedString(nonNull)); + } + + SetOfOperationContract contracts + = jsf.createJMLOperationContractsAndInherit(pm, specCase); + result = result.union(contracts); + } + + return result; + } + + + + public LoopInvariant extractLoopInvariant(ProgramMethod pm, + LoopStatement loop) + throws SLTranslationException { + LoopInvariant result = null; + + //get type declaration, file name + TypeDeclaration td + = (TypeDeclaration) pm.getContainerType().getJavaType(); + String fileName = td.getPositionInfo().getFileName(); + + //get comments + Comment[] comments = loop.getComments(); + if(comments.length == 0) { + return result; + } + + //concatenate comments, determine position + String concatenatedComment = concatenate(comments); + Position pos = comments[0].getStartPosition(); + + //call preparser + KeYJMLPreParser preParser + = new KeYJMLPreParser(concatenatedComment, fileName, pos); + ListOfTextualJMLConstruct constructs + = preParser.parseMethodlevelComment(); + + //create JML loop invariant out of last construct + if(constructs.size() == 0) { + return result; + } + TextualJMLConstruct c = constructs.take(constructs.size() - 1).head(); + if(c instanceof TextualJMLLoopSpec) { + TextualJMLLoopSpec textualLoopSpec = (TextualJMLLoopSpec) c; + result = jsf.createJMLLoopInvariant(pm, loop, textualLoopSpec); + } + + return result; + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/JMLTranslator.java b/system/de/uka/ilkd/key/speclang/jml/JMLTranslator.java deleted file mode 100644 index 65dfecbfdc9..00000000000 --- a/system/de/uka/ilkd/key/speclang/jml/JMLTranslator.java +++ /dev/null @@ -1,75 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.speclang.jml; - -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.SetOfLocationDescriptor; -import de.uka.ilkd.key.logic.op.ListOfParsableVariable; -import de.uka.ilkd.key.logic.op.ParsableVariable; -import de.uka.ilkd.key.speclang.FormulaWithAxioms; - - -/** - * Translates JML expressions to DL. - */ -public class JMLTranslator { - private final Services services; - - - public JMLTranslator(Services services) { - this.services = services; - } - - - public FormulaWithAxioms translateRequires(String requires, - ParsableVariable selfVar, - ListOfParsableVariable paramVars) { - return null;//TODO - } - - - public FormulaWithAxioms translateEnsures(String ensures, - ParsableVariable selfVar, - ListOfParsableVariable paramVars, - ParsableVariable resultVar, - ParsableVariable excVar) { - return null;//TODO - } - - - public FormulaWithAxioms translateSignals(String signals, - ParsableVariable selfVar, - ListOfParsableVariable paramVars, - ParsableVariable resultVar, - ParsableVariable excVar) { - return null;//TODO - } - - - public FormulaWithAxioms translateDiverges(String diverges, - ParsableVariable selfVar, - ListOfParsableVariable paramVars) { - return null;//TODO - } - - - public SetOfLocationDescriptor translateAssignable( - String modifies, - ParsableVariable selfVar, - ListOfParsableVariable paramVars) { - return null;//TODO - } - - - public FormulaWithAxioms translateInv(String inv, ParsableVariable selfVar) { - return null;//TODO - } -} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/Behavior.java b/system/de/uka/ilkd/key/speclang/jml/pretranslation/Behavior.java new file mode 100644 index 00000000000..103e0ca3258 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/Behavior.java @@ -0,0 +1,40 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.pretranslation; + + +/** + * Enum type for the JML behavior kinds. + */ +public class Behavior { + + public static final Behavior NONE + = new Behavior(""); + public static final Behavior BEHAVIOR + = new Behavior("behavior "); + public static final Behavior NORMAL_BEHAVIOR + = new Behavior("normal_behavior "); + public static final Behavior EXCEPTIONAL_BEHAVIOR + = new Behavior("exceptional_behavior "); + + + private final String name; + + + private Behavior(String name) { + this.name = name; + } + + + public String toString() { + return name; + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/TestJMLPreTranslator.java b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TestJMLPreTranslator.java new file mode 100644 index 00000000000..18e1074a654 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TestJMLPreTranslator.java @@ -0,0 +1,134 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + + +package de.uka.ilkd.key.speclang.jml.pretranslation; + +import de.uka.ilkd.key.java.Position; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + +import junit.framework.TestCase; + + +public class TestJMLPreTranslator extends TestCase { + + private ListOfTextualJMLConstruct parseMethodSpec(String ms) + throws SLTranslationException { + KeYJMLPreParser preParser + = new KeYJMLPreParser(ms, "no file", Position.UNDEFINED); + return preParser.parseClasslevelComment(); + } + + + public void testSimpleSpec() throws SLTranslationException { + ListOfTextualJMLConstruct constructs + = parseMethodSpec( "/*@ normal_behavior\n" + + " requires true;\n" + + " */"); + + assertTrue(constructs != null); + assertTrue(constructs.size() == 1); + assertTrue(constructs.head() instanceof TextualJMLSpecCase); + TextualJMLSpecCase specCase = (TextualJMLSpecCase) constructs.head(); + + assertTrue(specCase.getBehavior() == Behavior.NORMAL_BEHAVIOR); + assertTrue(specCase.getRequires().size() == 1); + assertTrue(specCase.getAssignable().size() == 0); + assertTrue(specCase.getEnsures().size() == 0); + assertTrue(specCase.getSignals().size() == 0); + assertTrue(specCase.getSignalsOnly().size() == 0); + + assertTrue(specCase.getRequires().head().text.trim().equals("true;")); + } + + + public void testComplexSpec() throws SLTranslationException { + ListOfTextualJMLConstruct constructs + = parseMethodSpec( "/*@ behaviour\n" + + " @ requires true;\n" + + " @ requires ((;;(;););(););\n" + + " @ ensures false;\n" + + " @ signals exception;\n" + + " @ signals_only onlythis;\n" + + " @ assignable \\nothing;\n" + + " @*/"); + + assertTrue(constructs != null); + assertTrue(constructs.size() == 1); + assertTrue(constructs.head() instanceof TextualJMLSpecCase); + TextualJMLSpecCase specCase = (TextualJMLSpecCase) constructs.head(); + + assertTrue(specCase.getBehavior() == Behavior.BEHAVIOR); + assertTrue(specCase.getRequires().size() == 2); + assertTrue(specCase.getAssignable().size() == 1); + assertTrue(specCase.getEnsures().size() == 1); + assertTrue(specCase.getSignals().size() == 1); + assertTrue(specCase.getSignalsOnly().size() == 1); + + assertTrue(specCase.getEnsures().head().text.trim().equals("false;")); + assertTrue(specCase.getAssignable().head().text.trim().equals( + "\\nothing;")); + } + + + public void testMultipleSpecs() throws SLTranslationException { + ListOfTextualJMLConstruct constructs + = parseMethodSpec( "//@ normal_behaviour\n" + + "//@ ensures false\n" + + "//@ || true;\n" + + "//@ assignable \\nothing;\n" + + "//@ also exceptional_behaviour\n" + + "//@ requires o == null;\n" + + "//@ signals Exception;\n"); + + assertTrue(constructs != null); + assertTrue(constructs.size() == 2); + assertTrue(constructs.head() instanceof TextualJMLSpecCase); + assertTrue(constructs.tail().head() instanceof TextualJMLSpecCase); + TextualJMLSpecCase specCase1 = (TextualJMLSpecCase) constructs.head(); + TextualJMLSpecCase specCase2 = (TextualJMLSpecCase) constructs.tail().head(); + + assertTrue(specCase1.getBehavior() == Behavior.NORMAL_BEHAVIOR); + assertTrue(specCase1.getRequires().size() == 0); + assertTrue(specCase1.getAssignable().size() == 1); + assertTrue(specCase1.getEnsures().size() == 1); + assertTrue(specCase1.getSignals().size() == 0); + assertTrue(specCase1.getSignalsOnly().size() == 0); + + assertTrue(specCase2.getBehavior() == Behavior.EXCEPTIONAL_BEHAVIOR); + assertTrue(specCase2.getRequires().size() == 1); + assertTrue(specCase2.getAssignable().size() == 0); + assertTrue(specCase2.getEnsures().size() == 0); + assertTrue(specCase2.getSignals().size() == 1); + assertTrue(specCase2.getSignalsOnly().size() == 0); + } + + + public void testFailure() { + try { + parseMethodSpec("/*@ normal_behaviour @ signals ohoh;" + " @*/"); + assertTrue(false); + } catch (SLTranslationException e) { + //fine + } + } + + + public void testFailure2() { + try { + parseMethodSpec( "/*@ behaviour\n" + + " @ requires (;((;;);();();(();;;(;)));\n" + + " @*/"); + assertTrue(false); + } catch (SLTranslationException e) { + //fine + } + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLClassInv.java b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLClassInv.java new file mode 100644 index 00000000000..a819ac8d385 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLClassInv.java @@ -0,0 +1,51 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.pretranslation; + +import de.uka.ilkd.key.collection.ListOfString; +import de.uka.ilkd.key.speclang.PositionedString; + + +public class TextualJMLClassInv extends TextualJMLConstruct { + + private final PositionedString inv; + + + public TextualJMLClassInv(ListOfString mods, PositionedString inv) { + super(mods); + assert inv != null; + this.inv = inv; + } + + + public PositionedString getInv() { + return inv; + } + + + public String toString() { + return inv.toString(); + } + + + public boolean equals(Object o) { + if(!(o instanceof TextualJMLClassInv)) { + return false; + } + TextualJMLClassInv ci = (TextualJMLClassInv) o; + return mods.equals(ci.mods) && inv.equals(ci.inv); + } + + + public int hashCode() { + return mods.hashCode() + inv.hashCode(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLConstruct.java b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLConstruct.java new file mode 100644 index 00000000000..62c81850b64 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLConstruct.java @@ -0,0 +1,34 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.pretranslation; + +import de.uka.ilkd.key.collection.ListOfString; + + +/** + * Objects of this type represent the various JML specification constructs + * in textual, unprocessed form. + */ +public abstract class TextualJMLConstruct { + + protected final ListOfString mods; + + + public TextualJMLConstruct(ListOfString mods) { + assert mods != null; + this.mods = mods; + } + + + public ListOfString getMods() { + return mods; + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLFieldDecl.java b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLFieldDecl.java new file mode 100644 index 00000000000..5c2fe94a1e6 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLFieldDecl.java @@ -0,0 +1,51 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.pretranslation; + +import de.uka.ilkd.key.collection.ListOfString; +import de.uka.ilkd.key.speclang.PositionedString; + + +public class TextualJMLFieldDecl extends TextualJMLConstruct { + + private final PositionedString decl; + + + public TextualJMLFieldDecl(ListOfString mods, PositionedString decl) { + super(mods); + assert decl != null; + this.decl = decl; + } + + + public PositionedString getDecl() { + return decl; + } + + + public String toString() { + return decl.toString(); + } + + + public boolean equals(Object o) { + if(!(o instanceof TextualJMLFieldDecl)) { + return false; + } + TextualJMLFieldDecl fd = (TextualJMLFieldDecl) o; + return mods.equals(fd.mods) && decl.equals(fd.decl); + } + + + public int hashCode() { + return mods.hashCode() + decl.hashCode(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLLoopSpec.java b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLLoopSpec.java new file mode 100644 index 00000000000..8a59624b6a5 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLLoopSpec.java @@ -0,0 +1,141 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.pretranslation; + +import de.uka.ilkd.key.collection.ListOfString; +import de.uka.ilkd.key.speclang.IteratorOfPositionedString; +import de.uka.ilkd.key.speclang.ListOfPositionedString; +import de.uka.ilkd.key.speclang.PositionedString; +import de.uka.ilkd.key.speclang.SLListOfPositionedString; + + +public class TextualJMLLoopSpec extends TextualJMLConstruct { + + private ListOfPositionedString invariant + = SLListOfPositionedString.EMPTY_LIST; + private ListOfPositionedString skolemDeclarations + = SLListOfPositionedString.EMPTY_LIST; + private ListOfPositionedString predicates + = SLListOfPositionedString.EMPTY_LIST; + private ListOfPositionedString assignable + = SLListOfPositionedString.EMPTY_LIST; + private PositionedString variant + = null; + + + public TextualJMLLoopSpec(ListOfString mods) { + super(mods); + } + + + public void addInvariant(PositionedString ps) { + invariant = invariant.append(ps); + } + + + public void addSkolemDeclaration(PositionedString ps) { + skolemDeclarations = skolemDeclarations.append(ps); + } + + + public void addPredicates(PositionedString ps) { + predicates = predicates.append(ps); + } + + + public void addAssignable(PositionedString ps) { + assignable = assignable.append(ps); + } + + + public void setVariant(PositionedString ps) { + assert variant == null; + variant = ps; + } + + + public ListOfPositionedString getInvariant() { + return invariant; + } + + + public ListOfPositionedString getSkolemDeclarations() { + return skolemDeclarations; + } + + + public ListOfPositionedString getPredicates() { + return predicates; + } + + + public ListOfPositionedString getAssignable() { + return assignable; + } + + + public PositionedString getVariant() { + return variant; + } + + + public String toString() { + StringBuffer sb = new StringBuffer(); + IteratorOfPositionedString it; + + it = invariant.iterator(); + while(it.hasNext()) { + sb.append("invariant: " + it.next() + "\n"); + } + it = skolemDeclarations.iterator(); + while(it.hasNext()) { + sb.append("skolem_constant: " + it.next() + "\n"); + } + it = predicates.iterator(); + while(it.hasNext()) { + sb.append("loop_predicate: " + it.next() + "\n"); + } + it = assignable.iterator(); + while(it.hasNext()) { + sb.append("assignable: " + it.next() + "\n"); + } + if(variant != null) { + sb.append("decreases: " + variant); + } + + return sb.toString(); + } + + + + public boolean equals(Object o) { + if(!(o instanceof TextualJMLLoopSpec)) { + return false; + } + TextualJMLLoopSpec ls = (TextualJMLLoopSpec) o; + return mods.equals(ls.mods) + && invariant.equals(ls.invariant) + && skolemDeclarations.equals(ls.skolemDeclarations) + && predicates.equals(ls.predicates) + && assignable.equals(ls.assignable) + && (variant == null && ls.variant == null + || variant.equals(ls.variant)); + } + + + public int hashCode() { + return mods.hashCode() + + invariant.hashCode() + + skolemDeclarations.hashCode() + + predicates.hashCode() + + assignable.hashCode(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLMethodDecl.java b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLMethodDecl.java new file mode 100644 index 00000000000..444a2aa7583 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLMethodDecl.java @@ -0,0 +1,62 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.pretranslation; + +import de.uka.ilkd.key.collection.ListOfString; +import de.uka.ilkd.key.speclang.PositionedString; + + +public class TextualJMLMethodDecl extends TextualJMLConstruct { + + private final PositionedString decl; + private final String methodName; + + + public TextualJMLMethodDecl(ListOfString mods, + PositionedString decl, + String methodName) { + super(mods); + assert decl != null; + this.decl = decl; + this.methodName = methodName; + } + + + public PositionedString getDecl() { + return decl; + } + + + public String getMethodName() { + return methodName; + } + + + public String toString() { + return decl.toString(); + } + + + public boolean equals(Object o) { + if(!(o instanceof TextualJMLMethodDecl)) { + return false; + } + TextualJMLMethodDecl md = (TextualJMLMethodDecl) o; + return mods.equals(md.mods) + && decl.equals(md.decl) + && methodName.equals(md.methodName); + } + + + public int hashCode() { + return mods.hashCode() + decl.hashCode() + methodName.hashCode(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLSetStatement.java b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLSetStatement.java new file mode 100644 index 00000000000..a90f9e62a01 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLSetStatement.java @@ -0,0 +1,52 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.pretranslation; + +import de.uka.ilkd.key.collection.ListOfString; +import de.uka.ilkd.key.speclang.PositionedString; + + +public class TextualJMLSetStatement extends TextualJMLConstruct { + + private final PositionedString assignment; + + + public TextualJMLSetStatement(ListOfString mods, + PositionedString assignment) { + super(mods); + assert assignment != null; + this.assignment = assignment; + } + + + public PositionedString getAssignment() { + return assignment; + } + + + public String toString() { + return assignment.toString(); + } + + + public boolean equals(Object o) { + if(!(o instanceof TextualJMLSetStatement)) { + return false; + } + TextualJMLSetStatement ss = (TextualJMLSetStatement) o; + return mods.equals(ss.mods) && assignment.equals(ss.assignment); + } + + + public int hashCode() { + return mods.hashCode() + assignment.hashCode(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLSpecCase.java b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLSpecCase.java new file mode 100644 index 00000000000..c8bfa8ce455 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/TextualJMLSpecCase.java @@ -0,0 +1,175 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.pretranslation; + +import de.uka.ilkd.key.collection.ListOfString; +import de.uka.ilkd.key.speclang.IteratorOfPositionedString; +import de.uka.ilkd.key.speclang.ListOfPositionedString; +import de.uka.ilkd.key.speclang.PositionedString; +import de.uka.ilkd.key.speclang.SLListOfPositionedString; + + +public class TextualJMLSpecCase extends TextualJMLConstruct { + + private final Behavior behavior; + private ListOfPositionedString requires + = SLListOfPositionedString.EMPTY_LIST; + private ListOfPositionedString assignable + = SLListOfPositionedString.EMPTY_LIST; + private ListOfPositionedString ensures + = SLListOfPositionedString.EMPTY_LIST; + private ListOfPositionedString signals + = SLListOfPositionedString.EMPTY_LIST; + private ListOfPositionedString signalsOnly + = SLListOfPositionedString.EMPTY_LIST; + private ListOfPositionedString diverges + = SLListOfPositionedString.EMPTY_LIST; + + + + public TextualJMLSpecCase(ListOfString mods, Behavior behavior) { + super(mods); + assert behavior != null; + this.behavior = behavior; + } + + + public void addRequires(PositionedString ps) { + requires = requires.append(ps); + } + + + public void addRequires(ListOfPositionedString l) { + requires = requires.append(l); + } + + + public void addAssignable(PositionedString ps) { + assignable = assignable.append(ps); + } + + + public void addEnsures(PositionedString ps) { + ensures = ensures.append(ps); + } + + + public void addSignals(PositionedString ps) { + signals = signals.append(ps); + } + + + public void addSignalsOnly(PositionedString ps) { + signalsOnly = signalsOnly.append(ps); + } + + + public void addDiverges(PositionedString ps) { + diverges = diverges.append(ps); + } + + + public Behavior getBehavior() { + return behavior; + } + + + public ListOfPositionedString getRequires() { + return requires; + } + + + public ListOfPositionedString getAssignable() { + return assignable; + } + + + public ListOfPositionedString getEnsures() { + return ensures; + } + + + public ListOfPositionedString getSignals() { + return signals; + } + + + public ListOfPositionedString getSignalsOnly() { + return signalsOnly; + } + + + public ListOfPositionedString getDiverges() { + return diverges; + } + + + public String toString() { + StringBuffer sb = new StringBuffer(); + IteratorOfPositionedString it; + + sb.append(behavior + "\n"); + it = requires.iterator(); + while(it.hasNext()) { + sb.append("requires: " + it.next() + "\n"); + } + it = assignable.iterator(); + while(it.hasNext()) { + sb.append("assignable: " + it.next() + "\n"); + } + it = ensures.iterator(); + while(it.hasNext()) { + sb.append("ensures: " + it.next() + "\n"); + } + it = signals.iterator(); + while(it.hasNext()) { + sb.append("signals: " + it.next() + "\n"); + } + it = signalsOnly.iterator(); + while(it.hasNext()) { + sb.append("signals_only: " + it.next() + "\n"); + } + it = diverges.iterator(); + while(it.hasNext()) { + sb.append("diverges: " + it.next() + "\n"); + } + + return sb.toString(); + } + + + public boolean equals(Object o) { + if(!(o instanceof TextualJMLSpecCase)) { + return false; + } + TextualJMLSpecCase sc = (TextualJMLSpecCase) o; + return mods.equals(sc.mods) + && behavior.equals(sc.behavior) + && requires.equals(sc.requires) + && assignable.equals(sc.assignable) + && ensures.equals(sc.ensures) + && signals.equals(sc.signals) + && signalsOnly.equals(sc.signalsOnly) + && diverges.equals(sc.diverges); + } + + + public int hashCode() { + return mods.hashCode() + + behavior.hashCode() + + requires.hashCode() + + assignable.hashCode() + + ensures.hashCode() + + signals.hashCode() + + signalsOnly.hashCode() + + diverges.hashCode(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/jmlprelexer.g b/system/de/uka/ilkd/key/speclang/jml/pretranslation/jmlprelexer.g new file mode 100644 index 00000000000..05dfa5a12c4 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/jmlprelexer.g @@ -0,0 +1,296 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +header { + package de.uka.ilkd.key.speclang.jml.pretranslation; +} + + +class KeYJMLPreLexer extends Lexer; + + +options { + charVocabulary = '\3'..'\377'; + k=3; +} + + +tokens { + ABSTRACT = "abstract"; + ALSO = "also"; + ASSIGNABLE = "assignable"; + ASSIGNABLE_RED = "assignable_redundantly"; + BEHAVIOR = "behavior"; + BEHAVIOUR = "behaviour"; + CAPTURES = "captures"; + CAPTURES_RED = "captures_redundantly"; + CODE = "code"; + CODE_BIGINT_MATH = "code_bigint_math"; + CODE_JAVA_MATH = "code_java_math"; + CODE_SAFE_MATH = "code_safe_math"; + CONST = "const"; + CONSTRAINT = "constraint"; + CONSTRAINT_RED = "constraint_redundantly"; + DECREASES = "decreases"; + DECREASES_REDUNDANTLY = "decreases_redundantly"; + DECREASING = "decreasing"; + DECREASING_REDUNDANTLY = "decreasing_redundantly"; + DIVERGES = "diverges"; + DIVERGES_RED = "diverges_redundantly"; + DURATION = "duration"; + DURATION_RED = "duration_redundantly"; + ENSURES = "ensures"; + ENSURES_RED = "ensures_redundantly"; + EXCEPTIONAL_BEHAVIOR = "exceptional_behavior"; + EXCEPTIONAL_BEHAVIOUR = "exceptional_behaviour"; + FINAL = "final"; + FORALL = "forall"; + GHOST = "ghost"; + HELPER = "helper"; + IN = "in"; + IN_RED = "in_redundantly"; + INITIALLY = "initially"; + INSTANCE = "instance"; + INVARIANT = "invariant"; + INVARIANT_RED = "invariant_redundantly"; + LOOP_INVARIANT = "loop_invariant"; + LOOP_INVARIANT_RED = "loop_invariant_redundantly"; + LOOP_PREDICATE = "loop_predicate"; + MAINTAINING = "maintaining"; + MAINTAINING_REDUNDANTLY = "maintaining_redundantly"; + MAPS = "maps"; + MAPS_RED = "maps_redundantly"; + MODEL = "model"; + MODIFIABLE = "modifiable"; + MODIFIABLE_RED = "modifiable_redundantly"; + MODIFIES = "modifies"; + MODIFIES_RED = "modifies_redundantly"; + MONITORS_FOR = "monitors_for"; + NATIVE = "native"; + NON_NULL = "non_null"; + NORMAL_BEHAVIOR = "normal_behavior"; + NORMAL_BEHAVIOUR = "normal_behaviour"; + NULLABLE = "nullable"; + NULLABLE_BY_DEFAULT = "nullable_by_default"; + PRIVATE = "private"; + PROTECTED = "protected"; + PUBLIC = "public"; + PURE = "pure"; + READABLE = "readable"; + REPRESENTS = "represents"; + REPRESENTS_RED = "represents_redundantly"; + REQUIRES = "requires"; + REQUIRES_RED = "requires_redundantly"; + SET = "set"; + SIGNALS = "signals"; + SIGNALS_ONLY = "signals_only"; + SIGNALS_ONLY_RED = "signals_only_redundantly"; + SIGNALS_RED = "signals_redundantly"; + SKOLEM_CONSTANT = "skolem_constant"; + SPEC_BIGINT_MATH = "spec_bigint_math"; + SPEC_JAVA_MATH = "spec_java_math"; + SPEC_PROTECTED = "spec_protected"; + SPEC_PUBLIC = "spec_public"; + SPEC_SAFE_MATH = "spec_safe_math"; + STATIC = "static"; + STRICTFP = "strictfp"; + SYNCHRONIZED = "synchronized"; + TRANSIENT = "transient"; + UNINITIALIZED = "uninitialized"; + VOLATILE = "volatile"; + WHEN = "when"; + WHEN_RED = "when_redundantly"; + WORKING_SPACE = "working_space"; + WORKING_SPACE_RED = "working_space_redundantly"; + WRITABLE = "writable"; +} + + +{ + private boolean expressionMode = false; + + public void setExpressionMode(boolean b) { + expressionMode = b; + } +} + + +protected SL_COMMENT +options { + paraphrase = "a single-line non-specification comment"; +} +: + "//" + ( + (~('@'|'\n')) + => + ~('@'|'\n') + ( + options { greedy = true; } + : + ~'\n' + )* + )? +; + + +protected ML_COMMENT +options { + paraphrase = "a multi-line non-specification comment"; +} +: + "/*" + ( + (~('*').|'*'~'/') + => + ( '\n' { newline(); } + | ~('@'|'\n') + ) + ( + options { greedy = false; } + : + '\n' { newline(); } + | ~('\n') + )* + )? + "*/" +; + + +WS +options { + paraphrase = "white space"; +} +{ + boolean acceptAt = false; +} +: + {!expressionMode}? + ( + ' ' + | '\t' + | '\n' { newline(); acceptAt = true; } + | '\r' + | {acceptAt}? '@' + | ("//@") => "//@" + | "/*@" + | "@*/" + | "*/" + | SL_COMMENT + | ML_COMMENT + )+ + { + $setType(Token.SKIP); + } +; + + +protected LETTER +options { + paraphrase = "letter"; +} +: + 'a'..'z' + | 'A'..'Z' + | '_' + | '$' +; + + +protected DIGIT +: + '0'..'9' +; + + +IDENT +options { + paraphrase = "an identifier"; +} +: + {!expressionMode}? + LETTER + ( options { greedy = true; } + : + LETTER + | DIGIT + | "[]" + | '.' + )* +; + + +PARAM_LIST +options { + paraphrase = "a parameter list"; +} +: + {!expressionMode}? + '(' + (IDENT IDENT)? + (',' IDENT IDENT)* + ')' +; + + +BODY +options { + paraphrase = "a method body"; +} +{ + int braceCounter = 0; +} +: + {!expressionMode}? + '{' + ( + '{' { braceCounter++; } + | {braceCounter > 0}? '}' { braceCounter--; } + | '\n' { newline(); } + | ~'}' + )* + {braceCounter == 0}? '}' +; + + +INITIALISER +options { + paraphrase = "an initialiser"; +} +: + {!expressionMode}? + ( + ';' + | ( + '=' { setExpressionMode(true); } + EXPRESSION { setExpressionMode(false); } + ) + ) +; + + +EXPRESSION +{ + int parenthesesCounter = 0; +} +: + {expressionMode}? + ( + '(' { parenthesesCounter++; } + | ')' { parenthesesCounter--; } + | {parenthesesCounter > 0}? ';' + | '\n' { newline(); } + | ~';' + )* + {parenthesesCounter == 0}? ';' + { + expressionMode = false; + } +; diff --git a/system/de/uka/ilkd/key/speclang/jml/pretranslation/jmlpreparser.g b/system/de/uka/ilkd/key/speclang/jml/pretranslation/jmlpreparser.g new file mode 100644 index 00000000000..8fae8d20a75 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/pretranslation/jmlpreparser.g @@ -0,0 +1,992 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +header { + package de.uka.ilkd.key.speclang.jml.pretranslation; + + import java.io.StringReader; + + import de.uka.ilkd.key.collection.ListOfString; + import de.uka.ilkd.key.collection.SLListOfString; + import de.uka.ilkd.key.java.Position; + import de.uka.ilkd.key.speclang.ListOfPositionedString; + import de.uka.ilkd.key.speclang.PositionedString; + import de.uka.ilkd.key.speclang.SLListOfPositionedString; + import de.uka.ilkd.key.speclang.translation.SLTranslationException; + import de.uka.ilkd.key.speclang.translation.SLTranslationExceptionManager; +} + + +class KeYJMLPreParser extends Parser; + + +options { + k = 1; //do not change - interplay with lexer depends on k=1! + defaultErrorHandler = false; + importVocab = KeYJMLPreLexer; +} + + +{ + private KeYJMLPreLexer lexer; + private SLTranslationExceptionManager excManager; + + + private KeYJMLPreParser(KeYJMLPreLexer lexer, + String fileName, + Position offsetPos) { + this(lexer); + this.lexer = lexer; + this.excManager = new SLTranslationExceptionManager(this, + fileName, + offsetPos); + } + + + public KeYJMLPreParser(String comment, + String fileName, + Position offsetPos) { + this(new KeYJMLPreLexer(new StringReader(comment)), + fileName, + offsetPos); + } + + + private PositionedString createPositionedString(String text, + Token t) { + return excManager.createPositionedString(text, t); + } + + + private void raiseError(String msg) throws SLTranslationException { + throw excManager.createException(msg); + } + + + private void raiseNotSupported(String feature) + throws SLTranslationException { + throw excManager.createException("JML feature not supported: " + + feature); + } + + + public ListOfTextualJMLConstruct parseClasslevelComment() + throws SLTranslationException { + try { + return classlevel_comment(); + } catch(ANTLRException e) { + throw excManager.convertException(e); + } + } + + + public ListOfTextualJMLConstruct parseMethodlevelComment() + throws SLTranslationException { + try { + return methodlevel_comment(); + } catch(ANTLRException e) { + throw excManager.convertException(e); + } + } +} + + + +//----------------------------------------------------------------------------- +//comments +//----------------------------------------------------------------------------- + +classlevel_comment + returns [ListOfTextualJMLConstruct result + = SLListOfTextualJMLConstruct.EMPTY_LIST] + throws SLTranslationException +{ + ListOfString mods = SLListOfString.EMPTY_LIST; + ListOfTextualJMLConstruct list; +} +: + ( + options { greedy = false; } + : + mods=modifiers + list=classlevel_element[mods] + { + if(list!=null) { + result = result.append(list); + } + } + )* + EOF +; + + +classlevel_element[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +: + result=class_invariant[mods] + | result=method_specification[mods] + | (field_declaration[mods]) => result=field_declaration[mods] + | result=method_declaration[mods] + | result=history_constraint[mods] + | result=represents_clause[mods] + | result=initially_clause[mods] + | result=monitors_for_clause[mods] + | result=readable_if_clause[mods] + | result=writable_if_clause[mods] + | result=datagroup_clause[mods] + | EOF +; + + +methodlevel_comment + returns [ListOfTextualJMLConstruct result + = SLListOfTextualJMLConstruct.EMPTY_LIST] + throws SLTranslationException +{ + ListOfString mods = SLListOfString.EMPTY_LIST; + ListOfTextualJMLConstruct list; +} +: + ( + mods=modifiers + list=methodlevel_element[mods] { result = result.append(list); } + )* + EOF +; + + +methodlevel_element[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +: + result=field_declaration[mods] + | result=set_statement[mods] + | result=loop_specification[mods] +; + + + +//----------------------------------------------------------------------------- +//modifiers +//----------------------------------------------------------------------------- + +modifiers + returns [ListOfString result = SLListOfString.EMPTY_LIST] + throws SLTranslationException +{ + String s; +} +: + ( + options { greedy = true; } + : + s=modifier { result = result.append(s); } + )* +; + + +modifier returns [String result = null]: + fin:FINAL { result = fin.getText(); } + | gho:GHOST { result = gho.getText(); } + | hel:HELPER { result = hel.getText(); } + | ins:INSTANCE { result = ins.getText(); } + | mod:MODEL { result = mod.getText(); } + | nnu:NON_NULL { result = nnu.getText(); } + | nul:NULLABLE { result = nul.getText(); } + | nbd:NULLABLE_BY_DEFAULT { result = nbd.getText(); } + | pri:PRIVATE { result = pri.getText(); } + | pro:PROTECTED { result = pro.getText(); } + | pub:PUBLIC { result = pub.getText(); } + | pur:PURE { result = pur.getText(); } + | spr:SPEC_PROTECTED { result = spr.getText(); } + | spu:SPEC_PUBLIC { result = spu.getText(); } + | sta:STATIC { result = sta.getText(); } +; + + + +//----------------------------------------------------------------------------- +//class invariants +//----------------------------------------------------------------------------- + +class_invariant[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + PositionedString ps; +} +: + invariant_keyword ps=expression + { + TextualJMLClassInv inv = new TextualJMLClassInv(mods, ps); + result = SLListOfTextualJMLConstruct.EMPTY_LIST.prepend(inv); + } +; + + +invariant_keyword +: + INVARIANT + | INVARIANT_RED +; + + + +//----------------------------------------------------------------------------- +//method specifications +//----------------------------------------------------------------------------- + +method_specification[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + ListOfTextualJMLConstruct list = SLListOfTextualJMLConstruct.EMPTY_LIST; +} +: + (ALSO)? + result=spec_case[mods] + ( + options { greedy = true; } + : + also_keyword list=spec_case[SLListOfString.EMPTY_LIST] + { + result = result.append(list); + } + )* +; + + +also_keyword +: + ALSO + | FOR_EXAMPLE + | IMPLIES_THAT +; + + +spec_case[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +: + result=lightweight_spec_case[mods] + | result=heavyweight_spec_case[mods] +; + + + +//----------------------------------------------------------------------------- +//lightweight specification cases +//----------------------------------------------------------------------------- + +lightweight_spec_case[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +: + result=generic_spec_case[mods, Behavior.NONE] +; + + + +//----------------------------------------------------------------------------- +//heavyweight specification cases +//----------------------------------------------------------------------------- + +heavyweight_spec_case[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + String s; +} +: + (s=modifier { mods = mods.append(s); })? + ( + result=behavior_spec_case[mods] + | result=exceptional_behavior_spec_case[mods] + | result=normal_behavior_spec_case[mods] + ) +; + + +behavior_spec_case[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +: + behavior_keyword + result=generic_spec_case[mods, Behavior.BEHAVIOR] +; + + +behavior_keyword +: + BEHAVIOR + | BEHAVIOUR +; + + +normal_behavior_spec_case[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +: + normal_behavior_keyword + result=generic_spec_case[mods, Behavior.NORMAL_BEHAVIOR] +; + + +normal_behavior_keyword +: + NORMAL_BEHAVIOR + | NORMAL_BEHAVIOUR +; + + +exceptional_behavior_spec_case[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +: + exceptional_behavior_keyword + result=generic_spec_case[mods, Behavior.EXCEPTIONAL_BEHAVIOR] +; + + +exceptional_behavior_keyword +: + EXCEPTIONAL_BEHAVIOR + | EXCEPTIONAL_BEHAVIOUR +; + + + +//----------------------------------------------------------------------------- +//generic specification cases +//----------------------------------------------------------------------------- + +generic_spec_case[ListOfString mods, Behavior b] + returns [ListOfTextualJMLConstruct result + = SLListOfTextualJMLConstruct.EMPTY_LIST] + throws SLTranslationException +{ + ListOfPositionedString requires; +} +: + (spec_var_decls)? + ( + requires=spec_header + ( + (generic_spec_body[mods, b]) + => + result=generic_spec_body[mods, b] + )? + { + if(result.isEmpty()) { + result = result.append(new TextualJMLSpecCase(mods, b)); + } + + for(IteratorOfTextualJMLConstruct it = result.iterator(); + it.hasNext(); ) { + TextualJMLSpecCase sc = (TextualJMLSpecCase) it.next(); + sc.addRequires(requires); + } + } + | + result=generic_spec_body[mods, b] + ) +; + + +spec_var_decls throws SLTranslationException +{ + PositionedString ps; +} +: + (FORALL ps=expression)+ + { + raiseNotSupported("specification variables"); + } +; + + +spec_header + returns [ListOfPositionedString result + = SLListOfPositionedString.EMPTY_LIST] + throws SLTranslationException +{ + PositionedString ps; +} +: + ( + options { greedy = true; } + : + ps=requires_clause { result = result.append(ps); } + )+ +; + + +requires_clause + returns [PositionedString result = null] + throws SLTranslationException +: + requires_keyword result=expression +; + + +requires_keyword +: + REQUIRES | + REQUIRES_RED +; + + +generic_spec_body[ListOfString mods, Behavior b] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + TextualJMLSpecCase sc; +} +: + result=simple_spec_body[mods, b] + | + "{|" + result=generic_spec_case_seq[mods, b] + "|}" +; + + +generic_spec_case_seq[ListOfString mods, Behavior b] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + ListOfTextualJMLConstruct list; +} +: + result=generic_spec_case[mods, b] + ( + also_keyword + list=generic_spec_case[mods, b] + { + result = result.append(list); + } + )* +; + + +simple_spec_body[ListOfString mods, Behavior b] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + TextualJMLSpecCase sc = new TextualJMLSpecCase(mods, b); + result = SLListOfTextualJMLConstruct.EMPTY_LIST.prepend(sc); +} +: + ( + options { greedy = true; } + : + simple_spec_body_clause[sc, b] + )+ +; + + +simple_spec_body_clause[TextualJMLSpecCase sc, Behavior b] + throws SLTranslationException +{ + PositionedString ps; +} +: + ( + ps=assignable_clause { sc.addAssignable(ps); } + | ps=ensures_clause { sc.addEnsures(ps); } + | ps=signals_clause { sc.addSignals(ps); } + | ps=signals_only_clause { sc.addSignalsOnly(ps); } + | ps=diverges_clause { sc.addDiverges(ps); } + | captures_clause + | when_clause + | working_space_clause + | duration_clause + ) + { + if(b == Behavior.EXCEPTIONAL_BEHAVIOR + && !sc.getEnsures().isEmpty()) { + raiseError("ensures not allowed in exceptional behavior."); + } else if(b == Behavior.NORMAL_BEHAVIOR + && !sc.getSignals().isEmpty()) { + raiseError("signals not allowed in normal behavior."); + } else if(b == Behavior.NORMAL_BEHAVIOR + && !sc.getSignalsOnly().isEmpty()) { + raiseError("signals_only not allowed in normal behavior."); + } + } +; + + + +//----------------------------------------------------------------------------- +//simple specification body clauses +//----------------------------------------------------------------------------- + +assignable_clause + returns [PositionedString result = null] + throws SLTranslationException +: + assignable_keyword result=expression +; + + +assignable_keyword +: + ASSIGNABLE + | ASSIGNABLE_RED + | MODIFIABLE + | MODIFIABLE_RED + | MODIFIES + | MODIFIES_RED +; + + +ensures_clause + returns [PositionedString result = null] + throws SLTranslationException +: + ensures_keyword result=expression +; + + +ensures_keyword +: + ENSURES + | ENSURES_RED +; + + +signals_clause + returns [PositionedString result = null] + throws SLTranslationException +: + signals_keyword result=expression +; + + +signals_keyword +: + SIGNALS + | SIGNALS_RED + | EXSURES + | EXSURES_RED +; + + +signals_only_clause + returns [PositionedString result = null] + throws SLTranslationException +: + signals_only_keyword result=expression +; + + +signals_only_keyword +: + SIGNALS_ONLY + | SIGNALS_ONLY_RED +; + + +diverges_clause + returns [PositionedString result = null] + throws SLTranslationException +: + diverges_keyword result=expression +; + + +diverges_keyword +: + DIVERGES + | DIVERGES_RED +; + + +captures_clause throws SLTranslationException +{ + PositionedString ps; +} +: + captures_keyword ps=expression + { + raiseNotSupported("captures clauses"); + } +; + + +captures_keyword +: + CAPTURES + | CAPTURES_RED +; + + +when_clause throws SLTranslationException +{ + PositionedString ps; +} +: + when_keyword ps=expression + { + raiseNotSupported("when clauses"); + } +; + + +when_keyword +: + WHEN + | WHEN_RED +; + + +working_space_clause throws SLTranslationException +{ + PositionedString ps; +} +: + working_space_keyword ps=expression + { + raiseNotSupported("working_space clauses"); + } +; + + +working_space_keyword +: + WORKING_SPACE + | WORKING_SPACE_RED +; + + +duration_clause throws SLTranslationException +{ + PositionedString ps; +} +: + duration_keyword ps=expression + { + raiseNotSupported("duration clauses"); + } +; + + +duration_keyword +: + DURATION + | DURATION_RED +; + + + +//----------------------------------------------------------------------------- +//field declarations +//----------------------------------------------------------------------------- + +field_declaration[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] +{ + StringBuffer sb = new StringBuffer(); + String s; +} +: + type:IDENT { sb.append(type.getText() + " "); } + name:IDENT { sb.append(name.getText()); } + init:INITIALISER { sb.append(init.getText()); } + { + PositionedString ps = createPositionedString(sb.toString(), type); + TextualJMLFieldDecl fd = new TextualJMLFieldDecl(mods, ps); + result = SLListOfTextualJMLConstruct.EMPTY_LIST.prepend(fd); + } +; + + + + +//----------------------------------------------------------------------------- +//method declarations +//----------------------------------------------------------------------------- + +method_declaration[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] +{ + StringBuffer sb = new StringBuffer(); + String s; +} +: + type:IDENT { sb.append(type.getText() + " "); } + name:IDENT { sb.append(name.getText()); } + params:PARAM_LIST { sb.append(params.getText()); } + body:BODY { sb.append(body.getText()); } + { + PositionedString ps = createPositionedString(sb.toString(), type); + TextualJMLMethodDecl md + = new TextualJMLMethodDecl(mods, ps, name.getText()); + result = SLListOfTextualJMLConstruct.EMPTY_LIST.prepend(md); + } +; + + + +//----------------------------------------------------------------------------- +//unsupported classlevel stuff +//----------------------------------------------------------------------------- + +history_constraint[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + PositionedString ps; +} +: + constraint_keyword ps=expression + { + raiseNotSupported("history constraints"); + } +; + + +constraint_keyword +: + CONSTRAINT + | CONSTRAINT_RED +; + + +represents_clause[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + PositionedString ps; +} +: + represents_keyword ps=expression + { + //TODO + //raiseNotSupported("represents clauses"); + } +; + + +represents_keyword +: + REPRESENTS + | REPRESENTS_RED +; + + +initially_clause[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + PositionedString ps; +} +: + INITIALLY ps=expression + { + raiseNotSupported("initially clauses"); + } +; + + +monitors_for_clause[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + PositionedString ps; +} +: + MONITORS_FOR ps=expression + { + raiseNotSupported("monitors_for clauses"); + } +; + + +readable_if_clause[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + PositionedString ps; +} +: + READABLE ps=expression + { + raiseNotSupported("readable-if clauses"); + } +; + + +writable_if_clause[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + PositionedString ps; +} +: + WRITABLE ps=expression + { + raiseNotSupported("writable-if clauses"); + } +; + + +datagroup_clause[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +: + in_group_clause | maps_into_clause +; + + +in_group_clause throws SLTranslationException +{ + PositionedString ps; +} +: + in_keyword ps=expression + { + raiseNotSupported("in-group clauses"); + } +; + + +in_keyword +: + IN + | IN_RED +; + + +maps_into_clause throws SLTranslationException +{ + PositionedString ps; +} +: + maps_keyword ps=expression + { + raiseNotSupported("maps-into clauses"); + } +; + + +maps_keyword +: + MAPS + | MAPS_RED +; + + + +//----------------------------------------------------------------------------- +//set statements +//----------------------------------------------------------------------------- + +set_statement[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] +{ + PositionedString ps; +} +: + SET ps=expression + { + TextualJMLSetStatement ss = new TextualJMLSetStatement(mods, ps); + result = SLListOfTextualJMLConstruct.EMPTY_LIST.prepend(ss); + } +; + + + +//----------------------------------------------------------------------------- +//loop specifications +//----------------------------------------------------------------------------- + +loop_specification[ListOfString mods] + returns [ListOfTextualJMLConstruct result = null] + throws SLTranslationException +{ + PositionedString ps; + TextualJMLLoopSpec ls = new TextualJMLLoopSpec(mods); + result = SLListOfTextualJMLConstruct.EMPTY_LIST.prepend(ls); +} +: + ( + options { greedy = true; } + : + ps=loop_invariant { ls.addInvariant(ps); } + | ps=skolem_declaration { ls.addSkolemDeclaration(ps); } + | ps=loop_predicates { ls.addPredicates(ps); } + | ps=assignable_clause { ls.addAssignable(ps); } + | ps=variant_function { ls.setVariant(ps); } + )+ +; + + +loop_invariant returns [PositionedString result = null] +: + maintaining_keyword result=expression +; + + +maintaining_keyword +: + MAINTAINING + | MAINTAINING_REDUNDANTLY + | LOOP_INVARIANT + | LOOP_INVARIANT_REDUNDANTLY +; + + +skolem_declaration returns [PositionedString result = null] +: + SKOLEM_CONSTANT result=expression +; + + +loop_predicates returns [PositionedString result = null] +: + LOOP_PREDICATE result=expression +; + + +variant_function returns [PositionedString result = null] +: + decreasing_keyword result=expression +; + + +decreasing_keyword +: + DECREASING + | DECREASING_REDUNDANTLY + | DECREASES + | DECREASES_REDUNDANTLY +; + + + +//----------------------------------------------------------------------------- +//expressions +//----------------------------------------------------------------------------- + + +expression returns [PositionedString result = null] +{ + lexer.setExpressionMode(true); +} +: + t:EXPRESSION + { + lexer.setExpressionMode(false); + result = createPositionedString(t.getText(), t); + } +; diff --git a/system/de/uka/ilkd/key/proof/mgt/HoareTripleContract.java b/system/de/uka/ilkd/key/speclang/jml/translation/JMLExpression.java similarity index 50% rename from system/de/uka/ilkd/key/proof/mgt/HoareTripleContract.java rename to system/de/uka/ilkd/key/speclang/jml/translation/JMLExpression.java index 8e2ea208be2..090a2d1b775 100644 --- a/system/de/uka/ilkd/key/proof/mgt/HoareTripleContract.java +++ b/system/de/uka/ilkd/key/speclang/jml/translation/JMLExpression.java @@ -8,26 +8,20 @@ // // -package de.uka.ilkd.key.proof.mgt; +package de.uka.ilkd.key.speclang.jml.translation; -import de.uka.ilkd.key.java.Statement; -import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.op.Modality; +import de.uka.ilkd.key.speclang.translation.SLExpression; -/** - * @deprecated - */ -public interface HoareTripleContract extends Contract{ - Term getPre(); +class JMLExpression extends SLExpression { - Term getPost(); - - SetOfLocationDescriptor getModifies(); - - Modality getModality(); - - Statement getStatement(); + public JMLExpression(Term term) { + super(term); + } + public JMLExpression(KeYJavaType type) { + super(type); + } } diff --git a/system/de/uka/ilkd/key/speclang/jml/translation/JMLResolverManager.java b/system/de/uka/ilkd/key/speclang/jml/translation/JMLResolverManager.java new file mode 100644 index 00000000000..bf524686e24 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/translation/JMLResolverManager.java @@ -0,0 +1,42 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.translation; + +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.speclang.translation.SLResolverManager; +import de.uka.ilkd.key.speclang.translation.SLCollection; +import de.uka.ilkd.key.speclang.translation.SLExpression; +import de.uka.ilkd.key.util.Debug; + + +class JMLResolverManager extends SLResolverManager { + + public JMLResolverManager(JavaInfo javaInfo, KeYJavaType specInClass) { + super(javaInfo, specInClass, true, true, true); + } + + public SLExpression createSLExpression(Term t) { + return new JMLExpression(t); + } + + public SLExpression createSLExpression(KeYJavaType t) { + return new JMLExpression(t); + } + + // There is no collection type in JML + public SLExpression createSLExpression(SLCollection t) { + Debug.fail(); + return null; + } + +} diff --git a/system/de/uka/ilkd/key/speclang/jml/translation/JMLSpecFactory.java b/system/de/uka/ilkd/key/speclang/jml/translation/JMLSpecFactory.java new file mode 100644 index 00000000000..afd935300ec --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/translation/JMLSpecFactory.java @@ -0,0 +1,674 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.translation; + +import java.util.LinkedHashMap; +import java.util.Map; + +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.Statement; +import de.uka.ilkd.key.java.StatementContainer; +import de.uka.ilkd.key.java.abstraction.IteratorOfKeYJavaType; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; +import de.uka.ilkd.key.java.declaration.ArrayOfVariableSpecification; +import de.uka.ilkd.key.java.declaration.LocalVariableDeclaration; +import de.uka.ilkd.key.java.declaration.ParameterDeclaration; +import de.uka.ilkd.key.java.statement.BranchStatement; +import de.uka.ilkd.key.java.statement.For; +import de.uka.ilkd.key.java.statement.LoopStatement; +import de.uka.ilkd.key.logic.EverythingLocationDescriptor; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.SetAsListOfLocationDescriptor; +import de.uka.ilkd.key.logic.SetAsListOfTerm; +import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.logic.SetOfTerm; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.op.IteratorOfLogicVariable; +import de.uka.ilkd.key.logic.op.IteratorOfProgramMethod; +import de.uka.ilkd.key.logic.op.ListOfLogicVariable; +import de.uka.ilkd.key.logic.op.ListOfParsableVariable; +import de.uka.ilkd.key.logic.op.ListOfProgramMethod; +import de.uka.ilkd.key.logic.op.LogicVariable; +import de.uka.ilkd.key.logic.op.Modality; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.logic.op.SLListOfParsableVariable; +import de.uka.ilkd.key.logic.op.SetAsListOfProgramMethod; +import de.uka.ilkd.key.logic.op.SetOfProgramMethod; +import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.speclang.ClassInvariant; +import de.uka.ilkd.key.speclang.ClassInvariantImpl; +import de.uka.ilkd.key.speclang.FormulaWithAxioms; +import de.uka.ilkd.key.speclang.IteratorOfPositionedString; +import de.uka.ilkd.key.speclang.ListOfPositionedString; +import de.uka.ilkd.key.speclang.LoopInvariant; +import de.uka.ilkd.key.speclang.LoopInvariantImpl; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.OperationContractImpl; +import de.uka.ilkd.key.speclang.PositionedString; +import de.uka.ilkd.key.speclang.SetAsListOfOperationContract; +import de.uka.ilkd.key.speclang.SetOfOperationContract; +import de.uka.ilkd.key.speclang.SignatureVariablesFactory; +import de.uka.ilkd.key.speclang.jml.pretranslation.Behavior; +import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLClassInv; +import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLLoopSpec; +import de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLSpecCase; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + + +/** + * A factory for creating class invariants and operation contracts + * from textual JML specifications. This is the public interface to the + * jml.translation package. + */ +public class JMLSpecFactory { + + private static final TermBuilder TB + = TermBuilder.DF; + private static final SignatureVariablesFactory SVF + = SignatureVariablesFactory.INSTANCE; + + private final Services services; + private final JMLTranslator translator; + + private int invCounter; + private int contractCounter; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public JMLSpecFactory(Services services) { + assert services != null; + this.services = services; + this.translator = new JMLTranslator(services); + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private String getInvName() { + return "JML class invariant (id: " + invCounter++ + ")"; + } + + + private String getContractName(Behavior behavior) { + return "JML " + + behavior + + "operation contract (id: " + contractCounter++ + ")"; + } + + + private SetOfProgramMethod getOverridingMethods(ProgramMethod pm) { + JavaInfo ji = services.getJavaInfo(); + String name = pm.getMethodDeclaration().getName(); + int numParams = pm.getParameterDeclarationCount(); + SetOfProgramMethod result = SetAsListOfProgramMethod.EMPTY_SET; + + ListOfKeYJavaType subs = ji.getAllSubtypes(pm.getContainerType()); + for(IteratorOfKeYJavaType it = subs.iterator(); it.hasNext(); ) { + KeYJavaType sub = it.next(); + ListOfProgramMethod subPms + = ji.getAllProgramMethodsLocallyDeclared(sub); + for(IteratorOfProgramMethod it2 = subPms.iterator(); + it2.hasNext(); ) { + ProgramMethod subPm = it2.next(); + if(subPm.getMethodDeclaration().getName().equals(name) + && subPm.getParameterDeclarationCount() == numParams) { + boolean paramsEqual = true; + for(int i = 0; i < numParams; i++) { + if(!subPm.getParameterType(i) + .equals(pm.getParameterType(i))) { + paramsEqual = false; + break; + } + } + + if(paramsEqual) { + result = result.add(subPm); + } + } + } + } + + return result; + } + + + /** + * Collects local variables of the passed statement that are visible for + * the passed loop. Returns null if the loop has not been found. + */ + private ListOfParsableVariable collectLocalVariables(StatementContainer sc, + LoopStatement loop){ + ListOfParsableVariable result = SLListOfParsableVariable.EMPTY_LIST; + for(int i = 0; i < sc.getStatementCount(); i++) { + Statement s = sc.getStatementAt(i); + if(s == loop) { + if(loop instanceof For) { + for(int j = 0; loop.getInitializers() != null + && j < loop.getInitializers().size(); j++) { + if(loop.getInitializers().getLoopInitializer(j) + instanceof LocalVariableDeclaration) { + ArrayOfVariableSpecification vars = + ((LocalVariableDeclaration) + loop.getInitializers() + .getLoopInitializer(j)) + .getVariables(); + for(int k=0; k < vars.size(); k++) { + ProgramVariable pv + = (ProgramVariable) + vars.getVariableSpecification(k) + .getProgramVariable(); + result = result.prepend(pv); + } + } + } + } + return result; + } else if(s instanceof LocalVariableDeclaration) { + ArrayOfVariableSpecification vars = + ((LocalVariableDeclaration) s).getVariables(); + for(int j = 0; j < vars.size(); j++) { + ProgramVariable pv + = (ProgramVariable) vars.getVariableSpecification(j) + .getProgramVariable(); + result = result.prepend(pv); + } + } else if(s instanceof StatementContainer) { + ListOfParsableVariable lpv + = collectLocalVariables((StatementContainer) s, loop); + if(lpv != null){ + result = result.prepend(lpv); + return result; + } + } else if(s instanceof BranchStatement) { + BranchStatement bs = (BranchStatement) s; + for(int j = 0; j < bs.getBranchCount(); j++) { + ListOfParsableVariable lpv + = collectLocalVariables(bs.getBranchAt(j), loop); + if(lpv != null){ + result = result.prepend(lpv); + return result; + } + } + } + } + return null; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public ClassInvariant createJMLClassInvariant(KeYJavaType kjt, + PositionedString originalInv) + throws SLTranslationException { + assert kjt != null; + assert originalInv != null; + + //create variable for self + Sort sort = kjt.getSort(); + ParsableVariable selfVar = new LogicVariable(new Name("self"), sort); + + //translate expression + FormulaWithAxioms inv = translator.translateExpression(originalInv, + kjt, + selfVar, + null, + null, + null, + null); + //create invariant + String name = getInvName(); + return new ClassInvariantImpl(name, + name, + kjt, + inv, + selfVar); + } + + + public ClassInvariant createJMLClassInvariant( + KeYJavaType kjt, + TextualJMLClassInv textualInv) + throws SLTranslationException { + return createJMLClassInvariant(kjt, textualInv.getInv()); + } + + + public SetOfOperationContract createJMLOperationContracts( + ProgramMethod programMethod, + Behavior originalBehavior, + ListOfPositionedString originalRequires, + ListOfPositionedString originalAssignable, + ListOfPositionedString originalEnsures, + ListOfPositionedString originalSignals, + ListOfPositionedString originalSignalsOnly, + ListOfPositionedString originalDiverges) + throws SLTranslationException { + assert programMethod != null; + assert originalBehavior != null; + assert originalRequires != null; + assert originalEnsures != null; + assert originalSignals != null; + assert originalSignalsOnly != null; + assert originalDiverges != null; + assert originalAssignable != null; + + //create variables for self, parameters, result, exception, + //and the map for atPre-Functions + ParsableVariable selfVar = SVF.createSelfVar(services, + programMethod, + false); + ListOfParsableVariable paramVars = SVF.createParamVars(services, + programMethod, + false); + ParsableVariable resultVar = SVF.createResultVar(services, + programMethod, + false); + ParsableVariable excVar = SVF.createExcVar(services, + programMethod, + false); + Map atPreFunctions = new LinkedHashMap(); + IteratorOfPositionedString it; + + //translate requires + FormulaWithAxioms requires = FormulaWithAxioms.TT; + it = originalRequires.iterator(); + while(it.hasNext()) { + FormulaWithAxioms translated + = translator.translateExpression( + it.next(), + programMethod.getContainerType(), + selfVar, + paramVars, + null, + null, + null); + requires = requires.conjoin(translated); + } + + //translate assignable + SetOfLocationDescriptor assignable; + if(originalAssignable.isEmpty()) { + assignable = EverythingLocationDescriptor.INSTANCE_AS_SET; + } else { + assignable = SetAsListOfLocationDescriptor.EMPTY_SET; + it = originalAssignable.iterator(); + while(it.hasNext()) { + SetOfLocationDescriptor translated + = translator.translateAssignableExpression( + it.next(), + programMethod.getContainerType(), + selfVar, + paramVars); + assignable = assignable.union(translated); + } + } + + //translate ensures + FormulaWithAxioms ensures = FormulaWithAxioms.TT; + it = originalEnsures.iterator(); + while(it.hasNext()) { + FormulaWithAxioms translated + = translator.translateExpression( + it.next(), + programMethod.getContainerType(), + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + ensures = ensures.conjoin(translated); + } + + //translate signals + FormulaWithAxioms signals = FormulaWithAxioms.TT; + it = originalSignals.iterator(); + while(it.hasNext()) { + FormulaWithAxioms translated + = translator.translateSignalsExpression( + it.next(), + programMethod.getContainerType(), + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + signals = signals.conjoin(translated); + } + + //translate signals_only + FormulaWithAxioms signalsOnly = FormulaWithAxioms.TT; + it = originalSignalsOnly.iterator(); + while(it.hasNext()) { + FormulaWithAxioms translated + = translator.translateSignalsOnlyExpression( + it.next(), + programMethod.getContainerType(), + excVar); + signalsOnly = signalsOnly.conjoin(translated); + } + + //translate diverges + FormulaWithAxioms diverges = FormulaWithAxioms.FF; + it = originalDiverges.iterator(); + while(it.hasNext()) { + FormulaWithAxioms translated + = translator.translateExpression( + it.next(), + programMethod.getContainerType(), + selfVar, + paramVars, + null, + null, + null); + diverges = diverges.disjoin(translated); + } + + //translate normal_behavior / exceptional_behavior + if(originalBehavior == Behavior.NORMAL_BEHAVIOR) { + assert originalSignals.isEmpty(); + assert originalSignalsOnly.isEmpty(); + signals = FormulaWithAxioms.FF; + signalsOnly = FormulaWithAxioms.FF; + } else if(originalBehavior == Behavior.EXCEPTIONAL_BEHAVIOR) { + assert originalEnsures.isEmpty(); + ensures = FormulaWithAxioms.FF; + } + + //create contract(s) + SetOfOperationContract result + = SetAsListOfOperationContract.EMPTY_SET; + FormulaWithAxioms excNull + = new FormulaWithAxioms(TB.equals(TB.var(excVar), + TB.NULL(services))); + FormulaWithAxioms post1 + = (originalBehavior == Behavior.NORMAL_BEHAVIOR + ? ensures + : excNull.imply(ensures)); + FormulaWithAxioms post2 + = (originalBehavior == Behavior.EXCEPTIONAL_BEHAVIOR + ? signals.conjoin(signalsOnly) + : excNull.negate().imply(signals.conjoin(signalsOnly))); + FormulaWithAxioms post + = post1.conjoin(post2); + if(diverges.equals(FormulaWithAxioms.FF)) { + String name = getContractName(originalBehavior); + OperationContract contract + = new OperationContractImpl(name, + name, + programMethod, + Modality.DIA, + requires, + post, + assignable, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + result = result.add(contract); + } else if(diverges.equals(FormulaWithAxioms.TT)) { + String name = getContractName(originalBehavior); + OperationContract contract + = new OperationContractImpl(name, + name, + programMethod, + Modality.BOX, + requires, + post, + assignable, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + result = result.add(contract); + } else { + String name1 = getContractName(originalBehavior); + String name2 = getContractName(originalBehavior); + OperationContract contract1 + = new OperationContractImpl(name1, + name1, + programMethod, + Modality.DIA, + requires.conjoin(diverges.negate()), + post, + assignable, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + OperationContract contract2 + = new OperationContractImpl(name2, + name2, + programMethod, + Modality.BOX, + requires, + post, + assignable, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + result = result.add(contract1).add(contract2); + } + + return result; + } + + + public SetOfOperationContract createJMLOperationContracts( + ProgramMethod programMethod, + TextualJMLSpecCase textualSpecCase) + throws SLTranslationException { + return createJMLOperationContracts( + programMethod, + textualSpecCase.getBehavior(), + textualSpecCase.getRequires(), + textualSpecCase.getAssignable(), + textualSpecCase.getEnsures(), + textualSpecCase.getSignals(), + textualSpecCase.getSignalsOnly(), + textualSpecCase.getDiverges()); + } + + + public SetOfOperationContract createJMLOperationContractsAndInherit( + ProgramMethod programMethod, + TextualJMLSpecCase textualSpecCase) + throws SLTranslationException { + SetOfOperationContract result + = createJMLOperationContracts(programMethod, textualSpecCase); + + SetOfProgramMethod overridingMethods + = getOverridingMethods(programMethod); + for(IteratorOfProgramMethod it = overridingMethods.iterator(); + it.hasNext(); ) { + ProgramMethod subPm = it.next(); + SetOfOperationContract subContracts + = createJMLOperationContracts(subPm, textualSpecCase); + result = result.union(subContracts); + } + + return result; + } + + + public LoopInvariant createJMLLoopInvariant( + ProgramMethod programMethod, + LoopStatement loop, + ListOfPositionedString originalInvariant, + ListOfPositionedString originalSkolemDeclarations, + ListOfPositionedString originalPredicates, + ListOfPositionedString originalAssignable, + PositionedString originalVariant) + throws SLTranslationException { + assert programMethod != null; + assert loop != null; + assert originalInvariant != null; + assert originalSkolemDeclarations != null; + assert originalPredicates != null; + assert originalAssignable != null; + + //create variables for self, parameters, other relevant local variables + //(disguised as parameters to the translator) and the map for + //atPre-Functions + ParsableVariable selfVar = SVF.createSelfVar(services, + programMethod, + false); + ListOfParsableVariable paramVars = SLListOfParsableVariable.EMPTY_LIST; + int numParams = programMethod.getParameterDeclarationCount(); + for(int i = numParams - 1; i >= 0; i--) { + ParameterDeclaration pd = programMethod.getParameterDeclarationAt(i); + paramVars = paramVars.prepend((ProgramVariable) + pd.getVariableSpecification() + .getProgramVariable()); + } + + ListOfParsableVariable localVars + = collectLocalVariables(programMethod.getBody(), loop); + paramVars = paramVars.append(localVars); + Map atPreFunctions = new LinkedHashMap(); + IteratorOfPositionedString it; + + //translate invariant + Term invariant; + if(originalInvariant.isEmpty()) { + invariant = null; + } else { + invariant = TB.tt(); + it = originalInvariant.iterator(); + while(it.hasNext()) { + FormulaWithAxioms translated + = translator.translateExpression( + it.next(), + programMethod.getContainerType(), + selfVar, + paramVars, + null, + null, + atPreFunctions); + assert translated.getAxioms().isEmpty(); + invariant = TB.and(invariant, translated.getFormula()); + } + } + + //translate skolem declarations + ListOfParsableVariable freeVars = SLListOfParsableVariable.EMPTY_LIST; + it = originalSkolemDeclarations.iterator(); + while(it.hasNext()) { + ListOfLogicVariable translated + = translator.translateVariableDeclaration(it.next()); + IteratorOfLogicVariable it2 = translated.iterator(); + while(it2.hasNext()) { + freeVars = freeVars.prepend(it2.next()); + } + } + + //translate predicates + SetOfTerm predicates = SetAsListOfTerm.EMPTY_SET; + it = originalPredicates.iterator(); + while(it.hasNext()) { + PositionedString ps = it.next(); + String[] exprs = ps.text.split(",", 0); + + for(int i = 0; i < exprs.length; i++) { + FormulaWithAxioms translated + = translator.translateExpression( + new PositionedString(exprs[i]), + programMethod.getContainerType(), + selfVar, + paramVars.append(freeVars), + null, + null, + atPreFunctions); + assert translated.getAxioms().isEmpty(); + predicates = predicates.add(translated.getFormula()); + } + } + + //translate assignable + SetOfLocationDescriptor assignable; + if(originalAssignable.isEmpty()) { + assignable = EverythingLocationDescriptor.INSTANCE_AS_SET; + } else { + assignable = SetAsListOfLocationDescriptor.EMPTY_SET; + it = originalAssignable.iterator(); + while(it.hasNext()) { + SetOfLocationDescriptor translated + = translator.translateAssignableExpression( + it.next(), + programMethod.getContainerType(), + selfVar, + paramVars); + assignable = assignable.union(translated); + } + } + + //translate variant + Term variant; + if(originalVariant == null) { + variant = null; + } else { + FormulaWithAxioms translated + = translator.translateExpression( + originalVariant, + programMethod.getContainerType(), + selfVar, + paramVars, + null, + null, + atPreFunctions); + assert translated.getAxioms().isEmpty(); + variant = translated.getFormula(); + } + + //create loop invariant annotation + return new LoopInvariantImpl(loop, + invariant, + predicates, + assignable, + variant, + selfVar, + atPreFunctions, + true); + } + + + public LoopInvariant createJMLLoopInvariant( + ProgramMethod programMethod, + LoopStatement loop, + TextualJMLLoopSpec textualLoopSpec) + throws SLTranslationException { + return createJMLLoopInvariant(programMethod, + loop, + textualLoopSpec.getInvariant(), + textualLoopSpec.getSkolemDeclarations(), + textualLoopSpec.getPredicates(), + textualLoopSpec.getAssignable(), + textualLoopSpec.getVariant()); + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/translation/JMLTranslator.java b/system/de/uka/ilkd/key/speclang/jml/translation/JMLTranslator.java new file mode 100644 index 00000000000..8190719c1c2 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/translation/JMLTranslator.java @@ -0,0 +1,217 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.jml.translation; + +import java.io.StringReader; +import java.util.Map; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.SetAsListOfLocationDescriptor; +import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.logic.op.ListOfLogicVariable; +import de.uka.ilkd.key.logic.op.ListOfParsableVariable; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.logic.op.SLListOfLogicVariable; +import de.uka.ilkd.key.speclang.FormulaWithAxioms; +import de.uka.ilkd.key.speclang.PositionedString; +import de.uka.ilkd.key.speclang.translation.AxiomCollector; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + + +/** + * Translates JML expressions to FOL. + */ +class JMLTranslator { + + private final Services services; + + + public JMLTranslator(Services services) { + this.services = services; + } + + + /** + * Translates a normal top-level JML expression, i.e. a formula. + */ + public FormulaWithAxioms translateExpression( + PositionedString expr, + KeYJavaType specInClass, + ParsableVariable selfVar, + ListOfParsableVariable paramVars, + ParsableVariable resultVar, + ParsableVariable excVar, + Map /*Operator (normal) + -> Function (atPre)*/ atPreFunctions) + throws SLTranslationException { + assert expr != null; + assert specInClass != null; + + AxiomCollector axiomCollector = new AxiomCollector(); + + KeYJMLParser parser = new KeYJMLParser(expr, + services, + specInClass, + axiomCollector, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + + FormulaWithAxioms result = null; + +// System.out.println("JMLTranslator.translateExpression("+expr+")"); + + result = parser.parseExpression(); + +// System.out.println(result.getFormula().toString()); +// System.out.println(); + + return result; + } + + + /** + * Translates an expression as it occurs in JML signals-clauses, + * i.e. something of the form + * "(typename) expression" + * or + * "(typename varname) expression" + */ + public FormulaWithAxioms translateSignalsExpression( + PositionedString signalsExpr, + KeYJavaType specInClass, + ParsableVariable selfVar, + ListOfParsableVariable paramVars, + ParsableVariable resultVar, + ParsableVariable excVar, + Map /*Operator (normal) + -> Function (atPre)*/ atPreFunctions) + throws SLTranslationException { + AxiomCollector axiomCollector = new AxiomCollector(); + + KeYJMLParser parser = new KeYJMLParser(signalsExpr, + services, + specInClass, + axiomCollector, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + + FormulaWithAxioms result = null; + +// System.out.println("JMLTranslator.translateSignalsExpression("+signalsExpr+") results: "); + + result = parser.parseSignals(); + +// System.out.println(result.getFormula().toString()); +// System.out.println(); + + return result; + } + + + /** + * Translates an expression as it occurs in JML signals_only-clauses, + * i.e. a list of types. + */ + public FormulaWithAxioms translateSignalsOnlyExpression( + PositionedString signalsOnlyExpr, + KeYJavaType specInClass, + ParsableVariable excVar) + throws SLTranslationException { + AxiomCollector axiomCollector = new AxiomCollector(); + + KeYJMLParser parser = new KeYJMLParser(signalsOnlyExpr, + services, + specInClass, + axiomCollector, + null, + null, + null, + excVar, + null); + + FormulaWithAxioms result = null; + +// System.out.println("JMLTranslator.translateSignalsOnlyExpression("+signalsOnlyExpr+") results: "); + + result = parser.parseSignalsOnly(); + +// System.out.println(result.getFormula().toString()); +// System.out.println(); + + return result; + } + + + /** + * Translates an expression as it occurs in JML assignable-clauses. + */ + public SetOfLocationDescriptor translateAssignableExpression( + PositionedString assignableExpr, + KeYJavaType specInClass, + ParsableVariable selfVar, + ListOfParsableVariable paramVars) + throws SLTranslationException { + AxiomCollector axiomCollector = new AxiomCollector(); + + KeYJMLParser parser = new KeYJMLParser(assignableExpr, + services, + specInClass, + axiomCollector, + selfVar, + paramVars, + null, + null, + null); + + SetOfLocationDescriptor result = SetAsListOfLocationDescriptor.EMPTY_SET; + +// System.out.println("JMLTranslator.translateAssignableExpression("+assignableExpr+") results: "); + + result = parser.parseAssignable(); + +// System.out.println(result); +// System.out.println(); + + return result; + } + + + public ListOfLogicVariable translateVariableDeclaration(PositionedString variableDecl) + throws SLTranslationException { + KeYJMLParser parser = new KeYJMLParser(variableDecl, + services, + null, + null, + null, + null, + null, + null, + null); + + ListOfLogicVariable result = SLListOfLogicVariable.EMPTY_LIST; + +// System.out.println("JMLTranslator.translateVariableDeclaration("+variableDecl+") results: "); + + result = parser.parseVariableDeclaration(); + +// System.out.println(result); +// System.out.println(); + + return result; + } +} diff --git a/system/de/uka/ilkd/key/speclang/jml/translation/TestJMLTranslator.java b/system/de/uka/ilkd/key/speclang/jml/translation/TestJMLTranslator.java new file mode 100644 index 00000000000..7f649c2df68 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/translation/TestJMLTranslator.java @@ -0,0 +1,324 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. + + + + +package de.uka.ilkd.key.speclang.jml.translation; + +import java.io.File; +import java.util.LinkedHashMap; +import java.util.Map; + +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; +import de.uka.ilkd.key.java.abstraction.PrimitiveType; +import de.uka.ilkd.key.java.abstraction.SLListOfKeYJavaType; +import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.logic.op.LocationVariable; +import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.speclang.FormulaWithAxioms; +import de.uka.ilkd.key.speclang.PositionedString; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; +import de.uka.ilkd.key.util.HelperClassForTests; + +import junit.framework.TestCase; + + +public class TestJMLTranslator extends TestCase { + + public static final String testFile = System.getProperty("key.home") + + File.separator + "examples" + + File.separator + "_testcase" + + File.separator + "speclang" + + File.separator + "testFile.key"; + + private static final TermBuilder tb = TermBuilder.DF; + + private static JavaInfo javaInfo; + private static Services services; + private static JMLTranslator translator; + private static KeYJavaType testClassType; + + + + protected void setUp() { + if(javaInfo != null) { + return; + } + javaInfo = new HelperClassForTests().parse( + new File(testFile)).getFirstProof().getJavaInfo(); + services = javaInfo.getServices(); + translator = new JMLTranslator(services); + testClassType = javaInfo.getKeYJavaType("testPackage.TestClass"); + } + + + protected void tearDown() { + } + + + protected ProgramVariable buildSelfVarAsProgVar() { + ProgramElementName classPEN = new ProgramElementName("self"); + ProgramVariable result = new LocationVariable(classPEN, testClassType); + return result; + } + + + protected ProgramVariable buildExcVar() { + KeYJavaType excType = javaInfo + .getTypeByClassName("java.lang.Exception"); + ProgramElementName excPEN = new ProgramElementName("exc"); + return new LocationVariable(excPEN, excType); + } + + + public void testTrueTerm() { + FormulaWithAxioms result = null; + + try { + result = translator.translateExpression(new PositionedString("true"), testClassType, + null, null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getFormula().equals(tb.tt())); + assertTrue(result.getAxioms().isEmpty()); + } + + + public void testSelfVar() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + + try { + result = translator.translateExpression(new PositionedString("this"), testClassType, + selfVar, null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + + assertTrue(result != null); + assert result != null; + assertTrue(result.getFormula().equals(tb.var(selfVar))); + assertTrue(result.getAxioms().isEmpty()); + } + + + public void testPrimitiveField() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + ProgramVariable i = javaInfo.getAttribute("testPackage.TestClass::i"); + + try { + result = translator.translateExpression(new PositionedString("this.i"), testClassType, + selfVar, null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getFormula().equals(tb.dot(tb.var(selfVar), i))); + assertTrue(result.getAxioms().isEmpty()); + } + + + public void testSimpleQuery() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + Term queryTerm = javaInfo.getProgramMethodTerm(tb.var(selfVar), + "getOne", new Term[] {}, "testPackage.TestClass"); + + try { + result = translator.translateExpression(new PositionedString("this.getOne()"), + testClassType, selfVar, null, null, null, + new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getFormula().equals(queryTerm)); + assertTrue(result.getAxioms().isEmpty()); + } + + + public void testForAll() { + FormulaWithAxioms result = null; + + try { + result = translator.translateExpression( + new PositionedString("(\\forall int i; (-2147483648 <= i && i <= 2147483647) )"), + this.testClassType, null, null, null, null, + new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getAxioms().isEmpty()); + assertTrue(result.getFormula().op().equals(Op.ALL)); + assertTrue(result.getFormula().sub(0).op().equals(Op.AND)); + assertTrue(result.getFormula().sub(0).sub(0).op() instanceof Function); + assertTrue(((Function) result.getFormula().sub(0).sub(0).op()).name() + .toString().equals("leq")); + } + + + public void testComplexExists() { + FormulaWithAxioms result = null; + + try { + result = translator.translateExpression( + new PositionedString("(\\exists TestClass t; t != null; t.i == 0) )"), + this.testClassType, null, null, null, null, + new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getAxioms().isEmpty()); + assertTrue(result.getFormula().op().equals(Op.EX)); + assertTrue(result.getFormula().sub(0).op().equals(Op.AND)); + } + + + public void testOld() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + ProgramVariable excVar = buildExcVar(); + + Map atPreDefs = new LinkedHashMap(); + + try { + result = translator.translateExpression(new PositionedString("this.i == \\old(this.i)"), + testClassType, selfVar, null, null, excVar, atPreDefs); + } catch (SLTranslationException e) { + e.printStackTrace(); + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getAxioms().isEmpty()); + assertTrue(atPreDefs.size() == 2); // one for "this" and one for "i" + assertTrue(result.getFormula().op().equals(Op.EQUALS)); + } + + + public void testComplexQueryResolving1() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + + ListOfKeYJavaType signature = SLListOfKeYJavaType.EMPTY_LIST; + signature = signature.append(javaInfo + .getKeYJavaType(PrimitiveType.JAVA_INT)); + + ProgramMethod pm = javaInfo.getProgramMethod(testClassType, "m", + signature, testClassType); + + try { + result = translator.translateExpression( + new PositionedString("this.m((long) 4 + 2) == this.m(l+i)"), testClassType, + selfVar, null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + e.printStackTrace(); + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getAxioms().isEmpty()); + assertTrue(result.getFormula().sub(0).op().equals(pm)); + assertTrue(result.getFormula().sub(1).op().equals(pm)); + } + + + public void testComplexQueryResolving2() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + + ListOfKeYJavaType signature = SLListOfKeYJavaType.EMPTY_LIST; + signature = signature.append(javaInfo + .getKeYJavaType(PrimitiveType.JAVA_LONG)); + + ProgramMethod pm = javaInfo.getProgramMethod(testClassType, "m", + signature, testClassType); + + try { + result = translator.translateExpression( + new PositionedString("this.m(l) == this.m((long)i)"), testClassType, selfVar, + null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + e.printStackTrace(); + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getAxioms().isEmpty()); + assertTrue(result.getFormula().sub(0).op().equals(pm)); + assertTrue(result.getFormula().sub(1).op().equals(pm)); + } + + + public void testStaticQueryResolving() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + + ListOfKeYJavaType signature = SLListOfKeYJavaType.EMPTY_LIST; + + ProgramMethod pm = javaInfo.getProgramMethod(testClassType, + "staticMethod", signature, testClassType); + + try { + result = translator.translateExpression( + new PositionedString("testPackage.TestClass.staticMethod() == 4"), testClassType, selfVar, + null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + e.printStackTrace(); + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getAxioms().isEmpty()); + assertTrue(result.getFormula().sub(0).op().equals(pm)); + } +} diff --git a/system/de/uka/ilkd/key/parser/jml/lexer.g b/system/de/uka/ilkd/key/speclang/jml/translation/jmllexer.g old mode 100755 new mode 100644 similarity index 89% rename from system/de/uka/ilkd/key/parser/jml/lexer.g rename to system/de/uka/ilkd/key/speclang/jml/translation/jmllexer.g index 2ece05e7cf3..1f99669750f --- a/system/de/uka/ilkd/key/parser/jml/lexer.g +++ b/system/de/uka/ilkd/key/speclang/jml/translation/jmllexer.g @@ -17,7 +17,7 @@ /* -*-Antlr-*- */ header { - package de.uka.ilkd.key.parser.jml; + package de.uka.ilkd.key.speclang.jml.translation; } class KeYJMLLexer extends Lexer; @@ -44,28 +44,6 @@ tokens { WRITEABLE = "writable"; MONITORS_FOR = "monitors_for"; AT = "@"; - THROWS = "throws"; - REQUIRES = "requires"; - ENSURES = "ensures"; - REQUIRES_REDUNDANTLY = "requires_redundantly"; - ENSURES_REDUNDANTLY = "ensures_redundantly"; - POST = "post"; - PRE = "pre"; - POST_REDUNDANTLY = "post_redundantly"; - PRE_REDUNDANTLY = "pre_redundantly"; - FOR_EXAMPLE = "for_example"; - IMPLIES_THAT = "implies_that"; - ASSIGNABLE = "assignable"; - MODIFIES = "modifies"; - MODIFIABLE = "modifiable"; - VOID = "void"; - ASSIGNABLE_REDUNDANTLY = "assignable_redundantly"; - MODIFIES_REDUNDANTLY = "modifies_redundantly"; - MODIFIABLE_REDUNDANTLY = "modifiable_redundantly"; - INVARIANT = "invariant"; - INVARIANT_REDUNDANTLY = "invariant_redundantly"; - CONSTRAINT = "constraint"; - CONSTRAINT_REDUNDANTLY = "constraint_redundantly"; IN = "in"; IN_REDUNDANTLY = "in_redundantly"; PLUS = "+"; @@ -149,6 +127,7 @@ tokens { CODE_BIGINT_MATH = "code_bigint_math"; CODE_CONTRACT = "code_contract"; NON_NULL = "non_null"; + NULLABLE = "nullable"; FINAL= "final"; MEASURED_BY_REDUNDANTLY = "measured_by_redundantly"; CALLABLE_REDUNDANTLY = "callable_redundantly"; @@ -205,6 +184,7 @@ EVERYTHING : "\\everything"; PRIVATEDATA : "\\private_data"; INTO : "\\into"; OLD : "\\old"; +PRE : "\\pre"; CREATED : "\\created"; BIGINT : "\\bigint"; COMMA : ","; diff --git a/system/de/uka/ilkd/key/speclang/jml/translation/jmlparser.g b/system/de/uka/ilkd/key/speclang/jml/translation/jmlparser.g new file mode 100644 index 00000000000..cd693c0184b --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/jml/translation/jmlparser.g @@ -0,0 +1,1683 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +//Universitaet Koblenz-Landau, Germany +//Chalmers University of Technology, Sweden + +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. + + + +/* -*-antlr-*- */ +header { + package de.uka.ilkd.key.speclang.jml.translation; + + import java.io.StringReader; + + import de.uka.ilkd.key.java.JavaInfo; + import de.uka.ilkd.key.java.Position; + import de.uka.ilkd.key.java.Services; + import de.uka.ilkd.key.java.abstraction.ArrayType; + import de.uka.ilkd.key.java.abstraction.IteratorOfKeYJavaType; + import de.uka.ilkd.key.java.abstraction.KeYJavaType; + import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; + import de.uka.ilkd.key.java.abstraction.PrimitiveType; + import de.uka.ilkd.key.java.abstraction.SLListOfKeYJavaType; + import de.uka.ilkd.key.java.expression.literal.BooleanLiteral; + import de.uka.ilkd.key.java.recoderext.ImplicitFieldAdder; + import de.uka.ilkd.key.logic.BasicLocationDescriptor; + import de.uka.ilkd.key.logic.EverythingLocationDescriptor; + import de.uka.ilkd.key.logic.IteratorOfTerm; + import de.uka.ilkd.key.logic.ListOfTerm; + import de.uka.ilkd.key.logic.LocationDescriptor; + import de.uka.ilkd.key.logic.Name; + import de.uka.ilkd.key.logic.SetAsListOfLocationDescriptor; + import de.uka.ilkd.key.logic.SetOfLocationDescriptor; + import de.uka.ilkd.key.logic.SLListOfTerm; + import de.uka.ilkd.key.logic.Term; + import de.uka.ilkd.key.logic.TermBuilder; + import de.uka.ilkd.key.logic.TermCreationException; + import de.uka.ilkd.key.logic.ldt.AbstractIntegerLDT; + import de.uka.ilkd.key.logic.op.Function; + import de.uka.ilkd.key.logic.op.InstanceofSymbol; + import de.uka.ilkd.key.logic.op.IteratorOfLogicVariable; + import de.uka.ilkd.key.logic.op.IteratorOfParsableVariable; + import de.uka.ilkd.key.logic.op.ListOfLogicVariable; + import de.uka.ilkd.key.logic.op.ListOfParsableVariable; + import de.uka.ilkd.key.logic.op.LogicVariable; + import de.uka.ilkd.key.logic.op.NonRigid; + import de.uka.ilkd.key.logic.op.Operator; + import de.uka.ilkd.key.logic.op.ParsableVariable; + import de.uka.ilkd.key.logic.op.ProgramVariable; + import de.uka.ilkd.key.logic.op.RigidFunction; + import de.uka.ilkd.key.logic.op.SLListOfLogicVariable; + import de.uka.ilkd.key.logic.sort.AbstractSort; + import de.uka.ilkd.key.logic.sort.ArraySort; + import de.uka.ilkd.key.logic.sort.ObjectSort; + import de.uka.ilkd.key.logic.sort.Sort; + import de.uka.ilkd.key.logic.sort.SortDefiningSymbols; + import de.uka.ilkd.key.proof.AtPreFactory; + import de.uka.ilkd.key.proof.OpReplacer; + import de.uka.ilkd.key.proof.init.CreatedAttributeTermFactory; + import de.uka.ilkd.key.speclang.FormulaWithAxioms; + import de.uka.ilkd.key.speclang.PositionedString; + import de.uka.ilkd.key.speclang.translation.*; + import de.uka.ilkd.key.util.Debug; + + import java.lang.RuntimeException; + import java.util.Map; + import java.util.LinkedHashMap; +} + +class KeYJMLParser extends Parser; +options { + importVocab=KeYJMLLexer; + k = 2; + defaultErrorHandler=false; +} + +{ + private static final TermBuilder tb = TermBuilder.DF; + private static final AtPreFactory APF = AtPreFactory.INSTANCE; + + private Services services; + private JavaInfo javaInfo; + private SLTranslationExceptionManager excManager; + + private static Sort boolSort; + private static Term trueLitTerm; + + private ParsableVariable selfVar; + private ListOfParsableVariable paramVars; + private ParsableVariable resultVar; + private ParsableVariable excVar; + private Map atPreFunctions; + + private String fileName; + private Position offsetPos; + + // Helper objects + private JMLResolverManager resolverManager; + private AxiomCollector axiomCollector; + private JavaIntegerSemanticsHelper intHelper; + + // Helper attributes + private boolean currentlyParsing = false; + private static int varCounter = 0; + + public KeYJMLParser(TokenStream lexer, + String fileName, + Position offsetPos, + Services services, + KeYJavaType specInClass, + AxiomCollector ac, + ParsableVariable self, + ListOfParsableVariable paramVars, + ParsableVariable result, + ParsableVariable exc, + /*inout*/ Map /*operator (normal) + -> function (atPre)*/ atPreFunctions) { + this(lexer); + + // save parameters + this.services = services; + this.javaInfo = services.getJavaInfo(); + this.excManager = new SLTranslationExceptionManager(this, + fileName, + offsetPos); + this.axiomCollector = ac; + this.selfVar = self; + this.paramVars = paramVars; + this.resultVar = result; + this.excVar = exc; + this.atPreFunctions = atPreFunctions; + + // initialize helper objects + this.resolverManager = new JMLResolverManager(this.javaInfo, specInClass); + + // initialize namespaces + resolverManager.pushLocalVariablesNamespace(); + if (selfVar != null) { + resolverManager.putIntoTopLocalVariablesNamespace(selfVar); + } + if (paramVars != null) { + IteratorOfParsableVariable it = paramVars.iterator(); + while(it.hasNext()) { + resolverManager.putIntoTopLocalVariablesNamespace(it.next()); + } + } + if (resultVar != null) { + resolverManager.putIntoTopLocalVariablesNamespace(resultVar); + } + + this.intHelper = new JavaIntegerSemanticsHelper(services); + + trueLitTerm = services.getTypeConverter() + .convertToLogicElement(BooleanLiteral.TRUE); + boolSort = services.getJavaInfo() + .getKeYJavaType(PrimitiveType.JAVA_BOOLEAN) + .getSort(); + } + + + public KeYJMLParser(PositionedString ps, + Services services, + KeYJavaType specInClass, + AxiomCollector ac, + ParsableVariable self, + ListOfParsableVariable paramVars, + ParsableVariable result, + ParsableVariable exc, + /*inout*/ Map /*operator (normal) + -> function (atPre)*/ atPreFunctions) { + this(new KeYJMLLexer(new StringReader(ps.text)), + ps.fileName, + ps.pos, + services, + specInClass, + ac, + self, + paramVars, + result, + exc, + atPreFunctions); + } + + + private void raiseError(String msg) throws SLTranslationException { + throw excManager.createException(msg); + } + + + private void raiseNotSupported(String feature) + throws SLTranslationException { + throw excManager.createException("JML feature not supported: " + + feature); + } + + + private Term castToJint(Term intTerm) { + return tb.tf().createCastTerm((AbstractSort)services.getTypeConverter() + .getIntLDT().targetSort(), + intTerm); + } + + + public FormulaWithAxioms parseExpression() throws SLTranslationException { + + Term result = null; + this.currentlyParsing = true; + + try { + result = expression(); + } catch (antlr.ANTLRException e) { + throw excManager.convertException(e); + } + + this.currentlyParsing = false; + + return new FormulaWithAxioms(convertToFormula(result), axiomCollector.getAxioms()); + } + + + public FormulaWithAxioms parseSignals() throws SLTranslationException { + + Term result = null; + this.currentlyParsing = true; + + try { + result = signalsclause(); + } catch (antlr.ANTLRException e) { + throw excManager.convertException(e); + } + + this.currentlyParsing = false; + + return new FormulaWithAxioms(convertToFormula(result), axiomCollector.getAxioms()); + } + + + public FormulaWithAxioms parseSignalsOnly() throws SLTranslationException { + + ListOfKeYJavaType signalsonly = null; + this.currentlyParsing = true; + + try { + signalsonly = signalsonlyclause(); + } catch (antlr.ANTLRException e) { + throw excManager.convertException(e); + } + + this.currentlyParsing = false; + + // Build appropriate term out of the parsed list of types + // i.e. disjunction of "excVar instanceof ExcType" + // for every ExcType in the list + Term result = tb.ff(); + + IteratorOfKeYJavaType it = signalsonly.iterator(); + while (it.hasNext()) { + KeYJavaType kjt = it.next(); + SortDefiningSymbols os = (SortDefiningSymbols)(kjt.getSort()); + Function instance + = (InstanceofSymbol) os.lookupSymbol(InstanceofSymbol.NAME); + result = tb.or( result, + tb.equals( + tb.func(instance, tb.var(this.excVar)), + trueLitTerm)); + } + + return new FormulaWithAxioms(result); + } + + + public SetOfLocationDescriptor parseAssignable() throws SLTranslationException { + + SetOfLocationDescriptor assignableClause = SetAsListOfLocationDescriptor.EMPTY_SET; + + this.currentlyParsing = true; + try { + assignableClause = assignableclause(); + } catch (antlr.ANTLRException e) { + throw excManager.convertException(e); + } + this.currentlyParsing = false; + + return assignableClause; + } + + + public ListOfLogicVariable parseVariableDeclaration() throws SLTranslationException { + + ListOfLogicVariable result = SLListOfLogicVariable.EMPTY_LIST; + + this.currentlyParsing = true; + try { + result = quantifiedvardecls(); + } catch (antlr.ANTLRException e) { + throw excManager.convertException(e); + } + this.currentlyParsing = false; + + return result; + } + + + + /** + * Extracts a term's subterms as an array. + */ + private Term[] getSubTerms(Term term) { + Term[] result = new Term[term.arity()]; + for(int i = 0; i < term.arity(); i++) { + result[i] = term.sub(i); + assert result[i] != null; + } + return result; + } + + + /** + * Extracts the sorts from an array of terms as an array. + */ + private Sort[] getSorts(Term[] terms) { + Sort[] result = new Sort[terms.length]; + for(int i = 0; i < terms.length; i++) { + result[i] = terms[i].sort(); + } + return result; + } + + /** + * Converts a term so that all of its non-rigid operators refer to the pre-state. + * Creates and saves new atPreFunctions when necessary. + */ + private Term convertToOld(Term term) { + assert atPreFunctions != null; + Operator newOp; + if(term.op() instanceof NonRigid) { + Function atPreFunc = (Function) atPreFunctions.get(term.op()); + if(atPreFunc == null) { + atPreFunc = APF.createAtPreFunction(term.op(), services); + atPreFunctions.put(term.op(), atPreFunc); + assert atPreFunc != null; + } + newOp = atPreFunc; + } else { + newOp = term.op(); + } + + Term[] subTerms = getSubTerms(term); + Term[] newSubTerms = new Term[subTerms.length]; + for(int i = 0; i < subTerms.length; i++) { + newSubTerms[i] = convertToOld(subTerms[i]); + } + + Term result = tb.tf().createTerm(newOp, + newSubTerms, + term.varsBoundHere(0), + term.javaBlock()); + return result; + } + + + private JMLExpression lookupIdentifier(String id, JMLExpression receiver, ListOfTerm callingParameters) throws SLTranslationException { + + // Identifier with suffix in parantheses? Probably a method call + // parse in the parameter list and call again + try { + if (LA(1) == LPAREN) { + return receiver; + } + } catch (TokenStreamException e) { + if(currentlyParsing) { + raiseError("internal Error: no further Token in Stream"); + } + } + + + ListOfSLExpression paramList = null; + SLParameters params = null; + if (callingParameters != null) { + paramList = SLListOfSLExpression.EMPTY_LIST; + + IteratorOfTerm it = callingParameters.iterator(); + while(it.hasNext()) { + paramList = paramList.append(new JMLExpression(it.next())); + } + params = new SLParameters(paramList); + } + + JMLExpression result = (JMLExpression) resolverManager.resolve(receiver, id, params); + if (result != null) { + return result; + } + + // no identifier found, maybe it was just a package prefix. + // but package prefixes don't have a receiver! + + if (receiver != null) { + raiseError("Identifier " + id + " not found!"); + } + + return null; + } + + + // If a is a boolean literal, the method returns the literal as a Formula. + private static Term convertToFormula(Term a) { + + if(a.sort() == boolSort) { + return tb.equals(a,trueLitTerm); + } + + return a; + } + + private Term buildEqualityTerm(Term a, Term b) throws SLTranslationException { + + Term result = null; + + try { + if(a.sort() != Sort.FORMULA && b.sort() != Sort.FORMULA) { + result = tb.equals(a,b); + } else { + result = tb.equiv(convertToFormula(a), convertToFormula(b)); + } + } catch (IllegalArgumentException e) { + try { + raiseError("Illegal Arguments in equality expression near " + LT(0)); + } catch (TokenStreamException tse) { + System.err.println("No further Token in stream"); + raiseError("Illegal Arguments in equality expression"); + } + } catch (TermCreationException e) { + raiseError("Error in equality-expression\n" + a.toString() + " == " + b.toString() + "."); + } + + return result; + } + + + + + + + /** + * @param maxmin true for max-Axiom, false for min-Axiom + * + * See minor thesis "A translation from JML to Java DL" by Christian Engel, p. 40 + */ + private Term buildMaxMinAxiom(boolean maxmin, Function y, ListOfLogicVariable qVars, Term pred, Term body) { + + Term result = tb.not(tb.ex(qVars.toArray(), pred)); + + ProgramVariable n; + String progVarName; + String className; + if (maxmin) { + progVarName = "MIN_VALUE"; + } else { + progVarName = "MAX_VALUE"; + } + +// System.out.println(); +// System.out.println(qVars.head().sort().toString()); +// System.out.println(); + + if (qVars.head().sort().toString().equals("jlong")) { + className = "java.lang.Long"; + } else { + className = "java.lang.Integer"; + } + + n = javaInfo.getAttribute(progVarName, className); + + result = tb.and(result, + tb.equals( + tb.func(y), + tb.var(n))); + + Term t = tb.func(y); + + if (maxmin) { + t = tb.geq(t,body, services); + } else { + t = tb.leq(t,body, services); + } + + t = tb.all(qVars.toArray(), tb.imp(pred,t)); + t = tb.and( + t, + tb.ex(qVars.toArray(), + tb.and( + pred, + tb.equals( + body, + tb.func(y))))); + + result = tb.or(result, t); + + return result; + } +} + +top throws SLTranslationException +{ + Term t; +} +: + t=expression + { + Debug.fail("Should be never entered. Only workaround of an antlr bug."); + } + ; + + +assignableclause returns [SetOfLocationDescriptor result=SetAsListOfLocationDescriptor.EMPTY_SET] throws SLTranslationException +: + result=storereflist + ; + + +storereflist returns [SetOfLocationDescriptor result=SetAsListOfLocationDescriptor.EMPTY_SET] throws SLTranslationException +{ + LocationDescriptor ld=null; +} +: + ld=storeref { if (ld != null) { result = result.add(ld); } } + ("," ld=storeref { if (ld != null) { result = result.add(ld); } })* + ; + + +storeref returns [LocationDescriptor ld=null] throws SLTranslationException +: + ld=storerefexpression + | { raiseError("informal descriptions not supported (for obvious reason)\n Ignoring it"); } +//TODO: should be a warning! +// | { raiseWarning("informal descriptions not supported (for obvious reason)\n Ignoring it"); } + LPAREN MULT + //informaldescription + | ld=storerefkeyword + ; + +storerefexpression returns [BasicLocationDescriptor ld=null] throws SLTranslationException +{ + JMLExpression expr; +} +: + expr=storerefname + ( + ld=storerefnamesuffix[expr] { expr = new JMLExpression(ld.getLocTerm()); } + )* + { + if(ld == null) { + ld = new BasicLocationDescriptor(expr.getTerm()); + } + } + ; + + +storerefname returns [JMLExpression result = null] throws SLTranslationException +: + id:IDENT + { + result = lookupIdentifier(id.getText(), null, null); + } + | "super" + { + raiseNotSupported("location \"super\""); + } + | "this" + { + result = new JMLExpression(tb.var(selfVar)); + } + ; + + +storerefnamesuffix[JMLExpression receiver] returns [BasicLocationDescriptor ld=null] throws SLTranslationException +{ + Term refTerm=null; +} +: + DOT id:IDENT + { + JMLExpression expr = lookupIdentifier(id.getText(), receiver, null); + if (!expr.isTerm()) { + raiseError("Error in store-ref-suffix"); + } + try { + ld = new BasicLocationDescriptor(expr.getTerm()); + } catch (IllegalArgumentException e) { + raiseError(e.getMessage()); + } + } + | DOT "this" + { + raiseNotSupported("location \"this\" as store-ref-suffix"); + } + | "[" ld=specarrayrefexpr[receiver] "]" + | DOT MULT + { + raiseNotSupported("location \"*\" as store-ref-suffix"); + } + ; + +specarrayrefexpr[JMLExpression receiver] returns [BasicLocationDescriptor result=null] throws SLTranslationException +{ + Term rangeFrom=null; + Term rangeTo=null; +} +: + ( + ( rangeFrom=specexpression (DOTDOT rangeTo=specexpression)? ) + | MULT + ) + { + if (rangeFrom == null) { + // We have a star + Function sub = services.getTypeConverter().getIntegerLDT().getSub(); + rangeFrom = tb.zTerm(services, "0"); + rangeTo = tb.func(sub, + tb.dot(receiver.getTerm(), javaInfo.getArrayLength()), + tb.zTerm(services, "1")); + } + + Term indexTerm; + Term guardTerm; + + if (rangeTo != null) { + LogicVariable indexVar = new LogicVariable(new Name("i"), + (Sort) services.getNamespaces().sorts().lookup(new Name("int"))); + indexTerm = tb.var(indexVar); + guardTerm = tb.and( + tb.leq(rangeFrom, indexTerm, services), + tb.leq(indexTerm, rangeTo, services) + ); + } else { + indexTerm = rangeFrom; + guardTerm = tb.tt(); + } + + try { + Term resTerm = tb.array(receiver.getTerm(), indexTerm); + result = new BasicLocationDescriptor(guardTerm, resTerm); + } catch (TermCreationException e) { + raiseError(e.getMessage()); + } catch (IllegalArgumentException e) { + raiseError(e.getMessage()); + } + } + ; + +storerefkeyword returns [LocationDescriptor ld=null] throws SLTranslationException +: + NOTHING + | EVERYTHING { ld = EverythingLocationDescriptor.INSTANCE; } + | NOT_SPECIFIED { ld = EverythingLocationDescriptor.INSTANCE; } +; + + +signalsonlyclause returns [ListOfKeYJavaType result = SLListOfKeYJavaType.EMPTY_LIST] throws SLTranslationException +{ + KeYJavaType t=null; +} +: + NOTHING + | t=referencetype { result = result.append(t); } ("," t=referencetype { result = result.append(t); })* + ; + +signalsclause returns [Term result=null] throws SLTranslationException +{ + KeYJavaType excType = null; + Term pred = null; + String vName = null; + LogicVariable eVar = null; +} +: + LPAREN excType=referencetype (id:IDENT { vName = id.getText(); })? RPAREN + { + if (vName != null) { + eVar = new LogicVariable(new Name(vName), excType.getSort()); + resolverManager.pushLocalVariablesNamespace(); + resolverManager.putIntoTopLocalVariablesNamespace(eVar); + } + } + (result = predornot)? + { + if (vName != null) { + resolverManager.popLocalVariablesNamespace(); + } + if (result == null) { + result = tb.tt(); + } else { + Map /* Operator -> Operator */ replaceMap = new LinkedHashMap(); + replaceMap.put(eVar, excVar); + OpReplacer excVarReplacer = new OpReplacer(replaceMap); + + SortDefiningSymbols os = (SortDefiningSymbols)(excType.getSort()); + Function instance + = (InstanceofSymbol) os.lookupSymbol(InstanceofSymbol.NAME); + + result = tb.imp( + tb.equals(tb.func(instance, tb.var(excVar)), trueLitTerm), + convertToFormula(excVarReplacer.replace(result))); + } + } + ; + +predornot returns [Term result=null] throws SLTranslationException +: + result=predicate + | "\\not_specified" + | "\\same" + ; + +predicate returns [Term result=null] throws SLTranslationException +: + result=specexpression + ; + +specexpression returns [Term result=null] throws SLTranslationException +: + result=expression + ; + +spec_expression_list throws SLTranslationException +{ + Term t; +} +: + t=specexpression ("," t=specexpression)* + ; + +expression returns [Term result=null] throws SLTranslationException +: + result=assignmentexpr + ; + +assignmentexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=conditionalexpr +// not used in JML expressions +// ( +// assignmentOp t=assignmentexpr +// )? + ; + + +/* not used JML expressions +assignmentOp +: + "=" + | "+=" + | "-=" + | "*=" + | "/=" + | "%=" + | ">>=" + | ">>>=" + | "<<=" + | "&=" + | "|=" + | "^=" + ; +*/ +conditionalexpr returns [Term result=null] throws SLTranslationException +{ + Term a,b; +} +: + result=equivalenceexpr + ( + "?" a=conditionalexpr ":" b=conditionalexpr + { + result = tb.ife(convertToFormula(result),a,b); + } + )? + ; + +equivalenceexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=impliesexpr + ( + EQV t=equivalenceexpr + { + result = buildEqualityTerm(result,t); + } + + | + ANTIV t=equivalenceexpr + { + t = buildEqualityTerm(result,t); + result = tb.not(t); + } + + )? + ; + +impliesexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=logicalorexpr + ( + "==>" t=impliesnonbackwardexpr + { + result = tb.imp(convertToFormula(result),convertToFormula(t)); + } + + | + ( + "<==" t=logicalorexpr + { + result = tb.imp(convertToFormula(t),convertToFormula(result)); + } + )+ + )? +; + +impliesnonbackwardexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=logicalorexpr + ( + "==>" t=impliesnonbackwardexpr + { + result = tb.imp(convertToFormula(result),convertToFormula(t)); + } + )? +; + +logicalorexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=logicalandexpr + ( + "||" t=logicalorexpr + { + result = intHelper.buildOrExpression(t,result); + } + )? +; + +logicalandexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=inclusiveorexpr + ( + "&&" t=logicalandexpr + { + result = intHelper.buildAndExpression(t,result); + } + )? +; + + +inclusiveorexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=exclusiveorexpr + ( + "|" t=inclusiveorexpr + { + result = intHelper.buildPromotedOrExpression(result,t); + } + )? +; + + +exclusiveorexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=andexpr + ( + XOR t=exclusiveorexpr + { + result = intHelper.buildPromotedXorExpression(result,t); + } + )? +; + + +andexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=equalityexpr + ( + "&" t=andexpr + { + result = intHelper.buildPromotedAndExpression(result,t); + } + )? +; + + +equalityexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=relationalexpr + ( + "==" t=equalityexpr + { + result = buildEqualityTerm(result,t); + } + | + "!=" t=equalityexpr + { + t = buildEqualityTerm(result,t); + result = tb.not(t); + } + + )? +; + +relationalexpr returns [Term result=null] throws SLTranslationException +{ + Term t = null; + Function f = null; + KeYJavaType type = null; +} +: + result=shiftexpr + ( + LT t=shiftexpr + { + f = services.getTypeConverter().getIntegerLDT().getLessThan(); + } + | + GT t=shiftexpr + { + f = services.getTypeConverter().getIntegerLDT().getGreaterThan(); + } + | + LEQ t=shiftexpr + { + f = services.getTypeConverter().getIntegerLDT().getLessOrEquals(); + } + | + GEQ t=shiftexpr + { + f = services.getTypeConverter().getIntegerLDT().getGreaterOrEquals(); + } + | + INSTANCEOF type=typespec + { + SortDefiningSymbols os = (SortDefiningSymbols)(type.getSort()); + f = (InstanceofSymbol) os.lookupSymbol(InstanceofSymbol.NAME); + } + | + ST t=shiftexpr + { + raiseNotSupported("<:"); + } + )? + { + if (f != null) { + try { + result = (t == null ? tb.func(f, result) : tb.func(f,result,t)); + } catch (TermCreationException e) { + raiseError("Error in relational expression."); + } catch (IllegalArgumentException e) { + raiseError("Internal error."); + } + } + } +; + +shiftexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=additiveexpr + ( + ">>" t=additiveexpr + { + result = intHelper.buildRightShiftExpression(result,t); + } + | + "<<" t=additiveexpr + { + result = intHelper.buildLeftShiftExpression(result,t); + } + | + ">>>" t=additiveexpr + { + result = intHelper.buildUnsignedRightShiftExpression(result,t); + } + )* +; + + +additiveexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=multexpr + ( + "+" t=multexpr + { + result = intHelper.buildAddExpression(result,t); + } + | + "-" t=multexpr + { + result = intHelper.buildSubExpression(result,t); + } + )* +; + + +multexpr returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + result=unaryexpr + ( + MULT t=unaryexpr + { + result = intHelper.buildMulExpression(result,t); + } + | + DIV t=unaryexpr + { + result = intHelper.buildDivExpression(result,t); + } + | + "%" t=unaryexpr + { + result = intHelper.buildModExpression(result,t); + } + )* +; + + +unaryexpr returns [Term result=null] throws SLTranslationException +{ + KeYJavaType type = null; +} +: +( + "+" result=unaryexpr + { + result = intHelper.buildPromotedUnaryPlusExpression(result); + } + | + "-" result=unaryexpr + { + result = intHelper.buildUnaryMinusExpression(result); + } + | + ("(" type=builtintype ")") => + "(" type=builtintype ")" result=unaryexpr + + | + ("(" type=referencetype ")" ) => + "(" type=referencetype ")" result=unaryexpr + + | + result=unaryexprnotplusminus +) + { + if (type != null) { + if (!(type.getSort() instanceof AbstractSort)) { + raiseError("Wrong type argument in cast expression."); + } + + result = tb.tf().createCastTerm( + (AbstractSort) type.getSort(), + result); + } + } +; + + +unaryexprnotplusminus returns [Term result=null] throws SLTranslationException +{ + Term t; +} +: + "!" t=unaryexpr + { + if (t.sort() == Sort.FORMULA) { + result = tb.not(t); + } else if (t.sort() == boolSort) { + result = tb.not(tb.equals(t,trueLitTerm)); + } else { + raiseError("Wrong type in not-expression: " + t); + } + } + | + "~" result=unaryexpr + { + result = intHelper.buildPromotedNegExpression(result); + } + + | + result=postfixexpr +; + + +postfixexpr returns [Term result=null] throws SLTranslationException +{ + String fullyQualifiedName = ""; + JMLExpression expr = null; +} +: + expr=primaryexpr + { + fullyQualifiedName = LT(0).getText(); + } + ( + expr=primarysuffix[expr, fullyQualifiedName] + { + fullyQualifiedName += "." + LT(0).getText(); + } + )* + + { + if (expr == null || !expr.isTerm()) { + raiseError("Expression " + fullyQualifiedName + " not found!"); + } + + result = expr.getTerm(); + } + +; + +primaryexpr returns [JMLExpression result=null] throws SLTranslationException +{ + Term t; +} +: + t=constant { result = new JMLExpression(t); } + | id:IDENT { result = lookupIdentifier(id.getText(), null, null); } + | "true" { result = new JMLExpression(tb.tt()); } + | "false" { result = new JMLExpression(tb.ff()); } + | "null" { result = new JMLExpression(tb.NULL(services)); } + | t=jmlprimary { result = new JMLExpression(t); } + | "this" { result = new JMLExpression(tb.var(selfVar)); } + | new_expr +; + +primarysuffix[JMLExpression receiver, String fullyQualifiedName] returns [JMLExpression result=null] throws SLTranslationException +{ + Term t; + String lookupName = null; + + ListOfTerm callingParameters = SLListOfTerm.EMPTY_LIST; +} +: +{ + lookupName = fullyQualifiedName; +} +( + DOT id:IDENT + { + if (receiver == null) { + // Receiver was only a package/classname prefix + lookupName = fullyQualifiedName + "." + id.getText(); + } else { + lookupName = id.getText(); + } + result = lookupIdentifier(lookupName, receiver, null); + } + | + LPAREN (callingParameters=expressionlist)? RPAREN + { +/* + System.out.println("Looking up: " + lookupName); + System.out.println("method lookup with parameters:"); + System.out.println(callingParameters.toString()); + System.out.println("and receiver: " + receiver); + System.out.println(); +*/ + result = lookupIdentifier(lookupName, receiver, callingParameters); + if (result == null) { + // method calls must result in an object! + raiseError("Method " + lookupName + " not found!"); + } + } + | + "[" t=expression "]" + { + if (receiver==null || !receiver.isTerm()) { + raiseError("Error in Array-Expression."); + } + + try { + result = new JMLExpression(tb.array(receiver.getTerm(),t)); + } catch (TermCreationException e) { + raiseError(e.getMessage()); + } catch (IllegalArgumentException e) { + raiseError(e.getMessage()); + } + } +) +; + +new_expr throws SLTranslationException +{ + KeYJavaType typ = null; +} +: + "new" typ=type new_suffix + + ; + +new_suffix throws SLTranslationException +{ + ListOfTerm terms; +} +: + "(" ( terms=expressionlist )? ")" + ; + +expressionlist returns [ListOfTerm result=SLListOfTerm.EMPTY_LIST] throws SLTranslationException +{ + Term t; +} +: + t=expression { result = result.append(t); } ("," t=expression {result = result.append(t);} )* +; + +constant returns [Term result=null] throws SLTranslationException +: + result=javaliteral +; + +javaliteral returns [Term result=null] throws SLTranslationException +: + result=integerliteral + | + STRING_LITERAL + { + raiseNotSupported("string literals"); + } + | + CHAR_LITERAL + { + raiseNotSupported("character literals"); + } + ; + +integerliteral returns [Term result=null] throws SLTranslationException +: + result=decimalintegerliteral +; + +decimalintegerliteral returns [Term result=null] throws SLTranslationException +: + result=decimalnumeral +; + +decimalnumeral returns [Term result=null] throws SLTranslationException +: + n:DIGITS + { + result = castToJint(tb.zTerm(services,n.getText())); + } +; + +jmlprimary returns [Term result=null] throws SLTranslationException +{ + Term t; + KeYJavaType typ; +} +: + RESULT + { + if (resultVar==null) { + raiseError("\\result used in wrong context"); + } + result = tb.var(resultVar); + } + | + ("(" QUANTIFIER) => result=specquantifiedexpression + | + (OLD | PRE) "(" t=specexpression ")" + { + if (atPreFunctions == null) { + raiseError("JML construct " + + "\\old not allowed in this context."); + } + + result = convertToOld(t); + } + | + CREATED "(" t=specexpression ")" + { + if (t.sort() instanceof ObjectSort) { + result = CreatedAttributeTermFactory.INSTANCE. + createCreatedTerm(services, t); + } else { + raiseError("\\created only allowed for reference types."); + } + } + + | + NONNULLELEMENTS "(" t=specexpression ")" + { + result = tb.not(tb.equals(t, tb.NULL(services))); + + if (t.sort() instanceof ArraySort) { + LogicVariable i = new LogicVariable(new Name("i"), javaInfo + .getKeYJavaType(PrimitiveType.JAVA_INT) + .getSort()); + + // See JML reference manual + // http://www.cs.iastate.edu/~leavens/JML/jmlrefman/jmlrefman_11.html#SEC139 + Term range = tb.and( + tb.leq(tb.zTerm(services, "0"), tb.var(i), services), + tb.leq(tb.var(i), tb.dot(t,javaInfo.getArrayLength()), services)); + Term body = tb.equals( + tb.array(t, tb.var(i)), + tb.NULL(services)); + body = tb.not(body); + body = tb.imp(range, body); + + result = tb.and(result, tb.all(i, body)); + } + } + + | INFORMAL_DESCRIPTION + { + raiseNotSupported("informal predicates"); + } +// | NOT_MODIFIED "(" storereflist ")" + + | FRESH "(" spec_expression_list ")" + { + raiseNotSupported("\\fresh"); + } + + | REACH "(" t=specexpression ")" + { + raiseNotSupported("\\reach"); + } + + | DURATION "(" t=expression ")" + { + raiseNotSupported("\\duration"); + } + + | SPACE "(" t=specexpression ")" + { + raiseNotSupported("\\space"); + } + + | WORKINGSPACE "(" t=expression ")" + { + raiseNotSupported("\\working_space"); + } + + | TYPEOF "(" t=specexpression ")" + { + raiseNotSupported("\\typeof"); + } + + | ELEMTYPE "(" t=specexpression ")" + { + raiseNotSupported("\\elemtype"); + } + + | TYPE_SMALL "(" typ=type ")" + { + raiseNotSupported("\\type"); + } + + | LOCKSET + { + raiseNotSupported("\\lockset"); + } + + | IS_INITIALIZED "(" typ=referencetype ")" + { + result = tb.equals( + tb.var( + javaInfo.getAttribute(ImplicitFieldAdder.IMPLICIT_CLASS_INITIALIZED, + typ)), + tb.TRUE(services)); + } + + | INVARIANT_FOR "(" t=specexpression ")" + { + raiseNotSupported("\\invariant_for"); + } + + | ( "(" LBLNEG ) => "(" LBLNEG IDENT result=specexpression ")" + { +// raiseNotSupported("\\lblneg"); + } + + | ( "(" LBLPOS ) => "(" LBLPOS IDENT result=specexpression ")" + { +// raiseNotSupported("\\lblpos"); + } + + | + NOWARN + { + raiseNotSupported("\\nowarn"); + } + + | + "(" result=expression ")" +; + +specquantifiedexpression returns [Term result = null] throws SLTranslationException +{ + Term t = null; + Term p = null; + boolean nullable = false; + ListOfLogicVariable declVars = null; +} +: + "(" + q:QUANTIFIER (nullable=boundvarmodifiers)? declVars=quantifiedvardecls ";" + + { + resolverManager.pushLocalVariablesNamespace(); + resolverManager.putIntoTopLocalVariablesNamespace(declVars); + } + ( + ((p=predicate)? ";" ) => (p=predicate)? ";" t=specexpression + | + (";")? t=specexpression + ) + + { + resolverManager.popLocalVariablesNamespace(); + + if (!nullable) { + if (declVars.head().sort() instanceof ObjectSort) { + IteratorOfLogicVariable it = declVars.iterator(); + while (it.hasNext()) { + p = tb.and(p, + tb.not( + tb.equals( + tb.var(it.next()), + tb.NULL(services)))); + } + } + } + + t = convertToFormula(t); + + if (q.getText().equals("\\forall")) { + if (p != null) { + t = tb.imp(p, t); + } + result = tb.all(declVars.toArray(), t); + } + else if (q.getText().equals("\\exists")) { + if (p != null) { + t = tb.and(p, t); + } + result = tb.ex(declVars.toArray(), t); + } + else if (q.getText().equals("\\min")) { + Function y = new RigidFunction( + new Name("_jml_ymin"+(varCounter++)), + declVars.head().sort(), + new Sort[] {}); + axiomCollector.collectAxiom(y, + buildMaxMinAxiom(false, y, declVars, p, t)); + result = tb.func(y); + services.getNamespaces().functions().addSafely(y); + } + else if (q.getText().equals("\\max")) { + Function y = new RigidFunction( + new Name("_jml_ymax"+(varCounter++)), + declVars.head().sort(), + new Sort[] {}); + axiomCollector.collectAxiom(y, + buildMaxMinAxiom(true, y, declVars, p, t)); + result = tb.func(y); + services.getNamespaces().functions().addSafely(y); + } + else if (q.getText().equals("\\num_of")) { + raiseNotSupported("\\num_of"); + } + else if (q.getText().equals("\\product")) { + raiseNotSupported("\\product"); + } + else if (q.getText().equals("\\sum")) { + raiseNotSupported("\\sum"); + } + else { + raiseError("Unknown quantifier: " + q.getText() + "!"); + } + } + ")" +; + +quantifiedvardecls returns [ListOfLogicVariable vars = SLListOfLogicVariable.EMPTY_LIST] throws SLTranslationException +{ + KeYJavaType t = null; + LogicVariable v = null; +} +: + t=typespec v=quantifiedvariabledeclarator[t] + + { vars = vars.append(v); } + + ( + "," v=quantifiedvariabledeclarator[t] + + { vars = vars.append(v); } + )* +; + +boundvarmodifiers returns [boolean nullable = false] throws SLTranslationException +: + NON_NULL | NULLABLE { nullable = true; } +; + +typespec returns [KeYJavaType t = null] throws SLTranslationException +{ + int dim = 0; +} +: + t=type + ( + dim=dims + { + String fullName = t.getFullName(); + for (int i=0; i < dim; i++) { + fullName += "[]"; + } + t = javaInfo.getKeYJavaType(fullName); + if(t == null && dim > 0) { + //try to create missing array type + try { + javaInfo.readJavaBlock("{" + fullName + " k;}"); + t = javaInfo.getKeYJavaType(fullName); + } catch (Exception e) { + t = null; + } + } + } + )? +; + +dims returns [int dimension = 0] throws SLTranslationException +: + ("[" "]" { dimension++; } )+ + ; + +type returns [KeYJavaType t = null] throws SLTranslationException +: + (builtintype) => t=builtintype + | + t=referencetype + | + TYPE + { + raiseNotSupported("\\TYPE"); + } + +; + +referencetype returns [KeYJavaType type = null] throws SLTranslationException +{ + String typename; +} +: + typename=name + { + try { + type = resolverManager.resolve(null, typename, null).getKeYJavaType(javaInfo); + } catch (NullPointerException e) { + raiseError("Type " + typename + " not found."); + } + } +; + +builtintype returns [KeYJavaType type = null] throws SLTranslationException +: + ( + "byte" + { + type = javaInfo.getKeYJavaType(PrimitiveType.JAVA_BYTE); + } + | + "short" + { + type = javaInfo.getKeYJavaType(PrimitiveType.JAVA_SHORT); + } + | + "int" + { + type = javaInfo.getKeYJavaType(PrimitiveType.JAVA_INT); + } + | + "long" + { + type = javaInfo.getKeYJavaType(PrimitiveType.JAVA_LONG); + } + | + "boolean" + { + type = javaInfo.getKeYJavaType(PrimitiveType.JAVA_BOOLEAN); + } + | + "void" + { + type = null; + } + | + BIGINT + { + raiseNotSupported("\\bigint"); + } + | + REAL + { + raiseNotSupported("\\real"); + } + ) + +; + +name returns [String result = ""] throws SLTranslationException +: + id:IDENT + { result += id.getText(); } + ( + DOT id1:IDENT + { result += "." + id1.getText(); } + )* +; + +quantifiedvariabledeclarator[KeYJavaType t] returns [LogicVariable v = null] throws SLTranslationException +{ + int dim = 0; + KeYJavaType varType = null; +} +: + id:IDENT (dim=dims)? + { + if (dim > 0) { + String fullName; + if (t.getJavaType() instanceof ArrayType) { + fullName = ((ArrayType) t.getJavaType()).getAlternativeNameRepresentation(); + } else { + fullName = t.getFullName(); + } + for (int i=0; i < dim; i++) { + fullName += "[]"; + } + + varType = javaInfo.getKeYJavaType(fullName); + } else { + varType = t; + } + + v = new LogicVariable(new Name(id.getText()), varType.getSort()); + } +; diff --git a/system/de/uka/ilkd/key/speclang/ocl/OCLClassInvariant.java b/system/de/uka/ilkd/key/speclang/ocl/OCLClassInvariant.java deleted file mode 100644 index b239ba90a5e..00000000000 --- a/system/de/uka/ilkd/key/speclang/ocl/OCLClassInvariant.java +++ /dev/null @@ -1,76 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.speclang.ocl; - -import de.uka.ilkd.key.casetool.ModelClass; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.Name; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.op.LogicVariable; -import de.uka.ilkd.key.logic.op.Op; -import de.uka.ilkd.key.logic.op.ParsableVariable; -import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.proof.init.CreatedAttributeTermFactory; -import de.uka.ilkd.key.speclang.AbstractClassInvariant; -import de.uka.ilkd.key.speclang.FormulaWithAxioms; -import de.uka.ilkd.key.speclang.SLTranslationError; - - -public class OCLClassInvariant extends AbstractClassInvariant { - private final String originalInv; - - - public OCLClassInvariant(ModelClass modelClass, String originalInv) { - super(modelClass); - this.originalInv = originalInv; - } - - - public FormulaWithAxioms getInv(Services services) throws SLTranslationError { - Sort sort = getKJT(services).getSort(); - LogicVariable selfVar = new LogicVariable(new Name("self"), sort); - - FormulaWithAxioms inv - = services.getOCLTranslator().translateInv(originalInv, selfVar); - - CreatedAttributeTermFactory catf = CreatedAttributeTermFactory.INSTANCE; - Term closedInv = catf.createCreatedNotNullQuantifierTerm(services, - Op.ALL, - selfVar, - inv.getFormula()); - - return new FormulaWithAxioms(closedInv, inv.getAxioms()); - } - - - public FormulaWithAxioms getOpenInv(ParsableVariable selfVar, - Services services) throws SLTranslationError { - return services.getOCLTranslator().translateInv(originalInv, selfVar); - } - - - public String toString() { - return originalInv; - } - - - public boolean equals(Object o) { - if(!(o instanceof OCLClassInvariant)) { - return false; - } - return originalInv.equals(((OCLClassInvariant)o).originalInv); - } - - - public int hashCode() { - return originalInv.hashCode(); - } -} diff --git a/system/de/uka/ilkd/key/speclang/ocl/OCLOperationContract.java b/system/de/uka/ilkd/key/speclang/ocl/OCLOperationContract.java deleted file mode 100644 index 99ec4ffb93b..00000000000 --- a/system/de/uka/ilkd/key/speclang/ocl/OCLOperationContract.java +++ /dev/null @@ -1,71 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.speclang.ocl; - -import de.uka.ilkd.key.casetool.ModelMethod; -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.SetOfLocationDescriptor; -import de.uka.ilkd.key.logic.op.ListOfParsableVariable; -import de.uka.ilkd.key.logic.op.Modality; -import de.uka.ilkd.key.logic.op.ParsableVariable; -import de.uka.ilkd.key.speclang.AbstractOperationContract; -import de.uka.ilkd.key.speclang.FormulaWithAxioms; -import de.uka.ilkd.key.speclang.SLTranslationError; - - -public class OCLOperationContract extends AbstractOperationContract { - private final String originalPre; - private final String originalPost; - private final String originalModifies; - - - public OCLOperationContract(ModelMethod modelMethod, - boolean terminationRequired, - String originalPre, - String originalPost, - String originalModifies) { - super(modelMethod, terminationRequired ? Modality.DIA : Modality.BOX); - this.originalPre = originalPre; - this.originalPost = originalPost; - this.originalModifies = originalModifies; - } - - - public FormulaWithAxioms getPre(ParsableVariable selfVar, - ListOfParsableVariable paramVars, - Services services) throws SLTranslationError { - return services.getOCLTranslator().translatePre(originalPre, - selfVar, - paramVars); - } - - - public FormulaWithAxioms getPost(ParsableVariable selfVar, - ListOfParsableVariable paramVars, - ParsableVariable resultVar, - ParsableVariable excVar, - Services services) throws SLTranslationError { - return services.getOCLTranslator().translatePost(originalPost, - selfVar, - paramVars, - resultVar, - excVar); - } - - - public SetOfLocationDescriptor getModifies(ParsableVariable selfVar, - ListOfParsableVariable paramVars, - Services services) throws SLTranslationError { - return services.getOCLTranslator().translateModifies(originalModifies, - selfVar, - paramVars); - } -} diff --git a/system/de/uka/ilkd/key/speclang/ocl/OCLSpecExtractor.java b/system/de/uka/ilkd/key/speclang/ocl/OCLSpecExtractor.java new file mode 100644 index 00000000000..f6a3b271a06 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/ocl/OCLSpecExtractor.java @@ -0,0 +1,165 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.ocl; + +import de.uka.ilkd.key.java.Comment; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.declaration.TypeDeclaration; +import de.uka.ilkd.key.java.statement.LoopStatement; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.speclang.ClassInvariant; +import de.uka.ilkd.key.speclang.LoopInvariant; +import de.uka.ilkd.key.speclang.SetAsListOfClassInvariant; +import de.uka.ilkd.key.speclang.SetAsListOfOperationContract; +import de.uka.ilkd.key.speclang.SetOfClassInvariant; +import de.uka.ilkd.key.speclang.SetOfOperationContract; +import de.uka.ilkd.key.speclang.SpecExtractor; +import de.uka.ilkd.key.speclang.ocl.translation.OCLSpecFactory; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + + +/** + * Extracts OCL class invariants and operation contracts from OCL comments. + * This is the public interface to the ocl package. + */ +public class OCLSpecExtractor implements SpecExtractor { + + private final Services services; + private final OCLSpecFactory osf; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public OCLSpecExtractor(Services services) { + this.services = services; + this.osf = new OCLSpecFactory(services); + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private String shorten(String s) { + int lineEndIndex = s.indexOf("\n"); + if(lineEndIndex >= 0) { + String startString = s.substring(0, lineEndIndex); + String restString = s.substring(lineEndIndex).trim(); + if(restString.startsWith("*")) { + restString = restString.substring(1).trim(); + } + if(restString.startsWith("@") | restString.startsWith("/")) { + return startString; + } else { + return startString.concat(shorten(restString)); + } + } else { + int commentEndIndex = s.indexOf("*/"); + if(commentEndIndex >= 0) { + return s.substring(0, commentEndIndex); + } else { + return s; + } + } + } + + + private String extractProperty(String comment, String keyword) { + int beginIndex = comment.indexOf(keyword); + if(beginIndex >= 0) { + comment = comment.substring(beginIndex + keyword.length()); + comment = shorten(comment); + return comment; + } else { + return null; + } + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public SetOfOperationContract extractOperationContracts(ProgramMethod pm) + throws SLTranslationException { + if(((TypeDeclaration) pm.getContainerType() + .getJavaType()).isLibraryClass()) { + return SetAsListOfOperationContract.EMPTY_SET; + } + + SetOfOperationContract result = SetAsListOfOperationContract.EMPTY_SET; + + Comment[] comments = pm.getComments(); + for(int i = 0; i < comments.length; i++) { + String originalPre = extractProperty(comments[i].getText(), + "@preconditions"); + String originalPost = extractProperty(comments[i].getText(), + "@postconditions"); + String originalModifies = extractProperty(comments[i].getText(), + "@modifies"); + if(originalPre != null + || originalPost != null + || originalModifies != null) { + SetOfOperationContract contracts + = osf.createOCLOperationContracts(pm, + originalPre, + originalPost, + originalModifies); + result = result.union(contracts); + } + } + + return result; + } + + + + public SetOfClassInvariant extractClassInvariants(KeYJavaType kjt) + throws SLTranslationException { + if(!(kjt.getJavaType() instanceof TypeDeclaration)) { + return SetAsListOfClassInvariant.EMPTY_SET; + } + TypeDeclaration td = (TypeDeclaration) kjt.getJavaType(); + if(td.isLibraryClass()) { + return SetAsListOfClassInvariant.EMPTY_SET; + } + + SetOfClassInvariant result = SetAsListOfClassInvariant.EMPTY_SET; + + int numChildren = td.getChildCount(); + for(int i = 0; i < numChildren; i++) { + Comment[] comments = ((TypeDeclaration)kjt.getJavaType()).getChildAt(i).getComments(); + for(int j = 0; j < comments.length; j++) { + String originalInv = extractProperty(comments[j].getText(), + "@invariants"); + + if(originalInv != null) { + ClassInvariant inv + = osf.createOCLClassInvariant(kjt, originalInv); + result = result.add(inv); + } + } + } + + return result; + } + + + public LoopInvariant extractLoopInvariant(ProgramMethod pm, LoopStatement loop) + throws SLTranslationException { + return null; //OCL has no loop invariants + } +} diff --git a/system/de/uka/ilkd/key/speclang/ocl/OCLTranslator.java b/system/de/uka/ilkd/key/speclang/ocl/OCLTranslator.java deleted file mode 100644 index 361c86b21e4..00000000000 --- a/system/de/uka/ilkd/key/speclang/ocl/OCLTranslator.java +++ /dev/null @@ -1,169 +0,0 @@ -//This file is part of KeY - Integrated Deductive Software Design -//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany -// Universitaet Koblenz-Landau, Germany -// Chalmers University of Technology, Sweden -// -//The KeY system is protected by the GNU General Public License. -//See LICENSE.TXT for details. -// -// - -package de.uka.ilkd.key.speclang.ocl; - -import java.io.StringReader; -import java.util.Map; - -import antlr.ANTLRException; - -import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.logic.EverythingLocationDescriptor; -import de.uka.ilkd.key.logic.ListOfInteger; -import de.uka.ilkd.key.logic.NamespaceSet; -import de.uka.ilkd.key.logic.SLListOfInteger; -import de.uka.ilkd.key.logic.SetAsListOfLocationDescriptor; -import de.uka.ilkd.key.logic.SetOfLocationDescriptor; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.TermBuilder; -import de.uka.ilkd.key.logic.TermFactory; -import de.uka.ilkd.key.logic.op.IteratorOfParsableVariable; -import de.uka.ilkd.key.logic.op.ListOfParsableVariable; -import de.uka.ilkd.key.logic.op.LogicVariable; -import de.uka.ilkd.key.logic.op.ParsableVariable; -import de.uka.ilkd.key.logic.op.ProgramVariable; -import de.uka.ilkd.key.parser.KeYLexer; -import de.uka.ilkd.key.parser.KeYParser; -import de.uka.ilkd.key.parser.ParserMode; -import de.uka.ilkd.key.parser.ocl.AxiomCollector; -import de.uka.ilkd.key.parser.ocl.FunctionFactory; -import de.uka.ilkd.key.parser.ocl.KeYOclLexer; -import de.uka.ilkd.key.parser.ocl.KeYOclParser; -import de.uka.ilkd.key.parser.ocl.OCLTranslationError; -import de.uka.ilkd.key.speclang.FormulaWithAxioms; -import de.uka.ilkd.key.speclang.SLTranslationError; -import de.uka.ilkd.key.util.Debug; - - -/** - * Translates OCL expressions to DL. - */ -public class OCLTranslator { - private final Services services; - private ListOfInteger parserCounters = SLListOfInteger.EMPTY_LIST; - - - public OCLTranslator(Services services) { - this.services = services; - } - - - private FormulaWithAxioms translatePrePostInv( - String expr, - ParsableVariable selfVar, - ListOfParsableVariable paramVars, - ParsableVariable resultVar, - ParsableVariable excVar) throws SLTranslationError { - AxiomCollector ac = new AxiomCollector(); - FunctionFactory.INSTANCE.resetFactory(services, ac); - - Term resultFormula = null; - Map resultAxioms = null; - - try { - //create lexer and parser - StringReader stream = new StringReader(expr); - KeYOclLexer lexer = new KeYOclLexer(stream); - KeYOclParser parser = new KeYOclParser(lexer, - services, - ac, - selfVar, - paramVars, - resultVar, - excVar); - - //initialise counters - parser.setCounters(parserCounters); - - //parse the expression - if (expr.length() > 0) { - resultFormula = parser.parseExpression(); - } else { - resultFormula = TermBuilder.DF.tt(); - } - - //get created Axioms - resultAxioms = ac.getAxioms(); - - //save counter values - parserCounters = parser.getCounters(); - } catch (ANTLRException e) { - if(e instanceof OCLTranslationError) { - throw ((OCLTranslationError)e).getSLTranslationError(); - } else { - Debug.fail("OCLTranslator : " + e.getMessage()); - } - } - return new FormulaWithAxioms(resultFormula, resultAxioms); - } - - - public FormulaWithAxioms translatePre(String pre, - ParsableVariable selfVar, - ListOfParsableVariable paramVars) throws SLTranslationError { - return translatePrePostInv(pre, selfVar, paramVars, null, null); - } - - - public FormulaWithAxioms translatePost(String post, - ParsableVariable selfVar, - ListOfParsableVariable paramVars, - ParsableVariable resultVar, - ParsableVariable exceptionVar) throws SLTranslationError { - return translatePrePostInv(post, - selfVar, - paramVars, - resultVar, - exceptionVar); - } - - - public SetOfLocationDescriptor translateModifies( - String modifies, - ParsableVariable selfVar, - ListOfParsableVariable paramVars) throws SLTranslationError { - if(modifies == null || modifies.equals("")) { - return SetAsListOfLocationDescriptor.EMPTY_SET - .add(EverythingLocationDescriptor.INSTANCE); - } - - NamespaceSet nss = services.getNamespaces().copy(); - IteratorOfParsableVariable it = paramVars.prepend(selfVar).iterator(); - while(it.hasNext()) { - ParsableVariable pv = it.next(); - if(pv instanceof LogicVariable) { - nss.variables().add(pv); - } else { - assert pv instanceof ProgramVariable; - nss.programVariables().add(pv); - } - } - - try { - KeYParser parser = new KeYParser(ParserMode.TERM, - new KeYLexer(new StringReader(modifies), - null), - "", - TermFactory.DEFAULT, - services, - nss); - return parser.location_list(); - } catch(Exception e) { - throw new SLTranslationError(e.getMessage(), 0, 0); - } - } - - - public FormulaWithAxioms translateInv(String inv, - ParsableVariable selfVar) throws SLTranslationError { - return translatePrePostInv(inv, selfVar, null, null, null); - } -} diff --git a/system/de/uka/ilkd/key/parser/ocl/AssociationResolver.java b/system/de/uka/ilkd/key/speclang/ocl/translation/AssociationResolver.java similarity index 53% rename from system/de/uka/ilkd/key/parser/ocl/AssociationResolver.java rename to system/de/uka/ilkd/key/speclang/ocl/translation/AssociationResolver.java index 6e0e486ef18..352ab7c48f8 100644 --- a/system/de/uka/ilkd/key/parser/ocl/AssociationResolver.java +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/AssociationResolver.java @@ -8,40 +8,38 @@ // // -package de.uka.ilkd.key.parser.ocl; +package de.uka.ilkd.key.speclang.ocl.translation; import de.uka.ilkd.key.casetool.Association; import de.uka.ilkd.key.casetool.ListOfAssociation; import de.uka.ilkd.key.casetool.UMLInfo; -import de.uka.ilkd.key.java.JavaInfo; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.TermFactory; import de.uka.ilkd.key.logic.op.Function; import de.uka.ilkd.key.logic.sort.AbstractCollectionSort; -import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.util.Debug; -import de.uka.ilkd.key.util.AssertionFailure; +import de.uka.ilkd.key.speclang.translation.SLResolverManager; +import de.uka.ilkd.key.speclang.translation.SLExpression; +import de.uka.ilkd.key.speclang.translation.SLExpressionResolver; +import de.uka.ilkd.key.speclang.translation.SLParameters; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; /** * Resolves association accesses. */ -class AssociationResolver implements PropertyResolver { +class AssociationResolver extends SLExpressionResolver { private static final TermFactory tf = TermFactory.DEFAULT; private final Services services; - private final JavaInfo javaInfo; private final UMLInfo umlInfo; - public AssociationResolver(Services services) { + public AssociationResolver(Services services, SLResolverManager man) { + super(services.getJavaInfo(), man); this.services = services; - this.javaInfo = services.getJavaInfo(); this.umlInfo = services.getUMLInfo(); - assert javaInfo != null; - assert umlInfo != null; } @@ -62,55 +60,52 @@ private static Function getAssociationFunction(Association assoc, return assoc.getPredicate(); } - - public OCLEntity resolve(OCLEntity receiver, - String name, - OCLParameters parameters) throws OCLTranslationError { + + public boolean needVarDeclaration(String propertyName) { + return false; + } + + + public boolean canHandleReceiver(SLExpression receiver) { + return receiver != null && (receiver.isTerm() || receiver.isCollection()); + } + + + public SLExpression doResolving(SLExpression receiver, String name, SLParameters parameters) throws SLTranslationException { + if(parameters != null) { return null; } - Sort containingSort = receiver.getSort(); - KeYJavaType containingKjt = javaInfo.getKeYJavaType(containingSort); + KeYJavaType containingKjt = receiver.getKeYJavaType(javaInfo); ListOfAssociation assocs = umlInfo.getAssociations(containingKjt, name); if(!assocs.isEmpty()) { Term recTerm = receiver.getTerm(); - OCLCollection recCollection = receiver.getCollection(); + OCLCollection recCollection = (OCLCollection) receiver.getCollection(); Association assoc = assocs.head(); Function assocFunc = getAssociationFunction(assoc, name); - try { - if(recTerm != null) { - if (assocFunc.sort() instanceof AbstractCollectionSort) { - // we have a binary association with multiplicity greater than 1 - OCLCollection collection = new OCLCollection(recTerm,assoc,name); - return new OCLEntity(collection); - } else { - // either the association-end has multiplicity 1 or it is no binary association - Term functionTerm = tf.createFunctionTerm(assocFunc,recTerm); - return new OCLEntity(functionTerm); - } - } else if(recCollection != null) { - OCLCollection newCollection - = recCollection.collect(services, - assoc, - name); - return new OCLEntity(newCollection); + if(recTerm != null) { + if (assocFunc.sort() instanceof AbstractCollectionSort) { + // we have a binary association with multiplicity greater than 1 + OCLCollection collection = new OCLCollection(recTerm,assoc,name); + return new OCLEntity(collection); + } else { + // either the association-end has multiplicity 1 or it is no binary association + Term functionTerm = tf.createFunctionTerm(assocFunc,recTerm); + return new OCLEntity(functionTerm); } - } catch(Exception e) { - if (e instanceof OCLTranslationError) { - throw (OCLTranslationError) e; - } + } else if(recCollection != null) { + OCLCollection newCollection + = recCollection.collect(services, + assoc, + name); + return new OCLEntity(newCollection); } } return null; } - - - public boolean needVarDeclaration(String propertyName) { - return false; - } } diff --git a/system/de/uka/ilkd/key/parser/ocl/BuiltInPropertyResolver.java b/system/de/uka/ilkd/key/speclang/ocl/translation/BuiltInPropertyResolver.java similarity index 59% rename from system/de/uka/ilkd/key/parser/ocl/BuiltInPropertyResolver.java rename to system/de/uka/ilkd/key/speclang/ocl/translation/BuiltInPropertyResolver.java index 2c1e281aaf6..63dc792c5c4 100644 --- a/system/de/uka/ilkd/key/parser/ocl/BuiltInPropertyResolver.java +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/BuiltInPropertyResolver.java @@ -8,13 +8,12 @@ // // -package de.uka.ilkd.key.parser.ocl; +package de.uka.ilkd.key.speclang.ocl.translation; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.logic.Name; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.TermBuilder; @@ -28,21 +27,23 @@ import de.uka.ilkd.key.logic.op.Op; import de.uka.ilkd.key.logic.op.ParsableVariable; import de.uka.ilkd.key.logic.op.Quantifier; -import de.uka.ilkd.key.logic.sort.AbstractCollectionSort; import de.uka.ilkd.key.logic.sort.AbstractSort; -import de.uka.ilkd.key.logic.sort.ArraySort; import de.uka.ilkd.key.logic.sort.CollectionSort; import de.uka.ilkd.key.logic.sort.Sort; import de.uka.ilkd.key.proof.OpReplacer; import de.uka.ilkd.key.proof.init.CreatedAttributeTermFactory; -import de.uka.ilkd.key.util.Debug; +import de.uka.ilkd.key.speclang.translation.SLResolverManager; +import de.uka.ilkd.key.speclang.translation.SLExpression; +import de.uka.ilkd.key.speclang.translation.SLExpressionResolver; +import de.uka.ilkd.key.speclang.translation.SLParameters; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; /** * Resolves built-in ocl property calls. */ -class BuiltInPropertyResolver implements PropertyResolver { +class BuiltInPropertyResolver extends SLExpressionResolver { private static final TermFactory tf = TermFactory.DEFAULT; private static final TermBuilder tb = TermBuilder.DF; @@ -56,47 +57,68 @@ class BuiltInPropertyResolver implements PropertyResolver { private ParsableVariable excVar; - public BuiltInPropertyResolver(Services services, ParsableVariable excVar) { + public BuiltInPropertyResolver(Services services, ParsableVariable excVar, SLResolverManager man) { + super(services.getJavaInfo(), man); this.services = services; this.excVar = excVar; } private Term replaceVar(LogicVariable lv1, LogicVariable lv2, Term term) { - Map map = new HashMap(); + Map map = new LinkedHashMap(); map.put(lv1, lv2); OpReplacer or = new OpReplacer(map); return or.replace(term); } - private void raiseError(String message) throws OCLTranslationError { - throw new OCLTranslationError("OCL Parser Error (PropertyResolver): " + message); + private void raiseError(String message) throws SLTranslationException { + throw new SLTranslationException("OCL Parser Error (PropertyResolver): " + message); } - - public OCLEntity resolve(OCLEntity receiver, - String name, - OCLParameters parameters) throws OCLTranslationError { + + public boolean needVarDeclaration(String propertyName) { + return (propertyName.equals("forAll") + || propertyName.equals("exists") + || propertyName.equals("select") + || propertyName.equals("reject") + || propertyName.equals("collect") + || propertyName.equals("isUnique")); + } + + + public boolean canHandleReceiver(SLExpression receiver) { + return true; + } + + + protected SLExpression doResolving(SLExpression receiver, String name, SLParameters parameters) throws SLTranslationException { + + OCLParameters oclParameters = null; + + if (parameters instanceof OCLParameters) { + oclParameters = (OCLParameters) parameters; + } + //allInstances--------------------------------------------------------- if(name.equals("allInstances")) { if(!receiver.isType() - || parameters == null - || !parameters.getDeclaredVars().isEmpty() - || !parameters.getEntities().isEmpty()) { + || oclParameters == null + || !oclParameters.getDeclaredVars().isEmpty() + || !oclParameters.getEntities().isEmpty()) { return null; } - return new OCLEntity(new OCLCollection(receiver.getSort(), services)); + return new OCLEntity(new OCLCollection(receiver.getKeYJavaType(javaInfo).getSort(), services)); } //quantifiers---------------------------------------------------------- if(name.equals("forAll") || name.equals("exists")) { if(!receiver.isCollection() - || parameters == null - || parameters.getDeclaredVars().isEmpty() - || parameters.getEntities().size() != 1) { + || oclParameters == null + || oclParameters.getDeclaredVars().isEmpty() + || oclParameters.getEntities().size() != 1) { return null; } @@ -112,11 +134,11 @@ public OCLEntity resolve(OCLEntity receiver, Term restrictions = trueTerm; IteratorOfLogicVariable it - = parameters.getDeclaredVars().iterator(); + = oclParameters.getDeclaredVars().iterator(); while(it.hasNext()) { - Term t = replaceVar(receiver.getCollection().getPredVar(), + Term t = replaceVar(((OCLCollection) receiver.getCollection()).getPredVar(), it.next(), - receiver.getCollection().getPredicativeRestriction()); + ((OCLCollection) receiver.getCollection()).getPredicativeRestriction()); restrictions = tf.createJunctorTermAndSimplify(Op.AND, restrictions, t); @@ -125,11 +147,11 @@ public OCLEntity resolve(OCLEntity receiver, Term subTerm = tf.createJunctorTermAndSimplify(j, restrictions, - parameters.getEntities().head().getTerm()); - Term resTerm = createdFactory.createCreatedNotNullQuantifierTerm( + oclParameters.getEntities().head().getTerm()); + Term resTerm = createdFactory.createCreatedOrNullQuantifierTerm( services, q, - parameters.getDeclaredVars().toArray(), + oclParameters.getDeclaredVars().toArray(), subTerm); return new OCLEntity(resTerm); @@ -139,26 +161,27 @@ public OCLEntity resolve(OCLEntity receiver, //select/reject-------------------------------------------------------- if(name.equals("select") || name.equals("reject")) { if(!receiver.isCollection() - || parameters == null - || parameters.getDeclaredVars().size() != 1 - || parameters.getEntities().size() != 1) { + || oclParameters == null + || oclParameters.getDeclaredVars().size() != 1 + || oclParameters.getEntities().size() != 1) { return null; } //Replace all occurrences of the new selectorVar with the //appropriate collectionVar - Term selectTerm = replaceVar(parameters.getDeclaredVars().head(), - receiver.getCollection().getPredVar(), - parameters.getEntities().head().getTerm()); + Term selectTerm = replaceVar(oclParameters.getDeclaredVars().head(), + ((OCLCollection) receiver.getCollection()).getPredVar(), + oclParameters.getEntities().head().getTerm()); if (name.equals("reject")) { selectTerm = tf.createJunctorTerm(Op.NOT,selectTerm); } - LogicVariable selectVar = receiver.getCollection().getPredVar(); - - OCLCollection resCollection = receiver.getCollection().select(selectVar, selectTerm); + LogicVariable selectVar = ((OCLCollection) receiver.getCollection()).getPredVar(); + + OCLCollection resCollection; + resCollection = ((OCLCollection) receiver.getCollection()).select(selectVar, selectTerm); return new OCLEntity(resCollection); } @@ -167,32 +190,33 @@ public OCLEntity resolve(OCLEntity receiver, //collect-------------------------------------------------------------- if(name.equals("collect")) { if(!receiver.isCollection() - || parameters == null - || parameters.getDeclaredVars().size() > 1 - || parameters.getEntities().size() != 1) { + || oclParameters == null + || oclParameters.getDeclaredVars().size() > 1 + || oclParameters.getEntities().size() != 1) { return null; } - Term collectTerm = parameters.getEntities().head().getTerm(); + Term collectTerm = oclParameters.getEntities().head().getTerm(); if (collectTerm==null) { - // collectTerm was a collection - raiseError("Automatic flattening only supported for navigation over associations!"); - - // System.out.println(parameters.getEntities().head().getCollection()); - //OCLCollection result = receiver.getCollection().collect(services, - // parameters.getEntities().head().getCollection()); - //return new OCLEntity(result); - + // collectTerm was a collection + raiseError("Automatic flattening only supported for navigation over associations!"); + + // System.out.println(parameters.getEntities().head().getCollection()); + //OCLCollection result = ((OCLCollection) receiver.getCollection()).collect(services, + // parameters.getEntities().head().getCollection()); + //return new OCLEntity(result); + } - if(!parameters.getDeclaredVars().isEmpty()) { - collectTerm = replaceVar(parameters.getDeclaredVars().head(), - receiver.getCollection().getPredVar(), + if(!oclParameters.getDeclaredVars().isEmpty()) { + collectTerm = replaceVar(oclParameters.getDeclaredVars().head(), + ((OCLCollection) receiver.getCollection()).getPredVar(), collectTerm); } - OCLCollection result = receiver.getCollection().collect(services, collectTerm); + OCLCollection result + = ((OCLCollection) receiver.getCollection()).collect(services, collectTerm); return new OCLEntity(result); } @@ -201,15 +225,15 @@ public OCLEntity resolve(OCLEntity receiver, //includes/excludes---------------------------------------------------- if(name.equals("includes") || name.equals("excludes")) { if(!receiver.isCollection() - || parameters == null - || !parameters.getDeclaredVars().isEmpty() - || parameters.getEntities().size() != 1) { + || oclParameters == null + || !oclParameters.getDeclaredVars().isEmpty() + || oclParameters.getEntities().size() != 1) { return null; } Term opTerm - = tf.createEqualityTerm(receiver.getCollection().getPredVarAsTerm(), - parameters.getEntities().head().getTerm()); + = tf.createEqualityTerm(((OCLCollection) receiver.getCollection()).getPredVarAsTerm(), + oclParameters.getEntities().head().getTerm()); Quantifier q; Junctor j; @@ -224,10 +248,10 @@ public OCLEntity resolve(OCLEntity receiver, opTerm = tf.createJunctorTermAndSimplify( j, - receiver.getCollection().getPredicativeRestriction(), + ((OCLCollection) receiver.getCollection()).getPredicativeRestriction(), opTerm); - LogicVariable[] vars = {receiver.getCollection().getPredVar()}; + LogicVariable[] vars = {((OCLCollection) receiver.getCollection()).getPredVar()}; Term resTerm = createdFactory.createCreatedNotNullQuantifierTerm( services, q, @@ -241,9 +265,9 @@ public OCLEntity resolve(OCLEntity receiver, //isEmpty/notEmpty----------------------------------------------------- if(name.equals("isEmpty") || name.equals("notEmpty")) { if(!receiver.isCollection() - || parameters == null - || !parameters.getDeclaredVars().isEmpty() - || !parameters.getEntities().isEmpty()) { + || oclParameters == null + || !oclParameters.getDeclaredVars().isEmpty() + || !oclParameters.getEntities().isEmpty()) { return null; } @@ -262,10 +286,10 @@ public OCLEntity resolve(OCLEntity receiver, opTerm = tf.createJunctorTerm( j, - receiver.getCollection().getPredicativeRestriction(), + ((OCLCollection) receiver.getCollection()).getPredicativeRestriction(), opTerm); - LogicVariable[] vars = {receiver.getCollection().getPredVar()}; + LogicVariable[] vars = {((OCLCollection) receiver.getCollection()).getPredVar()}; Term resTerm = createdFactory.createCreatedNotNullQuantifierTerm( services, q, @@ -279,25 +303,25 @@ public OCLEntity resolve(OCLEntity receiver, //isUnique------------------------------------------------------------- if(name.equals("isUnique")) { if(!receiver.isCollection() - || parameters == null - || parameters.getDeclaredVars().size() != 1 - || parameters.getEntities().size() != 1) { + || oclParameters == null + || oclParameters.getDeclaredVars().size() != 1 + || oclParameters.getEntities().size() != 1) { return null; } Term restrictions = trueTerm; - LogicVariable temp = parameters.getDeclaredVars().head(); + LogicVariable temp = oclParameters.getDeclaredVars().head(); LogicVariable lv1 = new LogicVariable(new Name(temp.name()+"_1"),temp.sort()); LogicVariable lv2 = new LogicVariable(new Name(temp.name()+"_2"),temp.sort()); - Term t1 = replaceVar(receiver.getCollection().getPredVar(), + Term t1 = replaceVar(((OCLCollection) receiver.getCollection()).getPredVar(), lv1, - receiver.getCollection().getPredicativeRestriction()); - Term t2 = replaceVar(receiver.getCollection().getPredVar(), + ((OCLCollection) receiver.getCollection()).getPredicativeRestriction()); + Term t2 = replaceVar(((OCLCollection) receiver.getCollection()).getPredVar(), lv2, - receiver.getCollection().getPredicativeRestriction()); + ((OCLCollection) receiver.getCollection()).getPredicativeRestriction()); restrictions = tf.createJunctorTermAndSimplify(Op.AND, t1, @@ -305,10 +329,10 @@ public OCLEntity resolve(OCLEntity receiver, t1 = replaceVar(temp, lv1, - parameters.getEntities().head().getTerm()); + oclParameters.getEntities().head().getTerm()); t2 = replaceVar(temp, lv2, - parameters.getEntities().head().getTerm()); + oclParameters.getEntities().head().getTerm()); restrictions = tf.createJunctorTermAndSimplify(Op.AND, restrictions, @@ -338,15 +362,15 @@ public OCLEntity resolve(OCLEntity receiver, name.equals("count")) { if(!receiver.isCollection() - || parameters == null - || parameters.getDeclaredVars().size() > 0 - || parameters.getEntities().size() != 0) { + || oclParameters == null + || oclParameters.getDeclaredVars().size() > 0 + || oclParameters.getEntities().size() != 0) { return null; } CollectionSort ssort = FunctionFactory.getCollectionSort( - receiver.getSort(), - receiver.getCollection().getCollectionType()); + receiver.getKeYJavaType(javaInfo).getSort(), + ((OCLCollection) receiver.getCollection()).getCollectionType()); assert ssort!=null; @@ -356,22 +380,22 @@ public OCLEntity resolve(OCLEntity receiver, return new OCLEntity( tf.createFunctionTerm( f, - receiver.getCollection().getFunctionalRestriction())); + ((OCLCollection) receiver.getCollection()).getFunctionalRestriction())); } //oclIsKindOf------------------------------------------------------------ if(name.equals("oclIsKindOf")) { if(!receiver.isTerm() - || parameters == null - || !parameters.getDeclaredVars().isEmpty() - || !(parameters.getEntities().size() == 1) - || !(parameters.getEntities().head().isType())) { + || oclParameters == null + || !oclParameters.getDeclaredVars().isEmpty() + || !(oclParameters.getEntities().size() == 1) + || !(oclParameters.getEntities().head().isType())) { return null; } Function instance = (Function) services.getNamespaces().functions().lookup( - new Name(parameters.getEntities().head().getType().getFullName()+"::instance")); + new Name(oclParameters.getEntities().head().getType().getFullName()+"::instance")); Term result = tf.createFunctionTerm(instance,receiver.getTerm()); @@ -382,15 +406,15 @@ public OCLEntity resolve(OCLEntity receiver, //oclIsTypeOf------------------------------------------------------------ if(name.equals("oclIsTypeOf")) { if(!receiver.isTerm() - || parameters == null - || !parameters.getDeclaredVars().isEmpty() - || !(parameters.getEntities().size() == 1) - || !(parameters.getEntities().head().isType())) { + || oclParameters == null + || !oclParameters.getDeclaredVars().isEmpty() + || !(oclParameters.getEntities().size() == 1) + || !(oclParameters.getEntities().head().isType())) { return null; } Function instance = (Function) services.getNamespaces().functions().lookup( - new Name(parameters.getEntities().head().getType().getFullName()+"::exactInstance")); + new Name(oclParameters.getEntities().head().getType().getFullName()+"::exactInstance")); Term result = tf.createFunctionTerm(instance,receiver.getTerm()); @@ -401,15 +425,15 @@ public OCLEntity resolve(OCLEntity receiver, //oclAsType------------------------------------------------------------ if(name.equals("oclAsType")) { if(!receiver.isTerm() - || parameters == null - || !parameters.getDeclaredVars().isEmpty() - || !(parameters.getEntities().size() == 1) - || !(parameters.getEntities().head().isType())) { + || oclParameters == null + || !oclParameters.getDeclaredVars().isEmpty() + || !(oclParameters.getEntities().size() == 1) + || !(oclParameters.getEntities().head().isType())) { return null; } Term result = tf.createCastTerm( - (AbstractSort)parameters.getEntities().head().getSort(), + (AbstractSort)oclParameters.getEntities().head().getSort(), receiver.getTerm()); return new OCLEntity(result); @@ -419,9 +443,9 @@ public OCLEntity resolve(OCLEntity receiver, //get (array access)------------------------------------------------------------ if(name.equals("get")) { if(!receiver.isTerm() - || parameters == null - || !parameters.getDeclaredVars().isEmpty() - || !(parameters.getEntities().size() == 1) + || oclParameters == null + || !oclParameters.getDeclaredVars().isEmpty() + || !(oclParameters.getEntities().size() == 1) //|| !parameters.getEntities().head().getTerm().sort().name().toString().equals("int") //|| !(receiver.getSort() instanceof ArraySort)# ) { @@ -429,30 +453,30 @@ public OCLEntity resolve(OCLEntity receiver, } Term res = tf.createArrayTerm( - ArrayOp.getArrayOp(receiver.getSort()), + ArrayOp.getArrayOp(receiver.getKeYJavaType(javaInfo).getSort()), receiver.getTerm(), - parameters.getEntities().head().getTerm()); + oclParameters.getEntities().head().getTerm()); return new OCLEntity(res); } //signals (exception-handling)-------------------------------------------------- if(name.equals("signals")) { - if(parameters == null - || !parameters.getDeclaredVars().isEmpty() - || !(parameters.getEntities().size() == 1) - || !parameters.getEntities().head().isType() + if(oclParameters == null + || !oclParameters.getDeclaredVars().isEmpty() + || !(oclParameters.getEntities().size() == 1) + || !oclParameters.getEntities().head().isType() ) { - return null; + return null; } - Sort excSort = parameters.getEntities().head().getType().getSort(); + Sort excSort = oclParameters.getEntities().head().getType().getSort(); Function instance = (Function) services.getNamespaces().functions().lookup( new Name(excSort.name().toString()+"::instance")); Term res = tb.and( - tb.not(tb.equals(tb.var(excVar),tb.NULL(services))), - tb.equals(tb.func(instance,tb.var(excVar)),tb.TRUE(services))); + tb.not(tb.equals(tb.var(excVar),tb.NULL(services))), + tb.equals(tb.func(instance,tb.var(excVar)),tb.TRUE(services))); return new OCLEntity(res); @@ -464,15 +488,15 @@ public OCLEntity resolve(OCLEntity receiver, getIntegerLDT(); final Sort integerSort = integerLDT.targetSort(); if (!receiver.isTerm() - || parameters == null - || !(parameters.getEntities().size() == 1) - || !(receiver.getSort().extendsTrans(integerSort)) - || !(parameters.getEntities().head().getSort().extendsTrans(integerSort))) { + || oclParameters == null + || !(oclParameters.getEntities().size() == 1) + || !(receiver.getKeYJavaType(javaInfo).getSort().extendsTrans(integerSort)) + || !(oclParameters.getEntities().head().getSort().extendsTrans(integerSort))) { return null; } - return new OCLEntity(tb.func(integerLDT.getArithModulo(), + return new OCLEntity(tb.func(integerLDT.getMod(), receiver.getTerm(), - parameters.getEntities().head().getTerm())); + oclParameters.getEntities().head().getTerm())); } // div operation @@ -481,15 +505,15 @@ public OCLEntity resolve(OCLEntity receiver, getIntegerLDT(); final Sort integerSort = integerLDT.targetSort(); if (!receiver.isTerm() - || parameters == null - || !(parameters.getEntities().size() == 1) - || !(receiver.getSort().extendsTrans(integerSort)) - || !(parameters.getEntities().head().getSort().extendsTrans(integerSort))) { + || oclParameters == null + || !(oclParameters.getEntities().size() == 1) + || !(receiver.getKeYJavaType(javaInfo).getSort().extendsTrans(integerSort)) + || !(oclParameters.getEntities().head().getSort().extendsTrans(integerSort))) { return null; } - return new OCLEntity(tb.func(integerLDT.getArithDivision(), + return new OCLEntity(tb.func(integerLDT.getDiv(), receiver.getTerm(), - parameters.getEntities().head().getTerm())); + oclParameters.getEntities().head().getTerm())); } /* @@ -501,7 +525,7 @@ public OCLEntity resolve(OCLEntity receiver, return null; } - return new OCLEntity(receiver.getCollection().asSet()); + return new OCLEntity(((OCLCollection) receiver.getCollection()).asSet()); } @@ -511,7 +535,7 @@ public OCLEntity resolve(OCLEntity receiver, return null; } - return new OCLEntity(receiver.getCollection().asBag()); + return new OCLEntity(((OCLCollection) receiver.getCollection()).asBag()); } @@ -521,20 +545,10 @@ public OCLEntity resolve(OCLEntity receiver, return null; } - return new OCLEntity(receiver.getCollection().asSequence()); + return new OCLEntity(((OCLCollection) receiver.getCollection()).asSequence()); } */ return null; - } - - - public boolean needVarDeclaration(String propertyName) { - return (propertyName.equals("forAll") - || propertyName.equals("exists") - || propertyName.equals("select") - || propertyName.equals("reject") - || propertyName.equals("collect") - || propertyName.equals("isUnique")); } } diff --git a/system/de/uka/ilkd/key/parser/ocl/FormulaBoolConverter.java b/system/de/uka/ilkd/key/speclang/ocl/translation/FormulaBoolConverter.java similarity index 99% rename from system/de/uka/ilkd/key/parser/ocl/FormulaBoolConverter.java rename to system/de/uka/ilkd/key/speclang/ocl/translation/FormulaBoolConverter.java index 4d2834864fa..2dec920fe8a 100644 --- a/system/de/uka/ilkd/key/parser/ocl/FormulaBoolConverter.java +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/FormulaBoolConverter.java @@ -8,7 +8,7 @@ // // -package de.uka.ilkd.key.parser.ocl; +package de.uka.ilkd.key.speclang.ocl.translation; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.java.abstraction.PrimitiveType; diff --git a/system/de/uka/ilkd/key/parser/ocl/FunctionFactory.java b/system/de/uka/ilkd/key/speclang/ocl/translation/FunctionFactory.java similarity index 94% rename from system/de/uka/ilkd/key/parser/ocl/FunctionFactory.java rename to system/de/uka/ilkd/key/speclang/ocl/translation/FunctionFactory.java index c0a43532e61..f4b489ff1cd 100644 --- a/system/de/uka/ilkd/key/parser/ocl/FunctionFactory.java +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/FunctionFactory.java @@ -8,11 +8,12 @@ // // -package de.uka.ilkd.key.parser.ocl; +package de.uka.ilkd.key.speclang.ocl.translation; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; +import de.uka.ilkd.key.java.Position; import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.Name; import de.uka.ilkd.key.logic.Namespace; @@ -22,7 +23,8 @@ import de.uka.ilkd.key.logic.sort.*; import de.uka.ilkd.key.proof.OpReplacer; import de.uka.ilkd.key.proof.init.CreatedAttributeTermFactory; -import de.uka.ilkd.key.util.Debug; +import de.uka.ilkd.key.speclang.translation.AxiomCollector; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; /** * ATTENTION: This is not a real factory in the sense of the design @@ -37,7 +39,7 @@ * Don't forget to reset (resetFactory) the factory for initialization! * */ -public class FunctionFactory { +class FunctionFactory { public static final FunctionFactory INSTANCE = new FunctionFactory(); @@ -164,11 +166,11 @@ public Function createAllInstancesConstant(Sort sort) { * * @param selectVar Translation of e * @param selectTerm Translation of b - * @throws OCLTranslationError + * @throws SLTranslationException */ public Function createSelectFunction(LogicVariable selectVar, Term selectTerm, - int collectionType) throws OCLTranslationError + int collectionType) throws SLTranslationException { CollectionSort csort = getCollectionSort(selectVar.sort(),collectionType); assert csort!=null; @@ -270,11 +272,11 @@ public Function createSelectFunction(LogicVariable selectVar, * * @param rejectVar Translation of e * @param rejectTerm Translation of b - * @throws OCLTranslationError + * @throws SLTranslationException */ public Function createRejectFunction(LogicVariable rejectVar, Term rejectTerm, - int collectionType) throws OCLTranslationError + int collectionType) throws SLTranslationException { return createSelectFunction(rejectVar, tb.not(rejectTerm), @@ -292,11 +294,11 @@ public Function createRejectFunction(LogicVariable rejectVar, * * @param collectVar Translation of e * @param selectTerm Translation of b - * @throws OCLTranslationError + * @throws SLTranslationException */ public Function createCollectFunction(LogicVariable collectVar, Term collectTerm, - int collectionType) throws OCLTranslationError + int collectionType) throws SLTranslationException { CollectionSort csort = getCollectionSort(collectVar.sort(),collectionType); @@ -361,7 +363,7 @@ public Function createCollectFunction(LogicVariable collectVar, axiomCollector.collectAxiom(collectE, axiom1); - System.out.println("Creating axiom2"); + //System.out.println("Creating axiom2"); // axiom 2 qvars2[0] = createVar(csort); qvars2[1] = createVar(csort.elementSort()); @@ -383,16 +385,16 @@ public Function createCollectFunction(LogicVariable collectVar, tb.func(collectE,varTerms2), replaceVar(collectVar,qvars2[1],collectTerm)); } else if (collectTerm.sort() instanceof AbstractCollectionSort) { - System.out.println("Building union"); + //System.out.println("Building union"); eq2 = union( tb.func(collectE,varTerms2), replaceVar(collectVar,qvars2[1],collectTerm)); - System.out.println("union-term: " + eq2); + //System.out.println("union-term: " + eq2); } else { raiseError("wrong sort in collectTerm!"); } - System.out.println("axiom2"); + //System.out.println("axiom2"); Term axiom2 = tb.equals( tb.func(collectE,varTerms1), eq2); @@ -401,17 +403,17 @@ public Function createCollectFunction(LogicVariable collectVar, axiomCollector.collectAxiom(collectE, axiom2); - System.out.println("Returning from Collect-Creation"); + //System.out.println("Returning from Collect-Creation"); return collectE; } - private void raiseError(String msg) throws OCLTranslationError{ - throw new OCLTranslationError("Error while generating Functions: " + msg); + private void raiseError(String msg) throws SLTranslationException { + throw new SLTranslationException("Error while generating Functions: " + msg, "no file", Position.UNDEFINED); } private Term replaceVar(LogicVariable lv1, LogicVariable lv2, Term term) { - Map map = new HashMap(); + Map map = new LinkedHashMap(); map.put(lv1, lv2); OpReplacer or = new OpReplacer(map); return or.replace(term); @@ -549,7 +551,7 @@ public Function getEmptySequence(Sort sort) { } - public Term including(Term setSymbol, Term element) throws OCLTranslationError { + public Term including(Term setSymbol, Term element) throws SLTranslationException { if( !(setSymbol.sort() instanceof AbstractCollectionSort) || !(element.sort().extendsTrans( ((AbstractCollectionSort)setSymbol.sort()).elementSort() )) ) { @@ -563,7 +565,7 @@ public Term including(Term setSymbol, Term element) throws OCLTranslationError { return tb.func(inc,setSymbol,element); } - public Term excluding(Term setSymbol, Term element) throws OCLTranslationError { + public Term excluding(Term setSymbol, Term element) throws SLTranslationException { if( !(setSymbol.sort() instanceof AbstractCollectionSort) || !(element.sort().extendsTrans( ((AbstractCollectionSort)setSymbol.sort()).elementSort() )) ) { @@ -577,7 +579,7 @@ public Term excluding(Term setSymbol, Term element) throws OCLTranslationError { return tb.func(inc,setSymbol,element); } - public Term union(Term t1, Term t2) throws OCLTranslationError { + public Term union(Term t1, Term t2) throws SLTranslationException { if( !(t1.sort() instanceof AbstractCollectionSort) || !(t2.sort() instanceof AbstractCollectionSort)) @@ -607,24 +609,26 @@ public Term union(Term t1, Term t2) throws OCLTranslationError { public Term simplify(Term t) { + Term result = t; + if (t.op().name().toString().indexOf("::union") != -1) { if(t.sub(1).op().name().toString().indexOf("::including") != -1) { if(t.sub(1).sub(0).op().name().toString().indexOf("::emptySet") != -1) { - t = tb.func((Function)t.sub(1).op(),t.sub(0),t.sub(1).sub(1)); + result = tb.func((Function)t.sub(1).op(),t.sub(0),t.sub(1).sub(1)); } } else if(t.sub(0).op().name().toString().indexOf("::including") != -1) { if(t.sub(0).sub(0).op().name().toString().indexOf("::emptySet") != -1) { - t = tb.func((Function)t.sub(0).op(),t.sub(1),t.sub(0).sub(1)); + result = tb.func((Function)t.sub(0).op(),t.sub(1),t.sub(0).sub(1)); } } } - return t; + return result; } - public Term createRangedSet(Term lowerBound, Term upperBound, Function leq) throws OCLTranslationError { + public Term createRangedSet(Term lowerBound, Term upperBound, Function leq) throws SLTranslationException { if(lowerBound.sort()!=upperBound.sort()) { raiseError("Set{"+lowerBound.toString()+".."+upperBound.toString()+"} : sorts don't match"); @@ -668,7 +672,7 @@ public Term createRangedSet(Term lowerBound, Term upperBound, Function leq) thro - public Term createRangedBag(Term lowerBound, Term upperBound, Function leq) throws OCLTranslationError { + public Term createRangedBag(Term lowerBound, Term upperBound, Function leq) throws SLTranslationException { if(lowerBound.sort()!=upperBound.sort()) { raiseError("Bag{"+lowerBound.toString()+".."+upperBound.toString()+"} : sorts don't match"); @@ -720,7 +724,7 @@ public Term createRangedBag(Term lowerBound, Term upperBound, Function leq) thro } - public Term createRangedSequence(Term lowerBound, Term upperBound, Function leq) throws OCLTranslationError { + public Term createRangedSequence(Term lowerBound, Term upperBound, Function leq) throws SLTranslationException { if(lowerBound.sort()!=upperBound.sort()) { raiseError("Sequence{"+lowerBound.toString()+".."+upperBound.toString()+"} : sorts don't match"); @@ -886,7 +890,7 @@ private LogicVariable createVar(Sort sort) { return v; } - public Term unionAndSimplify(Term t1, Term t2) throws OCLTranslationError { + public Term unionAndSimplify(Term t1, Term t2) throws SLTranslationException { Term res = union(t1,t2); Term oldRes; diff --git a/system/de/uka/ilkd/key/speclang/ocl/translation/OCLAttributeResolver.java b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLAttributeResolver.java new file mode 100644 index 00000000000..7419b88af7a --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLAttributeResolver.java @@ -0,0 +1,82 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.ocl.translation; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermFactory; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.speclang.translation.SLResolverManager; +import de.uka.ilkd.key.speclang.translation.SLExpression; +import de.uka.ilkd.key.speclang.translation.SLExpressionResolver; +import de.uka.ilkd.key.speclang.translation.SLParameters; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + + +/** + * Resolves attribute accesses. + */ +class OCLAttributeResolver extends SLExpressionResolver { + + private static final TermFactory tf = TermFactory.DEFAULT; + private final Services services; + + public OCLAttributeResolver(Services services, SLResolverManager manager) { + super(services.getJavaInfo(), manager); + this.services = services; + } + + + public boolean needVarDeclaration(String propertyName) { + return false; + } + + + public boolean canHandleReceiver(SLExpression receiver) { + return receiver != null && receiver.isCollection(); + } + + + protected SLExpression doResolving(SLExpression receiver, String name, SLParameters parameters) throws SLTranslationException { + + if(parameters != null) { + return null; + } + + ProgramVariable attribute; + + try{ + + //try as fully qualified name + attribute = javaInfo.getAttribute(name); + } catch(IllegalArgumentException e){ + + //try as short name + KeYJavaType containingType = receiver.getKeYJavaType(javaInfo); + attribute = javaInfo.lookupVisibleAttribute(name, containingType); + } + + if(attribute != null) { + OCLCollection recCollection = (OCLCollection) receiver.getCollection(); + + + Term recVarTerm = recCollection.getPredVarAsTerm(); + Term attributeTerm = tf.createAttributeTerm(attribute, + recVarTerm); + OCLCollection newCollection + = recCollection.collect(services, attributeTerm); + return new OCLEntity(newCollection); + } + + return null; + } +} diff --git a/system/de/uka/ilkd/key/parser/ocl/OCLCollection.java b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLCollection.java similarity index 87% rename from system/de/uka/ilkd/key/parser/ocl/OCLCollection.java rename to system/de/uka/ilkd/key/speclang/ocl/translation/OCLCollection.java index 30cc2f36319..6f25a18de82 100644 --- a/system/de/uka/ilkd/key/parser/ocl/OCLCollection.java +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLCollection.java @@ -8,7 +8,7 @@ // // -package de.uka.ilkd.key.parser.ocl; +package de.uka.ilkd.key.speclang.ocl.translation; import de.uka.ilkd.key.casetool.Association; import de.uka.ilkd.key.java.Services; @@ -17,13 +17,14 @@ import de.uka.ilkd.key.logic.op.Function; import de.uka.ilkd.key.logic.op.LogicVariable; import de.uka.ilkd.key.logic.sort.Sort; -import de.uka.ilkd.key.util.Debug; +import de.uka.ilkd.key.speclang.translation.SLCollection; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; /** * This class represents the CollectionType of OCL. * */ -class OCLCollection { +class OCLCollection extends SLCollection{ public static final int OCL_SET = 0; public static final int OCL_BAG = 1; @@ -87,9 +88,9 @@ public OCLCollection(Sort sort, int collectionType, Services services) { /** * Creates a collection which contains a single element. - * @throws OCLTranslationError + * @throws SLTranslationException */ - public OCLCollection(Term element, int collectionType) throws OCLTranslationError { + public OCLCollection(Term element, int collectionType) throws SLTranslationException { predInterpretation = new OCLPredicativeCollection(element); funcInterpretation = new OCLFunctionalCollection(collectionType, element); } @@ -97,9 +98,9 @@ public OCLCollection(Term element, int collectionType) throws OCLTranslationErro /** * Creates a set which contains a single element. - * @throws OCLTranslationError + * @throws SLTranslationException */ - public OCLCollection(Term element) throws OCLTranslationError { + public OCLCollection(Term element) throws SLTranslationException { this(element, OCL_SET); } @@ -107,12 +108,12 @@ public OCLCollection(Term element) throws OCLTranslationError { /** * Creates a collection which contains all integers between a lower and * an upper bound (described by terms of sort int). - * @throws OCLTranslationError + * @throws SLTranslationException */ public OCLCollection(Term lowerBound, Term upperBound, Function leq, - int collectionType) throws OCLTranslationError { + int collectionType) throws SLTranslationException { predInterpretation = new OCLPredicativeCollection(lowerBound,upperBound,leq); funcInterpretation = new OCLFunctionalCollection(lowerBound,upperBound,leq,collectionType); } @@ -121,11 +122,11 @@ public OCLCollection(Term lowerBound, /** * Creates a set which contains all integers between a lower and * an upper bound (described by terms of sort int). - * @throws OCLTranslationError + * @throws SLTranslationException */ public OCLCollection(Term lowerBound, Term upperBound, - Function leq) throws OCLTranslationError { + Function leq) throws SLTranslationException { this(lowerBound,upperBound,leq,OCL_SET); } @@ -206,9 +207,9 @@ public String toString() { * * @param c collection to union with * @return Collection containing all the elements from this and c - * @throws OCLTranslationError + * @throws SLTranslationException */ - public OCLCollection union(OCLCollection c) throws OCLTranslationError { + public OCLCollection union(OCLCollection c) throws SLTranslationException { return new OCLCollection( getPredVar(), predInterpretation.union(c).getRestriction(), @@ -225,9 +226,9 @@ public OCLCollection union(OCLCollection c) throws OCLTranslationError { * @param services global services * @param collectTerm e * @return the appropriate collection - * @throws OCLTranslationError + * @throws SLTranslationException */ - public OCLCollection collect(Services services, Term collectTerm) throws OCLTranslationError { + public OCLCollection collect(Services services, Term collectTerm) throws SLTranslationException { OCLPredicativeCollection pc = predInterpretation.navigate(services, collectTerm); OCLFunctionalCollection fc = funcInterpretation.collect(collectTerm); @@ -243,9 +244,9 @@ public OCLCollection collect(Services services, Term collectTerm) throws OCLTran * @param services global services * @param assoc the Association over which is navigated * @return the appropriate collection (hopefully) :) - * @throws OCLTranslationError + * @throws SLTranslationException */ - public OCLCollection collect(Services services, Association assoc, String name) throws OCLTranslationError { + public OCLCollection collect(Services services, Association assoc, String name) throws SLTranslationException { Function assocFunc = getAssociationFunction(assoc, name); @@ -285,9 +286,9 @@ public OCLCollection collect(Services services, OCLCollection collection) { * @param selectVar variable used in e for referring to the instances of c * @param selectTerm e * @return the appropriate collection - * @throws OCLTranslationError + * @throws SLTranslationException */ - public OCLCollection select(LogicVariable selectVar, Term selectTerm) throws OCLTranslationError { + public OCLCollection select(LogicVariable selectVar, Term selectTerm) throws SLTranslationException { OCLPredicativeCollection pc = predInterpretation.narrow(selectTerm); OCLFunctionalCollection fc = funcInterpretation.select(selectVar, selectTerm); @@ -312,4 +313,18 @@ private static Function getAssociationFunction(Association assoc, return assoc.getPredicate(); } + + + public static OCLCollection convertToOCLCollection(SLCollection c) { + + if (c instanceof OCLCollection) { + return (OCLCollection) c; + } + + // TODO ... sometime in the future if this is needed. For now + // the only collections existing are OCLCollections. + return new OCLCollection(); + + } + } diff --git a/system/de/uka/ilkd/key/speclang/ocl/translation/OCLEntity.java b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLEntity.java new file mode 100644 index 00000000000..1899ccff4fe --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLEntity.java @@ -0,0 +1,67 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.ocl.translation; + +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.speclang.translation.SLExpression; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + + +/** + * A Term, a KeYJavaType, or an OCLCollection. + */ +class OCLEntity extends SLExpression { + + public OCLEntity(Term term) { + super(term); + } + + public OCLEntity(KeYJavaType type) { + super(type); + } + + public OCLEntity(OCLCollection collection) { + super(collection); + } + + /** + * returns a collection containing only the element which is represented + * by the Term of this entity + * @throws SLTranslationException + */ + public OCLEntity asCollection() throws SLTranslationException { + return this.getTerm() != null ? new OCLEntity(new OCLCollection(this.getTerm())) : null; + } + + /** + * For types and terms, this method returns the corresponding sort. + * For collections it returns the sort of the elements, the collection + * contains. + * + * @return non-collection-sort of this entity + */ + public Sort getSort() { + Sort result; + + if(isType()) { + result = this.getType().getSort(); + } else if(isTerm()) { + result = this.getTerm().sort(); + } else { + result = this.getCollection().getElementSort(); + } + + return result; + } + +} diff --git a/system/de/uka/ilkd/key/parser/ocl/OCLFunctionalCollection.java b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLFunctionalCollection.java similarity index 82% rename from system/de/uka/ilkd/key/parser/ocl/OCLFunctionalCollection.java rename to system/de/uka/ilkd/key/speclang/ocl/translation/OCLFunctionalCollection.java index b498886e6bd..b446fbc7571 100644 --- a/system/de/uka/ilkd/key/parser/ocl/OCLFunctionalCollection.java +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLFunctionalCollection.java @@ -1,4 +1,14 @@ -package de.uka.ilkd.key.parser.ocl; +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.ocl.translation; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.TermFactory; @@ -7,6 +17,7 @@ import de.uka.ilkd.key.logic.op.SetOfQuantifiableVariable; import de.uka.ilkd.key.logic.sort.SequenceSort; import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; import de.uka.ilkd.key.util.Debug; class OCLFunctionalCollection { @@ -62,9 +73,9 @@ protected OCLFunctionalCollection(Sort sort) { /** * Creates a collection which contains a single element. - * @throws OCLTranslationError + * @throws SLTranslationException */ - protected OCLFunctionalCollection(int collectionType, Term element) throws OCLTranslationError { + protected OCLFunctionalCollection(int collectionType, Term element) throws SLTranslationException { this.restriction = funcFactory.including( tf.createFunctionTerm(funcFactory.getEmptySet(element.sort())), element); @@ -74,9 +85,9 @@ protected OCLFunctionalCollection(int collectionType, Term element) throws OCLTr /** * Creates a collection which contains a single element. - * @throws OCLTranslationError + * @throws SLTranslationException */ - protected OCLFunctionalCollection(Term element) throws OCLTranslationError { + protected OCLFunctionalCollection(Term element) throws SLTranslationException { this(OCLCollection.OCL_SET,element); } @@ -84,12 +95,12 @@ protected OCLFunctionalCollection(Term element) throws OCLTranslationError { /** * Creates a collection which contains all integers between a lower and * an upper bound (described by terms of sort int). - * @throws OCLTranslationError + * @throws SLTranslationException */ protected OCLFunctionalCollection(Term lowerBound, Term upperBound, Function leq, - int collectionType) throws OCLTranslationError { + int collectionType) throws SLTranslationException { switch (collectionType) { case OCLCollection.OCL_SET : this.restriction = funcFactory.createRangedSet(lowerBound,upperBound,leq); @@ -110,11 +121,11 @@ protected OCLFunctionalCollection(Term lowerBound, /** * Creates a collection which contains all integers between a lower and * an upper bound (described by terms of sort int). - * @throws OCLTranslationError + * @throws SLTranslationException */ protected OCLFunctionalCollection(Term lowerBound, Term upperBound, - Function leq) throws OCLTranslationError { + Function leq) throws SLTranslationException { this(lowerBound,upperBound,leq,OCLCollection.OCL_SET); } @@ -127,6 +138,7 @@ protected OCLFunctionalCollection(Term lowerBound, protected OCLFunctionalCollection(Term recTerm, Function assocFunc) { Debug.assertTrue(assocFunc!=null); + assert assocFunc!=null; Debug.assertTrue(assocFunc.arity()==1); Debug.assertTrue(assocFunc.argSort(0)==recTerm.sort()); this.restriction = tf.createFunctionTerm(assocFunc,recTerm); @@ -168,9 +180,9 @@ public String toString() { /** * Creates a collection which is the union of this one and another one. - * @throws OCLTranslationError + * @throws SLTranslationException */ - protected OCLFunctionalCollection union(OCLCollection c) throws OCLTranslationError { + protected OCLFunctionalCollection union(OCLCollection c) throws SLTranslationException { return new OCLFunctionalCollection( funcFactory.unionAndSimplify( this.restriction, @@ -185,9 +197,9 @@ protected OCLFunctionalCollection union(OCLCollection c) throws OCLTranslationEr * * @param collectTerm b * @return new functional description of the appropriate collection - * @throws OCLTranslationError + * @throws SLTranslationException */ - public OCLFunctionalCollection collect(Term collectTerm) throws OCLTranslationError { + public OCLFunctionalCollection collect(Term collectTerm) throws SLTranslationException { // is this right? // or are there any collect-expressions which don't have the collectorVar as first subterm? @@ -209,12 +221,12 @@ public OCLFunctionalCollection collect(Term collectTerm) throws OCLTranslationEr params[i+1] = tf.createVariableTerm((LogicVariable) vars.toArray()[i]); } - Term restriction = tf.createFunctionTerm(f,params); + Term newRestriction = tf.createFunctionTerm(f,params); - int collectionType = (this.collectionType == OCLCollection.OCL_SEQUENCE) ? + int newCollectionType = (this.collectionType == OCLCollection.OCL_SEQUENCE) ? OCLCollection.OCL_SEQUENCE : OCLCollection.OCL_BAG; - return new OCLFunctionalCollection(restriction,collectionType); + return new OCLFunctionalCollection(newRestriction,newCollectionType); } @@ -225,9 +237,9 @@ public OCLFunctionalCollection collect(Term collectTerm) throws OCLTranslationEr * @param selectVar x * @param selectTerm b * @return new functional description of the appropriate collection - * @throws OCLTranslationError + * @throws SLTranslationException */ - public OCLFunctionalCollection select(LogicVariable selectVar, Term selectTerm) throws OCLTranslationError { + public OCLFunctionalCollection select(LogicVariable selectVar, Term selectTerm) throws SLTranslationException { Function f = funcFactory.createSelectFunction( selectVar, @@ -245,9 +257,9 @@ public OCLFunctionalCollection select(LogicVariable selectVar, Term selectTerm) params[i+1] = tf.createVariableTerm((LogicVariable) vars.toArray()[i]); } - Term restriction = tf.createFunctionTerm(f,params); + Term newRestriction = tf.createFunctionTerm(f,params); - return new OCLFunctionalCollection(restriction,this.collectionType); + return new OCLFunctionalCollection(newRestriction,this.collectionType); } } diff --git a/system/de/uka/ilkd/key/speclang/ocl/translation/OCLMethodResolver.java b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLMethodResolver.java new file mode 100644 index 00000000000..e15b30074b9 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLMethodResolver.java @@ -0,0 +1,106 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.ocl.translation; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.speclang.translation.SLResolverManager; +import de.uka.ilkd.key.speclang.translation.SLExpression; +import de.uka.ilkd.key.speclang.translation.SLExpressionResolver; +import de.uka.ilkd.key.speclang.translation.SLParameters; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + + +/** + * Resolves method (query) calls. + */ +class OCLMethodResolver extends SLExpressionResolver { + + private final Services services; + private final FormulaBoolConverter fbc; + + public OCLMethodResolver(Services services, FormulaBoolConverter fbc, SLResolverManager man) { + super(services.getJavaInfo(),man); + this.services = services; + this.fbc = fbc; + } + + + private boolean isFullyQualified(String name) { + return name.indexOf("::") >= 0; + } + + + private String extractTypeName(String fullyQualifiedName) { + return fullyQualifiedName.substring(0, + fullyQualifiedName.indexOf("::")); + } + + + private String extractPropertyName(String fullyQualifiedName) { + return fullyQualifiedName.substring(fullyQualifiedName.indexOf("::")+2); + } + + public boolean needVarDeclaration(String propertyName) { + return false; + } + + + public boolean canHandleReceiver(SLExpression receiver) { + return receiver != null && receiver.isCollection(); + } + + + protected SLExpression doResolving(SLExpression receiver, String name, SLParameters parameters) throws SLTranslationException { + + if(parameters == null + || !(parameters instanceof OCLParameters) + || !((OCLParameters)parameters).getDeclaredVars().isEmpty()) { + return null; + } + + String containingName; + String propertyName = name; + + if(isFullyQualified(name)) { + containingName = extractTypeName(name); + propertyName = extractPropertyName(name); + } else { + KeYJavaType containingType = receiver.getKeYJavaType(javaInfo); + if(containingType == null) { + return null; + } + containingName = containingType.getFullName(); + } + + Term[] args + = fbc.convertFormulasToBool(((OCLParameters)parameters).getEntities()).toArray(); + + OCLCollection recCollection = (OCLCollection) receiver.getCollection(); + + try { + Term recVarTerm = recCollection.getPredVarAsTerm(); + Term methodTerm = javaInfo.getProgramMethodTerm( + recVarTerm, + propertyName, + args, + containingName); + OCLCollection newCollection + = recCollection.collect(services, methodTerm); + return new OCLEntity(newCollection); + } catch (IllegalArgumentException e) { + return null; + } + + } + +} diff --git a/system/de/uka/ilkd/key/parser/ocl/OCLParameters.java b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLParameters.java similarity index 71% rename from system/de/uka/ilkd/key/parser/ocl/OCLParameters.java rename to system/de/uka/ilkd/key/speclang/ocl/translation/OCLParameters.java index 96e5aaf2409..a441b7a25f0 100644 --- a/system/de/uka/ilkd/key/parser/ocl/OCLParameters.java +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLParameters.java @@ -8,19 +8,23 @@ // // -package de.uka.ilkd.key.parser.ocl; +package de.uka.ilkd.key.speclang.ocl.translation; import de.uka.ilkd.key.logic.op.IteratorOfLogicVariable; import de.uka.ilkd.key.logic.op.ListOfLogicVariable; +import de.uka.ilkd.key.speclang.translation.ListOfSLExpression; +import de.uka.ilkd.key.speclang.translation.SLListOfSLExpression; +import de.uka.ilkd.key.speclang.translation.SLParameters; import de.uka.ilkd.key.util.Debug; -class OCLParameters { +class OCLParameters extends SLParameters { private final ListOfLogicVariable declaredVars; private final ListOfOCLEntity entities; public OCLParameters(ListOfLogicVariable declaredVars, ListOfOCLEntity entities) { + super(convertToListOfSLExpression(entities)); Debug.assertTrue(declaredVars != null); Debug.assertTrue(entities != null); this.declaredVars = declaredVars; @@ -28,6 +32,19 @@ public OCLParameters(ListOfLogicVariable declaredVars, } + private static ListOfSLExpression convertToListOfSLExpression(ListOfOCLEntity list) { + ListOfSLExpression result = SLListOfSLExpression.EMPTY_LIST; + + IteratorOfOCLEntity it = list.iterator(); + + while(it.hasNext()) { + result = result.append(it.next()); + } + + return result; + } + + public ListOfOCLEntity getEntities() { return entities; } diff --git a/system/de/uka/ilkd/key/parser/ocl/OCLPredicativeCollection.java b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLPredicativeCollection.java similarity index 98% rename from system/de/uka/ilkd/key/parser/ocl/OCLPredicativeCollection.java rename to system/de/uka/ilkd/key/speclang/ocl/translation/OCLPredicativeCollection.java index ffbb4a5f08a..f2ad7a289d8 100644 --- a/system/de/uka/ilkd/key/parser/ocl/OCLPredicativeCollection.java +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLPredicativeCollection.java @@ -8,9 +8,9 @@ // -package de.uka.ilkd.key.parser.ocl; +package de.uka.ilkd.key.speclang.ocl.translation; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -144,7 +144,7 @@ private static Term createPredicateTerm( private Term replaceVar(LogicVariable lv1, LogicVariable lv2, Term term) { - Map map = new HashMap(); + Map map = new LinkedHashMap(); map.put(lv1, lv2); OpReplacer or = new OpReplacer(map); return or.replace(term); diff --git a/system/de/uka/ilkd/key/speclang/ocl/translation/OCLSpecFactory.java b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLSpecFactory.java new file mode 100644 index 00000000000..de13a655c63 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLSpecFactory.java @@ -0,0 +1,212 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.ocl.translation; + +import java.util.LinkedHashMap; +import java.util.Map; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.EverythingLocationDescriptor; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.logic.op.ListOfParsableVariable; +import de.uka.ilkd.key.logic.op.LogicVariable; +import de.uka.ilkd.key.logic.op.Modality; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.speclang.ClassInvariant; +import de.uka.ilkd.key.speclang.ClassInvariantImpl; +import de.uka.ilkd.key.speclang.FormulaWithAxioms; +import de.uka.ilkd.key.speclang.OperationContract; +import de.uka.ilkd.key.speclang.OperationContractImpl; +import de.uka.ilkd.key.speclang.SetAsListOfOperationContract; +import de.uka.ilkd.key.speclang.SetOfOperationContract; +import de.uka.ilkd.key.speclang.SignatureVariablesFactory; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + + +/** + * A factory for creating class invariants and operation contracts + * from OCL specifications. This is the public interface to the + * ocl.translation package. + */ +public class OCLSpecFactory { + + private static final SignatureVariablesFactory SVF + = SignatureVariablesFactory.INSTANCE; + + private final Services services; + private final OCLTranslator translator; + + private int invCounter; + private int contractCounter; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public OCLSpecFactory(Services services) { + assert services != null; + this.services = services; + this.translator = new OCLTranslator(services); + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private String getInvName() { + return "OCL class invariant (id: " + invCounter++ + ")"; + } + + + private String getContractName() { + return "OCL operation contract (id: " + contractCounter++ + ")"; + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + public ClassInvariant createOCLClassInvariant(KeYJavaType kjt, + String originalInv) + throws SLTranslationException { + assert kjt != null; + assert originalInv != null; + + //create logical variable for self + Sort sort = kjt.getSort(); + LogicVariable selfVar = new LogicVariable(new Name("self"), sort); + + //translate expression + FormulaWithAxioms inv = translator.translateExpression(originalInv, + kjt, + selfVar, + null, + null, + null, + null); + //all-quantify + inv = inv.allClose(services); + + //create invariant + String name = getInvName(); + return new ClassInvariantImpl(name, + name, + kjt, + inv, + selfVar); + } + + + public SetOfOperationContract createOCLOperationContracts( + ProgramMethod programMethod, + String originalPre, + String originalPost, + String originalModifies) + throws SLTranslationException { + assert programMethod != null; + + //create variables for self, parameters, result, exception, + //and the map for atPre-Functions + ParsableVariable selfVar = SVF.createSelfVar(services, + programMethod, + false); + ListOfParsableVariable paramVars = SVF.createParamVars(services, + programMethod, + false); + ParsableVariable resultVar = SVF.createResultVar(services, + programMethod, + false); + ParsableVariable excVar = SVF.createExcVar(services, + programMethod, + false); + Map atPreFunctions = new LinkedHashMap(); + + //translate pre + FormulaWithAxioms pre; + if(originalPre == null) { + pre = FormulaWithAxioms.TT; + } else { + pre = translator.translateExpression(originalPre, + programMethod.getContainerType(), + selfVar, + paramVars, + null, + null, + null); + } + + //translate post + FormulaWithAxioms post; + if(originalPost == null) { + post = FormulaWithAxioms.TT; + } else { + post = translator.translateExpression(originalPost, + programMethod.getContainerType(), + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + } + + //translate modifies + SetOfLocationDescriptor modifies; + if(originalModifies == null) { + modifies = EverythingLocationDescriptor.INSTANCE_AS_SET; + } else { + modifies = translator.translateModifiesExpression(originalModifies, + selfVar, + paramVars); + } + + //create contracts + SetOfOperationContract result = SetAsListOfOperationContract.EMPTY_SET; + String name1 = getContractName(); + String name2 = getContractName(); + OperationContract contract1 + = new OperationContractImpl(name1, + name1, + programMethod, + Modality.DIA, + pre, + post, + modifies, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + OperationContract contract2 + = new OperationContractImpl(name2, + name2, + programMethod, + Modality.BOX, + pre, + post, + modifies, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + result = result.add(contract1).add(contract2); + return result; + } +} diff --git a/system/de/uka/ilkd/key/speclang/ocl/translation/OCLTranslator.java b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLTranslator.java new file mode 100644 index 00000000000..c28d485ba1a --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/OCLTranslator.java @@ -0,0 +1,152 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.ocl.translation; + +import java.io.StringReader; +import java.util.Map; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.ListOfInteger; +import de.uka.ilkd.key.logic.Namespace; +import de.uka.ilkd.key.logic.SLListOfInteger; +import de.uka.ilkd.key.logic.SetOfLocationDescriptor; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.TermFactory; +import de.uka.ilkd.key.logic.op.IteratorOfParsableVariable; +import de.uka.ilkd.key.logic.op.ListOfParsableVariable; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.parser.KeYLexer; +import de.uka.ilkd.key.parser.KeYParser; +import de.uka.ilkd.key.parser.ParserMode; +import de.uka.ilkd.key.speclang.FormulaWithAxioms; +import de.uka.ilkd.key.speclang.translation.AxiomCollector; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; + + +/** + * Translates OCL expressions to FOL. + */ +class OCLTranslator { + private final Services services; + private ListOfInteger parserCounters = SLListOfInteger.EMPTY_LIST; + + + public OCLTranslator(Services services) { + this.services = services; + } + + + /** + * Translates a normal top-level OCL expression, i.e. a formula. + */ + public FormulaWithAxioms translateExpression( + String expr, + KeYJavaType specInClass, + ParsableVariable selfVar, + ListOfParsableVariable paramVars, + ParsableVariable resultVar, + ParsableVariable excVar, + Map /*Operator (normal) + -> Function (atPre)*/ atPreFunctions) + throws SLTranslationException { + assert expr != null && !expr.equals(""); + AxiomCollector ac = new AxiomCollector(); + FunctionFactory.INSTANCE.resetFactory(services, ac); + + Term resultFormula = null; + Map resultAxioms = null; + + //create lexer and parser + StringReader stream = new StringReader(expr); + KeYOCLLexer lexer = new KeYOCLLexer(stream); + KeYOCLParser parser = new KeYOCLParser(lexer, + services, + specInClass, + ac, + selfVar, + paramVars, + resultVar, + excVar, + atPreFunctions); + + //initialise counters + parser.setCounters(parserCounters); + + //parse the expression + if (expr.length() > 0) { + resultFormula = parser.parseExpression(); + } else { + resultFormula = TermBuilder.DF.tt(); + } + + //get created Axioms + resultAxioms = ac.getAxioms(); + + //save counter values + parserCounters = parser.getCounters(); + + return new FormulaWithAxioms(resultFormula, resultAxioms); + } + + + /** + * Translates an expression as it occurs in KeY-OCL modifies expressions. + */ + public SetOfLocationDescriptor translateModifiesExpression( + String modifiesExpr, + ParsableVariable selfVar, + ListOfParsableVariable paramVars) + throws SLTranslationException { + assert modifiesExpr != null && !modifiesExpr.equals(""); + + //add self and parameter variables to namespace + Namespace originalProgVars + = services.getNamespaces().programVariables(); + Namespace extendedProgVars + = originalProgVars.copy(); + extendedProgVars.add(selfVar); + IteratorOfParsableVariable it = paramVars.iterator(); + while(it.hasNext()) { + extendedProgVars.add(it.next()); + } + services.getNamespaces().setProgramVariables(extendedProgVars); + + //create parser + KeYParser parser + = new KeYParser(ParserMode.TERM, + new KeYLexer(new StringReader(modifiesExpr), + null), + "modifier string", + TermFactory.DEFAULT, + services, + services.getNamespaces()); + + //parse + try { + return parser.location_list(); + } catch(RecognitionException e) { + throw new SLTranslationException(e.getMessage(), + "no file", + e.getLine(), + e.getColumn()); + } catch(TokenStreamException e) { + throw new SLTranslationException(e.getMessage(),"no file", -1, -1); + } finally { + //set back namespace + services.getNamespaces().setProgramVariables(originalProgVars); + } + } +} diff --git a/system/de/uka/ilkd/key/speclang/ocl/translation/PropertyManager.java b/system/de/uka/ilkd/key/speclang/ocl/translation/PropertyManager.java new file mode 100644 index 00000000000..f064f52c490 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/PropertyManager.java @@ -0,0 +1,52 @@ +//This file is part of KeY - Integrated Deductive Software Design +//Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +//The KeY system is protected by the GNU General Public License. +//See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.ocl.translation; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.speclang.translation.SLResolverManager; +import de.uka.ilkd.key.speclang.translation.SLCollection; +import de.uka.ilkd.key.speclang.translation.SLExpression; + + +/** + * Resolves property calls of any kind. + * Keeps a stack of namespaces to deal with several levels of local variables + * (e.g. "self", or iterator variables in forall() or select() subtrees). + */ +class PropertyManager extends SLResolverManager { + + public PropertyManager(Services services, KeYJavaType specInClass, FormulaBoolConverter fbc, ParsableVariable excVar) { + super(services.getJavaInfo(), specInClass, true, true, true); + resolvers = resolvers.append(new OCLAttributeResolver(services, this)); + resolvers = resolvers.append(new OCLMethodResolver(services, fbc, this)); + resolvers = resolvers.append(new BuiltInPropertyResolver(services, excVar, this)); + // AssociationResolver does not work without Together! (needs UMLInfo) + //resolvers = resolvers.append(new AssociationResolver(services, this)); + } + + + public SLExpression createSLExpression(Term t) { + return new OCLEntity(t); + } + + + public SLExpression createSLExpression(KeYJavaType t) { + return new OCLEntity(t); + } + + + public SLExpression createSLExpression(SLCollection c) { + return new OCLEntity(OCLCollection.convertToOCLCollection(c)); + } +} diff --git a/system/de/uka/ilkd/key/speclang/ocl/translation/TestOCLTranslator.java b/system/de/uka/ilkd/key/speclang/ocl/translation/TestOCLTranslator.java new file mode 100644 index 00000000000..5fb23efc5ff --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/TestOCLTranslator.java @@ -0,0 +1,319 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. + + +package de.uka.ilkd.key.speclang.ocl.translation; + +import java.io.File; +import java.util.LinkedHashMap; +import java.util.Map; + +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; +import de.uka.ilkd.key.java.abstraction.PrimitiveType; +import de.uka.ilkd.key.java.abstraction.SLListOfKeYJavaType; +import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.op.LocationVariable; +import de.uka.ilkd.key.logic.op.LogicVariable; +import de.uka.ilkd.key.logic.op.Op; +import de.uka.ilkd.key.logic.op.ProgramMethod; +import de.uka.ilkd.key.logic.op.ProgramVariable; +import de.uka.ilkd.key.proof.init.CreatedAttributeTermFactory; +import de.uka.ilkd.key.speclang.FormulaWithAxioms; +import de.uka.ilkd.key.speclang.ocl.translation.OCLTranslator; +import de.uka.ilkd.key.speclang.translation.SLTranslationException; +import de.uka.ilkd.key.util.HelperClassForTests; +import junit.framework.TestCase; + +public class TestOCLTranslator extends TestCase { + + public static final String testFile = System.getProperty("key.home") + + File.separator + "examples" + File.separator + "_testcase" + + File.separator + "speclang" + File.separator + "testFile.key"; + + private static final TermBuilder tb = TermBuilder.DF; + + private static JavaInfo javaInfo; + private static Services services; + private static OCLTranslator translator; + private static KeYJavaType testClassType; + + + protected void setUp() { + if(javaInfo != null) { + return; + } + javaInfo = new HelperClassForTests().parse(new File(testFile)).getFirstProof().getJavaInfo(); + services = javaInfo.getServices(); + translator = new OCLTranslator(services); + testClassType = javaInfo.getKeYJavaType("testPackage.TestClass"); + } + + protected void tearDown() { + } + + protected ProgramVariable buildSelfVarAsProgVar() { + ProgramElementName classPEN = new ProgramElementName("self"); + ProgramVariable result = new LocationVariable(classPEN, testClassType); + return result; + } + + protected ProgramVariable buildExcVar() { + KeYJavaType excType = javaInfo + .getTypeByClassName("java.lang.Exception"); + ProgramElementName excPEN = new ProgramElementName("exc"); + return new LocationVariable(excPEN, excType); + } + + public void testTrueTerm() { + FormulaWithAxioms result = null; + + try { + result = translator.translateExpression("true", javaInfo + .getKeYJavaType("testPackage.TestClass"), null, null, null, + null, new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + assertTrue(result != null); + + assert result != null; + assertTrue(result.getFormula().equals(TermBuilder.DF.tt())); + assertTrue(result.getAxioms().isEmpty()); + } + + public void testSelfVar() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + + try { + result = translator.translateExpression("self", testClassType, + selfVar, null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getFormula().equals(tb.var(selfVar))); + assertTrue(result.getAxioms().isEmpty()); + } + + public void testPrimitiveField() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + ProgramVariable i = javaInfo.getAttribute("testPackage.TestClass::i"); + + try { + result = translator.translateExpression("self.i", testClassType, + selfVar, null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getFormula().equals(tb.dot(tb.var(selfVar), i))); + assertTrue(result.getAxioms().isEmpty()); + } + + public void testSimpleQuery() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + Term queryTerm = javaInfo.getProgramMethodTerm(tb.var(selfVar), + "getOne", new Term[] {}, "testPackage.TestClass"); + + try { + result = translator.translateExpression("self.getOne()", + testClassType, selfVar, null, null, null, + new LinkedHashMap()); + } catch (SLTranslationException e) { + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getFormula().equals(queryTerm)); + assertTrue(result.getAxioms().isEmpty()); + } + + public void testForAll() { + FormulaWithAxioms result = null; + + try { + result = translator.translateExpression( + "TestClass.allInstances()->forAll(t | t <> null)", + this.testClassType, null, null, null, null, + new LinkedHashMap()); + } catch (SLTranslationException e) { + e.printStackTrace(); + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + /* + System.out.println("nr. of axioms: " + result.getAxioms().size()); + Iterator it = result.getAxioms().keySet().iterator(); + while(it.hasNext()) { + Operator op = (Operator) it.next(); + System.out.println("axiom for " + op + ": " + result.getAxioms().get(op)); + } + System.out.println(); + System.out.println("formula: " + result.getFormula()); + System.out.println(); + System.out.println(); + */ + // There sould be 1 axiom defining allInstances (in functional representation) + assertTrue(result.getAxioms().size() == 1); + assertTrue(result.getFormula().op().equals(Op.ALL)); + assertTrue(result.getFormula().sub(0).op().equals(Op.IMP)); + assertTrue(result.getFormula().varsBoundHere(0).size() == 1); + LogicVariable q = (LogicVariable) result.getFormula().varsBoundHere(0) + .getQuantifiableVariable(0); + + Term subTerm = tb.imp(CreatedAttributeTermFactory.INSTANCE + .createCreatedOrNullTerm(services, tb.var(q)), tb.imp(tb.not(tb + .equals(tb.var(q), tb.NULL(services))), tb.not(tb.equals(tb + .var(q), tb.NULL(services))))); + Term expectedTerm = tb.all(q, subTerm); + assertTrue(result.getFormula().equals(expectedTerm)); + } + + public void testComplexExists() { + FormulaWithAxioms result = null; + + try { + result = translator + .translateExpression( + "TestClass.allInstances()->select(t | t <> null)->exists(t | t = null)", + this.testClassType, null, null, null, null, + new LinkedHashMap()); + } catch (SLTranslationException e) { + e.printStackTrace(); + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + /* + System.out.println("nr. of axioms: " + result.getAxioms().size()); + Iterator it = result.getAxioms().keySet().iterator(); + while(it.hasNext()) { + Operator op = (Operator) it.next(); + System.out.println("axiom for " + op + ": " + result.getAxioms().get(op)); + } + System.out.println(); + System.out.println("formula: " + result.getFormula()); + System.out.println(); + System.out.println(); + */ + // There sould be 1 axiom defining allInstances (in functional representation) + // and 1 axiom defining the call to select + assertTrue(result.getAxioms().size() == 2); + assertTrue(result.getFormula().op().equals(Op.EX)); + assertTrue(result.getFormula().sub(0).op().equals(Op.AND)); + assertTrue(result.getFormula().varsBoundHere(0).size() == 1); + } + + public void testAtPre() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + ProgramVariable excVar = buildExcVar(); + + Map atPreDefs = new LinkedHashMap(); + + try { + result = translator.translateExpression("self.i = self.i@pre", + testClassType, selfVar, null, null, excVar, // needed to make the translator think it's a postcondition + atPreDefs); + } catch (SLTranslationException e) { + e.printStackTrace(); + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getAxioms().isEmpty()); + assertTrue(atPreDefs.size() == 1); + assertTrue(result.getFormula().op().equals(Op.EQUALS)); + } + + public void testComplexQueryResolving1() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + + ListOfKeYJavaType signature = SLListOfKeYJavaType.EMPTY_LIST; + signature = signature.append(javaInfo + .getKeYJavaType(PrimitiveType.JAVA_INT)); + + ProgramMethod pm = javaInfo.getProgramMethod(testClassType, "m", + signature, testClassType); + + try { + result = translator.translateExpression( + "self.m(4 + 2) = self.m(l + i)", testClassType, selfVar, + null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + e.printStackTrace(); + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getAxioms().isEmpty()); + assertTrue(result.getFormula().sub(0).op().equals(pm)); + assertTrue(result.getFormula().sub(1).op().equals(pm)); + } + + public void testComplexQueryResolving2() { + FormulaWithAxioms result = null; + + ProgramVariable selfVar = buildSelfVarAsProgVar(); + + ListOfKeYJavaType signature = SLListOfKeYJavaType.EMPTY_LIST; + signature = signature.append(javaInfo + .getKeYJavaType(PrimitiveType.JAVA_LONG)); + + ProgramMethod pm = javaInfo.getProgramMethod(testClassType, "m", + signature, testClassType); + + try { + result = translator.translateExpression( + "self.m(l) = self.m(i.oclAsType(long))", testClassType, + selfVar, null, null, null, new LinkedHashMap()); + } catch (SLTranslationException e) { + e.printStackTrace(); + assertTrue(false); + } + + assertTrue(result != null); + + assert result != null; + assertTrue(result.getAxioms().isEmpty()); + assertTrue(result.getFormula().sub(0).op().equals(pm)); + assertTrue(result.getFormula().sub(1).op().equals(pm)); + } + +} diff --git a/system/de/uka/ilkd/key/parser/ocl/lexer.g b/system/de/uka/ilkd/key/speclang/ocl/translation/ocllexer.g similarity index 93% rename from system/de/uka/ilkd/key/parser/ocl/lexer.g rename to system/de/uka/ilkd/key/speclang/ocl/translation/ocllexer.g index 0e7cedc7649..3bd4a52b413 100644 --- a/system/de/uka/ilkd/key/parser/ocl/lexer.g +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/ocllexer.g @@ -17,10 +17,10 @@ /* -*-Antlr-*- */ header { - package de.uka.ilkd.key.parser.ocl; + package de.uka.ilkd.key.speclang.ocl.translation; } -class KeYOclLexer extends Lexer; +class KeYOCLLexer extends Lexer; options { testLiterals=true; @@ -58,16 +58,16 @@ DCOLON : "::"; COMMA : ","; EQUAL : "="; NEQUAL : "<>"; -LT : "<"; -GT : ">"; -LE : "<="; -GE : ">="; +LT : "<"; +GT : ">"; +LE : "<="; +GE : ">="; RARROW : "->"; DOTDOT : ".."; -DOT : "."; +DOT : "."; POUND : "#"; SEMICOL : ";"; -BAR : "|"; +BAR : "|"; ATSIGN : "@"; PLUS : "+"; MINUS : "-"; diff --git a/system/de/uka/ilkd/key/parser/ocl/ocl.g b/system/de/uka/ilkd/key/speclang/ocl/translation/oclparser.g similarity index 69% rename from system/de/uka/ilkd/key/parser/ocl/ocl.g rename to system/de/uka/ilkd/key/speclang/ocl/translation/oclparser.g index 9f67d36e764..6bbc149ecd6 100644 --- a/system/de/uka/ilkd/key/parser/ocl/ocl.g +++ b/system/de/uka/ilkd/key/speclang/ocl/translation/oclparser.g @@ -10,7 +10,7 @@ /* -*-antlr-*- */ header { - package de.uka.ilkd.key.parser.ocl; + package de.uka.ilkd.key.speclang.ocl.translation; import de.uka.ilkd.key.collection.IteratorOfString; import de.uka.ilkd.key.collection.ListOfString; @@ -22,17 +22,22 @@ header { import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.logic.sort.*; + import de.uka.ilkd.key.speclang.translation.AxiomCollector; + import de.uka.ilkd.key.speclang.translation.JavaIntegerSemanticsHelper; + import de.uka.ilkd.key.speclang.translation.SLTranslationException; import de.uka.ilkd.key.util.Debug; + import de.uka.ilkd.key.proof.AtPreFactory; + import java.lang.*; import java.lang.AssertionError; import java.util.Map; - import java.util.HashMap; + import java.util.LinkedHashMap; } -class KeYOclParser extends Parser; +class KeYOCLParser extends Parser; options { - importVocab=KeYOclLexer; + importVocab=KeYOCLLexer; k=2; defaultErrorHandler=false; } @@ -41,6 +46,7 @@ options { //constants private static final FunctionFactory funcFactory = FunctionFactory.INSTANCE; private static final TermBuilder tb = TermBuilder.DF; + private static final AtPreFactory APF = AtPreFactory.INSTANCE; //parameters private Services services; @@ -48,9 +54,7 @@ options { private Namespace funcNS; private Namespace sortNS; private Namespace varNS; - - //functions - private Map localAtPreFunctions = new HashMap(); + private Map /*operator (normal) -> function (atPre)*/ atPreFunctions; //variables for variables private ParsableVariable selfVar; @@ -62,19 +66,23 @@ options { private FormulaBoolConverter formulaBoolConverter; private PropertyManager propertyManager; private AxiomCollector axiomCollector; + private JavaIntegerSemanticsHelper intHelper; private boolean preConditionParser; /** * @param lexer the associated lexer */ - public KeYOclParser(TokenStream lexer, - Services services, + public KeYOCLParser(TokenStream lexer, + Services services, + KeYJavaType specInClass, AxiomCollector ac, ParsableVariable selfVar, ListOfParsableVariable paramVars, ParsableVariable resultVar, - ParsableVariable excVar){ + ParsableVariable excVar, + /*inout*/ Map /*operator (normal) + -> function (atPre)*/ atPreFunctions) { this(lexer); //save parameters @@ -84,10 +92,11 @@ options { funcNS = nss.functions(); sortNS = nss.sorts(); varNS = nss.variables(); - this.selfVar = selfVar; - this.paramVars = paramVars; - this.resultVar = resultVar; - this.excVar = excVar; + this.selfVar = selfVar; + this.paramVars = paramVars; + this.resultVar = resultVar; + this.excVar = excVar; + this.atPreFunctions = atPreFunctions; //set axiomCollector axiomCollector = ac; @@ -95,8 +104,11 @@ options { //initialise formula-bool-converter formulaBoolConverter = new FormulaBoolConverter(services, nss); + //initialise integer helper + intHelper = new JavaIntegerSemanticsHelper(services); + //initialise property manager - propertyManager = new PropertyManager(services, formulaBoolConverter, excVar); + propertyManager = new PropertyManager(services, specInClass, formulaBoolConverter, excVar); propertyManager.pushLocalVariablesNamespace(); if(selfVar != null) { propertyManager.putIntoTopLocalVariablesNamespace(selfVar); @@ -139,8 +151,14 @@ options { return col; } - private void raiseError(String message) throws OCLTranslationError { - throw new OCLTranslationError("OCL Parser Error: " + message, getLine(), getColumn()); + + private void raiseError(Exception e) throws SLTranslationException { + throw new SLTranslationException(e.getMessage(), "no file", getLine(), getColumn()); + } + + + private void raiseError(String message) throws SLTranslationException { + throw new SLTranslationException("OCL Parser Error: " + message, "no file", getLine(), getColumn()); } @@ -168,84 +186,32 @@ options { } - /** - * Helper for buildAtPreDefinition(). - */ - private Term[] getTerms(ArrayOfQuantifiableVariable vars) { - int numVars = vars.size(); - Term[] result = new Term[numVars]; - - for(int i = 0; i < numVars; i++) { - LogicVariable var - = (LogicVariable)(vars.getQuantifiableVariable(i)); - result[i] = tb.var(var); - } - - return result; - } - - - /** - * Creates a definition for an atPre function - * (helper for convertToAtPre()). - * @param f1 original function - * @param f2 atPre function - */ - protected Term buildAtPreDefinition(Operator f1, Function f2) { - Term result = tb.tt(); - - int arity = f1.arity(); - assert arity == f2.arity(); - LogicVariable[] args = new LogicVariable[arity]; - for(int i = 0; i < arity; i++) { - args[i] = new LogicVariable(new Name("x" + i), f2.argSort(i)); - } - - Term[] argTerms = getTerms(new ArrayOfQuantifiableVariable(args)); - - Term f1Term = TermFactory.DEFAULT.createTerm(f1, - argTerms, - (ArrayOfQuantifiableVariable)null, - null); - Term f2Term = tb.func(f2, argTerms); - Term equalsTerm = tb.equals(f1Term, f2Term); - Term quantifTerm; - if(arity > 0) { - quantifTerm = tb.all(args, equalsTerm); - } else { - quantifTerm = equalsTerm; - } - result = tb.and(result, quantifTerm); - return result; - } - - /** - * Converts a term so that it's top-level operator refers to the pre-state. + * Converts a term so that its top-level operator refers to the pre-state. * Creates and saves new atPreFunctions when necessary. */ private Term convertToAtPre(Term term) { - Term[] subTerms = getSubTerms(term); - - Function atPreFunction = (Function) localAtPreFunctions.get(term.op()); - if(atPreFunction == null) { - String name = term.op().name().toString() + "@pre"; - if(name.startsWith(".")) { - name = name.substring(1); - } - atPreFunction = new RigidFunction(new Name(name), - term.sort(), - getSorts(subTerms)); - localAtPreFunctions.put(term.op(), atPreFunction); - funcNS.add(atPreFunction); - axiomCollector.collectAxiom(atPreFunction, - buildAtPreDefinition(term.op(), - atPreFunction)); - } - - Term result = tb.func(atPreFunction, subTerms); - return result; + assert atPreFunctions != null; + + Operator newOp; + if(term.op() instanceof NonRigid) { + Function atPreFunc = (Function) atPreFunctions.get(term.op()); + if(atPreFunc == null) { + atPreFunc = APF.createAtPreFunction(term.op(), services); + atPreFunctions.put(term.op(), atPreFunc); + assert atPreFunc != null; + } + newOp = atPreFunc; + } else { + newOp = term.op(); + } + + Term result = tb.tf().createTerm(newOp, + getSubTerms(term), + term.varsBoundHere(0), + term.javaBlock()); + return result; } @@ -272,30 +238,30 @@ options { } } if(a.isCollection() && b.isCollection()) { - Sort csort = a.getCollection().getFunctionalRestriction().sort(); + Sort csort = ((OCLCollection) a.getCollection()).getFunctionalRestriction().sort(); LogicVariable v = new LogicVariable( //TODO: change variable-name new Name("e"), ((AbstractCollectionSort) csort).elementSort()); - if(a.getCollection().isSet() && b.getCollection().isSet()) { + if(((OCLCollection) a.getCollection()).isSet() && ((OCLCollection) b.getCollection()).isSet()) { Function isIn = (Function) funcNS.lookup(new Name(csort.name().toString()+"::includes")); Term subTerm = tb.equiv( tb.func(isIn, - a.getCollection().getFunctionalRestriction(), + ((OCLCollection) a.getCollection()).getFunctionalRestriction(), tb.var(v)), tb.func(isIn, - b.getCollection().getFunctionalRestriction(), + ((OCLCollection) b.getCollection()).getFunctionalRestriction(), tb.var(v))); result = tb.all(v,subTerm); } - if(a.getCollection().isBag() && b.getCollection().isBag()) { + if(((OCLCollection) a.getCollection()).isBag() && ((OCLCollection) b.getCollection()).isBag()) { Function count = (Function) funcNS.lookup(new Name(csort.name().toString()+"::count")); Term subTerm = tb.equiv( tb.func(count, - a.getCollection().getFunctionalRestriction(), + ((OCLCollection) a.getCollection()).getFunctionalRestriction(), tb.var(v)), tb.func(count, - b.getCollection().getFunctionalRestriction(), + ((OCLCollection) b.getCollection()).getFunctionalRestriction(), tb.var(v))); result = tb.all(v,subTerm); } @@ -330,27 +296,17 @@ options { /** * Parses the expression passed to the constructor. */ - public Term parseExpression() throws OCLTranslationError { + public Term parseExpression() throws SLTranslationException { OCLEntity expr = null; try { - expr = expression(); - } catch(RecognitionException e) { - if (e instanceof OCLTranslationError) - throw (OCLTranslationError)e; - else - throw new OCLTranslationError( - ((antlr.RecognitionException)e).getMessage(), - ((antlr.RecognitionException)e).getLine(), - ((antlr.RecognitionException)e).getColumn()); - } catch (ANTLRException e) { - raiseError("Unknown OCL-Translation error (from ANTLR): " + e.getMessage()); - } catch (Exception e) { - raiseError("OCL-Translation error: " + e.getMessage()); - } - + expr = expression(); + } catch (antlr.ANTLRException e) { + raiseError(e); + } + if(expr == null) { - raiseError("OCL-Translation error."); + raiseError("Fatal OCL-Translation error."); } Term result = expr.getTerm(); @@ -384,7 +340,7 @@ options { //Rules which are not currently used, since we only parse at expression level //----------------------------------------------------------------------------- -top +top throws SLTranslationException { OCLEntity t; } @@ -396,12 +352,12 @@ top ; -oclFile +oclFile throws SLTranslationException : ( "package" packageName oclExpressions "endpackage" )+ ; -packageName +packageName throws SLTranslationException { String s; } @@ -409,12 +365,12 @@ packageName ; -oclExpressions +oclExpressions throws SLTranslationException : (constraint)* ; -constraint +constraint throws SLTranslationException { OCLEntity t; } @@ -428,38 +384,38 @@ constraint ; -contextDeclaration +contextDeclaration throws SLTranslationException : "context" (operationContext | classifierContext) ; -classifierContext +classifierContext throws SLTranslationException : (NAME COLON NAME) | NAME ; -operationContext +operationContext throws SLTranslationException : NAME DCOLON operationName LPAREN formalParameterList RPAREN ( COLON returnType )? ; -returnType +returnType throws SLTranslationException : typeSpecifier ; -stereotype +stereotype throws SLTranslationException : "pre" | "post" | "inv" ; -operationName +operationName throws SLTranslationException : NAME | EQUAL | PLUS @@ -480,12 +436,12 @@ operationName ; -oclExpression returns [OCLEntity result=null] +oclExpression returns [OCLEntity result=null] throws SLTranslationException : ( (letExpression)* "in" )? result=expression ; -letExpression +letExpression throws SLTranslationException { OCLEntity t; } @@ -497,7 +453,7 @@ letExpression ; -formalParameterList +formalParameterList throws SLTranslationException : ( NAME COLON typeSpecifier @@ -512,12 +468,12 @@ formalParameterList //Rules for expressions and below //----------------------------------------------------------------------------- -expression returns [OCLEntity result=null] +expression returns [OCLEntity result=null] throws SLTranslationException : result=implicationExpression ; -implicationExpression returns [OCLEntity result=null] +implicationExpression returns [OCLEntity result=null] throws SLTranslationException { OCLEntity a=null; } @@ -533,7 +489,7 @@ implicationExpression returns [OCLEntity result=null] ; -logicalExpression returns [OCLEntity result=null] +logicalExpression returns [OCLEntity result=null] throws SLTranslationException { OCLEntity a=null; Junctor j=null; @@ -562,7 +518,7 @@ logicalExpression returns [OCLEntity result=null] ; -relationalExpression returns [OCLEntity result=null] +relationalExpression returns [OCLEntity result=null] throws SLTranslationException { OCLEntity a=null; Function f=null; @@ -600,27 +556,48 @@ relationalExpression returns [OCLEntity result=null] ; -additiveExpression returns [OCLEntity result=null] +additiveExpression returns [OCLEntity result=null] throws SLTranslationException { OCLEntity a=null; Operator op=null; } : result=multiplicativeExpression - ( - op=addOperator a=multiplicativeExpression - { - result = new OCLEntity( - tb.func( - (Function) op, - result.getTerm(), - a.getTerm())); - } + ( + PLUS a=multiplicativeExpression + { + try { + if (!result.isTerm() | !a.isTerm()) { + raiseError("Wrong expression in additive expression. One of the summands is not a term."); + } + + result = new OCLEntity( + intHelper.buildAddExpression(result.getTerm(),a.getTerm())); + } catch (SLTranslationException e) { + raiseError(e); + } + } + + | + + MINUS a=multiplicativeExpression + { + try { + if (!result.isTerm() | !a.isTerm()) { + raiseError("Wrong expression in subtractive expression. One of the summands is not a term."); + } + + result = new OCLEntity( + intHelper.buildSubExpression(result.getTerm(),a.getTerm())); + } catch (SLTranslationException e) { + raiseError(e); + } + } )* ; -multiplicativeExpression returns [OCLEntity result=null] +multiplicativeExpression returns [OCLEntity result=null] throws SLTranslationException { OCLEntity a=null; Operator op=null; @@ -628,19 +605,31 @@ multiplicativeExpression returns [OCLEntity result=null] : result=unaryExpression ( - op=multiplyOperator a=unaryExpression - { - result = new OCLEntity( - tb.func( - (Function) op, - result.getTerm(), - a.getTerm())); - } + MULT a=unaryExpression + { + try { + if (!result.isTerm() | !a.isTerm()) { + raiseError("Wrong expression in multiplicative expression. One of the factors is not a term."); + } + + result = new OCLEntity( + intHelper.buildMulExpression(result.getTerm(),a.getTerm())); + } catch (SLTranslationException e) { + raiseError(e); + } + } + + | + + DIVIDE a=unaryExpression + { + raiseError("division '/' not supported (no reals supported)."); + } )* ; -unaryExpression returns [OCLEntity result=null] +unaryExpression returns [OCLEntity result=null] throws SLTranslationException : (NOT postfixExpression) => NOT result=postfixExpression { @@ -659,7 +648,7 @@ unaryExpression returns [OCLEntity result=null] ; -postfixExpression returns [OCLEntity result=null] +postfixExpression returns [OCLEntity result=null] throws SLTranslationException { OCLEntity entity=null; } @@ -678,7 +667,7 @@ postfixExpression returns [OCLEntity result=null] ; -primaryExpression returns [OCLEntity result=null] +primaryExpression returns [OCLEntity result=null] throws SLTranslationException { Term t; OCLCollection c; @@ -699,7 +688,7 @@ primaryExpression returns [OCLEntity result=null] ; -ifExpression returns [Term result=null] +ifExpression returns [Term result=null] throws SLTranslationException { OCLEntity condition; OCLEntity branchA; @@ -727,7 +716,7 @@ ifExpression returns [Term result=null] ; -literal returns [Term result=null] +literal returns [Term result=null] throws SLTranslationException : STRING {raiseError("String literals are currently not supported.");} | n:NUMBER { result=tb.zTerm(services, n.getText()); } // | enumLiteral //this looks just like a property call with a long name -> not good @@ -744,7 +733,7 @@ enumLiteral ; -literalCollection returns [OCLCollection resCollection=new OCLCollection()] +literalCollection returns [OCLCollection resCollection=new OCLCollection()] throws SLTranslationException { OCLCollection c1; int colType; @@ -765,7 +754,7 @@ literalCollection returns [OCLCollection resCollection=new OCLCollection()] ; -collectionItem[int colType] returns [OCLCollection result=null] +collectionItem[int colType] returns [OCLCollection result=null] throws SLTranslationException { OCLEntity t=null; OCLEntity a=null; @@ -788,7 +777,7 @@ collectionItem[int colType] returns [OCLCollection result=null] ; -propertyCall[OCLEntity receiver] returns [OCLEntity result = null] +propertyCall[OCLEntity receiver] returns [OCLEntity result = null] throws SLTranslationException { String propertyName = null; boolean atPre = false; @@ -805,9 +794,13 @@ propertyCall[OCLEntity receiver] returns [OCLEntity result = null] } (parameters=propertyCallParameters[receiver, needVarDeclaration])? { - result = propertyManager.resolve(receiver, - propertyName, - parameters); + try { + result = (OCLEntity) propertyManager.resolve(receiver, + propertyName, + parameters); + } catch (SLTranslationException e) { + raiseError(e); + } if(result == null) { raiseError("The property call \"" + propertyName @@ -839,8 +832,8 @@ propertyCall[OCLEntity receiver] returns [OCLEntity result = null] ; -propertyCallParameters[OCLEntity receiver, boolean needVarDeclaration] - returns [OCLParameters result = null] +propertyCallParameters[OCLEntity receiver, boolean needVarDeclaration] + returns [OCLParameters result = null] throws SLTranslationException { ListOfLogicVariable resultVars = SLListOfLogicVariable.EMPTY_LIST; ListOfOCLEntity resultEntities = SLListOfOCLEntity.EMPTY_LIST; @@ -867,7 +860,7 @@ propertyCallParameters[OCLEntity receiver, boolean needVarDeclaration] { if(needVarDeclaration) { LogicVariable collectionVar - = receiver.getCollection().getPredVar(); + = ((OCLCollection) receiver.getCollection()).getPredVar(); propertyManager.putIntoTopLocalVariablesNamespace(collectionVar); resultVars = resultVars.append(collectionVar); } @@ -883,7 +876,7 @@ propertyCallParameters[OCLEntity receiver, boolean needVarDeclaration] ; -declarator[Sort expectedSort] returns [ListOfLogicVariable result = null] +declarator[Sort expectedSort] returns [ListOfLogicVariable result = null] throws SLTranslationException { ListOfString varNames=SLListOfString.EMPTY_LIST; KeYJavaType kjt=null; @@ -912,7 +905,7 @@ declarator[Sort expectedSort] returns [ListOfLogicVariable result = null] -typeSpecifier +typeSpecifier throws SLTranslationException { KeYJavaType kjt; } @@ -921,7 +914,7 @@ typeSpecifier ; -simpleTypeSpecifier returns [KeYJavaType result=null] +simpleTypeSpecifier returns [KeYJavaType result=null] throws SLTranslationException { String s; } @@ -929,7 +922,7 @@ simpleTypeSpecifier returns [KeYJavaType result=null] ; -collectionType +collectionType throws SLTranslationException { KeYJavaType kjt; int colType; @@ -938,7 +931,7 @@ collectionType ; -actualParameterList returns [ListOfOCLEntity result=SLListOfOCLEntity.EMPTY_LIST] +actualParameterList returns [ListOfOCLEntity result=SLListOfOCLEntity.EMPTY_LIST] throws SLTranslationException { OCLEntity t=null; } @@ -948,12 +941,12 @@ actualParameterList returns [ListOfOCLEntity result=SLListOfOCLEntity.EMPTY_LIST ; -qualifiers returns [ListOfOCLEntity result=null] +qualifiers returns [ListOfOCLEntity result=null] throws SLTranslationException : LBRACK result=actualParameterList RBRACK ; -pathName returns [String result=""] +pathName returns [String result=""] throws SLTranslationException : (n1:NAME DCOLON {result += n1.getText() + "."; })* n:NAME { @@ -975,13 +968,13 @@ timeExpression -logicalOperator returns [Junctor result=null] +logicalOperator returns [Junctor result=null] throws SLTranslationException : AND { result=Op.AND; } | OR { result=Op.OR; } ; -collectionKind returns [int colType=-1] +collectionKind returns [int colType=-1] throws SLTranslationException : SET { colType=OCLCollection.OCL_SET; } | BAG { colType=OCLCollection.OCL_BAG; } | SEQUENCE { colType=OCLCollection.OCL_SEQUENCE; } @@ -989,22 +982,22 @@ collectionKind returns [int colType=-1] ; -relationalOperator returns [Function result=null] - : GT { result = (Function) funcNS.lookup(new Name("gt")); } - | LT { result = (Function) funcNS.lookup(new Name("lt")); } - | GE { result = (Function) funcNS.lookup(new Name("geq")); } - | LE { result = (Function) funcNS.lookup(new Name("leq")); } +relationalOperator returns [Function result=null] throws SLTranslationException + : GT { result = services.getTypeConverter().getIntegerLDT().getGreaterThan(); } + | LT { result = services.getTypeConverter().getIntegerLDT().getLessThan(); } + | GE { result = services.getTypeConverter().getIntegerLDT().getGreaterOrEquals(); } + | LE { result = services.getTypeConverter().getIntegerLDT().getLessOrEquals(); } ; - -addOperator returns [Operator result=null] - : PLUS { result = (Function) funcNS.lookup(new Name("add")); } - | MINUS { result = (Function) funcNS.lookup(new Name("sub")); } +/* +addOperator returns [Operator result=null] throws SLTranslationException + : PLUS { result = services.getTypeConverter().getIntegerLDT().getAdd(); } + | MINUS { result = services.getTypeConverter().getIntegerLDT().getSub(); } ; -multiplyOperator returns [Operator result=null] - : MULT { result = (Function) funcNS.lookup(new Name("mul")); } +multiplyOperator returns [Operator result=null] throws SLTranslationException + : MULT { result = services.getTypeConverter().getIntegerLDT().getMul(); } | DIVIDE { raiseError("reals are not supported ('/' is defined on real)"); } ; - +*/ diff --git a/system/de/uka/ilkd/key/parser/ocl/AxiomCollector.java b/system/de/uka/ilkd/key/speclang/translation/AxiomCollector.java similarity index 82% rename from system/de/uka/ilkd/key/parser/ocl/AxiomCollector.java rename to system/de/uka/ilkd/key/speclang/translation/AxiomCollector.java index 20bb6d57d0e..1519a505feb 100644 --- a/system/de/uka/ilkd/key/parser/ocl/AxiomCollector.java +++ b/system/de/uka/ilkd/key/speclang/translation/AxiomCollector.java @@ -1,6 +1,6 @@ -package de.uka.ilkd.key.parser.ocl; +package de.uka.ilkd.key.speclang.translation; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import de.uka.ilkd.key.logic.Named; @@ -15,7 +15,7 @@ public class AxiomCollector { private static final TermBuilder tb = TermBuilder.DF; - private Map /*Named -> Term */ axioms = new HashMap(); + private Map /*Named -> Term */ axioms = new LinkedHashMap(); public void collectAxiom(Named n, Term a) { diff --git a/system/de/uka/ilkd/key/speclang/translation/JavaIntegerSemanticsHelper.java b/system/de/uka/ilkd/key/speclang/translation/JavaIntegerSemanticsHelper.java new file mode 100644 index 00000000000..8137f489474 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/JavaIntegerSemanticsHelper.java @@ -0,0 +1,353 @@ +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.TypeConverter; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.abstraction.PrimitiveType; +import de.uka.ilkd.key.java.expression.literal.BooleanLiteral; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.TermCreationException; +import de.uka.ilkd.key.logic.ldt.AbstractIntegerLDT; +import de.uka.ilkd.key.logic.sort.AbstractSort; +import de.uka.ilkd.key.logic.sort.Sort; + +public class JavaIntegerSemanticsHelper { + + private static final TermBuilder tb = TermBuilder.DF; + + private final TypeConverter tc; + private final Term trueLitTerm; + private final Sort boolSort; + + + public JavaIntegerSemanticsHelper(Services services) { + assert services != null; + + this.tc = services.getTypeConverter(); + trueLitTerm = services.getTypeConverter().convertToLogicElement( + BooleanLiteral.TRUE); + boolSort = services.getJavaInfo().getKeYJavaType( + PrimitiveType.JAVA_BOOLEAN).getSort(); + } + + + private void raiseError(String message) throws SLTranslationException { + throw new SLTranslationException(message); + } + + + /* + * If a is a boolean literal, the method returns the + * literal as a formula + */ + private Term convertToFormula(Term a) { + + if (a.sort() == boolSort) { + return tb.equals(a, trueLitTerm); + } + + return a; + } + + + public Term castToJint(Term intTerm) { + return tb.tf().createCastTerm( + (AbstractSort) tc.getIntLDT().targetSort(), intTerm); + } + + + public Term buildOrExpression(Term a, Term b) throws SLTranslationException { + + try { + return tb.or(convertToFormula(b), convertToFormula(a)); + } catch (TermCreationException e) { + raiseError("Error in or-expression\n" + a.toString() + " || " + + b.toString() + "."); + } + + return null; + } + + + public Term buildAndExpression(Term a, Term b) + throws SLTranslationException { + + try { + return tb.and(convertToFormula(b), convertToFormula(a)); + } catch (TermCreationException e) { + raiseError("Error in and-expression\n" + a.toString() + " && " + + b.toString() + "."); + } + + return null; + } + + + public Term buildPromotedOrExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + if (a.sort() == Sort.FORMULA) { + return buildOrExpression(a, b); + } + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in or expression " + a.toString() + " | " + + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getBitwiseOr(), a, b)); + } + + + public Term buildPromotedAndExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + if (a.sort() == Sort.FORMULA) { + return buildAndExpression(a, b); + } + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in and expression " + a.toString() + " & " + + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getBitwiseAnd(), a, b)); + } + + + public Term buildPromotedXorExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in xor expression " + a.toString() + " ^ " + + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getBitwiseXor(), a, b)); + } + + + public Term buildPromotedNegExpression(Term a) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a)); + } catch (RuntimeException e) { + raiseError("Error in neg expression " + a.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getBitwiseNegation(), a)); + } + + + public Term buildAddExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in additive expression " + a.toString() + " + " + + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getAdd(), a, b)); + } + + + public Term buildSubExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in additive expression " + a.toString() + " - " + + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getSub(), a, b)); + } + + + public Term buildMulExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in additive expression " + a.toString() + " * " + + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getMul(), a, b)); + } + + + public Term buildDivExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in additive expression " + a.toString() + " / " + + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getDiv(), a, b)); + } + + + public Term buildModExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in modulo expression " + a.toString() + " % " + + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getMod(), a, b)); + } + + + public Term buildRightShiftExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in shift-right expression " + a.toString() + + " >> " + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getShiftRight(), a, b)); + } + + + public Term buildLeftShiftExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in shift-left expression " + a.toString() + + " << " + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getShiftLeft(), a, b)); + } + + + public Term buildUnsignedRightShiftExpression(Term a, Term b) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a), tc + .getKeYJavaType(b)); + } catch (RuntimeException e) { + raiseError("Error in unsigned shift-right expression " + + a.toString() + " >>> " + b.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getUnsignedShiftRight(), a, + b)); + } + + + public Term buildUnaryMinusExpression(Term a) throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a)); + } catch (RuntimeException e) { + raiseError("Error in unary minus expression -" + a.toString() + "."); + } + + assert resultType != null; + + return castToJint(tb.func(((AbstractIntegerLDT) tc + .getModelFor(resultType.getSort())).getNeg(), a)); + } + + + public Term buildPromotedUnaryPlusExpression(Term a) + throws SLTranslationException { + KeYJavaType resultType = null; + + try { + resultType = tc.getPromotedType(tc.getKeYJavaType(a)); + } catch (RuntimeException e) { + raiseError("Error in unary plus expression +" + a.toString() + "."); + } + + assert resultType != null; + + return tb.tf().createCastTerm((AbstractSort) resultType.getSort(), a); + } + +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLAttributeResolver.java b/system/de/uka/ilkd/key/speclang/translation/SLAttributeResolver.java new file mode 100644 index 00000000000..5ef65bc6538 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLAttributeResolver.java @@ -0,0 +1,78 @@ +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.TermCreationException; +import de.uka.ilkd.key.logic.op.Function; +import de.uka.ilkd.key.logic.op.NonRigidHeapDependentFunction; +import de.uka.ilkd.key.logic.op.ProgramVariable; + +class SLAttributeResolver extends SLExpressionResolver { + + private static TermBuilder tb = TermBuilder.DF; + + + public SLAttributeResolver(JavaInfo javaInfo, SLResolverManager manager) { + super(javaInfo, manager); + } + + protected SLExpression doResolving(SLExpression receiver, String name, + SLParameters parameters) throws SLTranslationException { + + if (parameters != null) { + return null; + } + + ProgramVariable attribute; + try { + //try as fully qualified name + attribute = javaInfo.getAttribute(name); + } catch(IllegalArgumentException e){ + //try as short name + KeYJavaType containingType = receiver.getKeYJavaType(javaInfo); + attribute = javaInfo.lookupVisibleAttribute(name, containingType); + } + + if(attribute != null) { + if(receiver.getTerm() == null && !attribute.isStatic()) { + throw new SLTranslationException("Reference to non-static field without receiver: " + attribute.name()); + } + try { + Term attributeTerm = tb.dot(receiver.getTerm(), attribute); + return manager.createSLExpression(attributeTerm); + } catch (TermCreationException e) { + throw new SLTranslationException("Wrong attribute reference " + name + "."); + } + } + + //try non-rigid heap-dependent function symbol instead of attribute + Function f = (Function) javaInfo.getServices() + .getNamespaces() + .functions().lookup(new Name(name)); + if(f instanceof NonRigidHeapDependentFunction) { + if(receiver.isTerm() + && f.possibleSubs(new Term[]{receiver.getTerm()})) { + Term functionTerm = tb.func(f, receiver.getTerm()); + return manager.createSLExpression(functionTerm); + } else if(receiver.isType() && f.arity() == 0) { + Term functionTerm = tb.func(f); + return manager.createSLExpression(functionTerm); + } + } + + return null; + + } + + public boolean canHandleReceiver(SLExpression receiver) { + return receiver != null && (receiver.isTerm() || receiver.isType()); + } + + public boolean needVarDeclaration(String name) { + return false; + } + +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLCollection.java b/system/de/uka/ilkd/key/speclang/translation/SLCollection.java new file mode 100644 index 00000000000..73bc8575a9a --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLCollection.java @@ -0,0 +1,30 @@ +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.util.Debug; + +public abstract class SLCollection { + + private final SLCollectionType type; + + // HACK for OCLCollection to work! + public SLCollection() { + this.type = null; + } + + public SLCollection(SLCollectionType t) { + Debug.assertTrue(t != null); + this.type = t; + } + + public SLCollectionType getType() { + return type; + } + + public boolean isType(SLCollectionType t) { + return type.equals(t); + } + + public abstract Sort getElementSort(); + +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLCollectionType.java b/system/de/uka/ilkd/key/speclang/translation/SLCollectionType.java new file mode 100644 index 00000000000..e7f5499181a --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLCollectionType.java @@ -0,0 +1,35 @@ +package de.uka.ilkd.key.speclang.translation; + +/** + * This class represents a specific type of a collection (such as the ocl's set, + * bag or sequence) + * + */ +public class SLCollectionType { + + public static final SLCollectionType SET = new SLCollectionType("Set"); + public static final SLCollectionType BAG = new SLCollectionType("Bag"); + public static final SLCollectionType SEQUENCE = new SLCollectionType("Sequence"); + + + private final String name; + + public SLCollectionType(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public boolean equals(Object t) { + if (t instanceof SLCollectionType) { + return this.name.equals(((SLCollectionType) t).getName()); + } + return false; + } + + public int hashCode() { + return 37*19 + this.name.hashCode(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLExpression.java b/system/de/uka/ilkd/key/speclang/translation/SLExpression.java new file mode 100644 index 00000000000..ac1534f8ece --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLExpression.java @@ -0,0 +1,123 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// + +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.sort.Sort; +import de.uka.ilkd.key.util.Debug; + +/** + * This class represents an expression of an arbitrary specification language. + * We assume that every expression is either a Term, Type or a Collection. + */ +public abstract class SLExpression { + + private final Term term; + private final KeYJavaType type; + private final SLCollection collection; + + + public SLExpression(Term term) { + Debug.assertTrue(term != null); + this.term = term; + this.type = null; + this.collection = null; + } + + + public SLExpression(KeYJavaType type) { + Debug.assertTrue(type != null); + this.term = null; + this.type = type; + this.collection = null; + } + + + public SLExpression(SLCollection c) { + Debug.assertTrue(c != null); + this.term = null; + this.type = null; + this.collection = c; + } + + + public boolean isTerm() { + return this.term != null; + } + + + public boolean isType() { + return this.type != null; + } + + + public boolean isCollection() { + return this.collection != null; + } + + + public Term getTerm() { + return this.term; + } + + + public KeYJavaType getType() { + return this.type; + } + + + public SLCollection getCollection() { + return this.collection; + } + + + public KeYJavaType getKeYJavaType(JavaInfo javaInfo) { + if (this.isTerm()) { + if (this.getTerm().sort() != Sort.FORMULA) { + return javaInfo.getServices().getTypeConverter() + .getKeYJavaType(this.getTerm()); + } else { + return javaInfo.getServices().getTypeConverter() + .getBooleanType(); + } + } else if (this.isType()) { + return this.getType(); + } else { + // receiver is a collection + return javaInfo.getKeYJavaType(this.getCollection() + .getElementSort()); + } + } + + + public String toString() { + if (isTerm()) { + return term.toString(); + } else if (isType()) { + return type.toString(); + } else { + return collection.toString(); + } + } + + + public Sort getSort() { + if (this.isTerm()) { + return this.getTerm().sort(); + } else if (this.isType()) { + return this.getType().getSort(); + } else { + // receiver is a collection + return this.getCollection().getElementSort(); + } + } +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLExpressionResolver.java b/system/de/uka/ilkd/key/speclang/translation/SLExpressionResolver.java new file mode 100644 index 00000000000..86e1408b8af --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLExpressionResolver.java @@ -0,0 +1,45 @@ +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.java.JavaInfo; + +public abstract class SLExpressionResolver { + + protected final JavaInfo javaInfo; + protected final SLResolverManager manager; + + public SLExpressionResolver(JavaInfo javaInfo, SLResolverManager manager) { + assert javaInfo != null; + assert manager != null; + + this.javaInfo = javaInfo; + this.manager = manager; + } + + /** + * Resolves property calls on explicit receivers. + * @param receiver receiver (may *not* be null) + * @param name name of the property + * @param parameters the actual parameters, or null if not applicable + * @return a suitable term or collection if successful, null otherwise + * @throws SLTranslationException + */ + protected abstract SLExpression doResolving(SLExpression receiver, + String name, + SLParameters parameters) throws SLTranslationException; + + + public SLExpression resolve(SLExpression receiver, + String name, + SLParameters parameters) throws SLTranslationException { + if (!canHandleReceiver(receiver)) { + return null; + } + + return doResolving(receiver, name, parameters); + + } + + + protected abstract boolean canHandleReceiver(SLExpression receiver); + public abstract boolean needVarDeclaration(String name); +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLMethodResolver.java b/system/de/uka/ilkd/key/speclang/translation/SLMethodResolver.java new file mode 100644 index 00000000000..3b3c92e5880 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLMethodResolver.java @@ -0,0 +1,76 @@ +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.op.ProgramMethod; + +class SLMethodResolver extends SLExpressionResolver { + + private TermBuilder tb = TermBuilder.DF; + + public SLMethodResolver(JavaInfo javaInfo, SLResolverManager manager) { + super(javaInfo, manager); + } + + protected SLExpression doResolving(SLExpression receiver, String methodName, + SLParameters parameters) throws SLTranslationException { + + if(parameters == null || !parameters.isListOfTerm()) { + return null; + } + + KeYJavaType containingType = receiver.getKeYJavaType(javaInfo); + if(containingType == null) { + return null; + } + + ListOfKeYJavaType signature = parameters.getSignature(javaInfo.getServices()); + + ProgramMethod pm = javaInfo.getProgramMethod( + containingType, + methodName, + signature, + containingType); + + if (pm == null) + { + return null; + } + + int i; + Term subs[]; + + if (!pm.isStatic()) { + if (!receiver.isTerm()) { + throw new SLTranslationException("non-static method invocation on Type " + receiver.getType()); + } + subs = new Term[parameters.getParameters().size()+1]; + subs[0] = receiver.getTerm(); + i = 1; + } else { + subs = new Term[parameters.getParameters().size()]; + i = 0; + } + + IteratorOfSLExpression it = parameters.getParameters().iterator(); + while(it.hasNext()) { + //Remember: parameters.isLisOfTerm() is true! + subs[i++] = it.next().getTerm(); + } + + return manager.createSLExpression(tb.func(pm,subs)); + } + + + public boolean canHandleReceiver(SLExpression receiver) { + return receiver != null && (receiver.isTerm() || receiver.isType()) && !receiver.getKeYJavaType(javaInfo).getFullName().endsWith("[]") ; + } + + public boolean needVarDeclaration(String name) { + return false; + } + +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLParameters.java b/system/de/uka/ilkd/key/speclang/translation/SLParameters.java new file mode 100644 index 00000000000..841c1923018 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLParameters.java @@ -0,0 +1,46 @@ +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.java.abstraction.ListOfKeYJavaType; +import de.uka.ilkd.key.java.abstraction.SLListOfKeYJavaType; + +public class SLParameters { + + + private final ListOfSLExpression parameters; + + public SLParameters(ListOfSLExpression parameters) { + this.parameters = parameters; + } + + public ListOfSLExpression getParameters() { + return parameters; + } + + + public boolean isListOfTerm() { + + IteratorOfSLExpression it = parameters.iterator(); + + while(it.hasNext()) { + if (!it.next().isTerm()) + return false; + } + + return true; + } + + public ListOfKeYJavaType getSignature(Services services) { + + ListOfKeYJavaType result = SLListOfKeYJavaType.EMPTY_LIST; + IteratorOfSLExpression it = parameters.iterator(); + + while(it.hasNext()) { + result = result.append( it.next().getKeYJavaType(services.getJavaInfo()) ); + } + + return result; + } + + +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLResolverManager.java b/system/de/uka/ilkd/key/speclang/translation/SLResolverManager.java new file mode 100644 index 00000000000..be57d165f08 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLResolverManager.java @@ -0,0 +1,243 @@ +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; +import de.uka.ilkd.key.logic.IteratorOfNamed; +import de.uka.ilkd.key.logic.IteratorOfNamespace; +import de.uka.ilkd.key.logic.ListOfNamed; +import de.uka.ilkd.key.logic.ListOfNamespace; +import de.uka.ilkd.key.logic.Name; +import de.uka.ilkd.key.logic.Namespace; +import de.uka.ilkd.key.logic.SLListOfNamespace; +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.TermBuilder; +import de.uka.ilkd.key.logic.op.IteratorOfLogicVariable; +import de.uka.ilkd.key.logic.op.ListOfLogicVariable; +import de.uka.ilkd.key.logic.op.ParsableVariable; +import de.uka.ilkd.key.logic.sort.ObjectSort; +import de.uka.ilkd.key.util.Debug; + +public abstract class SLResolverManager { + + + private static final TermBuilder tb = TermBuilder.DF; + + protected final JavaInfo javaInfo; + + protected ListOfNamespace /*ParsableVariable*/ + localVariablesNamespaces = SLListOfNamespace.EMPTY_LIST; + + protected ListOfSLExpressionResolver + resolvers = SLListOfSLExpressionResolver.EMPTY_LIST; + + protected final KeYJavaType specInClass; + + protected SLResolverManager(JavaInfo javaInfo, + KeYJavaType specInClass, + boolean typeResolver, + boolean methodResolver, + boolean attributeResolver) { + + Debug.assertTrue(javaInfo != null); + this.javaInfo = javaInfo; + this.specInClass = specInClass; + + if (typeResolver) { + resolvers = resolvers.prepend(new SLTypeResolver(javaInfo, this)); + } + + if (methodResolver) { + resolvers = resolvers.prepend(new SLMethodResolver(javaInfo, this)); + } + + if (attributeResolver) { + resolvers = resolvers.prepend(new SLAttributeResolver(javaInfo, this)); + } + } + + + /** + * Tries to resolve a name as a local variable. + */ + private SLExpression resolveLocal(String name) { + Name n = new Name(name); + IteratorOfNamespace it = localVariablesNamespaces.iterator(); + while(it.hasNext()) { + ParsableVariable localVar = (ParsableVariable) it.next().lookup(n); + if(localVar != null) { + Term varTerm = tb.var(localVar); + return createSLExpression(varTerm); + } + } + + return null; + } + + + /** + * Tries to resolve a name as a property call on any available implicit + * receiver. + * @throws SLTranslationException + */ + private SLExpression resolveImplicit(String name, SLParameters parameters) throws SLTranslationException { + IteratorOfNamespace it = localVariablesNamespaces.iterator(); + while(it.hasNext()) { + Namespace ns = it.next(); + ListOfNamed elements = ns.elements(); + + IteratorOfNamed it2 = elements.iterator(); + while(it2.hasNext()) { + ParsableVariable localVar = (ParsableVariable) it2.next(); + if(localVar.sort() instanceof ObjectSort) { + Term recTerm = tb.var(localVar); + SLExpression result + = resolveExplicit(createSLExpression(recTerm), + name, + parameters); + if(result != null) { + return result; + } + } + } + } + + // the class where the specification is written can be an implicit type receiver + // (e.g. for static attributes or static methods) + SLExpression result = resolveExplicit(createSLExpression(specInClass), + name, + parameters); + if(result != null) { + return result; + } + + return null; + } + + private SLExpression resolveIt(SLExpression receiver, + String name, + SLParameters parameters) throws SLTranslationException { + SLExpression result = null; + + if(receiver != null) { + result = resolveExplicit(receiver, name, parameters); + } else { + result = resolveLocal(name); + if (result == null) { + result = resolveImplicit(name, parameters); + } + if (result == null) { + result = resolveExplicit(null, name, parameters); + } + } + + return result; + } + + + private SLExpression resolveExplicit(SLExpression receiver, String name, SLParameters params) throws SLTranslationException { + + IteratorOfSLExpressionResolver it = resolvers.iterator(); + + while(it.hasNext()) { + SLExpression result = it.next().resolve(receiver, name, params); + if (result != null) { + return result; + } + } + + return null; + } + + /** + * Resolves arbitrary property calls. + * @param receiver the specified explicit receiver, or null + * @param name name of the property + * @param parameters actual parameters of the property call, or null + * @return corresponding term, type or collection if successful, null + * otherwise + * @throws SLTranslationException + */ + public SLExpression resolve(SLExpression receiver, + String name, + SLParameters parameters) throws SLTranslationException { + + String shortName = name; + + if (isFullyQualified(name)) { + SLExpression result = resolveIt(receiver, name, parameters); + if (result != null) { + return result; + } + shortName = getShortName(name); + } + + return resolveIt(receiver, shortName, parameters); + } + + + private String getShortName(String name) { + return name.substring(name.lastIndexOf(".") + 1); + } + + + private boolean isFullyQualified(String name) { + return name.indexOf(".") > -1; + } + + + /** + * Pushes a new, empty namespace onto the stack. + */ + public void pushLocalVariablesNamespace() { + Namespace ns = new Namespace(); + localVariablesNamespaces = localVariablesNamespaces.prepend(ns); + } + + + /** + * Puts a local variable into the topmost namespace on the stack + */ + public void putIntoTopLocalVariablesNamespace(ParsableVariable pv) { + localVariablesNamespaces.head().addSafely(pv); + } + + + /** + * Puts a list of local variables into the topmost namespace on the stack. + */ + public void putIntoTopLocalVariablesNamespace(ListOfLogicVariable pvs) { + IteratorOfLogicVariable it = pvs.iterator(); + while(it.hasNext()) { + localVariablesNamespaces.head().addSafely(it.next()); + } + } + + + /** + * Determines whether a variable has to be put into localVariableNamespace + * @param name2BeResolved name of the element to be resolved + * @return true, if name2BeResolved needs a variable to be put into + * localVariableNamespace + */ + public boolean needVarDeclaration(String name2BeResolved) { + IteratorOfSLExpressionResolver it = resolvers.iterator(); + while(it.hasNext()) { + if (it.next().needVarDeclaration(name2BeResolved)) { + return true; + } + } + return false; + } + + + /** + * Throws away the topmost namespace on the stack. + */ + public void popLocalVariablesNamespace() { + localVariablesNamespaces = localVariablesNamespaces.tail(); + } + + public abstract SLExpression createSLExpression(Term t); + public abstract SLExpression createSLExpression(KeYJavaType t); + public abstract SLExpression createSLExpression(SLCollection t); +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLTranslationException.java b/system/de/uka/ilkd/key/speclang/translation/SLTranslationException.java new file mode 100644 index 00000000000..5475662d769 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLTranslationException.java @@ -0,0 +1,74 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.java.Position; +import de.uka.ilkd.key.proof.init.ProofInputException; + + +public class SLTranslationException extends ProofInputException { + + private final String fileName; + private final Position pos; + + + public SLTranslationException(String message, + String fileName, + Position pos) { + super(message); + assert fileName != null; + assert pos != null; + this.fileName = fileName; + this.pos = pos; + } + + + public SLTranslationException(String message, + String fileName, + Position pos, + StackTraceElement[] stackTrace) { + this(message, fileName, pos); + setStackTrace(stackTrace); + } + + + public SLTranslationException(String message, + String fileName, + int line, + int column) { + this(message, fileName, new Position(line, column)); + } + + + public SLTranslationException(String message) { + this(message, "no file", Position.UNDEFINED); + } + + + public String getFileName() { + return fileName; + } + + + public Position getPosition() { + return pos; + } + + + public int getLine() { + return pos.getLine(); + } + + + public int getColumn() { + return pos.getColumn(); + } +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLTranslationExceptionManager.java b/system/de/uka/ilkd/key/speclang/translation/SLTranslationExceptionManager.java new file mode 100644 index 00000000000..b2875667a65 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLTranslationExceptionManager.java @@ -0,0 +1,124 @@ +// This file is part of KeY - Integrated Deductive Software Design +// Copyright (C) 2001-2005 Universitaet Karlsruhe, Germany +// Universitaet Koblenz-Landau, Germany +// Chalmers University of Technology, Sweden +// +// The KeY system is protected by the GNU General Public License. +// See LICENSE.TXT for details. +// +// + +package de.uka.ilkd.key.speclang.translation; + +import antlr.ANTLRException; +import antlr.LLkParser; +import antlr.RecognitionException; +import antlr.Token; +import de.uka.ilkd.key.java.Position; +import de.uka.ilkd.key.speclang.PositionedString; + + +/** + * Some common exception / position management functionality used + * by SL translation parsers. + */ +public class SLTranslationExceptionManager { + + private final LLkParser parser; + private final String fileName; + private final Position offsetPos; + + + //------------------------------------------------------------------------- + //constructors + //------------------------------------------------------------------------- + + public SLTranslationExceptionManager(LLkParser parser, + String fileName, + Position offsetPos) { + this.parser = parser; + this.fileName = fileName; + this.offsetPos = offsetPos; + } + + + + //------------------------------------------------------------------------- + //internal methods + //------------------------------------------------------------------------- + + private Position createAbsolutePosition(int relativeLine, + int relativeColumn) { + int absoluteLine = offsetPos.getLine() + relativeLine - 1; + int absoluteColumn = (relativeLine == 1 ? offsetPos.getColumn() : 1) + + relativeColumn - 1; + return new Position(absoluteLine, absoluteColumn); + } + + + /** + * Returns the absolute source code position of the previous token. + */ + private Position getPosition() { + int line, column; + try { + line = parser.LT(0).getLine(); + column = parser.LT(0).getColumn(); + } catch(Exception e) { + line = 1; + column = 1; + } + return createAbsolutePosition(line, column); + } + + + + //------------------------------------------------------------------------- + //public interface + //------------------------------------------------------------------------- + + /** + * Creates a string with the position information of the passed token. + */ + public PositionedString createPositionedString(String text, Token t) { + return new PositionedString(text, + fileName, + createAbsolutePosition(t.getLine(), + t.getColumn())); + } + + + /** + * Creates an SLTranslationException with current absolute position + * information. + */ + public SLTranslationException createException(String message) { + return new SLTranslationException(message, + fileName, + getPosition()); + } + + + /** + * Converts an ANTLRException into an SLTranslationException with the + * same message and stack trace, and with current absolute position + * information. + */ + public SLTranslationException convertException(ANTLRException e) { + Position pos; + if(e instanceof RecognitionException) { + RecognitionException re = (RecognitionException) e; + pos = createAbsolutePosition(re.getLine(), re.getColumn()); + } else { + pos = getPosition(); + } + + return new SLTranslationException(e.getMessage() + + " (" + + e.getClass().getName() + + ")", + fileName, + pos, + e.getStackTrace()); + } +} diff --git a/system/de/uka/ilkd/key/speclang/translation/SLTypeResolver.java b/system/de/uka/ilkd/key/speclang/translation/SLTypeResolver.java new file mode 100644 index 00000000000..569df352fb0 --- /dev/null +++ b/system/de/uka/ilkd/key/speclang/translation/SLTypeResolver.java @@ -0,0 +1,32 @@ +package de.uka.ilkd.key.speclang.translation; + +import de.uka.ilkd.key.java.JavaInfo; +import de.uka.ilkd.key.java.abstraction.KeYJavaType; + +class SLTypeResolver extends SLExpressionResolver { + + public SLTypeResolver(JavaInfo javaInfo, SLResolverManager manager) { + super(javaInfo, manager); + } + + protected boolean canHandleReceiver(SLExpression receiver) { + return receiver == null; + } + + protected SLExpression doResolving(SLExpression receiver, String name, + SLParameters parameters) throws SLTranslationException { + + try { + KeYJavaType type = javaInfo.getTypeByClassName(name); + return manager.createSLExpression(type); + } catch (RuntimeException e) { + // Type not found + return null; + } + } + + public boolean needVarDeclaration(String name) { + return false; + } + +} diff --git a/system/de/uka/ilkd/key/strategy/FindTacletAppContainer.java b/system/de/uka/ilkd/key/strategy/FindTacletAppContainer.java index 4de44cce8c6..c3f33bc708f 100644 --- a/system/de/uka/ilkd/key/strategy/FindTacletAppContainer.java +++ b/system/de/uka/ilkd/key/strategy/FindTacletAppContainer.java @@ -72,9 +72,6 @@ protected boolean isStillApplicable ( Goal p_goal ) { return false; if ( subformulaOrPreceedingUpdateHasChanged ( p_goal ) ) return false; - if (!p_goal.proof().mgt().ruleApplicable(getRuleApp(), p_goal)) { - return false; - } return true; } diff --git a/system/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java b/system/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java index fe0dc296d9e..f26c740b6d3 100644 --- a/system/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java +++ b/system/de/uka/ilkd/key/strategy/JavaCardDLStrategy.java @@ -27,7 +27,7 @@ import de.uka.ilkd.key.logic.sort.Sort; import de.uka.ilkd.key.proof.Goal; import de.uka.ilkd.key.proof.Proof; -import de.uka.ilkd.key.proof.UseMethodContractRuleFilter; +import de.uka.ilkd.key.proof.UseOperationContractRuleFilter; import de.uka.ilkd.key.rule.RuleApp; import de.uka.ilkd.key.strategy.feature.*; import de.uka.ilkd.key.strategy.quantifierHeuristics.*; @@ -122,7 +122,7 @@ private Feature setupGlobalF(Feature dispatcher, Proof p_proof) { private Feature methodSpecFeature(Feature cost) { return ConditionalFeature.createConditional( - UseMethodContractRuleFilter.INSTANCE, cost ); + UseOperationContractRuleFilter.INSTANCE, cost ); } @@ -1272,7 +1272,7 @@ private void setupInEqSimp(RuleSetDispatchFeature d, applyTF ( "tautRightBigger", tf.polynomial ), PolynomialValuesCmpFeature .leq ( instOf ( "tautRightSmaller" ), - opTerm ( numbers.getArithAddition (), + opTerm ( numbers.getAdd(), one, instOf ( "tautRightBigger" ) ) ) } ) ); bindRuleSet ( d, "inEqSimp_or_weaken", @@ -1281,7 +1281,7 @@ private void setupInEqSimp(RuleSetDispatchFeature d, applyTF ( "weakenRightSmaller", tf.polynomial ), applyTF ( "weakenRightBigger", tf.polynomial ), PolynomialValuesCmpFeature - .eq ( opTerm ( numbers.getArithAddition (), + .eq ( opTerm ( numbers.getAdd (), one, instOf ( "weakenRightSmaller" ) ), instOf ( "weakenRightBigger" ) ) } ) ); @@ -1291,7 +1291,7 @@ one, instOf ( "weakenRightSmaller" ) ), applyTF ( "antiSymmRightSmaller", tf.polynomial ), applyTF ( "antiSymmRightBigger", tf.polynomial ), PolynomialValuesCmpFeature - .eq ( opTerm ( numbers.getArithAddition (), + .eq ( opTerm ( numbers.getAdd (), two, instOf ( "antiSymmRightSmaller" ) ), instOf ( "antiSymmRightBigger" ) ) } ) ); @@ -1952,10 +1952,10 @@ private class ArithTermFeatures { public ArithTermFeatures (IntegerLDT numbers){ Z = numbers.getNumberSymbol (); - add = numbers.getArithAddition(); - mul = numbers.getArithMultiplication (); - mod = numbers.getArithModulo (); - div = numbers.getArithDivision (); + add = numbers.getAdd(); + mul = numbers.getMul(); + mod = numbers.getMod(); + div = numbers.getDiv (); jmod = numbers.getJModulo (); jdiv = numbers.getJDivision (); diff --git a/system/de/uka/ilkd/key/strategy/NoFindTacletAppContainer.java b/system/de/uka/ilkd/key/strategy/NoFindTacletAppContainer.java index 88e8b36812d..62088bd7fd0 100644 --- a/system/de/uka/ilkd/key/strategy/NoFindTacletAppContainer.java +++ b/system/de/uka/ilkd/key/strategy/NoFindTacletAppContainer.java @@ -32,9 +32,6 @@ public class NoFindTacletAppContainer extends TacletAppContainer { * (if-formulas are not considered) */ protected boolean isStillApplicable(Goal p_goal) { - if (!p_goal.proof().mgt().ruleApplicable(getRuleApp(), p_goal)) { - return false; - } return true; } diff --git a/system/de/uka/ilkd/key/strategy/feature/AbstractMonomialSmallerThanFeature.java b/system/de/uka/ilkd/key/strategy/feature/AbstractMonomialSmallerThanFeature.java index 4a711e50a92..be0bb48bc77 100644 --- a/system/de/uka/ilkd/key/strategy/feature/AbstractMonomialSmallerThanFeature.java +++ b/system/de/uka/ilkd/key/strategy/feature/AbstractMonomialSmallerThanFeature.java @@ -33,8 +33,8 @@ public abstract class AbstractMonomialSmallerThanFeature private Goal currentGoal = null; protected AbstractMonomialSmallerThanFeature(IntegerLDT numbers) { - this.add = numbers.getArithAddition (); - this.mul = numbers.getArithMultiplication (); + this.add = numbers.getAdd(); + this.mul = numbers.getMul(); this.Z = numbers.getNumberSymbol (); } diff --git a/system/de/uka/ilkd/key/strategy/feature/FindRightishFeature.java b/system/de/uka/ilkd/key/strategy/feature/FindRightishFeature.java index ee56ed014d3..725a08c1e40 100644 --- a/system/de/uka/ilkd/key/strategy/feature/FindRightishFeature.java +++ b/system/de/uka/ilkd/key/strategy/feature/FindRightishFeature.java @@ -37,7 +37,7 @@ public static Feature create(IntegerLDT numbers) { } private FindRightishFeature(IntegerLDT numbers) { - add = numbers.getArithAddition (); + add = numbers.getAdd(); } public RuleAppCost compute ( RuleApp app, PosInOccurrence pos, Goal goal ) { diff --git a/system/de/uka/ilkd/key/strategy/feature/MonomialsSmallerThanFeature.java b/system/de/uka/ilkd/key/strategy/feature/MonomialsSmallerThanFeature.java index 66c4e3a9fae..cf43f3b901f 100644 --- a/system/de/uka/ilkd/key/strategy/feature/MonomialsSmallerThanFeature.java +++ b/system/de/uka/ilkd/key/strategy/feature/MonomialsSmallerThanFeature.java @@ -41,8 +41,8 @@ private MonomialsSmallerThanFeature(ProjectionToTerm left, ProjectionToTerm righ super ( numbers ); this.left = left; this.right = right; - this.add = numbers.getArithAddition (); - this.mul = numbers.getArithMultiplication (); + this.add = numbers.getAdd(); + this.mul = numbers.getMul (); this.Z = numbers.getNumberSymbol (); hasCoeff = createHasCoeffTermFeature ( numbers ); @@ -51,7 +51,7 @@ private MonomialsSmallerThanFeature(ProjectionToTerm left, ProjectionToTerm righ static TermFeature createHasCoeffTermFeature(final IntegerLDT numbers) { return BinarySumTermFeature.createSum ( - OperatorTF.create ( numbers.getArithMultiplication() ), + OperatorTF.create ( numbers.getMul() ), SubTermFeature.create ( new TermFeature[] { ConstTermFeature.createConst ( LongRuleAppCost.ZERO_COST ), OperatorTF.create ( numbers.getNumberSymbol()) } ) ); diff --git a/system/de/uka/ilkd/key/strategy/quantifierHeuristics/HandleArith.java b/system/de/uka/ilkd/key/strategy/quantifierHeuristics/HandleArith.java index 226bec9c5b6..aaacb85e8fa 100644 --- a/system/de/uka/ilkd/key/strategy/quantifierHeuristics/HandleArith.java +++ b/system/de/uka/ilkd/key/strategy/quantifierHeuristics/HandleArith.java @@ -96,7 +96,7 @@ public static Term provedByArith(Term problem, Term axiom, Services services) { Term cd = formatArithTerm ( problem, services ); Term ab = formatArithTerm ( axiom, services ); if ( cd.op() == Op.FALSE || ab.op() == Op.FALSE ) return problem; - Function addfun = services.getTypeConverter ().getIntegerLDT ().getArithAddition (); + Function addfun = services.getTypeConverter ().getIntegerLDT ().getAdd(); Term arithTerm = tb.geq ( tb.func ( addfun, cd.sub ( 0 ), ab.sub ( 1 ) ), tb.func ( addfun, ab.sub ( 0 ), cd.sub ( 1 ) ), services ); @@ -133,7 +133,7 @@ private static Term formatArithTerm(Term problem, Services services) { if ( op == geq ) { if ( opNot ) pro = tb.geq ( pro.sub ( 1 ), - tb.func ( ig.getArithAddition (), + tb.func ( ig.getAdd(), pro.sub ( 0 ), tb.zTerm ( services, "1" ) ), services ); @@ -141,7 +141,7 @@ private static Term formatArithTerm(Term problem, Services services) { if ( op == leq ) { if ( opNot ) pro = tb.geq ( pro.sub ( 0 ), - tb.func ( ig.getArithAddition (), + tb.func ( ig.getAdd (), pro.sub ( 1 ), tb.zTerm ( services, "1" ) ), services ); diff --git a/system/de/uka/ilkd/key/strategy/quantifierHeuristics/LiteralsSmallerThanFeature.java b/system/de/uka/ilkd/key/strategy/quantifierHeuristics/LiteralsSmallerThanFeature.java index 781e1c8a994..cb9080ade1e 100644 --- a/system/de/uka/ilkd/key/strategy/quantifierHeuristics/LiteralsSmallerThanFeature.java +++ b/system/de/uka/ilkd/key/strategy/quantifierHeuristics/LiteralsSmallerThanFeature.java @@ -174,7 +174,7 @@ private MonomialIterator(Term polynomial) { private void findNextMonomial() { while ( nextMonomial == null && polynomial != null ) { - if ( polynomial.op () == numbers.getArithAddition () ) { + if ( polynomial.op () == numbers.getAdd() ) { nextMonomial = polynomial.sub ( 1 ); polynomial = polynomial.sub ( 0 ); } else { diff --git a/system/de/uka/ilkd/key/strategy/termProjection/AbstractDividePolynomialsProjection.java b/system/de/uka/ilkd/key/strategy/termProjection/AbstractDividePolynomialsProjection.java index 6955117aa3c..38a4fa28668 100644 --- a/system/de/uka/ilkd/key/strategy/termProjection/AbstractDividePolynomialsProjection.java +++ b/system/de/uka/ilkd/key/strategy/termProjection/AbstractDividePolynomialsProjection.java @@ -39,7 +39,7 @@ protected abstract Term divide(Monomial numerator, BigInteger denominator, private Term quotient(BigInteger monoCoeff, Term rightPoly, Services services) { final TermSymbol add = - services.getTypeConverter ().getIntegerLDT ().getArithAddition (); + services.getTypeConverter ().getIntegerLDT ().getAdd (); if ( rightPoly.op () == add ) { final Term left = quotient ( monoCoeff, rightPoly.sub ( 0 ), services ); diff --git a/system/de/uka/ilkd/key/unittest/EquivalenceClass.java b/system/de/uka/ilkd/key/unittest/EquivalenceClass.java index d894560ee25..19aadfe59d4 100644 --- a/system/de/uka/ilkd/key/unittest/EquivalenceClass.java +++ b/system/de/uka/ilkd/key/unittest/EquivalenceClass.java @@ -403,10 +403,8 @@ public Integer getConcreteIntValue(HashMap term2class){ while(it.hasNext()){ Term t = it.next(); Operator op = t.op(); - // Do you really want the addition operators below or should it be - // getJavaAddInt, getJavaAddLong? (RB) - if(op == serv.getTypeConverter().getIntegerLDT().getArithAddition() || - op == serv.getTypeConverter().getIntLDT().getArithJavaIntAddition()){ + if(op == serv.getTypeConverter().getIntLDT().getAdd() || + op == serv.getTypeConverter().getLongLDT().getAdd()){ Integer res = null; for(int i=0; i<2; i++){ EquivalenceClass ec = diff --git a/system/de/uka/ilkd/key/unittest/TestGenerator.java b/system/de/uka/ilkd/key/unittest/TestGenerator.java index f004f2d3289..18aff3e5dd7 100644 --- a/system/de/uka/ilkd/key/unittest/TestGenerator.java +++ b/system/de/uka/ilkd/key/unittest/TestGenerator.java @@ -289,7 +289,7 @@ pvsNotDecl[i], new New( IndexReplaceVisitor irv = new IndexReplaceVisitor(testLocation[i][k], testLocation, singleTuple, partCounter, - testArray); + testArray, serv); irv.start(); irv.result(); testDataAssignments = testDataAssignments.append( @@ -369,7 +369,7 @@ pvsNotDecl[i], new New( Expression cons = (Expression) loc2cons.get(loc); IndexReplaceVisitor irv = new IndexReplaceVisitor(loc, testLocation, - singleTuple, partCounter, testArray); + singleTuple, partCounter, testArray, serv); irv.start(); irv.result(); assignments = @@ -475,7 +475,7 @@ length, new ArrayReference( s = s.append(body); StatementBlock mBody = new StatementBlock(s.toArray()); - FieldReplaceVisitor frv = new FieldReplaceVisitor(mBody); + FieldReplaceVisitor frv = new FieldReplaceVisitor(mBody, serv); frv.start(); l.add(frv.result()); l.add(new Comment("\n Covered execution trace:\n"+ @@ -589,7 +589,7 @@ private MethodDeclaration createSuiteMethod(){ s[1] = new CopyAssignment(suite, cons); s[2] = new Return(suite); StatementBlock mBody = new StatementBlock(s); - FieldReplaceVisitor frv = new FieldReplaceVisitor(mBody); + FieldReplaceVisitor frv = new FieldReplaceVisitor(mBody, serv); frv.start(); l.add(frv.result()); return new MethodDeclaration(l, false); @@ -1021,7 +1021,7 @@ private MethodDeclaration buildMethodDeclaration(Statement[] body, l.addAll(params); l.add(type); StatementBlock mBody = new StatementBlock(body); - FieldReplaceVisitor frv = new FieldReplaceVisitor(mBody); + FieldReplaceVisitor frv = new FieldReplaceVisitor(mBody, serv); frv.start(); l.add(frv.result()); MethodDeclaration md = new MethodDeclaration(l, false); @@ -1125,7 +1125,7 @@ private ExtList getArguments(Term t){ SetOfProgramVariable programVars = SetAsListOfProgramVariable.EMPTY_SET; TermProgramVariableCollector pvColl = - new TermProgramVariableCollector(); + new TermProgramVariableCollector(serv); t.execPreOrder(pvColl); Iterator itp = pvColl.result().iterator(); while(itp.hasNext()){ diff --git a/system/de/uka/ilkd/key/unittest/UseMethodContractRuleForTestGen.java b/system/de/uka/ilkd/key/unittest/UseMethodContractRuleForTestGen.java deleted file mode 100644 index 027dd0d7dd3..00000000000 --- a/system/de/uka/ilkd/key/unittest/UseMethodContractRuleForTestGen.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.uka.ilkd.key.unittest; - -import de.uka.ilkd.key.java.*; -import de.uka.ilkd.key.logic.*; -import de.uka.ilkd.key.proof.mgt.InstantiatedMethodContract; -import de.uka.ilkd.key.rule.UseMethodContractRule; -import de.uka.ilkd.key.rule.metaconstruct.ExpandMethodBody; -import de.uka.ilkd.key.rule.updatesimplifier.Update; - -public class UseMethodContractRuleForTestGen extends UseMethodContractRule { - - /** The only instance of this rule */ - public static UseMethodContractRule INSTANCE = new UseMethodContractRuleForTestGen(); - - private Name name = new Name("Use Method Contract (TestCase Gen. version)"); - - private UseMethodContractRuleForTestGen() { - } - - protected UseMethodContractRule getContractRule() { - return UseMethodContractRuleForTestGen.INSTANCE; - } - - /** - * returns the name of this rule - */ - public Name name() { - return name; - } - - protected Term preFma(InstantiatedMethodContract iCt, - MbsInfo mbsPos, UpdateFactory uf, - Update u, Services services){ - - ExpandMethodBody exMB = new ExpandMethodBody(mbsPos.mbs); - StatementBlock methodReplaceStatements = - new StatementBlock((Statement) exMB.symbolicExecution( - mbsPos.mbs, services, null)); - - final Term focus = mbsPos.pio.subTerm(); - final JavaNonTerminalProgramElement all = - (JavaNonTerminalProgramElement)focus.javaBlock().program(); - final NonTerminalProgramElement npe = - replaceStatement(all, mbsPos, methodReplaceStatements); - Term restFma = TermBuilder.DF.tf().createProgramTerm(iCt.getModality(), - JavaBlock.createJavaBlock((StatementBlock)npe), - focus.sub(0)); - - return uf.apply(u, restFma); -// return postFmaHelp(iCt, mbsPos, uf, u, methodReplaceStatements, extraPre); - } - - protected String getPreLabel() { - return "Expanded Method Body"; - } - -} diff --git a/system/de/uka/ilkd/key/util/Debug.java b/system/de/uka/ilkd/key/util/Debug.java index 1ce17d74496..4c1a0688d5e 100644 --- a/system/de/uka/ilkd/key/util/Debug.java +++ b/system/de/uka/ilkd/key/util/Debug.java @@ -11,6 +11,9 @@ /** this class offers some methods for assertions, debug output and so * on */ package de.uka.ilkd.key.util; + +import de.uka.ilkd.key.visualization.TraceElement; + public final class Debug { private Debug() {} @@ -237,5 +240,18 @@ public static String stackTrace() { t.printStackTrace(new java.io.PrintStream(baos)); return(baos.toString()); } + + public static String getCassAndMethod() { + try { + throw new Exception(); + } catch(Exception e) { + StackTraceElement[] trace = e.getStackTrace(); + if(trace.length > 1) { + int line = trace[1].getLineNumber(); + return trace[1].getClass() + "." + trace[1].getMethodName() + (line > 0 ? " [line " + line +"]" : ""); + } + return ""; + } + } } diff --git a/system/de/uka/ilkd/key/visualdebugger/DebuggerPO.java b/system/de/uka/ilkd/key/visualdebugger/DebuggerPO.java index 2f72b19d49c..9c3211bc1f3 100644 --- a/system/de/uka/ilkd/key/visualdebugger/DebuggerPO.java +++ b/system/de/uka/ilkd/key/visualdebugger/DebuggerPO.java @@ -8,8 +8,6 @@ import de.uka.ilkd.key.proof.ProofAggregate; import de.uka.ilkd.key.proof.TacletIndex; import de.uka.ilkd.key.proof.init.*; -import de.uka.ilkd.key.proof.mgt.Contract; -import de.uka.ilkd.key.proof.mgt.Contractable; import de.uka.ilkd.key.visualdebugger.executiontree.ITNode; public class DebuggerPO implements ProofOblInput { @@ -62,10 +60,6 @@ public String getJavaPath() throws ProofInputException { return null; } - public Contractable[] getObjectOfContract() { - return new Contractable[0]; - } - /** * returns the proof to be loaded in the prover */ @@ -102,10 +96,6 @@ private ListOfTerm getTerms(ListOfConstrainedFormula list) { return result; } - public boolean initContract(Contract ct) { - // TODO Auto-generated method stub - return false; - } public void initJavaModelSettings(String classPath) { @@ -134,26 +124,13 @@ public String name() { } // all below are not used for this proof obligation - public void read(ModStrategy mod) { - } public void readActivatedChoices() { } - public Includes readIncludes() throws ProofInputException { - return null; - } - - public String readModel() throws ProofInputException { - return null; - } - public void readProblem(ModStrategy mod) { } - public void readSpecs() { - } - /** * the initial config containing for example the services which provide * access to the Java model @@ -175,10 +152,6 @@ public void setIndices(TacletIndex taclets, BuiltInRuleIndex builtInRules) { this.builtInRules = builtInRules; } - public void setInitConfig(InitConfig i) { - // TODO Auto-generated method stub - - } public void setPCImpl(ListOfTerm l1, ListOfTerm l2) { Term t1 = list2term(l1); @@ -282,8 +255,4 @@ public void setUp(Sequent precondition, ITNode n, SetOfTerm indexConf, .sequent(); } - - public void startProtocol() { - } - } diff --git a/system/de/uka/ilkd/key/visualdebugger/ProofStarter.java b/system/de/uka/ilkd/key/visualdebugger/ProofStarter.java index fe7d677119b..08ef1901c49 100644 --- a/system/de/uka/ilkd/key/visualdebugger/ProofStarter.java +++ b/system/de/uka/ilkd/key/visualdebugger/ProofStarter.java @@ -6,6 +6,7 @@ import de.uka.ilkd.key.gui.RuleAppListener; import de.uka.ilkd.key.proof.*; +import de.uka.ilkd.key.proof.init.ProofInputException; import de.uka.ilkd.key.proof.init.ProofOblInput; import de.uka.ilkd.key.proof.mgt.ProofEnvironment; import de.uka.ilkd.key.proof.proofevent.IteratorOfNodeReplacement; @@ -77,8 +78,8 @@ private void applySimplificationOnGoals(ListOfGoal goals, BuiltInRule decisionProcedureRule) { if (goals.isEmpty()) { return; - } - + } + final Proof p = goals.head().node().proof(); final IteratorOfGoal i = goals.iterator(); @@ -116,7 +117,12 @@ public void init(ProofOblInput po) { } this.po = po; - this.proof = po.getPO().getFirstProof(); + try { + this.proof = po.getPO().getFirstProof(); + } catch(ProofInputException e) { + System.err.println(e); + e.printStackTrace(); + } } /** @@ -203,15 +209,17 @@ public boolean run(ProofEnvironment env) { decisionProcedureRule = null; } - env.registerProof(po, po.getPO()); goalChooser.init(proof, proof.openGoals()); final ProofListener pl = new ProofListener(); Goal.addRuleAppListener(pl); - try { + ProofAggregate proofList = null; + try { + proofList = po.getPO(); + int countApplied = 0; synchronized (progressMonitors) { initProgressMonitors(maxSteps); @@ -229,8 +237,8 @@ public boolean run(ProofEnvironment env) { return false; } finally { Goal.removeRuleAppListener(pl); - env.removeProofList(po.getPO()); proof.setActiveStrategy(oldStrategy); + env.removeProofList(proofList); } return true; diff --git a/system/de/uka/ilkd/key/visualdebugger/VisualDebugger.java b/system/de/uka/ilkd/key/visualdebugger/VisualDebugger.java index ae7936cdabb..2f84be7c8ad 100644 --- a/system/de/uka/ilkd/key/visualdebugger/VisualDebugger.java +++ b/system/de/uka/ilkd/key/visualdebugger/VisualDebugger.java @@ -684,7 +684,7 @@ public void initialize() { if (m != null) { ProgramVariableCollector pvc = new ProgramVariableCollector( - m); + m, mediator.getServices()); pvc.start(); pvs.addAll(pvc.result()); } diff --git a/system/de/uka/ilkd/key/visualdebugger/executiontree/ITNode.java b/system/de/uka/ilkd/key/visualdebugger/executiontree/ITNode.java index 765702ec95c..8f6f2b1968b 100644 --- a/system/de/uka/ilkd/key/visualdebugger/executiontree/ITNode.java +++ b/system/de/uka/ilkd/key/visualdebugger/executiontree/ITNode.java @@ -281,7 +281,7 @@ private boolean calcIsMethodInvocation() { Term val = (Term) result.get(TermFactory.DEFAULT .createVariableTerm((ProgramVariable) baseVar.op())); map.put(baseVar.op(), val); - ProgVarReplacer pvr = new ProgVarReplacer(map); + ProgVarReplacer pvr = new ProgVarReplacer(map, serv); Term res = pvr.replace(t); programMethod = mbs.getProgramMethod(serv); diff --git a/system/de/uka/ilkd/key/visualdebugger/statevisualisation/SymbolicObjectDiagram.java b/system/de/uka/ilkd/key/visualdebugger/statevisualisation/SymbolicObjectDiagram.java index 329a7678329..11dea269e9c 100644 --- a/system/de/uka/ilkd/key/visualdebugger/statevisualisation/SymbolicObjectDiagram.java +++ b/system/de/uka/ilkd/key/visualdebugger/statevisualisation/SymbolicObjectDiagram.java @@ -961,7 +961,7 @@ private void setMethodStack(boolean pre) { // (ProgramVariable)((Term)vd.getInputPV2term().get(self)).op(); Term val = ((Term) vd.getInputPV2term().get(self)); map.put(self.op(), val); - ProgVarReplacer pvr = new ProgVarReplacer(map); + ProgVarReplacer pvr = new ProgVarReplacer(map,serv); Term res = pvr.replace(t); so = getObject(res, symbolicObjects); diff --git a/system/de/uka/ilkd/key/visualization/SimpleVisualizationStrategy.java b/system/de/uka/ilkd/key/visualization/SimpleVisualizationStrategy.java index 7d601e2c7eb..797f71c3ae7 100644 --- a/system/de/uka/ilkd/key/visualization/SimpleVisualizationStrategy.java +++ b/system/de/uka/ilkd/key/visualization/SimpleVisualizationStrategy.java @@ -1537,7 +1537,7 @@ private Semisequent rename(Semisequent semi, ListOfRenamingTable renamings){ while (it.hasNext()){ RenamingTable rt = it.next(); HashMap hm = rt.getHashMap(); - ProgVarReplacer pvr = new ProgVarReplacer(hm); + ProgVarReplacer pvr = new ProgVarReplacer(hm, services); SemisequentChangeInfo sci =pvr.replace(semi); semi = sci.semisequent(); } @@ -1553,7 +1553,7 @@ private Term rename(Term formula,ListOfRenamingTable renamings){ while (it.hasNext()){ RenamingTable rt = it.next(); HashMap hm = rt.getHashMap(); - ProgVarReplacer pvr = new ProgVarReplacer(hm); + ProgVarReplacer pvr = new ProgVarReplacer(hm, services); formula = pvr.replace(formula); } } diff --git a/system/resources/de/uka/ilkd/key/casetool/together/scripts/menuextension/KeyMenuExtension.properties b/system/resources/de/uka/ilkd/key/casetool/together/scripts/menuextension/KeyMenuExtension.properties index 2fd743337bd..28f04dc077d 100644 --- a/system/resources/de/uka/ilkd/key/casetool/together/scripts/menuextension/KeyMenuExtension.properties +++ b/system/resources/de/uka/ilkd/key/casetool/together/scripts/menuextension/KeyMenuExtension.properties @@ -3,6 +3,6 @@ # # how many OpMenuitems do we have -key.menu.op.menuitem-count=12 +key.menu.op.menuitem-count=11 # how many classmenuitems do we have -key.menu.class.menuitem-count=7 \ No newline at end of file +key.menu.class.menuitem-count=6 \ No newline at end of file diff --git a/system/resources/de/uka/ilkd/key/gui/images/toolbar/jml.png b/system/resources/de/uka/ilkd/key/gui/images/toolbar/jml.png new file mode 100644 index 0000000000000000000000000000000000000000..09fe8efbfb60ef99a1e45b92a1a144f1410be88c GIT binary patch literal 1374 zcmV-k1)=(hP)F0@F@e$;rvt zmw*3fuYX+>DOw~F(G0^_qm=SnES8r=veBvd*C9=W-vrzdl8aPX2+3b)(6A`*!d>$-l-Znv*?xm;wRoE?qk4^Z9m|rn%qg zuygaqbwUHdWq!YZ&tr9g#QGI=>sKK4RRBijbG_#p*XDPHXJSUfV8jQvui0YByeYhtq!@lHau=CJ}-EkI?-qx|Lqu#>keFV)Pa`^&WYclcQhImYoW!Le#b-ZryWE-rlFq0b> zJD?%dkJ3D&V9(st)r=nFK?EM23EhifpIZ4XIV8cl0N! z*Q|o?r=E(F;2#6e135r0U;_q#;F$N1k(x94y-TC%~bv>q{n0V9~rxW>~;54R#zl z%$ePLi3JBn=TB~VheJo&xY8H~VD7BpG^N7H-;z3=fdI&`HI* zVrI{50V4u6)6l0$l_pZ9iO6>%^0bJ2A|ii@NUMkhMI>?Rqia; g#m(gv)#(!d4^ko(yRC?kDF6Tf07*qoM6N<$f-fb9-v9sr literal 0 HcmV?d00001 diff --git a/system/resources/de/uka/ilkd/key/gui/images/toolbar/uml.png b/system/resources/de/uka/ilkd/key/gui/images/toolbar/uml.png new file mode 100644 index 0000000000000000000000000000000000000000..0dfdeb7fe094dc5b2e93d974213d3a926d889585 GIT binary patch literal 993 zcmX|9e`r-z9KX+8dwcHLv#Cv`+Cz+<)9PZ;o=eiZH{EW!)=g;LKT3BivWxxjPR*`K zi%Yn5Nobd8b8?g;wA_xt7Z<@5c? zcc8m#OFp+er)gTgv!i0AzG+UgH>I{RGRQP-UR(Fp?d{oY763}6l3^H@W!bjvx~}JW zzV8P?5QbqCMF^odjxolB5K1ZMTnHhhOp-(?RZT@HNNozGR6-=2Lp1@#K}NuBphX~A zPz(|bG6dm)aDiLE%D{A>jX(=PG)Q8Q0SE`U3ETiy0#*c?g{lNaAweL0kZG zq?#yD)r4|M7z+@#JdQB)BkG034OGhHLSianLfs%P+X7)8#l-Pr-9jZ(QpQ3=Y!6#5 zDjJH5gmE4s7DUt!iREI`i48kRX?{q(02_8(wvcYdx`|4LBvjzEvQHc@Dwa8liS1&` zk(h`W3l#GR-P88d1L;>~`mCIDP+qbCP1 ztzF-D_~e7nUSD>sXJ=dQX!rQOPY$*ozxL(*ca6;!n#Yd*d}D3R#hYjE4d?5NW*=Q~ zY){jxm1{q~J=3yh=celm-z%Ir*ELf3LH_#u@bp;6>!emiR~-j}P<*1fZ?>5HBtnF;OGk=3spdLuWp=D>>I`MCCd{UqJL zcXHLp>HI^RFaEi?ZfkDujzyU#YNlE$$zOM8F87bj9JuAw?x9_G)b&hlJM{U|$!8X} zo+)Qu`sbXPYZ!g^>Po(B_=V5T7ti1L^z5yfGphM1STg7iEUDkHcxZXACO^1f_K&Lk e#Psx6`EM$tSN5;@_O= #v & iv2 <= #a.#length) -> - {\for iv; \if (iv >= #v & iv < iv2) #a[iv] := #lit}post) & + \forall iv2; ((iv2 >= #se & iv2 <= #a.#length) -> + {\for iv; \if (iv >= #se & iv < iv2) #a[iv] := #lit}post) & {\for iv; \if (geq(iv,#v) & lt(iv,#a.#length)) #a[iv] := #lit} (post -> \throughout{.. ...}\endmodality(post))) \heuristics(simplify)