From cbbb63ee782695f212c6534808c164bb91230146 Mon Sep 17 00:00:00 2001 From: Robin Salkeld Date: Tue, 9 Jan 2024 15:03:03 -0800 Subject: [PATCH] snapshot v4 4 0 (#36) - Removing old latest - Documentation snapshot for v4.4.0 --- Snapshots.md | 1 + latest/DafnyRef/Attributes.md | 177 ++++++++-- latest/DafnyRef/Expressions.md | 1 - latest/DafnyRef/Features.md | 6 +- latest/DafnyRef/Grammar.md | 2 +- latest/DafnyRef/GrammarDetails.md | 3 +- latest/DafnyRef/Options.txt | 33 +- latest/DafnyRef/Specifications.md | 68 +++- latest/DafnyRef/Statements.md | 2 +- latest/DafnyRef/Types.md | 61 +++- latest/DafnyRef/UserGuide.md | 318 ++++++++++++------ latest/DafnyRef/concat | 0 latest/HowToFAQ/Errors-CommandLine.md | 2 +- latest/HowToFAQ/Errors-Parser.md | 4 +- latest/HowToFAQ/Errors-Parser.template | 2 +- latest/HowToFAQ/FAQFunctionByMethodProof.md | 87 +++++ latest/HowToFAQ/FAQFunctionByMethodProof1.dfy | 16 + latest/HowToFAQ/FAQFunctionByMethodProof1.txt | 2 + .../HowToFAQ/FAQFunctionByMethodProof2..txt | 1 + latest/HowToFAQ/FAQFunctionByMethodProof2.dfy | 28 ++ latest/HowToFAQ/FAQFunctionByMethodProof3.dfy | 17 + latest/HowToFAQ/FAQFunctionByMethodProof3.txt | 1 + latest/HowToFAQ/FAQFunctionByMethodProof4.dfy | 10 + latest/HowToFAQ/FAQFunctionByMethodProof4.txt | 1 + latest/HowToFAQ/check-errors | 0 latest/HowToFAQ/check-errors-a | 0 latest/HowToFAQ/index.md | 1 + latest/HowToFAQ/make-error-catalog | 0 latest/HowToFAQ/make-onepage | 0 latest/HowToFAQ/onepage.md | 88 ++++- latest/Installation.md | 16 +- latest/OnlineTutorial/Lemmas.3.expect | 2 - latest/OnlineTutorial/Lemmas.4.expect | 2 - latest/OnlineTutorial/guide.18.expect | 2 - latest/OnlineTutorial/guide.md | 2 +- latest/QuickReference.md | 0 latest/Snapshots.md | 2 + latest/check-examples | 0 latest/examples/README.md | 10 +- latest/make-snapshot | 37 +- latest/v4.3.0/DafnyRef/version.txt | 1 - latest/v4.3.0/dev/Coverage.md | 15 - .../Dafny-Documentation-Status-31May2023.md | 108 ------ latest/v4.3.0/dev/README.md | 47 --- latest/v4.3.0/dev/RELEASE.md | 131 -------- latest/v4.3.0/dev/TypeSystemRefresh.md | 130 ------- {latest/v4.3.0 => v4.4.0}/.gitignore | 0 .../Compilation/AutoInitialization.md | 0 .../v4.3.0 => v4.4.0}/Compilation/Boogie.md | 0 {latest/v4.3.0 => v4.4.0}/Compilation/Go.md | 0 .../Compilation/ReferenceTypes.md | 0 .../Compilation/StringsAndChars.md | 0 .../v4.3.0 => v4.4.0}/Dafny-cheat-sheet.pdf | Bin .../v4.3.0 => v4.4.0}/DafnyCheatsheet.docx | Bin {latest/v4.3.0 => v4.4.0}/DafnyCheatsheet.pdf | Bin {latest/v4.3.0 => v4.4.0}/DafnyRef/.gitignore | 0 .../DafnyRef/Attributes.1.expect | 0 .../DafnyRef/Attributes.3.expect | 0 .../DafnyRef/Attributes.4.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Attributes.md | 177 ++++++++-- .../DafnyRef/CommandLineOptions.md | 0 .../v4.3.0 => v4.4.0}/DafnyRef/DafnyRef.bib | 0 .../v4.3.0 => v4.4.0}/DafnyRef/DafnyRef.md | 0 .../DafnyRef/Expressions.1.expect | 0 .../DafnyRef/Expressions.2.expect | 0 .../DafnyRef/Expressions.3.expect | 0 .../DafnyRef/Expressions.4.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Expressions.md | 1 - .../v4.3.0 => v4.4.0}/DafnyRef/Features.md | 6 +- .../DafnyRef/Grammar.1.expect | 0 .../DafnyRef/Grammar.2.expect | 0 {latest/v4.3.0 => v4.4.0}/DafnyRef/Grammar.md | 2 +- .../DafnyRef/GrammarDetails.md | 3 +- .../DafnyRef/GrammarLinks.java | 0 .../DafnyRef/Introduction.md | 0 {latest/v4.3.0 => v4.4.0}/DafnyRef/Makefile | 0 .../DafnyRef/Modules.1.expect | 0 .../DafnyRef/Modules.10.expect | 0 .../DafnyRef/Modules.2.expect | 0 .../DafnyRef/Modules.3.expect | 0 .../DafnyRef/Modules.4.expect | 0 .../DafnyRef/Modules.5.expect | 0 .../DafnyRef/Modules.6.expect | 0 .../DafnyRef/Modules.7.expect | 0 {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.md | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Numbers.java | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Options.txt | 33 +- {latest/v4.3.0 => v4.4.0}/DafnyRef/Plugins.md | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Programs.md | 0 {latest/v4.3.0 => v4.4.0}/DafnyRef/README.md | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Refinement.md | 0 .../DafnyRef/Specifications.1.expect | 0 .../DafnyRef/Specifications.2.expect | 0 .../DafnyRef/Specifications.md | 68 +++- .../DafnyRef/Statements.1.expect | 0 .../DafnyRef/Statements.10.expect | 0 .../DafnyRef/Statements.13.expect | 0 .../DafnyRef/Statements.14.expect | 0 .../DafnyRef/Statements.15.expect | 0 .../DafnyRef/Statements.2.expect | 0 .../DafnyRef/Statements.3.expect | 0 .../DafnyRef/Statements.4.expect | 0 .../DafnyRef/Statements.5.expect | 0 .../DafnyRef/Statements.6.expect | 0 .../DafnyRef/Statements.7.expect | 0 .../DafnyRef/Statements.8.expect | 0 .../DafnyRef/Statements.9.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Statements.md | 2 +- .../v4.3.0 => v4.4.0}/DafnyRef/SyntaxTests.md | 0 .../DafnyRef/Topics.1.expect | 0 .../DafnyRef/Topics.2.expect | 0 .../DafnyRef/Topics.3.expect | 0 {latest/v4.3.0 => v4.4.0}/DafnyRef/Topics.md | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Types.1.expect | 0 .../DafnyRef/Types.10.expect | 0 .../DafnyRef/Types.10a.expect | 0 .../DafnyRef/Types.11.expect | 0 .../DafnyRef/Types.12.expect | 0 .../DafnyRef/Types.13.expect | 0 .../DafnyRef/Types.14.expect | 0 .../DafnyRef/Types.15.expect | 0 .../DafnyRef/Types.16.expect | 0 .../DafnyRef/Types.17.expect | 0 .../DafnyRef/Types.18.expect | 0 .../DafnyRef/Types.19.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Types.2.expect | 0 .../DafnyRef/Types.20.expect | 0 .../DafnyRef/Types.21.expect | 0 .../DafnyRef/Types.22.expect | 0 .../DafnyRef/Types.25.expect | 0 .../DafnyRef/Types.26.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Types.3.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Types.4.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Types.5.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Types.6.expect | 0 .../DafnyRef/Types.7a.expect | 0 .../DafnyRef/Types.7b.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Types.8.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/Types.9.expect | 0 {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.md | 61 +++- .../DafnyRef/UserGuide.1.expect | 0 .../DafnyRef/UserGuide.2.expect | 0 .../DafnyRef/UserGuide.3.expect | 0 .../DafnyRef/UserGuide.4.expect | 0 .../DafnyRef/UserGuide.5.expect | 0 .../DafnyRef/UserGuide.6.expect | 0 .../DafnyRef/UserGuide.7.expect | 0 .../DafnyRef/UserGuide.8.expect | 0 .../v4.3.0 => v4.4.0}/DafnyRef/UserGuide.md | 318 ++++++++++++------ .../v4.3.0 => v4.4.0}/DafnyRef/VSCodeIDE.md | 0 {latest/v4.3.0 => v4.4.0}/DafnyRef/concat | 0 .../DafnyRef/integration-cs/IntegrationCS.md | 0 .../DafnyRef/integration-go/IntegrationGo.md | 0 .../integration-java/IntegrationJava.md | 0 .../DafnyRef/integration-js/IntegrationJS.md | 0 .../integration-py/IntegrationPython.md | 0 .../v4.3.0 => v4.4.0}/DafnyRef/krml250.bib | 0 {latest/v4.3.0 => v4.4.0}/DafnyRef/out/README | 0 .../v4.3.0 => v4.4.0}/DafnyRef/paper-full.bib | 0 {latest/v4.3.0 => v4.4.0}/DafnyRef/poc.bib | 0 .../v4.3.0 => v4.4.0}/DafnyRef/references.bib | 0 v4.4.0/DafnyRef/version.txt | 1 + {latest/v4.3.0 => v4.4.0}/Gemfile | 0 {latest/v4.3.0 => v4.4.0}/Gemfile.lock | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/.gitignore | 0 .../HowToFAQ/ERROR_CloseParen.dfy | 0 .../HowToFAQ/ERROR_CloseParen.md | 0 .../HowToFAQ/ERROR_CloseParen.txt | 0 .../HowToFAQ/ERROR_Covariance.dfy | 0 .../HowToFAQ/ERROR_Covariance.md | 0 .../HowToFAQ/ERROR_Covariance.txt | 0 .../HowToFAQ/ERROR_DataTypeName.md | 0 .../HowToFAQ/ERROR_DuplicateImportName.md | 0 .../HowToFAQ/ERROR_FunctionPrecondition.md | 0 .../HowToFAQ/ERROR_InsufficientReads.dfy | 0 .../HowToFAQ/ERROR_InsufficientReads.md | 0 .../HowToFAQ/ERROR_InsufficientReads.txt | 0 .../HowToFAQ/ERROR_InsufficientReads1.dfy | 0 .../HowToFAQ/ERROR_IsFailure.md | 0 .../HowToFAQ/ERROR_ModifiesValue.dfy | 0 .../HowToFAQ/ERROR_ModifiesValue.md | 0 .../HowToFAQ/ERROR_ModifiesValue.txt | 0 .../HowToFAQ/ERROR_ModifiesValue1.dfy | 0 .../HowToFAQ/ERROR_MutableField.dfy | 0 .../HowToFAQ/ERROR_MutableField.md | 0 .../HowToFAQ/ERROR_MutableField.txt | 0 .../HowToFAQ/ERROR_MutableField1.dfy | 0 .../HowToFAQ/ERROR_NoCode.md | 0 .../HowToFAQ/ERROR_NoLHS.dfy | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/ERROR_NoLHS.md | 0 .../HowToFAQ/ERROR_NoLHS.txt | 0 .../HowToFAQ/ERROR_NoLHS1.dfy | 0 .../HowToFAQ/ERROR_NoLHS1.txt | 0 .../ERROR_NoReferenceTypeParameter.md | 0 .../HowToFAQ/ERROR_NoTriggers.md | 0 .../HowToFAQ/ERROR_PostconditionLemma.dfy | 0 .../HowToFAQ/ERROR_PostconditionLemma.md | 0 .../HowToFAQ/ERROR_PostconditionLemma.txt | 0 .../HowToFAQ/ERROR_ProverError1.md | 0 .../HowToFAQ/ERROR_Rbrace.md | 0 .../HowToFAQ/ERROR_Rbrace1.dfy | 0 .../HowToFAQ/ERROR_Rbrace1.txt | 0 .../HowToFAQ/ERROR_Rbrace2.dfy | 0 .../HowToFAQ/ERROR_Rbrace2.txt | 0 .../HowToFAQ/ERROR_Rbrace3.dfy | 0 .../HowToFAQ/ERROR_Rbrace3.txt | 0 .../HowToFAQ/ERROR_Rbrace4.dfy | 0 .../HowToFAQ/ERROR_Rbrace4.txt | 0 .../HowToFAQ/ERROR_SeqComp.dfy | 0 .../HowToFAQ/ERROR_SeqComp.md | 0 .../HowToFAQ/ERROR_SeqComp.txt | 0 .../HowToFAQ/ERROR_SeqComp1.dfy | 0 .../HowToFAQ/ERROR_SeqComp1.txt | 0 .../HowToFAQ/ERROR_SubsetConstraints.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Z3.md | 0 .../HowToFAQ/Errors-CommandLine.md | 2 +- .../HowToFAQ/Errors-Compiler.md | 0 .../HowToFAQ/Errors-Compiler.template | 0 .../HowToFAQ/Errors-Generic.md | 0 .../HowToFAQ/Errors-Parser.md | 4 +- .../HowToFAQ/Errors-Parser.template | 2 +- .../HowToFAQ/Errors-Refinement.md | 0 .../HowToFAQ/Errors-Resolution.md | 0 .../HowToFAQ/Errors-Resolver2.md | 0 .../HowToFAQ/Errors-Resolver3.md | 0 .../HowToFAQ/Errors-Rewriter.md | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors.md | 0 .../HowToFAQ/FAQAttribute.md | 0 .../HowToFAQ/FAQBVNegation.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQBoogie.md | 0 .../HowToFAQ/FAQClassInSpec.md | 0 .../HowToFAQ/FAQCompileTargets.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQCurry.md | 0 .../HowToFAQ/FAQDafnyAsLibrary.md | 0 .../HowToFAQ/FAQDefaultInitialValue.md | 0 .../HowToFAQ/FAQDefaultParameter.md | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQDie.md | 0 .../HowToFAQ/FAQDocGenerator.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQElephant.md | 0 .../HowToFAQ/FAQExternReturnsObject.md | 0 .../HowToFAQ/FAQFailingPost.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQForall.md | 0 .../HowToFAQ/FAQForallTricks.md | 0 v4.4.0/HowToFAQ/FAQFunctionByMethodProof.md | 87 +++++ v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.dfy | 16 + v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.txt | 2 + .../HowToFAQ/FAQFunctionByMethodProof2..txt | 1 + v4.4.0/HowToFAQ/FAQFunctionByMethodProof2.dfy | 28 ++ v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.dfy | 17 + v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.txt | 1 + v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.dfy | 10 + v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.txt | 1 + .../HowToFAQ/FAQFunctionMethod.md | 0 .../HowToFAQ/FAQFunctionMethodDiffs.md | 0 .../HowToFAQ/FAQFunctionTypes.md | 0 .../HowToFAQ/FAQFunctionUnroll.md | 0 .../HowToFAQ/FAQFunctionUnroll0.dfy | 0 .../HowToFAQ/FAQFunctionUnroll0.txt | 0 .../HowToFAQ/FAQFunctionUnroll1.dfy | 0 .../HowToFAQ/FAQFunctionUnroll2.dfy | 0 .../HowToFAQ/FAQGhostConstAsWitness.md | 0 .../HowToFAQ/FAQGhostMethod.md | 0 .../HowToFAQ/FAQGhostSideEffects.md | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQIff.md | 0 .../HowToFAQ/FAQImportAbstractModule.md | 0 .../HowToFAQ/FAQImportOneThing.md | 0 .../HowToFAQ/FAQImportOpened.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQIncludes.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQIssues.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQIterator.md | 0 .../HowToFAQ/FAQLambdaSpecifications.md | 0 .../HowToFAQ/FAQLoopModifies.md | 0 .../HowToFAQ/FAQMapExtensionality.md | 0 .../HowToFAQ/FAQMapMembership.md | 0 .../HowToFAQ/FAQMatchOnSet.md | 0 .../HowToFAQ/FAQMepSetSeq.md | 0 .../HowToFAQ/FAQMethodSequence.md | 0 .../HowToFAQ/FAQModifiesOne.md | 0 .../HowToFAQ/FAQModifiesThis.md | 0 .../HowToFAQ/FAQModuleImport.dfy | 0 .../HowToFAQ/FAQModuleImport.md | 0 .../HowToFAQ/FAQModuleImport.txt | 0 .../HowToFAQ/FAQModuleImport1.dfy | 0 .../HowToFAQ/FAQModuleNames.dfy | 0 .../HowToFAQ/FAQModuleNames.md | 0 .../HowToFAQ/FAQModuleNames0.dfy | 0 .../HowToFAQ/FAQModuleNames0.txt | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQMonadic.md | 0 .../HowToFAQ/FAQMultClauses.md | 0 .../HowToFAQ/FAQMutualRecursion.md | 0 .../HowToFAQ/FAQNameConflict.dfy | 0 .../HowToFAQ/FAQNameConflict.md | 0 .../HowToFAQ/FAQNameConflict.txt | 0 .../HowToFAQ/FAQNameConflict1.dfy | 0 .../HowToFAQ/FAQNeedsAssert.md | 0 .../HowToFAQ/FAQNestedModule.dfy | 0 .../HowToFAQ/FAQNestedModule.md | 0 .../HowToFAQ/FAQNestedModule.txt | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQNewline.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQNewtype.dfy | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQNewtype.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQNoBody.md | 0 .../HowToFAQ/FAQNoTermCheck.md | 0 .../HowToFAQ/FAQNonlinearArith.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQNuget.md | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQOld.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQParallel.md | 0 .../HowToFAQ/FAQPreconditionLabels.dfy | 0 .../HowToFAQ/FAQPreconditionLabels.md | 0 .../HowToFAQ/FAQPreconditionLabels.txt | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQReadFile.md | 0 .../HowToFAQ/FAQReadsClause.dfy | 0 .../HowToFAQ/FAQReadsClause.md | 0 .../HowToFAQ/FAQReadsClause.txt | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQRecord.md | 0 .../HowToFAQ/FAQRecursiveCalls.md | 0 .../HowToFAQ/FAQRecursiveTermination.md | 0 .../HowToFAQ/FAQRedundantCase.md | 0 .../HowToFAQ/FAQReferences.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQSeqTrait.md | 0 .../HowToFAQ/FAQSetConstructor.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQSetToSeq.md | 0 .../HowToFAQ/FAQSplitHere.md | 0 .../HowToFAQ/FAQStandardLibrary.md | 0 .../HowToFAQ/FAQStringOutput.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQStyle.md | 0 .../HowToFAQ/FAQTermination.md | 0 .../HowToFAQ/FAQTerminationFalse.md | 0 .../HowToFAQ/FAQThisFrameField.md | 0 .../HowToFAQ/FAQTraitsForDatatypes.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQTriggers.md | 0 .../HowToFAQ/FAQTypeCompare.dfy | 0 .../HowToFAQ/FAQTypeCompare.md | 0 .../HowToFAQ/FAQTypeInference.md | 0 .../HowToFAQ/FAQTypeParameterRestriction.md | 0 .../HowToFAQ/FAQTypeReasoning.md | 0 .../HowToFAQ/FAQUpdateArrayField.md | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/FAQWitness.md | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQZ3.md | 0 .../HowToFAQ/FAQ_GenericType.md | 0 .../HowToFAQ/MakeErrorCatalog.java | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/check-errors | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/check-errors-a | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/index.md | 1 + .../HowToFAQ/make-error-catalog | 0 .../v4.3.0 => v4.4.0}/HowToFAQ/make-onepage | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/onepage.md | 88 ++++- .../HowToFAQ/testfiles/a.dfy | 0 .../HowToFAQ/testsource/BadDoo.doo | 0 .../HowToFAQ/testsource/TestA.dfy | 0 .../HowToFAQ/testsource/test1.dfy | 0 .../HowToFAQ/testsource/test2.dfy | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/text1.dfy | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/text2.dfy | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/text3.dfy | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/text4.dfy | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/text5.dfy | 0 {latest/v4.3.0 => v4.4.0}/HowToFAQ/text6.dfy | 0 {latest/v4.3.0 => v4.4.0}/Installation.md | 16 +- .../KDESyntaxDefinition/dafny.theme | 0 .../KDESyntaxDefinition/dafny.theme-comments | 0 .../KDESyntaxDefinition/dafny.xml | 0 .../KDESyntaxDefinition/grammar.theme | 0 .../KDESyntaxDefinition/grammar.xml | 0 {latest/v4.3.0 => v4.4.0}/LICENSE | 0 .../OnlineTutorial/Lemmas.1.expect | 0 .../OnlineTutorial/Lemmas.10.expect | 0 .../OnlineTutorial/Lemmas.2.expect | 0 .../OnlineTutorial/Lemmas.3.expect | 2 - .../OnlineTutorial/Lemmas.4.expect | 2 - .../OnlineTutorial/Lemmas.5.expect | 0 .../OnlineTutorial/Lemmas.6.expect | 0 .../OnlineTutorial/Lemmas.7.expect | 0 .../OnlineTutorial/Lemmas.8.expect | 0 .../OnlineTutorial/Lemmas.9.expect | 0 .../OnlineTutorial/Lemmas.md | 0 .../OnlineTutorial/Modules.1.expect | 0 .../OnlineTutorial/Modules.2.expect | 0 .../OnlineTutorial/Modules.3.expect | 0 .../OnlineTutorial/Modules.4.expect | 0 .../OnlineTutorial/Modules.5.expect | 0 .../OnlineTutorial/Modules.6.expect | 0 .../OnlineTutorial/Modules.7.expect | 0 .../OnlineTutorial/Modules.md | 0 .../OnlineTutorial/Sequences.md | 0 .../OnlineTutorial/Sets.1.expect | 0 .../OnlineTutorial/Sets.W1.expect | 0 .../OnlineTutorial/Sets.W2.expect | 0 .../OnlineTutorial/Sets.W3.expect | 0 .../v4.3.0 => v4.4.0}/OnlineTutorial/Sets.md | 0 .../OnlineTutorial/Termination.md | 0 .../OnlineTutorial/ValueTypes.md | 0 .../OnlineTutorial/guide.1.expect | 0 .../OnlineTutorial/guide.10.expect | 0 .../OnlineTutorial/guide.11.expect | 0 .../OnlineTutorial/guide.12.expect | 0 .../OnlineTutorial/guide.13.expect | 0 .../OnlineTutorial/guide.14.expect | 0 .../OnlineTutorial/guide.15.expect | 0 .../OnlineTutorial/guide.16.expect | 0 .../OnlineTutorial/guide.17.expect | 0 .../OnlineTutorial/guide.18.expect | 2 - .../OnlineTutorial/guide.19.expect | 0 .../OnlineTutorial/guide.2.expect | 0 .../OnlineTutorial/guide.20.expect | 0 .../OnlineTutorial/guide.3.expect | 0 .../OnlineTutorial/guide.4.expect | 0 .../OnlineTutorial/guide.5.expect | 0 .../OnlineTutorial/guide.6.expect | 0 .../OnlineTutorial/guide.7.expect | 0 .../OnlineTutorial/guide.8.expect | 0 .../OnlineTutorial/guide.9.expect | 0 .../v4.3.0 => v4.4.0}/OnlineTutorial/guide.md | 2 +- {latest/v4.3.0 => v4.4.0}/QuickReference.md | 0 {latest/v4.3.0 => v4.4.0}/README.md | 0 {latest/v4.3.0 => v4.4.0}/Snapshots.md | 2 + .../StyleGuide/Style-Guide.md | 0 .../VerificationOptimization.md | 0 .../hover-assertion.png | Bin .../VerificationOptimization/hover-method.png | Bin {latest/v4.3.0 => v4.4.0}/_config.yml | 0 {latest/v4.3.0 => v4.4.0}/_includes/README | 0 .../v4.3.0 => v4.4.0}/_includes/footer.html | 0 {latest/v4.3.0 => v4.4.0}/_includes/head.html | 0 .../v4.3.0 => v4.4.0}/_layouts/default.html | 0 {latest/v4.3.0 => v4.4.0}/check-examples | 0 {latest/v4.3.0 => v4.4.0}/dafny.sty | 0 {latest/v4.3.0 => v4.4.0}/examples/README.md | 10 +- {latest/v4.3.0 => v4.4.0}/images/Demo.png | Bin .../v4.3.0 => v4.4.0}/images/DutchFlag.dfy | 0 .../v4.3.0 => v4.4.0}/images/dafny-banner.png | Bin .../v4.3.0 => v4.4.0}/images/dafny-banner.xcf | Bin .../images/dafny-favicon.png | Bin .../images/dafny-favicon.svg | 0 .../images/dafny-logo-230.png | Bin .../v4.3.0 => v4.4.0}/images/dafny-logo.jpg | Bin .../images/dafny-thumbnail.jpg | Bin {latest/v4.3.0 => v4.4.0}/index.html | 2 +- {latest/v4.3.0 => v4.4.0}/make-snapshot | 37 +- {latest/v4.3.0 => v4.4.0}/style.css | 0 {latest/v4.3.0 => v4.4.0}/toc.md | 0 441 files changed, 1589 insertions(+), 855 deletions(-) mode change 100644 => 100755 latest/DafnyRef/concat create mode 100644 latest/HowToFAQ/FAQFunctionByMethodProof.md create mode 100644 latest/HowToFAQ/FAQFunctionByMethodProof1.dfy create mode 100644 latest/HowToFAQ/FAQFunctionByMethodProof1.txt create mode 100644 latest/HowToFAQ/FAQFunctionByMethodProof2..txt create mode 100644 latest/HowToFAQ/FAQFunctionByMethodProof2.dfy create mode 100644 latest/HowToFAQ/FAQFunctionByMethodProof3.dfy create mode 100644 latest/HowToFAQ/FAQFunctionByMethodProof3.txt create mode 100644 latest/HowToFAQ/FAQFunctionByMethodProof4.dfy create mode 100644 latest/HowToFAQ/FAQFunctionByMethodProof4.txt mode change 100644 => 100755 latest/HowToFAQ/check-errors mode change 100644 => 100755 latest/HowToFAQ/check-errors-a mode change 100644 => 100755 latest/HowToFAQ/make-error-catalog mode change 100644 => 100755 latest/HowToFAQ/make-onepage mode change 100644 => 100755 latest/QuickReference.md mode change 100644 => 100755 latest/check-examples mode change 100644 => 100755 latest/make-snapshot delete mode 100644 latest/v4.3.0/DafnyRef/version.txt delete mode 100644 latest/v4.3.0/dev/Coverage.md delete mode 100644 latest/v4.3.0/dev/Dafny-Documentation-Status-31May2023.md delete mode 100644 latest/v4.3.0/dev/README.md delete mode 100644 latest/v4.3.0/dev/RELEASE.md delete mode 100644 latest/v4.3.0/dev/TypeSystemRefresh.md rename {latest/v4.3.0 => v4.4.0}/.gitignore (100%) rename {latest/v4.3.0 => v4.4.0}/Compilation/AutoInitialization.md (100%) rename {latest/v4.3.0 => v4.4.0}/Compilation/Boogie.md (100%) rename {latest/v4.3.0 => v4.4.0}/Compilation/Go.md (100%) rename {latest/v4.3.0 => v4.4.0}/Compilation/ReferenceTypes.md (100%) rename {latest/v4.3.0 => v4.4.0}/Compilation/StringsAndChars.md (100%) rename {latest/v4.3.0 => v4.4.0}/Dafny-cheat-sheet.pdf (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyCheatsheet.docx (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyCheatsheet.pdf (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/.gitignore (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Attributes.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Attributes.3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Attributes.4.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Attributes.md (84%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/CommandLineOptions.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/DafnyRef.bib (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/DafnyRef.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Expressions.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Expressions.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Expressions.3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Expressions.4.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Expressions.md (99%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Features.md (91%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Grammar.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Grammar.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Grammar.md (99%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/GrammarDetails.md (99%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/GrammarLinks.java (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Introduction.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Makefile (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.10.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.4.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.5.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.6.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.7.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Modules.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Numbers.java (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Options.txt (94%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Plugins.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Programs.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/README.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Refinement.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Specifications.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Specifications.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Specifications.md (92%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.10.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.13.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.14.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.15.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.4.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.5.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.6.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.7.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.8.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.9.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Statements.md (99%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/SyntaxTests.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Topics.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Topics.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Topics.3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Topics.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.10.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.10a.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.11.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.12.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.13.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.14.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.15.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.16.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.17.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.18.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.19.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.20.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.21.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.22.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.25.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.26.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.4.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.5.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.6.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.7a.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.7b.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.8.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.9.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/Types.md (99%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/UserGuide.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/UserGuide.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/UserGuide.3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/UserGuide.4.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/UserGuide.5.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/UserGuide.6.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/UserGuide.7.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/UserGuide.8.expect (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/UserGuide.md (91%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/VSCodeIDE.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/concat (100%) mode change 100644 => 100755 rename {latest/v4.3.0 => v4.4.0}/DafnyRef/integration-cs/IntegrationCS.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/integration-go/IntegrationGo.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/integration-java/IntegrationJava.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/integration-js/IntegrationJS.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/integration-py/IntegrationPython.md (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/krml250.bib (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/out/README (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/paper-full.bib (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/poc.bib (100%) rename {latest/v4.3.0 => v4.4.0}/DafnyRef/references.bib (100%) create mode 100644 v4.4.0/DafnyRef/version.txt rename {latest/v4.3.0 => v4.4.0}/Gemfile (100%) rename {latest/v4.3.0 => v4.4.0}/Gemfile.lock (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/.gitignore (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_CloseParen.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_CloseParen.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_CloseParen.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Covariance.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Covariance.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Covariance.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_DataTypeName.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_DuplicateImportName.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_FunctionPrecondition.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_InsufficientReads.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_InsufficientReads.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_InsufficientReads.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_InsufficientReads1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_IsFailure.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_ModifiesValue.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_ModifiesValue.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_ModifiesValue.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_ModifiesValue1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_MutableField.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_MutableField.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_MutableField.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_MutableField1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_NoCode.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_NoLHS.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_NoLHS.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_NoLHS.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_NoLHS1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_NoLHS1.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_NoReferenceTypeParameter.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_NoTriggers.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_PostconditionLemma.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_PostconditionLemma.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_PostconditionLemma.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_ProverError1.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Rbrace.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Rbrace1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Rbrace1.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Rbrace2.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Rbrace2.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Rbrace3.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Rbrace3.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Rbrace4.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Rbrace4.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_SeqComp.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_SeqComp.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_SeqComp.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_SeqComp1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_SeqComp1.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_SubsetConstraints.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/ERROR_Z3.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-CommandLine.md (98%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Compiler.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Compiler.template (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Generic.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Parser.md (99%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Parser.template (99%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Refinement.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Resolution.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Resolver2.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Resolver3.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors-Rewriter.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/Errors.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQAttribute.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQBVNegation.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQBoogie.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQClassInSpec.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQCompileTargets.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQCurry.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQDafnyAsLibrary.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQDefaultInitialValue.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQDefaultParameter.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQDie.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQDocGenerator.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQElephant.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQExternReturnsObject.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQFailingPost.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQForall.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQForallTricks.md (100%) create mode 100644 v4.4.0/HowToFAQ/FAQFunctionByMethodProof.md create mode 100644 v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.dfy create mode 100644 v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.txt create mode 100644 v4.4.0/HowToFAQ/FAQFunctionByMethodProof2..txt create mode 100644 v4.4.0/HowToFAQ/FAQFunctionByMethodProof2.dfy create mode 100644 v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.dfy create mode 100644 v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.txt create mode 100644 v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.dfy create mode 100644 v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.txt rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQFunctionMethod.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQFunctionMethodDiffs.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQFunctionTypes.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQFunctionUnroll.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQFunctionUnroll0.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQFunctionUnroll0.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQFunctionUnroll1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQFunctionUnroll2.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQGhostConstAsWitness.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQGhostMethod.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQGhostSideEffects.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQIff.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQImportAbstractModule.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQImportOneThing.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQImportOpened.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQIncludes.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQIssues.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQIterator.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQLambdaSpecifications.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQLoopModifies.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQMapExtensionality.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQMapMembership.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQMatchOnSet.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQMepSetSeq.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQMethodSequence.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModifiesOne.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModifiesThis.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModuleImport.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModuleImport.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModuleImport.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModuleImport1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModuleNames.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModuleNames.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModuleNames0.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQModuleNames0.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQMonadic.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQMultClauses.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQMutualRecursion.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNameConflict.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNameConflict.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNameConflict.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNameConflict1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNeedsAssert.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNestedModule.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNestedModule.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNestedModule.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNewline.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNewtype.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNewtype.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNoBody.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNoTermCheck.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNonlinearArith.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQNuget.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQOld.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQParallel.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQPreconditionLabels.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQPreconditionLabels.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQPreconditionLabels.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQReadFile.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQReadsClause.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQReadsClause.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQReadsClause.txt (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQRecord.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQRecursiveCalls.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQRecursiveTermination.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQRedundantCase.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQReferences.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQSeqTrait.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQSetConstructor.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQSetToSeq.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQSplitHere.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQStandardLibrary.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQStringOutput.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQStyle.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQTermination.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQTerminationFalse.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQThisFrameField.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQTraitsForDatatypes.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQTriggers.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQTypeCompare.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQTypeCompare.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQTypeInference.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQTypeParameterRestriction.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQTypeReasoning.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQUpdateArrayField.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQWitness.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQZ3.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/FAQ_GenericType.md (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/MakeErrorCatalog.java (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/check-errors (100%) mode change 100644 => 100755 rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/check-errors-a (100%) mode change 100644 => 100755 rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/index.md (98%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/make-error-catalog (100%) mode change 100644 => 100755 rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/make-onepage (100%) mode change 100644 => 100755 rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/onepage.md (96%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/testfiles/a.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/testsource/BadDoo.doo (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/testsource/TestA.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/testsource/test1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/testsource/test2.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/text1.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/text2.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/text3.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/text4.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/text5.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/HowToFAQ/text6.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/Installation.md (96%) rename {latest/v4.3.0 => v4.4.0}/KDESyntaxDefinition/dafny.theme (100%) rename {latest/v4.3.0 => v4.4.0}/KDESyntaxDefinition/dafny.theme-comments (100%) rename {latest/v4.3.0 => v4.4.0}/KDESyntaxDefinition/dafny.xml (100%) rename {latest/v4.3.0 => v4.4.0}/KDESyntaxDefinition/grammar.theme (100%) rename {latest/v4.3.0 => v4.4.0}/KDESyntaxDefinition/grammar.xml (100%) rename {latest/v4.3.0 => v4.4.0}/LICENSE (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.10.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.3.expect (77%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.4.expect (77%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.5.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.6.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.7.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.8.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.9.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Lemmas.md (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Modules.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Modules.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Modules.3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Modules.4.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Modules.5.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Modules.6.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Modules.7.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Modules.md (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Sequences.md (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Sets.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Sets.W1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Sets.W2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Sets.W3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Sets.md (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/Termination.md (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/ValueTypes.md (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.1.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.10.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.11.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.12.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.13.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.14.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.15.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.16.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.17.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.18.expect (77%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.19.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.2.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.20.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.3.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.4.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.5.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.6.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.7.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.8.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.9.expect (100%) rename {latest/v4.3.0 => v4.4.0}/OnlineTutorial/guide.md (99%) rename {latest/v4.3.0 => v4.4.0}/QuickReference.md (100%) mode change 100644 => 100755 rename {latest/v4.3.0 => v4.4.0}/README.md (100%) rename {latest/v4.3.0 => v4.4.0}/Snapshots.md (87%) rename {latest/v4.3.0 => v4.4.0}/StyleGuide/Style-Guide.md (100%) rename {latest/v4.3.0 => v4.4.0}/VerificationOptimization/VerificationOptimization.md (100%) rename {latest/v4.3.0 => v4.4.0}/VerificationOptimization/hover-assertion.png (100%) rename {latest/v4.3.0 => v4.4.0}/VerificationOptimization/hover-method.png (100%) rename {latest/v4.3.0 => v4.4.0}/_config.yml (100%) rename {latest/v4.3.0 => v4.4.0}/_includes/README (100%) rename {latest/v4.3.0 => v4.4.0}/_includes/footer.html (100%) rename {latest/v4.3.0 => v4.4.0}/_includes/head.html (100%) rename {latest/v4.3.0 => v4.4.0}/_layouts/default.html (100%) rename {latest/v4.3.0 => v4.4.0}/check-examples (100%) mode change 100644 => 100755 rename {latest/v4.3.0 => v4.4.0}/dafny.sty (100%) rename {latest/v4.3.0 => v4.4.0}/examples/README.md (53%) rename {latest/v4.3.0 => v4.4.0}/images/Demo.png (100%) rename {latest/v4.3.0 => v4.4.0}/images/DutchFlag.dfy (100%) rename {latest/v4.3.0 => v4.4.0}/images/dafny-banner.png (100%) rename {latest/v4.3.0 => v4.4.0}/images/dafny-banner.xcf (100%) rename {latest/v4.3.0 => v4.4.0}/images/dafny-favicon.png (100%) rename {latest/v4.3.0 => v4.4.0}/images/dafny-favicon.svg (100%) rename {latest/v4.3.0 => v4.4.0}/images/dafny-logo-230.png (100%) rename {latest/v4.3.0 => v4.4.0}/images/dafny-logo.jpg (100%) rename {latest/v4.3.0 => v4.4.0}/images/dafny-thumbnail.jpg (100%) rename {latest/v4.3.0 => v4.4.0}/index.html (98%) rename {latest/v4.3.0 => v4.4.0}/make-snapshot (81%) mode change 100644 => 100755 rename {latest/v4.3.0 => v4.4.0}/style.css (100%) rename {latest/v4.3.0 => v4.4.0}/toc.md (100%) diff --git a/Snapshots.md b/Snapshots.md index 3c10c4b..c84bc91 100644 --- a/Snapshots.md +++ b/Snapshots.md @@ -7,6 +7,7 @@ layout: default - [Current development version](https://dafny.org/dafny) - [Latest release snapshot](https://dafny.org/latest) +- [v4.4.0](https://dafny.org/v4.4.0) - [v4.3.0](https://dafny.org/v4.3.0) - [v4.2.0](https://dafny.org/v4.2.0) - [v4.1.0](https://dafny.org/v4.1.0) diff --git a/latest/DafnyRef/Attributes.md b/latest/DafnyRef/Attributes.md index 5207d10..47ce6ac 100644 --- a/latest/DafnyRef/Attributes.md +++ b/latest/DafnyRef/Attributes.md @@ -173,6 +173,9 @@ Dafny does not perform sanity checks on the arguments---it is the user's respons For more detail on the use of `{:extern}`, see the corresponding [section](#sec-extern-decls) in the user's guide. +### 11.1.5. `{:disable-nonlinear-arithmetic}` {#sec-disable-nonlinear-arithmetic} +This attribute only applies to module declarations. It overrides the global option `--disable-nonlinear-arithmetic` for that specific module. The attribute can be given true or false to disable or enable nonlinear arithmetic. When no value is given, the default value is true. + ## 11.2. Attributes on functions and methods ### 11.2.1. `{:abstemious}` @@ -256,10 +259,23 @@ The difference with [`{:extern}`](#sec-extern) is that [`{:extern}`](#sec-extern will still emit declaration code if necessary, whereas `{:compile false}` will just ignore the declaration for compilation purposes. -### 11.2.6. `{:extern }` {#sec-extern-method} +### 11.2.6. `{:concurrent}` {#sec-concurrent-attribute} +The `{:concurrent}` attribute indicates that the compiled code for a function or method +may be executed concurrently. +While Dafny is a sequential language and does not support any native concepts for spawning +or controlling concurrent execution, +it does support restricting the specification of declarations such that it is safe to execute them concurrently +using integration with the target language environment. + +Currently, the only way to satisfy this requirement is to ensure that the specification +of the function or method includes the equivalent of `reads {}` and `modifies {}`. +This ensures that the code does not read or write any shared mutable state, +although it is free to write and write newly allocated objects. + +### 11.2.7. `{:extern }` {#sec-extern-method} See [`{:extern }`](#sec-extern). -### 11.2.7. `{:fuel X}` {#sec-fuel} +### 11.2.8. `{:fuel X}` {#sec-fuel} The fuel attribute is used to specify how much "fuel" a function should have, i.e., how many times the verifier is permitted to unfold its definition. The `{:fuel}` annotation can be added to the function itself, in which @@ -282,11 +298,11 @@ fewer assert statements), but it may also increase verification time, so use it with care. Setting the fuel to 0,0 is similar to making the definition opaque, except when used with all literal arguments. -### 11.2.8. `{:id }` +### 11.2.9. `{:id }` Assign a custom unique ID to a function or a method to be used for verification result caching. -### 11.2.9. `{:induction}` {#sec-induction} +### 11.2.10. `{:induction}` {#sec-induction} The `{:induction}` attribute controls the application of proof by induction to two contexts. Given a list of variables on which induction might be applied, the @@ -336,7 +352,7 @@ lemma Correspondence() } ``` -### 11.2.10. `{:only}` {#sec-only-functions-methods} +### 11.2.11. `{:only}` {#sec-only-functions-methods} `method {:only} X() {}` or `function {:only} X() {}` temporarily disables the verification of all other non-`{:only}` members, e.g. other functions and methods, in the same file, even if they contain [assertions with `{:only}`](#sec-only). @@ -361,7 +377,9 @@ method TestUnverified() { `{:only}` can help focusing on a particular member, for example a lemma or a function, as it simply disables the verification of all other lemmas, methods and functions in the same file. It's equivalent to adding [`{:verify false}`](#sec-verify) to all other declarations simulatenously on the same file. Since it's meant to be a temporary construct, it always emits a warning. -### 11.2.11. `{:print}` {#sec-print} +More information about the Boogie implementation of `{:opaque}` is [here](https://github.com/dafny-lang/dafny/blob/master/docs/Compilation/Boogie.md). + +### 11.2.12. `{:print}` {#sec-print} This attribute declares that a method may have print effects, that is, it may use `print` statements and may call other methods that have print effects. The attribute can be applied to compiled @@ -371,11 +389,11 @@ allowed to use a `{:print}` attribute only if the overridden method does. Print effects are enforced only with `--track-print-effects`. -### 11.2.12. `{:priority}` +### 11.2.13. `{:priority}` `{:priority N}` assigns a positive priority 'N' to a method or function to control the order in which methods or functions are verified (default: N = 1). -### 11.2.13. `{:rlimit}` {#sec-rlimit} +### 11.2.14. `{:rlimit}` {#sec-rlimit} `{:rlimit N}` limits the verifier resource usage to verify the method or function at `N * 1000`. This is the per-method equivalent of the command-line flag `/rlimit:N`. @@ -421,15 +439,15 @@ To give orders of magnitude about resource usage, here is a list of examples ind Note that, the default solver Z3 tends to overshoot by `7K` to `8K`, so if you put `{:rlimit 20}` in the last example, the total resource usage would be `27K`. -### 11.2.14. `{:selective_checking}` +### 11.2.15. `{:selective_checking}` Turn all assertions into assumptions except for the ones reachable from after the assertions marked with the attribute `{:start_checking_here}`. Thus, `assume {:start_checking_here} something;` becomes an inverse of `assume false;`: the first one disables all verification before it, and the second one disables all verification after. -### 11.2.15. `{:tailrecursion}` -This attribute is used on method declarations. It has a boolean argument. +### 11.2.16. `{:tailrecursion}` +This attribute is used on method or function declarations. It has a boolean argument. If specified with a `false` value, it means the user specifically requested no tail recursion, so none is done. @@ -444,7 +462,81 @@ recursion was explicitly requested. * If `{:tailrecursion true}` was specified but the code does not allow it, an error message is given. -### 11.2.16. `{:test}` {#sec-test-attribute} +If you have a stack overflow, it might be that you have +a function on which automatic attempts of tail recursion +failed, but for which efficient iteration can be implemented by hand. To do this, +use a [function by method](#sec-function-by-method) and +define the loop in the method yourself, +proving that it implements the function. + +Using a function by method to implement recursion can +be tricky. It usually helps to look at the result of the function +on two to three iterations, without simplification, +and see what should be the first computation. For example, +consider the following tail-recursion implementation: + + +```dafny +datatype Result = Success(value: V) | Failure(error: E) + +function f(x: int): Result + +// {:tailrecursion true} Not possible here +function MakeTailRec( + obj: seq +): Result, string> +{ + if |obj| == 0 then Success([]) + else + var tail := MakeTailRec(obj[1..]); + var r := f(obj[0]); + if r.Failure? then + Failure(r.error) + else if tail.Failure? then + tail + else + Success([r.value] + tail.value) +} by method { + var i: nat := |obj|; + var tail := Success([]); // Base case + while i != 0 + decreases i + invariant tail == MakeTailRec(obj[i..]) + { + i := i - 1; + var r := f(obj[i]); + if r.Failure? { + tail := Failure(r.error); + } else if tail.Success? { + tail := Success([r.value] + tail.value); + } else { + } + } + return tail; +} +``` + +The rule of thumb to unroll a recursive call into a sequential one +is to look at how the result would be computed if the operations were not +simplified. For example, unrolling the function on `[1, 2, 3]` yields the result +`Success([f(1).value] + ([f(2).value] + ([f(3).value] + [])))`. +If you had to compute this expression manually, you'd start with +`([f(3).value] + [])`, then add `[f(2).value]` to the left, then +`[f(1).value]`. +This is why the method loop iterates with the objects +from the end, and why the intermediate invariants are +all about proving `tail == MakeTailRec(obj[i..])`, which +makes verification succeed easily because we replicate +exactly the behavior of `MakeTailRec`. +If we were not interested in the first error but the last one, +a possible optimization would be, on the first error, to finish +iterate with a ghost loop that is not executed. + +Note that the function definition can be changed by computing +the tail closer to where it's used or switching the order of computing +`r` and `tail`, but the `by method` body can stay the same. + +### 11.2.17. `{:test}` {#sec-test-attribute} This attribute indicates the target function or method is meant to be executed at runtime in order to test that the program is working as intended. @@ -482,10 +574,10 @@ harness that supplies input arguments but has no inputs of its own and that checks any output values, perhaps with `expect` statements. The test harness is then the method marked with `{:test}`. -### 11.2.17. `{:timeLimit N}` {#sec-time-limit} +### 11.2.18. `{:timeLimit N}` {#sec-time-limit} Set the time limit for verifying a given function or method. -### 11.2.18. `{:timeLimitMultiplier X}` +### 11.2.19. `{:timeLimitMultiplier X}` This attribute may be placed on a method or function declaration and has an integer argument. If `{:timeLimitMultiplier X}` was specified a `{:timeLimit Y}` attribute is passed on to Boogie @@ -493,11 +585,11 @@ where `Y` is `X` times either the default verification time limit for a function or method, or times the value specified by the Boogie `-timeLimit` command-line option. -### 11.2.19. `{:transparent}` {#sec-transparent} +### 11.2.20. `{:transparent}` {#sec-transparent} By default, the body of a function is transparent to its users. This can be overridden using the `--default-function-opacity` command line flag. If default function opacity is set to `opaque` or `autoRevealDependencies`, then this attribute can be used on functions to make them always non-opaque. -### 11.2.20. `{:verify false}` {#sec-verify} +### 11.2.21. `{:verify false}` {#sec-verify} Skip verification of a function or a method altogether, not even trying to verify the [well-formedness](#sec-assertion-batches) of postconditions and preconditions. @@ -506,7 +598,7 @@ which performs these minimal checks while not checking that the body satisfies t If you simply want to temporarily disable all verification except on a single function or method, use the [`{:only}`](#sec-only-functions-methods) attribute on that function or method. -### 11.2.21. `{:vcs_max_cost N}` {#sec-vcs_max_cost} +### 11.2.22. `{:vcs_max_cost N}` {#sec-vcs_max_cost} Per-method version of the command-line option `/vcsMaxCost`. The [assertion batch](#sec-assertion-batches) of a method @@ -515,7 +607,7 @@ number, defaults to 2000.0. In [keep-going mode](#sec-vcs_max_keep_going_splits), only applies to the first round. If [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) is set, then this parameter is useless. -### 11.2.22. `{:vcs_max_keep_going_splits N}` {#sec-vcs_max_keep_going_splits} +### 11.2.23. `{:vcs_max_keep_going_splits N}` {#sec-vcs_max_keep_going_splits} Per-method version of the command-line option `/vcsMaxKeepGoingSplits`. If set to more than 1, activates the _keep going mode_ where, after the first round of splitting, @@ -526,7 +618,7 @@ case an error is reported for that assertion). Defaults to 1. If [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) is set, then this parameter is useless. -### 11.2.23. `{:vcs_max_splits N}` {#sec-vcs_max_splits} +### 11.2.24. `{:vcs_max_splits N}` {#sec-vcs_max_splits} Per-method version of the command-line option `/vcsMaxSplits`. Maximal number of [assertion batches](#sec-assertion-batches) generated for this method. @@ -534,14 +626,14 @@ In [keep-going mode](#sec-vcs_max_keep_going_splits), only applies to the first Defaults to 1. If [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) is set, then this parameter is useless. -### 11.2.24. `{:vcs_split_on_every_assert}` {#sec-vcs_split_on_every_assert} +### 11.2.25. `{:vcs_split_on_every_assert}` {#sec-vcs_split_on_every_assert} Per-method version of the command-line option `/vcsSplitOnEveryAssert`. In the first and only verification round, this option will split the original [assertion batch](#sec-assertion-batches) into one assertion batch per assertion. This is mostly helpful for debugging which assertion is taking the most time to prove, e.g. to profile them. -### 11.2.25. `{:synthesize}` {#sec-synthesize-attr} +### 11.2.26. `{:synthesize}` {#sec-synthesize-attr} The `{:synthesize}` attribute must be used on methods that have no body and return one or more fresh objects. During compilation, @@ -575,7 +667,7 @@ BOUNDVARS = ID : ID | BOUNDVARS, BOUNDVARS ``` -### 11.2.26. `{:options OPT0, OPT1, ... }` {#sec-attr-options} +### 11.2.27. `{:options OPT0, OPT1, ... }` {#sec-attr-options} This attribute applies only to modules. It configures Dafny as if `OPT0`, `OPT1`, … had been passed on the command line. Outside of the module, @@ -584,9 +676,22 @@ options revert to their previous values. Only a small subset of Dafny's command line options is supported. Use the `/attrHelp` flag to see which ones. -## 11.3. Attributes on assertions, preconditions and postconditions {#sec-verification-attributes-on-assertions} +## 11.3. Attributes on reads and modifies clauses + +### 11.3.1. `{:assume_concurrent}` +This attribute is used to allow non-empty `reads` or `modifies` clauses on methods +with the `{:concurrent}` attribute, which would otherwise reject them. + +In some cases it is possible to know that Dafny code that reads or writes shared mutable state +is in fact safe to use in a concurrent setting, especially when that state is exclusively ghost. +Since the semantics of `{:concurrent}` aren't directly expressible in Dafny syntax, +it isn't possible to express this assumption with an `assume {:axiom} ...` statement. + +See also the [`{:concurrent}`](#sec-concurrent-attribute) attribute. + +## 11.4. Attributes on assertions, preconditions and postconditions {#sec-verification-attributes-on-assertions} -### 11.3.1. `{:only}` {#sec-only} +### 11.4.1. `{:only}` {#sec-only} `assert {:only} X;` temporarily transforms all other non-`{:only}` assertions in the surrounding declaration into assumptions. @@ -623,7 +728,7 @@ As soon as a declaration contains one `assert {:only}`, none of the postconditio You can also isolate the verification of a single member using [a similar `{:only}` attribute](#sec-only-functions-methods). -### 11.3.2. `{:focus}` {#sec-focus} +### 11.4.2. `{:focus}` {#sec-focus} `assert {:focus} X;` splits verification into two [assertion batches](#sec-assertion-batches). The first batch considers all assertions that are not on the block containing the `assert {:focus} X;` The second batch considers all assertions that are on the block containing the `assert {:focus} X;` and those that will _always_ follow afterwards. @@ -680,7 +785,7 @@ method doFocus2(x: bool) returns (y: int) { } ``` -### 11.3.3. `{:split_here}` {#sec-split_here} +### 11.4.3. `{:split_here}` {#sec-split_here} `assert {:split_here} X;` splits verification into two [assertion batches](#sec-assertion-batches). It verifies the code leading to this point (excluded) in a first assertion batch, and the code leading from this point (included) to the next `{:split_here}` or until the end in a second assertion batch. @@ -709,12 +814,12 @@ method doSplitHere(x: bool) returns (y: int) { } ``` -### 11.3.4. `{:subsumption n}` +### 11.4.4. `{:subsumption n}` Overrides the `/subsumption` command-line setting for this assertion. `{:subsumption 0}` checks an assertion but does not assume it after proving it. You can achieve the same effect using [labelled assertions](#sec-labeling-revealing-assertions). -### 11.3.5. `{:error "errorMessage", "successMessage"}` {#sec-error-attribute} +### 11.4.5. `{:error "errorMessage", "successMessage"}` {#sec-error-attribute} Provides a custom error message in case the assertion fails. As a hint, messages indicating what the user needs to do to fix the error are usually better than messages that indicate the error only. For example: @@ -743,9 +848,9 @@ method Test() The success message is optional but is recommended if errorMessage is set. -## 11.4. Attributes on variable declarations +## 11.5. Attributes on variable declarations -### 11.4.1. `{:assumption}` {#sec-assumption} +### 11.5.1. `{:assumption}` {#sec-assumption} This attribute can only be placed on a local ghost bool variable of a method. Its declaration cannot have a rhs, but it is allowed to participate as the lhs of exactly one assignment of the @@ -754,16 +859,16 @@ Boogie output to a declaration followed by an `assume b` command. See [@LeinoWuestholz2015], Section 3, for example uses of the `{:assumption}` attribute in Boogie. -## 11.5. Attributes on quantifier expressions (forall, exists) +## 11.6. Attributes on quantifier expressions (forall, exists) -### 11.5.1. `{:heapQuantifier}` +### 11.6.1. `{:heapQuantifier}` _This attribute has been removed._ -### 11.5.2. `{:induction}` {#sec-induction-quantifier} +### 11.6.2. `{:induction}` {#sec-induction-quantifier} See [`{:induction}`](#sec-induction) for functions and methods. -### 11.5.3. `{:trigger}` {#sec-trigger} +### 11.6.3. `{:trigger}` {#sec-trigger} Trigger attributes are used on quantifiers and comprehensions. The verifier instantiates the body of a quantified expression only when it can find an expression that matches the provided trigger. @@ -809,7 +914,7 @@ Here are ways one can prove `assert P(j + 4);`: * Remove `{:trigger Q(i)}` so that it will automatically determine all possible triggers thanks to the option `/autoTriggers:1` which is the default. -## 11.6. Deprecated attributes +## 11.7. Deprecated attributes These attributes have been deprecated or removed. They are no longer useful (or perhaps never were) or were experimental. They will likely be removed entirely sometime soon after the release of Dafny 4. @@ -822,7 +927,7 @@ Removed: Deprecated: - :opaque : This attribute has been promoted to a first-class modifier for functions. Find more information [here](#sec-opaque). -## 11.7. Other undocumented verification attributes +## 11.8. Other undocumented verification attributes A scan of Dafny's sources shows it checks for the following attributes. diff --git a/latest/DafnyRef/Expressions.md b/latest/DafnyRef/Expressions.md index 35827e5..b4a346a 100644 --- a/latest/DafnyRef/Expressions.md +++ b/latest/DafnyRef/Expressions.md @@ -900,7 +900,6 @@ Examples: ```dafny allocated(c) allocated({c1,c2}) -allocated@L(c) ``` For any expression `e`, the expression `allocated(e)` evaluates to `true` diff --git a/latest/DafnyRef/Features.md b/latest/DafnyRef/Features.md index d2c5470..c09e18d 100644 --- a/latest/DafnyRef/Features.md +++ b/latest/DafnyRef/Features.md @@ -37,11 +37,15 @@ | [Externally-implemented constructors](#sec-extern-decls) | X | | | X | X | X | X | | [Auto-initialization of tuple variables](#sec-tuple-types) | X | X | X | X | X | X | X | | [Subtype constraints in quantifiers](#sec-quantifier-expression) | X | X | X | X | X | X | X | -| [Tuples with more than 20 arguments](#sec-tuple-types) | | X | X | | X | X | X | +| [Tuples with more than 20 arguments](##sec-compilation-built-ins) | | X | X | | X | X | X | +| [Arrays with more than 16 dimensions](##sec-compilation-built-ins) | | X | X | | X | X | X | +| [Arrow types with more than 16 arguments](##sec-compilation-built-ins) | | X | X | | X | X | X | | [Unicode chars](##sec-characters) | X | X | X | X | X | | X | | [Converting values to strings](#sec-print-statement) | X | X | X | X | X | | X | | [Legacy CLI without commands](#sec-dafny-commands) | X | X | X | X | X | X | | | [Separate compilation](#sec-compilation) | X | | X | X | X | X | X | +| [All built-in types in runtime library](#sec-compilation-built-ins) | X | X | X | X | X | | X | +| [Execution coverage report](#sec-dafny-test) | X | | | | | | | [^compiler-feature-forall-note]: 'Sequentializing' a `forall` statement refers to compiling it directly to a series of nested loops with the statement's body directly inside. The alternative, default compilation strategy diff --git a/latest/DafnyRef/Grammar.md b/latest/DafnyRef/Grammar.md index 826110a..a7b7662 100644 --- a/latest/DafnyRef/Grammar.md +++ b/latest/DafnyRef/Grammar.md @@ -515,7 +515,7 @@ For example, in the quantifier domain `i | 0 <= i < |s|, y <- s[i] | i < y`, the because the range attached to `i` ensures `i` is a valid index in the sequence `s`. Allowing per-variable ranges is not fully backwards compatible, and so it is not yet allowed by default; -the `--quantifier-syntax:4` option needs to be provided to enable this feature (See [Section 13.8.5](#sec-controlling-language)). +the `--quantifier-syntax:4` option needs to be provided to enable this feature (See [Section 13.9.5](#sec-controlling-language)). ### 2.7.5. Numeric Literals ([grammar](#g-literal-expression)) {#sec-numeric-literals} diff --git a/latest/DafnyRef/GrammarDetails.md b/latest/DafnyRef/GrammarDetails.md index 6a7b1d9..52f5182 100644 --- a/latest/DafnyRef/GrammarDetails.md +++ b/latest/DafnyRef/GrammarDetails.md @@ -782,8 +782,7 @@ InvariantClause_ = ````grammar ReadsClause(allowLemma, allowLambda, allowWild) = - "reads" - { Attribute } + "reads" { Attribute } PossiblyWildFrameExpression(allowLemma, allowLambda, allowWild) { "," PossiblyWildFrameExpression(allowLemma, allowLambda, allowWild) } ```` diff --git a/latest/DafnyRef/Options.txt b/latest/DafnyRef/Options.txt index 5405c72..195121f 100644 --- a/latest/DafnyRef/Options.txt +++ b/latest/DafnyRef/Options.txt @@ -106,13 +106,24 @@ Usage: dafny [ option ... ] [ filename ... ] `opaque` means functions are always opaque so the opaque keyword is not needed, and functions must be revealed everywhere needed for a proof. /generalTraits: - 0 (default) - Every trait implicitly extends 'object', and thus is a reference type. Only traits and classes can extend traits. - 1 - A trait is a reference type iff it or one of its ancestor traits is 'object'. Any type with members can extend traits. + legacy (default) - Every trait implicitly extends 'object', and thus is a reference type. Only traits and reference types can extend traits. + datatype - A trait is a reference type only if it or one of its ancestor traits is 'object'. Any non-'newtype' type with members can extend traits. + full - (don't use; not yet completely supported) A trait is a reference type only if it or one of its ancestor traits is 'object'. Any type with members can extend traits. /ntitrace: 0 (default) - Don't print debug information for the new type system. 1 - Print debug information for the new type system. + /readsClausesOnMethods: + 0 (default) - Reads clauses on methods are forbidden. + 1 - Reads clauses on methods are permitted (with a default of 'reads *'). + + /standardLibraries: + 0 (default) - Do not allow Dafny code to depend on the standard libraries included with the Dafny distribution. + 1 - Allow Dafny code to depend on the standard libraries included with the Dafny distribution. + See https://github.com/dafny-lang/dafny/blob/master/Source/DafnyStandardLibraries/README.md for more information. + Not compatible with the /unicodeChar:0 option. + /titrace: 0 (default) - Don't print type-inference debug information. 1 - Print type-inference debug information. @@ -485,6 +496,7 @@ Usage: dafny [ option ... ] [ filename ... ] /printWithUniqueIds : print augmented information that uniquely identifies variables /printUnstructured : with /print option, desugars all structured statements + /printPassive : with /print option, prints passive version of program /printDesugared : with /print option, desugars calls /printLambdaLifting : with /print option, desugars lambda lifting @@ -501,6 +513,8 @@ Usage: dafny [ option ... ] [ filename ... ] unroll loops, following up to n back edges (and then some) /soundLoopUnrolling sound loop unrolling + /doModSetAnalysis + automatically infer modifies clauses /printModel: 0 (default) - do not print Z3's error model 1 - print Z3's error model @@ -642,8 +656,6 @@ Usage: dafny [ option ... ] [ filename ... ] /smokeTimeout: Timeout, in seconds, for a single theorem prover invocation during smoke test, defaults to 10. - /causalImplies - Translate Boogie's A ==> B into prover's A ==> A && B. /typeEncoding: Encoding of types when generating VC of a polymorphic program: m = monomorphic (default) @@ -663,6 +675,10 @@ Usage: dafny [ option ... ] [ filename ... ] Without pruning, due to the unstable nature of SMT solvers, a change to any part of a Boogie program has the potential to affect the verification of any other part of the program. + + Only use this if your program contains uses clauses + where required, otherwise pruning will break your program. + More information can be found here: https://github.com/boogie-org/boogie/blob/afe8eb0ffbb48d593de1ae3bf89712246444daa8/Source/ExecutionEngine/CommandLineOptions.cs#L160 /printPruned: After pruning, print the Boogie program to the specified file. /relaxFocus Process foci in a bottom-up fashion. This way only generates @@ -684,6 +700,13 @@ Usage: dafny [ option ... ] [ filename ... ] This option is implemented by renaming variables and reordering declarations in the input, and by setting solver options that have similar effects. + /trackVerificationCoverage + Track and report which program elements labeled with an + `{:id ...}` attribute were necessary to complete verification. + Assumptions, assertions, requires clauses, ensures clauses, + assignments, and calls can be labeled for inclusion in this + report. This generalizes and replaces the previous + (undocumented) `/printNecessaryAssertions` option. ---- Verification-condition splitting -------------------------------------- @@ -752,7 +775,7 @@ Usage: dafny [ option ... ] [ filename ... ] Limit the number of seconds spent trying to verify each procedure /rlimit: - Limit the Z3 resource spent trying to verify each procedure + Limit the Z3 resource spent trying to verify each procedure. /errorTrace: 0 - no Trace labels in the error output, 1 (default) - include useful Trace labels in error output, diff --git a/latest/DafnyRef/Specifications.md b/latest/DafnyRef/Specifications.md index 4b53caa..d068b05 100644 --- a/latest/DafnyRef/Specifications.md +++ b/latest/DafnyRef/Specifications.md @@ -58,7 +58,7 @@ of all the given Attributes. The order of conjunctions can be important: earlier conjuncts can set conditions that establish that later conjuncts are well-defined. -The attributes recognized for requires clauses are discussed in [Section 11.3](#sec-verification-attributes-on-assertions). +The attributes recognized for requires clauses are discussed in [Section 11.4](#sec-verification-attributes-on-assertions). A requires clause can have [custom error and success messages](#sec-error-attribute). @@ -86,7 +86,7 @@ The order of conjunctions can be important: earlier conjuncts can set conditions that establish that later conjuncts are well-defined. -The attributes recognized for ensures clauses are discussed in [Section 11.3](#sec-verification-attributes-on-assertions). +The attributes recognized for ensures clauses are discussed in [Section 11.4](#sec-verification-attributes-on-assertions). An ensures clause can have [custom error and success messages](#sec-error-attribute). @@ -464,6 +464,12 @@ function g() reads o, oo function h() reads { o } +method f() + reads * +method g() + reads o, oo +method h() + reads { o } ``` Functions are not allowed to have side effects; they may also be restricted in @@ -479,11 +485,24 @@ able to give invariants to preserve it in this case, it gets even more complex when manipulating data structures. In this case, framing is essential to making the verification process feasible. -It is not just the body of a function that is subject to `reads` +By default, methods are not required to list the memory location they read. +However, there are use cases for restricting what methods can read as well. +In particular, if you want to verify that imperative code is safe to execute concurrently when compiled, +you can specify that a method does not read or write any shared state, +and therefore cannot encounter race conditions or runtime crashes related to +unsafe communication between concurrent executions. +See [the `{:concurrent}` attribute](#sec-concurrent-attribute) for more details. + +It is not just the body of a function or method that is subject to `reads` checks, but also its precondition and the `reads` clause itself. A `reads` clause can list a wildcard `*`, which allows the enclosing -function to read anything. In many cases, and in particular in all cases +function or method to read anything. +This is the implicit default for methods with no `reads` clauses, +allowing methods to read whatever they like. +The default for functions, however, is to not allow reading any memory. +Allowing functions to read arbitrary memory is more problematic: +in many cases, and in particular in all cases where the function is defined recursively, this makes it next to impossible to make any use of the function. Nevertheless, as an experimental feature, the language allows it (and it is sound). @@ -491,7 +510,7 @@ If a `reads` clause uses `*`, then the `reads` clause is not allowed to mention anything else (since anything else would be irrelevant, anyhow). A `reads` clause specifies the set of memory locations that a function, -lambda, or iterator may read. The readable memory locations are all the fields +lambda, or method may read. The readable memory locations are all the fields of all of the references given in the set specified in the frame expression and the single fields given in [`FrameField`](#sec-frame-expression) elements of the frame expression. For example, in @@ -546,7 +565,7 @@ another function. For example, function `Sum` adds up the values of ```dafny function Sum(f: int ~> real, lo: int, hi: int): real requires lo <= hi - requires forall i :: lo <= i < hi ==> f.requires(i) + requires forall i :: f.requires(i) reads f.reads decreases hi - lo { @@ -562,9 +581,29 @@ read. More precise would be to specify that `Sum` reads only what `f` reads on the values from `lo` to `hi`, but the larger set denoted by `reads f.reads` is easier to write down and is often good enough.) +Without such `reads` function, one could also write the more precise +and more verbose: + +```dafny +function Sum(f: int ~> real, lo: int, hi: int): real + requires lo <= hi + requires forall i :: lo <= i < hi ==> f.requires(i) + reads set i, o | lo <= i < hi && o in f.reads(i) :: o + decreases hi - lo +{ + if lo == hi then 0.0 else + f(lo) + Sum(f, lo + 1, hi) +} +``` + Note, only `reads` clauses, not `modifies` clauses, are allowed to include functions as just described. +Iterator specifications also allow `reads` clauses, +with the same syntax and interpretation of arguments as above, +but the meaning is quite different! +See [Section 5.11](#sec-iterator-types) for more details. + ### 7.1.6. Modifies Clause ([grammar](#g-modifies-clause)) {#sec-modifies-clause} Examples: @@ -581,12 +620,11 @@ method Q() modifies o, p`f ``` -Frames also affect methods. Methods are not -required to list the things they read. Methods are allowed to read +By default, methods are allowed to read whatever memory they like, but they are required to list which parts of memory they modify, with a `modifies` annotation. These are almost identical to their `reads` cousins, except they say what can be changed, rather than -what the value of the function depends on. In combination with reads, +what the definition depends on. In combination with reads, modification restrictions allow Dafny to prove properties of code that would otherwise be very difficult or impossible. Reads and modifies are one of the tools that allow Dafny to work on one method at a time, @@ -684,10 +722,12 @@ class C { } ``` -A method specification consists of zero or more `modifies`, `requires`, +A method specification consists of zero or more `reads`, `modifies`, `requires`, `ensures` or `decreases` clauses, in any order. -A method does not have `reads` clauses because methods are allowed to -read any memory. +A method does not need `reads` clauses in most cases, +because methods are allowed to read any memory by default, +but `reads` clauses are supported for use cases such as verifying safe concurrent execution. +See [the `{:concurrent}` attribute](#sec-concurrent-attribute) for more details. ## 7.3. Function Specification ([grammar](#g-function-specification)) {#sec-function-specification} @@ -735,7 +775,7 @@ and `yield ensures` clauses. An iterator specification applies both to the iterator's constructor method and to its `MoveNext` method. - The `reads` and `modifies` -clauses apply to both of them. +clauses apply to both of them (but `reads` clauses have a [different meaning on iterators](#sec-iterator-types) than on functions or methods). - The `requires` and `ensures` clauses apply to the constructor. - The `yield requires` and `yield ensures` clauses apply to the `MoveNext` method. @@ -746,6 +786,8 @@ Examples of iterators, including iterator specifications, are given in - a decreases clause is used to show that the iterator will eventually terminate - a yield requires clause is a precondition for calling `MoveNext` - a yield ensures clause is a postcondition for calling `MoveNext` +- a reads clause gives a set of memory locations that will be unchanged after a `yield` statement +- a modifies clause gives a set of memory locations the iterator may write to ## 7.6. Loop Specification ([grammar](#g-loop-specification)) {#sec-loop-specification} diff --git a/latest/DafnyRef/Statements.md b/latest/DafnyRef/Statements.md index 667c023..70c1a77 100644 --- a/latest/DafnyRef/Statements.md +++ b/latest/DafnyRef/Statements.md @@ -1854,7 +1854,7 @@ Examples of this form of assert are given in the section of the [`reveal`](#sec- An assert statement may have a label, whose use is explained in [Section 8.20.1](#sec-reveal-assertions). -The attributes recognized for assert statements are discussed in [Section 11.3](#sec-verification-attributes-on-assertions). +The attributes recognized for assert statements are discussed in [Section 11.4](#sec-verification-attributes-on-assertions). Using `...` as the argument of the statement is deprecated. diff --git a/latest/DafnyRef/Types.md b/latest/DafnyRef/Types.md index 0d170b3..27c90a9 100644 --- a/latest/DafnyRef/Types.md +++ b/latest/DafnyRef/Types.md @@ -1262,7 +1262,8 @@ the domain, the range, and the 2-tuples holding the key-value associations in the map. Note that `m.Values` will have a different cardinality than `m.Keys` and `m.Items` if different keys are associated with the same value. If `m` is an `imap`, then these -expressions return `iset` values. +expressions return `iset` values. If `m` is a map, `m.Values` and `m.Items` +require the type of the range `U` to support equality. [^fn-map-membership]: This is likely to change in the future as follows: The `in` and `!in` operations will no longer be @@ -1684,13 +1685,14 @@ and the subset type `(TT) --> U` is called the _partial arrow type_. think of the little gap between the two hyphens in `-->` as showing a broken arrow.) -The built-in partial arrow type is defined as follows (here shown +Intuitively, the built-in partial arrow type is defined as follows (here shown for arrows with arity 1): ```dafny type A --> B = f: A ~> B | forall a :: f.reads(a) == {} ``` -(except that what is shown here left of the `=` is not legal Dafny syntax). +(except that what is shown here left of the `=` is not legal Dafny syntax +and that the restriction could not be verified as is). That is, the partial arrow type is defined as those functions `f` whose reads frame is empty for all inputs. More precisely, taking variance into account, the partial arrow type @@ -2669,6 +2671,16 @@ Note, in the precondition of the iterator, which is to hold upon construction of the iterator, the in-parameters are indeed in-parameters, not fields of `this`. +`reads` clauses on iterators have a different meaning than they do on functions and methods. +Iterators may read any memory they like, but because arbitrary code may be executed +whenever they `yield` control, they need to declare what memory locations must not be modified +by other code in order to maintain correctness. +The contents of an iterator's `reads` clauses become part of the `reads` clause +of the implicitly created `Valid()` predicate. +This means if client code modifies any of this state, +it will not be able to establish the precondition for the iterator's `MoveNext()` method, +and hence the iterator body will never resume if this state is modified. + It is regrettably tricky to use iterators. The language really ought to have a `foreach` statement to make this easier. Here is an example showing a definition and use of an iterator. @@ -2856,21 +2868,48 @@ body. For a function `f: T ~> U`, the value that the function yields for an input `t` of type `T` is denoted `f(t)` and has type `U`. Note that `f.reads` and `f.requires` are themselves functions. -Suppose `f` has type `T ~> U` and `t` has type `T`. Then, `f.reads` -is a function of type `T ~> set` whose `reads` and `requires` -properties are: +Without loss of generality, suppose `f` is defined as: + +```dafny +function f(x: T): U + reads R(x) + requires P(x) +{ + body(x) +} +``` +where `P`, `R`, and `body` are declared as: + +```dafny +predicate P(x: T) +function R(x: T): set +function body(x: T): U +``` +Then, `f.reads` is a function of type `T ~> set` +whose `reads` and `requires` properties are given by the definition: ```dafny -f.reads.reads(t) == f.reads(t) -f.reads.requires(t) == true +function f.reads(x: T): set + reads R(x) + requires P(x) +{ + R(x) +} ``` `f.requires` is a function of type `T ~> bool` whose `reads` and -`requires` properties are: +`requires` properties are given by the definition: ```dafny -f.requires.reads(t) == f.reads(t) -f.requires.requires(t) == true +predicate f_requires(x: T) + requires true + reads if P(x) then R(x) else * +{ + P(x) +} ``` +where `*` is a notation to indicate that any memory location can +be read, but is not valid Dafny syntax. + In these examples, if `f` instead had type `T --> U` or `T -> U`, then the type of `f.reads` is `T -> set` and the type of `f.requires` is `T -> bool`. diff --git a/latest/DafnyRef/UserGuide.md b/latest/DafnyRef/UserGuide.md index dc2d895..ef90686 100644 --- a/latest/DafnyRef/UserGuide.md +++ b/latest/DafnyRef/UserGuide.md @@ -91,7 +91,7 @@ includes or on the command-line.[^fn-duplicate-files] All files recursively included are always parsed and type-checked. However, which files are verified, built, run, or processed by other dafny commands depends on the individual command. -These commands are described in [Section 13.5.1](#sec-dafny-commands). +These commands are described in [Section 13.6.1](#sec-dafny-commands). [^fn-duplicate-files]: Files may be included more than once or both included and listed on the command line. Duplicate inclusions are detected and each file processed only once. For the purpose of detecting duplicates, file names are considered equal if they have the same absolute path, compared as case-sensitive strings (regardless of whether the underlying file-system is case sensitive). Using symbolic links may make the same file have a different absolute path; this will generally cause duplicate declaration errors. @@ -131,15 +131,21 @@ The exact file format is internal and may evolve over time to support additional Note that the library backend only supports the [newer command-style CLI interface](#sec-dafny-commands). -## 13.4. Dafny Code Style +## 13.4. Dafny Standard Libraries + +As of Dafny 4.4, the `dafny` tool includes standard libraries that any Dafny code base can depend on. +For now they are only available when the `--standard-libraries` option is provided, +but they will likely be available by default in the next major version of Dafny. + +See https://github.com/dafny-lang/dafny/blob/master/Source/DafnyStandardLibraries/README.md for details. + +## 13.5. Dafny Code Style There are coding style conventions for Dafny code, recorded [here](https://dafny-lang.github.io/dafny/StyleGuide/Style-Guide). Most significantly, code is written without tabs and with a 2 space indentation. Following code style conventions improves readability but does not alter program semantics. - - -## 13.5. Using Dafny From the Command Line {#command-line} +## 13.6. Using Dafny From the Command Line {#command-line} `dafny` is a conventional command-line tool, operating just like other command-line tools in Windows and Unix-like systems. @@ -147,7 +153,7 @@ In general, the format of a command-line is determined by the shell program that (.e.g., bash, the windows shell, COMMAND, etc.), but is expected to be a series of space-separated "words", each representing a command, option, option argument, file, or folder. -### 13.5.1. dafny commands {#sec-dafny-commands} +### 13.6.1. dafny commands {#sec-dafny-commands} As of v3.9.0, `dafny` uses a command-style command-line (like `git` for example); prior to v3.9.0, the command line consisted only of options and files. @@ -191,7 +197,7 @@ it can be explicitly set false (do verification) using `--no-verify:false` or `- - There is a potential ambiguity when the form `--option value` is used if the value is optional (such as for boolean values). In such a case an argument afer an option (that does not have an argument given with `:` or `=`) is interpreted as the value if it is indeed a valid value for that option. However, better style advises always using a ':' or '=' to set option values. No valid option values in dafny look like filenames or begin with `--`. -#### 13.5.1.1. Options that are not associated with a command +#### 13.6.1.1. Options that are not associated with a command A few options are not part of a command. In these cases any single-hyphen spelling also permits a spelling beginning with '/'. - `dafny --help` or `dafny -h` lists all the available commands @@ -199,7 +205,7 @@ A few options are not part of a command. In these cases any single-hyphen spelli - `dafny --version` (or `-version`) prints out the number of the version this build of dafny implements -#### 13.5.1.2. `dafny resolve` {#sec-dafny-resolve} +#### 13.6.1.2. `dafny resolve` {#sec-dafny-resolve} The `dafny resolve` command checks the command-line and then parses and typechecks the given files and any included files. @@ -244,7 +250,7 @@ The options relevant to this command are - `--warn-missing-constructor-parentheses` -#### 13.5.1.3. `dafny verify` {#sec-dafny-verify} +#### 13.6.1.3. `dafny verify` {#sec-dafny-verify} The `dafny verify` command performs the [`dafny resolve`](#sec-dafny-resolve) checks and then attempts to verify each declaration in the program. @@ -283,7 +289,7 @@ Various options control the verification process, in addition to all those descr - `--solver-path` -#### 13.5.1.4. `dafny translate ` {#sec-dafny-translate} +#### 13.6.1.4. `dafny translate ` {#sec-dafny-translate} The `dafny translate` command translates Dafny source code to source code for another target programming language. The command always performs the actions of `dafny resolve` and, unless the `--no-verify` option is specified, does the actions of `dafny verify`. @@ -318,7 +324,7 @@ Various options control the translation process, in addition to all those descri - `--enforce-determinism` - `--test-assumptions` --- (experimental) inserts runtime checks for unverified assumptions when they are compilable -#### 13.5.1.5. `dafny build` {#sec-dafny-build} +#### 13.6.1.5. `dafny build` {#sec-dafny-build} The `dafny build` command runs `dafny translate` and then compiles the result into an executable artifact for the target platform, such as a `.exe` or `.dll` or executable `.jar`, or just the source code for an interpreted language. @@ -335,7 +341,7 @@ Note that `dafny build` may do optimizations that `dafny run` does not. Details for specific target platforms are described [in Section 25.7](#sec-compilation). -#### 13.5.1.6. `dafny run` {#sec-dafny-run} +#### 13.6.1.6. `dafny run` {#sec-dafny-run} The `dafny run` command compiles the Dafny program and then runs the resulting executable. Note that `dafny run` is engineered to quickly compile and launch the program; @@ -368,14 +374,14 @@ then runs it with the three command-line arguments `1 2 3` - performance --- `dafny run` may not optimize as much as `dafny build` - target-language-specific configuration issues --- e.g. encoding issues: `dafny run` sets language-specific flags to request UTF-8 output for the [`print`](#print-encoding) statement in all languages, whereas `dafny build` leaves language-specific runtime configuration to the user. -#### 13.5.1.7. `dafny server` {#sec-dafny-server} +#### 13.6.1.7. `dafny server` {#sec-dafny-server} The `dafny server` command starts the Dafny Language Server, which is an [LSP-compliant](https://microsoft.github.io/language-server-protocol/) implementation of Dafny. The [Dafny VSCode extension]() uses this LSP implementation, which in turn uses the same core Dafny implementation as the command-line tool. The Dafny Language Server is described in more detail [here](#sec-dafny-language-server-vscode). -#### 13.5.1.8. `dafny audit` {#sec-dafny-audit} +#### 13.6.1.8. `dafny audit` {#sec-dafny-audit} The `dafny audit` command reports issues in the Dafny code that might limit the soundness claims of verification. @@ -420,11 +426,6 @@ Since Dafny cannot prove properties about code written in other languages, adding tests to provide evidence that any `ensures` clauses do hold can improve assurance. The same considerations apply to `requires` clauses on Dafny code intended to be called from external code. -* Any declaration marked with the `{:concurrent}` attribute. -This is intended to indicate that the code is safe for use in a concurrent setting, but Dafny currently cannot prove that form of safety. -The [addition of `reads` clauses to methods](https://github.com/dafny-lang/rfcs/pull/6) will be a step toward being able to prove safety in this case, -but until it exists, careful inspection and testing are appropriate. - * Any definition with an `assume` statement in its body. To improve assurance, attempt to convert it to an `assert` statement and prove that it holds. Such a definition will not be compilable unless the statement is also marked with `{:axiom}`. @@ -447,7 +448,7 @@ To improve assurance, provide a body that establishes any stated invariants. Any code that calls this declaration will assume that all `ensures` clauses are true after it returns. To improve assurance, provide a body that proves that any `ensures` clauses hold. -#### 13.5.1.9. `dafny format` {#sec-dafny-format} +#### 13.6.1.9. `dafny format` {#sec-dafny-format} Dafny supports a formatter, which for now only changes the indentation of lines in a Dafny file, so that it conforms to the idiomatic Dafny code formatting style. @@ -466,7 +467,7 @@ Each version of `dafny format` returns a non-zero return code if there are any c errors or if --check is stipulated and at least one file is not the same as its formatted version. `dafny format` does not necessarily report name or type resolution errors and does not attempt verification. -#### 13.5.1.10. `dafny test` {#sec-dafny-test} +#### 13.6.1.10. `dafny test` {#sec-dafny-test} This command (verifies and compiles the program and) runs every method in the program that is annotated with the [`{:test}` attribute](#sec-test-attribute). Verification can be disabled using the `--no-verify` option. `dafny test` also accepts all other options of the `dafny build` command. @@ -478,6 +479,8 @@ In particular, it accepts the `--target` option that specifies the programming l - `--output` - gives the folder and filename root for compilation artifacts - `--methods-to-test` - the value is a (.NET) regular expression that is matched against the fully qualified name of the method; only those methods that match are tested +- `--coverage-report` - the value is a directory in which Dafny will save an html coverage report highlighting parts of + the program that execution of the tests covered. The order in which the tests are run is not specified. @@ -529,7 +532,7 @@ Hi! PASSED ``` -#### 13.5.1.11. `dafny doc` [Experimental] {#sec-dafny-doc} +#### 13.6.1.11. `dafny doc` [Experimental] {#sec-dafny-doc} The `dafny doc` command generates HTML documentation pages describing the contents of each module in a set of files, using the documentation comments in the source files. @@ -561,7 +564,7 @@ The output files are HTML files, all contained in the given folder, one per modu an alphabetical by name list of all the declarations in all the modules. The documentation for the root module is in `_.html`. -#### 13.5.1.12. `dafny generate-tests` {#sec-dafny-generate-tests} +#### 13.6.1.12. `dafny generate-tests` {#sec-dafny-generate-tests} This _experimental_ command allows generating tests from Dafny programs. The tests provide complete coverage of the implementation and one can execute them using the [`dafny test`](#sec-dafny-test) command. @@ -607,7 +610,7 @@ etc.) must be a member of an explicitly named module, which is called `M` in the _This command is under development and not yet fully functional._ -#### 13.5.1.13. `Inlining` {#sec-dafny-generate-tests-inlining} +#### 13.6.1.13. `Inlining` {#sec-dafny-generate-tests-inlining} By default, when asked to generate tests, Dafny will produce _unit tests_, which guarantee coverage of basic blocks within the method they call but not within any of its callees. By contrast, system-level tests can @@ -683,7 +686,7 @@ module M { } ``` -#### 13.5.1.14. `Command Line Options` {#sec-dafny-generate-tests-clo} +#### 13.6.1.14. `Command Line Options` {#sec-dafny-generate-tests-clo} Test generation supports a number of command-line options that control its behavior. @@ -712,7 +715,7 @@ The following is a list of command-line-options supported by Dafny during test g Dafny will also automatically enforce the following options during test generation: `--enforce-determinism`, `/typeEncoding:p` (an option passed on to Boogie). -#### 13.5.1.15. `dafny find-dead-code` {#sec-dafny-find-dead-code} +#### 13.6.1.15. `dafny find-dead-code` {#sec-dafny-find-dead-code} This _experimental_ command finds dead code in a program, that is, basic-blocks within a method that are not reachable by any inputs that satisfy the method's preconditions. The underlying implementation is identical to that of @@ -751,13 +754,13 @@ reviewed. _This command is under development and not yet fully functional._ -#### 13.5.1.16. `dafny measure-complexity` {#sec-dafny-measure-complexity} +#### 13.6.1.16. `dafny measure-complexity` {#sec-dafny-measure-complexity} This _experimental_ command reports complexity metrics of a program. _This command is under development and not yet functional._ -#### 13.5.1.17. Plugins +#### 13.6.1.17. Plugins This execution mode is not a command, per se, but rather a command-line option that enables executing plugins to the dafny tool. Plugins may be either standalone tools or be additions to existing commands. @@ -767,7 +770,7 @@ where the argument to `--plugin` gives the path to the compiled assembly of the More on writing and building plugins can be found [in this section](#sec-plugins). -#### 13.5.1.18. Legacy operation +#### 13.6.1.18. Legacy operation Prior to implementing the command-based CLI, the `dafny` command-line simply took files and options and the arguments to options. That legacy mode of operation is still supported, though discouraged. The command `dafny -?` produces the list of legacy options. @@ -776,14 +779,14 @@ options like `-compile`, `-compileTarget` and `-spillTargetCode`. Users are encouraged to migrate to the command-based style of command-lines and the double-hyphen options. -### 13.5.2. In-tool help +### 13.6.2. In-tool help As is typical for command-line tools, `dafny` provides in-tool help through the `-h` and `--help` options: - `dafny -h`, `dafny --help` list the commands available in the `dafny` tool - `dafny -?` lists all the (legacy) options implemented in `dafny` - `dafny -h`, `dafny --help`, `dafny -?` list the options available for that command -### 13.5.3. dafny exit codes {#sec-exit-codes} +### 13.6.3. dafny exit codes {#sec-exit-codes} The basic resolve, verify, translate, build, run and commands of dafny terminate with these exit codes. @@ -801,7 +804,7 @@ Other dafny commands may have their own conventions for exit codes. However in all cases, an exit code of 0 indicates successful completion of the command's task and small positive integer values indicate errors of some sort. -### 13.5.4. dafny output +### 13.6.4. dafny output Most output from `dafny` is directed to the standard output of the shell invoking the tool, though some goes to standard error. - Command-line errors: these are produced by the dotnet CommandLineOptions package are directed to **standard-error** @@ -811,7 +814,7 @@ Most output from `dafny` is directed to the standard output of the shell invokin - Dafny `expect` statements (when they fail) send a message to **standard-out**. - Dafny I/O libraries send output explicitly to either **standard-out or standard-error** -### 13.5.5. Project files {#sec-project-files} +### 13.6.5. Project files {#sec-project-files} Commands on the Dafny CLI that can be passed a Dafny file can also be passed a Dafny project file. Such a project file may define which Dafny files the project contains and which Dafny options it uses. The project file must be a [TOML](https://toml.io/en/) file named `dfyconfig.toml` for it to work on both the CLI and in the Dafny IDE, although the CLI will accept any `.toml` file. Here's an example of a Dafny project file: @@ -836,18 +839,18 @@ The `excludes` does not remove any files that are listed explicitly on the comma It's not possible to use Dafny project files in combination with the legacy CLI UI. -## 13.6. Verification {#sec-verification} +## 13.7. Verification {#sec-verification} In this section, we suggest a methodology to figure out [why a single assertion might not hold](#sec-verification-debugging), we propose techniques to deal with [assertions that slow a proof down](#sec-verification-debugging-slow), we explain how to [verify assertions in parallel or in a focused way](#sec-assertion-batches), and we also give some more examples of [useful options and attributes to control verification](#sec-command-line-options-and-attributes-for-verification). -### 13.6.1. Verification debugging when verification fails {#sec-verification-debugging} +### 13.7.1. Verification debugging when verification fails {#sec-verification-debugging} Let's assume one assertion is failing ("assertion might not hold" or "postcondition might not hold"). What should you do next? The following section is textual description of the animation below, which illustrates the principle of debugging an assertion by computing the weakest precondition: ![weakestpreconditionDemo](https://user-images.githubusercontent.com/3601079/157976402-83fe4d37-8042-40fc-940f-bcfc235c7d2b.gif) -#### 13.6.1.1. Failing postconditions {#sec-failing-postconditions} +#### 13.7.1.1. Failing postconditions {#sec-failing-postconditions} Let's look at an example of a failing postcondition. ```dafny @@ -893,7 +896,7 @@ method FailingPostcondition(b: bool) returns (i: int) That's it! Now the postcondition is not failing anymore, but the `assert` contains the error! you can now move to the next section to find out how to debug this `assert`. -#### 13.6.1.2. Failing asserts {#sec-failing-asserts} +#### 13.7.1.2. Failing asserts {#sec-failing-asserts} In the [previous section](#sec-failing-postconditions), we arrived at the point where we have a failing assertion: ```dafny @@ -977,7 +980,7 @@ b ==> 2 <= (if !b then 3 else 1) Now we can understand what went wrong: When b is true, all of these formulas above are false, this is why the `dafny` verifier was not able to prove them. In the next section, we will explain how to "move asserts up" in certain useful patterns. -#### 13.6.1.3. Failing asserts cases {#sec-failing-asserts-special-cases} +#### 13.7.1.3. Failing asserts cases {#sec-failing-asserts-special-cases} This list is not exhaustive but can definitely be useful to provide the next step to figure out why Dafny could not prove an assertion. @@ -1007,13 +1010,13 @@ This list is not exhaustive but can definitely be useful to provide the next ste `method m_mod(i) returns (j: T)`
  ` requires A(i)`
  ` modifies this, i`
  ` ensures B(i, j)`
`{`
  ` ...`
`}`

`method n_mod() {`
  ` ...`




  ` var x: m_mod(a);`
  ` assert P(x);` | `method m_mod(i) returns (j: T)`
  ` requires A(i)`
  ` modifies this, i`
  ` ensures B(i, j)`
`{`
  ` ...`
`}`

`method n_mod() {`
  ` ...`
  ` assert A(k);`
  ` modify this, i; // Temporarily`
  ` var x := T; // Temporarily`
  ` assume B(k, x);`
  `// var x := m_mod(k);`
  ` assert P(x);`
`modify x, y;`
`assert P(x, y, z);` | `assert x != z && y != z;`
`modify x, y;`
`assert P(x, y, z);` -### 13.6.2. Verification debugging when verification is slow {#sec-verification-debugging-slow} +### 13.7.2. Verification debugging when verification is slow {#sec-verification-debugging-slow} In this section, we describe techniques to apply in the case when verification is slower than expected, does not terminate, or times out. Additional detail is available in the [verification optimization guide](../VerificationOptimization/VerificationOptimization). -#### 13.6.2.1. `assume false;` {#sec-assume-false} +#### 13.7.2.1. `assume false;` {#sec-assume-false} Assuming `false` is an empirical way to short-circuit the verifier and usually stop verification at a given point,[^explainer-assume-false] and since the final compilation steps do not accept this command, it is safe to use it during development. Another similar command, `assert false;`, would also short-circuit the verifier, but it would still make the verifier try to prove `false`, which can also lead to timeouts. @@ -1052,7 +1055,7 @@ method NotTerminating() { } ``` -This verifies instantly. This gives use a strategy to bisect, or do binary search to find the assertion that slows everything down. +This verifies instantly. This gives us a strategy to bisect, or do binary search to find the assertion that slows everything down. Now, we move the `assume false;` below the next assertion: @@ -1137,7 +1140,7 @@ If verification is fast, which of the two assertions `assert Z;` or `assert P;` We now hope you know enough of `assume false;` to locate assertions that make verification slow. Next, we will describe some other strategies at the assertion level to figure out what happens and perhaps fix it. -#### 13.6.2.2. `assert ... by {}` {#sec-verification-debugging-assert-by} +#### 13.7.2.2. `assert ... by {}` {#sec-verification-debugging-assert-by} If an assertion `assert X;` is slow, it is possible that calling a lemma or invoking other assertions can help to prove it: The postcondition of this lemma, or the added assertions, could help the `dafny` verifier figure out faster how to prove the result. @@ -1169,7 +1172,7 @@ Now, only `X` is available for the `dafny` verifier to prove the rest of the met [^verifier-lost]: By default, the expression of an assertion or a precondition is added to the knowledge base of the `dafny` verifier for further assertions or postconditions. However, this is not always desirable, because if the verifier has too much knowledge, it might get lost trying to prove something in the wrong direction. -#### 13.6.2.3. Labeling and revealing assertions {#sec-labeling-revealing-assertions} +#### 13.7.2.3. Labeling and revealing assertions {#sec-labeling-revealing-assertions} Another way to prevent assertions or preconditions from cluttering the verifier[^verifier-lost] is to label and reveal them. Labeling an assertion has the effect of "hiding" its result, until there is a "reveal" calling that label. @@ -1237,13 +1240,13 @@ method TestMethod(x: bool) To lift assertions, please refer to the techniques described in [Verification Debugging](#sec-verification-debugging). -#### 13.6.2.4. Non-opaque `function method` {#sec-non-opaque-function-method} +#### 13.7.2.4. Non-opaque `function method` {#sec-non-opaque-function-method} Functions are normally used for specifications, but their functional syntax is sometimes also desirable to write application code. However, doing so naively results in the body of a `function method Fun()` be available for every caller, which can cause the verifier to time out or get extremely slow[^verifier-lost]. A solution for that is to add the attribute [`{:opaque}`](#sec-opaque) right between `function method` and `Fun()`, and use [`reveal Fun();`](#sec-reveal-statement) in the calling functions or methods when needed. -#### 13.6.2.5. Conversion to and from bitvectors {#sec-conversion-to-and-from-bitvectors} +#### 13.7.2.5. Conversion to and from bitvectors {#sec-conversion-to-and-from-bitvectors} Bitvectors and natural integers are very similar, but they are not treated the same by the `dafny` verifier. As such, conversion from `bv8` to an `int` and vice-versa is not straightforward, and can result in slowdowns. @@ -1285,7 +1288,7 @@ method m() { One might consider refactoring this code into separate functions if used over and over. -#### 13.6.2.6. Nested loops {#sec-nested-loops} +#### 13.7.2.6. Nested loops {#sec-nested-loops} In the case of nested loops, the verifier might timeout sometimes because of inadequate or too much available information[^verifier-lost]. One way to mitigate this problem, when it happens, is to isolate the inner loop by refactoring it into a separate method, with suitable pre and postconditions that will usually assume and prove the invariant again. @@ -1321,7 +1324,7 @@ method innerLoop() In the next section, when everything can be proven in a timely manner, we explain another strategy to decrease proof time by parallelizing it if needed, and making the verifier focus on certain parts. -### 13.6.3. Assertion batches, well-formedness, correctness {#sec-assertion-batches} +### 13.7.3. Assertion batches, well-formedness, correctness {#sec-assertion-batches} To understand how to control verification, it is first useful to understand how `dafny` verifies functions and methods. @@ -1373,7 +1376,7 @@ assert c != 5/a; // Correctness Well-formedness is proved at the same time as correctness, except for [well-formedness of requires and ensures clauses](#sec-well-formedness-specifications) which is proved separatedly from the well-formedness and correctness of the rest of the method/function. -For the rest of this section, we don't diifferentiate between well-formedness assertions and correctness assertions. +For the rest of this section, we don't differentiate between well-formedness assertions and correctness assertions. We can also classify the assertions extracted by Dafny in a few categories: @@ -1438,7 +1441,7 @@ The fundamental unit of verification in `dafny` is an _assertion batch_, which c [^smaller-batches]: To create a smaller batch, `dafny` duplicates the assertion batch, and arbitrarily transforms the clones of an assertion into assumptions except in exactly one batch, so that each assertion is verified only in one batch. This results in "easier" formulas for the verifier because it has less to prove, but it takes more overhead because every verification instance have a common set of axioms and there is no knowledge sharing between instances because they run independently. -#### 13.6.3.1. Controlling assertion batches {#sec-assertion-batches-control} +#### 13.7.3.1. Controlling assertion batches {#sec-assertion-batches-control} Here is how you can control how `dafny` partitions assertions into batches. @@ -1452,7 +1455,7 @@ The effect of these attributes may vary, because they are low-level attributes a Usually, you would set [`{:vcs_max_cost 0}`](#sec-vcs_max_cost) and [`{:vcs_max_splits N}`](#sec-vcs_max_splits) to ensure it generates N assertion batches. * [`{:vcs_max_keep_going_splits N}`](#sec-vcs_max_keep_going_splits) where N > 1 on a method dynamically splits the initial assertion batch up to N components if the verifier is stuck the first time. -### 13.6.4. Command-line options and other attributes to control verification {#sec-command-line-options-and-attributes-for-verification} +### 13.7.4. Command-line options and other attributes to control verification {#sec-command-line-options-and-attributes-for-verification} There are many great options that control various aspects of verifying dafny programs. Here we mention only a few: @@ -1465,43 +1468,103 @@ There are many great options that control various aspects of verifying dafny pro You can search for them in [this file](https://dafny-lang.github.io/dafny/DafnyRef/DafnyRef) as some of them are still documented in raw text format. -### 13.6.5. Debugging variable verification +### 13.7.5. Analyzing proof dependencies {#sec-proof-dependencies} + +When Dafny successfully verifies a particular definition, it can ask the +solver for information about what parts of the program were actually +used in completing the proof. The program components that can +potentially form part of a proof include: + +* `assert` statements (and the implicit assumption that they hold in subsequent code), +* implicit assertions (such as array or sequence bounds checks), +* `assume` statements, +* `ensures` clauses, +* `requires` clauses, +* function definitions, +* method calls, and +* assignment statements. + +Understanding what portions of the program the proof depended on can +help identify mistakes, and to better understand the structure of your +proof (which can help when optimizing it, among other things). In +particular, there are two key dependency structures that tend to +indicate mistakes, both focused on what parts of the program were _not_ +included in the proof. + +* Redundant assumptions. In some cases, a proof can be completed without + the need of certain `assume` statements or `requires` clauses. This + situation might represent a mistake, and when the mistake is corrected + those program elements may become required. However, they may also + simply be redundant, and the program will become simpler if they're + removed. Dafny will report assumptions of this form when verifying + with the flag `--warn-redundant-assumptions`. Note that `assert` + statements may be warned about, as well, indicating that the fact + proved by the assertion wasn't needed to prove anything else in the + program. + +* Contradictory assumptions. If the combination of all assumptions in + scope at a particular program point is contradictory, anything can be + proved at that point. This indicates the serious situation that, unless done on purpose like in a proof by contradiction, your + proof may be entirely vacuous, and not say what you intended, giving + you a false sense of confidence. The + `--warn-contradictory-assumptions` flag instructs Dafny to warn about + any assertion that was proved through the use of contradictions + between assumptions. + +These options can be specified in `dfyconfig.toml`, and this is typically the most convenient way to use them with the IDE. + +More detailed information is available using either the `--log-format +text` or `--verification-coverage-report` option to `dafny verify`. The former will +include a list of proof dependencies (including source location and +description) alongside every assertion batch in the generated log +whenever one of the two warning options above is also included. The +latter will produce a highlighted HTML version of your source code, in +the same format used by `dafny test --coverage-report` +and `dafny generate-tests --verification-coverage-report`, +indicating which parts of the program were used, not used, or partly +used in the verification of the entire program. + +### 13.7.6. Debugging brittle verification When evolving a Dafny codebase, it can sometimes occur that a proof obligation succeeds at first only for the prover to time out or report a -potential error after minor, valid changes. This is ultimately due to -decidability limitations in the form of automated reasoning that Dafny -uses. The Z3 SMT solver that Dafny depends on attempts to efficiently -search for proofs, but does so using both incomplete heuristics and a -degree of randomness, with the result that it can sometimes fail to find -a proof even when one exists (or continue searching forever). +potential error after minor, valid changes. We refer to such a proof +obligation as _brittle_. This is ultimately due to decidability +limitations in the form of automated reasoning that Dafny uses. The Z3 +SMT solver that Dafny depends on attempts to efficiently search for +proofs, but does so using both incomplete heuristics and a degree of +randomness, with the result that it can sometimes fail to find a proof +even when one exists (or continue searching forever). Dafny provides some features to mitigate this issue, primarily focused on early detection. The philosophy is that, if Dafny programmers are -alerted to proofs that show early signs of variability, before they are -obviously so, they can refactor the proofs to make them less variable +alerted to proofs that show early signs of brittleness, before they are +obviously so, they can refactor the proofs to make them less brittle before further development becomes difficult. The mechanism for early detection focuses on measuring the resources -used to complete a proof (either using duration or a more deterministic -"resource count" metric available from Z3). Dafny can re-run a given -proof attempt multiple times after automatically making minor changes to -the structure of the input or to the random choices made by the solver. -If the resources used during these attempts (or the ability to find a -proof at all) vary widely, we say that the verification of the relevant -properties is _highly variable_. - -#### 13.6.5.1. Measuring proof variability - -To measure the variability of your proofs, start by using the -`-randomSeedIterations:N` flag to instruct Dafny to attempt each proof -goal `N` times, using a different random seed each time. The random seed -used for each attempt is derived from the global random seed `S` -specified with `-randomSeed:S`, which defaults to `0` (which means use -an arbitrary -- e.g. clock-based -- seed). +used to discharge a proof obligation (either using duration or a more +deterministic "resource count" metric available from Z3). Dafny can +re-run a given proof attempt multiple times after automatically making +minor changes to the structure of the input or to the random choices +made by the solver. If the resources used during these attempts (or the +ability to find a proof at all) vary widely, we use this as a proxy +metric indicating that the proof may be brittle. + +#### 13.7.6.1. Measuring proof brittleness + +To measure the brittleness of your proofs, start by using the `dafny +measure-complexity` command with the `--iterations N` flag to instruct +Dafny to attempt each proof goal `N` times, using a different random +seed each time. The random seed used for each attempt is derived from +the global random seed `S` specified with `-randomSeed:S`, which +defaults to `0`. The random seed affects the structure of the SMT +queries sent to the solver, changing the ordering of SMT commands, the +variable names used, and the random seed the solver itself uses when +making decisions that can be arbitary. For most use cases, it also makes sense to specify the -`-verificationLogger:csv` flag, to log verification cost statistics to a +`--log-format csv` flag, to log verification cost statistics to a CSV file. By default, the resulting CSV files will be created in the `TestResults` folder of the current directory. @@ -1529,24 +1592,24 @@ than 20%, perhaps even as low as 5%. However, when beginning to analyze a new project, it may be necessary to set limits as high as a few hundred percent and incrementally ratchet down the limit over time. -When first analyzing proof variability, you may also find that certain proof +When first analyzing proof brittleness, you may also find that certain proof goals succeed on some iterations and fail on others. If your aim is -first to ensure that variability doesn't worsen and then to start -improving it, integrating `dafny-reportgenerator` into CI and using the +first to ensure that brittleness doesn't worsen and then to start +reducing it, integrating `dafny-reportgenerator` into CI and using the `--allow-different-outcomes` flag may be appropriate. Then, once you've -improved variability sufficiently, you can likely remove that flag (and -likely have significantly lower limits on other variability metrics). +improved brittleness sufficiently, you can likely remove that flag (and +likely have significantly lower limits on other metrics). -#### 13.6.5.2. Improving proof variability +#### 13.7.6.2. Improving proof brittleness -Improving proof variability is typically closely related to improving +Reducing proof brittleness is typically closely related to improving performance overall. As such, [techniques for debugging slow verification](#sec-verification-debugging-slow) are typically useful for -debugging highly variable verification, as well. See also the +debugging brittle proofs, as well. See also the [verification optimization guide](../VerificationOptimization/VerificationOptimization). -## 13.7. Compilation {#sec-compilation} +## 13.8. Compilation {#sec-compilation} The `dafny` tool can compile a Dafny program to one of several target languages. Details and idiosyncrasies of each of these are described in the following subsections. In general note the following: @@ -1560,7 +1623,18 @@ included by default and must be explicitly requested using `--include-runtime`. To be compilable to an executable program, a Dafny program must contain a `Main` entry point, as described [here](#sec-user-guide-main). -### 13.7.1. `extern` declarations {#sec-extern-decls} +### 13.8.1.1 Built-in declarations {#sec-compilation-built-ins} + +Dafny includes several built-in types such as tuples, arrays, arrows (functions), and the `nat` subset type. +The supporting target language code for these declarations could be emitted on-demand, +but these could then become multiple definitions of the same symbols when compiling multiple components separately. +Instead, all such built-ins up to a pre-configured maximum size are included in most of the runtime libraries. +This means that when compiling to certain target languages, the use of such built-ins above these maximum sizes, +such as tuples with more than 20 elements, is not supported. +See the [Supported features by target language](#sec-supported-features-by-target-language) table +for the details on these limits. + +### 13.8.2. `extern` declarations {#sec-extern-decls} A Dafny declaration can be marked with the [`{:extern}`](#sec-extern) attribute to indicate that it refers to an external definition that is already @@ -1673,7 +1747,35 @@ Detailed description of the `dafny build` and `dafny run` commands and the `--input` option (needed when `dafny run` has more than one input file) is contained [in the section on command-line structure](#command-line). -### 13.7.2. C\# +### 13.8.3. Replaceable modules +To enable easily customising runtime behavior across an entire Dafny program, Dafny has placeholder modules. Here follows an example: + + +```dafny +replaceable module Foo { + method Bar() returns (i: int) + ensures i >= 2 +} + +method Main() { + var x := Foo.Bar(); + print x; +} +// At this point, the program can be verified but not run. + +module ConcreteFoo replaces Foo { + method Bar() returns (i: int) { + return 3; // Main will print 3. + } +} +// ConcreteFoo can be swapped out for different replacements of Foo, to customize runtime behavior. +``` + +When replacing a replaceable module, the same rules apply as when refining an abstract module. However, unlike an abstract module, a placeholder module can be used as if it is a concrete module. When executing code, using for example `dafny run` or `dafny translate`, any program that contains a placeholder module must also contain a replacement of this placeholder. When using `dafny verify`, placeholder modules do not have to be replaced. + +Replaceable modules are particularly useful for defining behavior that depends on which target language Dafny is translated to. + +### 13.8.4. C\# For a simple Dafny-only program, the translation step converts a `A.dfy` file into `A.cs`; the build step then produces a `A.dll`, which can be used as a library or as an executable (run using `dotnet A.dll`). @@ -1694,7 +1796,7 @@ which is then compiled by `dotnet` to a `.dll`. Examples of how to integrate C# libraries and source code with Dafny source code are contained in [this separate document](integration-cs/IntegrationCS). -### 13.7.3. Java +### 13.8.5. Java The Dafny-to-Java compiler translation phase writes out the translated files of a file _A_`.dfy` to a directory _A_`-java`. @@ -1716,7 +1818,7 @@ but not if dafny is only doing translation. Examples of how to integrate Java source code and libraries with Dafny source are contained in [this separate document](integration-java/IntegrationJava). -### 13.7.4. Javascript +### 13.8.6. Javascript The Dafny-to-Javascript compiler translates all the given `.dfy` files into a single `.js` file, which can then be run using `node`. (Javascript has no compilation step). @@ -1730,7 +1832,7 @@ Or, in one step, Examples of how to integrate Javascript libraries and source code with Dafny source are contained in [this separate document](integration-js/IntegrationJS). -### 13.7.5. Go +### 13.8.7. Go The Dafny-to-Go compiler translates all the given `.dfy` files into a single `.go` file in `A-go/src/A.go`; the output folder can be specified with the @@ -1754,7 +1856,7 @@ change, though the `./A` alternative will still be supported. Examples of how to integrate Go source code and libraries with Dafny source are contained in [this separate document](integration-go/IntegrationGo). -### 13.7.6. Python +### 13.8.8. Python The Dafny-to-Python compiler is still under development. However, simple Dafny programs can be built and run as follows. The Dafny-to-Python @@ -1772,7 +1874,7 @@ In one step: Examples of how to integrate Python libraries and source code with Dafny source are contained in [this separate document](integration-py/IntegrationPython). -### 13.7.7. C++ +### 13.8.9. C++ The C++ backend was written assuming that it would primarily support writing C/C++ style code in Dafny, which leads to some limitations in the current @@ -1792,7 +1894,7 @@ implementation. - The current backend also assumes the use of C++17 in order to cleanly and performantly implement datatypes. -### 13.7.8. Supported features by target language {#sec-supported-features-by-target-language} +### 13.8.10. Supported features by target language {#sec-supported-features-by-target-language} Some Dafny features are not supported by every target language. The table below shows which features are supported by each backend. @@ -1801,7 +1903,7 @@ while an X indicates that it is. {% include_relative Features.md %} -## 13.8. Dafny Command Line Options {#sec-command-line-options} +## 13.9. Dafny Command Line Options {#sec-command-line-options} There are many command-line options to the `dafny` tool. The most current documentation of the options is within the tool itself, @@ -1812,7 +1914,7 @@ Remember that options are typically stated with either a leading `--`. Legacy options begin with either '-' or '/'; however they are being migrated to the POSIX-compliant `--` form as needed. -### 13.8.1. Help and version information {#sec-controlling-help} +### 13.9.1. Help and version information {#sec-controlling-help} These options emit general information about commands, options and attributes. When present, the dafny program will terminates after emitting the requested information @@ -1842,7 +1944,7 @@ Legacy options: * `-wait` - wait for the user to press `Enter` before terminating after a successful execution. -### 13.8.2. Controlling input {#sec-controlling-input} +### 13.9.2. Controlling input {#sec-controlling-input} These options control how Dafny processes its input. @@ -1861,7 +1963,7 @@ a list of all .dfy files contained, recursively, in those folders how Dafny constructs are modeled. The default prelude is [here](https://github.com/dafny-lang/dafny/blob/master/Source/Dafny/DafnyPrelude.bpl). -### 13.8.3. Controlling plugins {#sec-controlling-plugins} +### 13.9.3. Controlling plugins {#sec-controlling-plugins} Dafny has a plugin capability. A plugin has access to an AST of the dafny input files @@ -1877,7 +1979,7 @@ and (b) example plugins in the The value of the option `--plugin` is a path to a dotnet dll that contains the compiled plugin. -### 13.8.4. Controlling output {#sec-controlling-output} +### 13.9.4. Controlling output {#sec-controlling-output} These options instruct Dafny to print various information about your program during processing, including variations of the original source @@ -2020,7 +2122,7 @@ Legacy options: } ``` -### 13.8.5. Controlling language features {#sec-controlling-language} +### 13.9.5. Controlling language features {#sec-controlling-language} These options allow some Dafny language features to be enabled or disabled. Some of these options exist for backward compatibility with @@ -2127,7 +2229,7 @@ Legacy options: implicitly static and field declarations are not allowed at the module scope. -### 13.8.6. Controlling warnings {#sec-controlling-warnings} +### 13.9.6. Controlling warnings {#sec-controlling-warnings} These options control what warnings Dafny produces, and whether to treat warnings as errors. @@ -2150,7 +2252,7 @@ Legacy options * `2` - issue warnings and advise about alternate syntax. -### 13.8.7. Controlling verification {#sec-controlling-verification} +### 13.9.7. Controlling verification {#sec-controlling-verification} These options control how Dafny verifies the input program, including how much it verifies, what techniques it uses to perform verification, @@ -2200,6 +2302,10 @@ and what information it produces about the verification process. operators. (This option will perhaps be replaced by `-arith` in the future. For now, it takes precedence over `-arith`.) + The behavior of `disable-nonlinear-arithmetic` can be turned on and off on a per-module basis + by placing the attribute [`{:disable-nonlinear-arithmetic}`](#sec-disable-nonlinear-arithmetic) after the module keyword. + The attribute optionally takes the value `false` to enable nonlinear arithmetic. + * `--manual-lemma-induction` - diables automatic inducntion for lemmas * `--isolate-assertions` - verify assertions individually @@ -2364,7 +2470,7 @@ Legacy options: `-proverOpt:O:model_compress=false` and `-proverOpt:O:model.completion=true` options. -### 13.8.8. Controlling compilation {#sec-controlling-compilation} +### 13.9.8. Controlling compilation {#sec-controlling-compilation} These options control what code gets compiled, what target language is used, how compilation proceeds, and whether the compiled program is @@ -2518,7 +2624,7 @@ out the textual target program as part of compilation, in which case method marked with the `{:extern}` attribute directly from a function or method marked with the `{:test}` attribute. -### 13.8.9. Controlling Boogie {#sec-controlling-boogie} +### 13.9.9. Controlling Boogie {#sec-controlling-boogie} Dafny builds on top of Boogie, a general-purpose intermediate language for verification. Options supported by Boogie on its own are also @@ -2620,11 +2726,11 @@ PROVER_OPTIONS="\ #"$BOOGIE" $BOOGIE_OPTIONS $PROVER_OPTIONS "$@" ``` -### 13.8.10. Controlling the prover {#sec-controlling-prover} +### 13.9.10. Controlling the prover {#sec-controlling-prover} Much of controlling the prover is accomplished by controlling verification condition generation ([25.9.7](#sec-controlling-verification)) or Boogie -([Section 13.8.9](#sec-controlling-boogie)). +([Section 13.9.9](#sec-controlling-boogie)). The following options are also commonly used: * `--verification-error-limit:` - limits the number of verification errors reported per procedure. @@ -2635,7 +2741,7 @@ The following options are also commonly used: the number of seconds spent trying to verify each procedure. -### 13.8.11. Controlling test generation {#sec-controlling-test-gen} +### 13.9.11. Controlling test generation {#sec-controlling-test-gen} Dafny is capable of generating unit (runtime) tests. It does so by asking the prover to solve for values of inputs to a method that cause the program to execute specific blocks or paths. diff --git a/latest/DafnyRef/concat b/latest/DafnyRef/concat old mode 100644 new mode 100755 diff --git a/latest/HowToFAQ/Errors-CommandLine.md b/latest/HowToFAQ/Errors-CommandLine.md index 0a7c0ed..e12b193 100644 --- a/latest/HowToFAQ/Errors-CommandLine.md +++ b/latest/HowToFAQ/Errors-CommandLine.md @@ -14,7 +14,7 @@ The `-t` or `--target` options specifies which backend compiler to use for those dafny commands that compile dafny to other programming languages. This error message says that the named language is not supported. -## **Error: No input files were specified in command-line _command_** {#cli_no_files} +## **Error: No input files were specified in command-line. Command-line arguments: _command_** {#cli_no_files} ```bash diff --git a/latest/HowToFAQ/Errors-Parser.md b/latest/HowToFAQ/Errors-Parser.md index 51af89b..7d93407 100644 --- a/latest/HowToFAQ/Errors-Parser.md +++ b/latest/HowToFAQ/Errors-Parser.md @@ -248,14 +248,14 @@ module N refines M { datatype D = ... Y | Z } There are limitations on refining a datatype, namely that the set of constructors cannot be changed. It is only allowed to add members to the body of the datatype. -## **Error: datatype extending traits is a beta feature; use /generalTraits:1 to engage** {#p_general_traits_beta} +## **Error: datatype extending traits is a beta feature; use /generalTraits:datatype to engage** {#p_general_traits_beta} ```dafny trait Trait { } datatype D extends Trait = A | B ``` -Use of traits as non-reference types is a beta feature. To engage, use /generalTraits:1. +Use of traits as non-reference types is a beta feature. To engage, use /generalTraits:datatype. ## **Warning: module-level const declarations are always non-instance, so the 'static' keyword is not allowed here {#p_module_level_const_always_static} diff --git a/latest/HowToFAQ/Errors-Parser.template b/latest/HowToFAQ/Errors-Parser.template index 571c711..f895891 100644 --- a/latest/HowToFAQ/Errors-Parser.template +++ b/latest/HowToFAQ/Errors-Parser.template @@ -204,7 +204,7 @@ module N refines M { datatype D = ... Y | Z } -## **Error: datatype extending traits is a beta feature; use /generalTraits:1 to engage** {#p_general_traits_beta} +## **Error: datatype extending traits is a beta feature; use /generalTraits:datatype to engage** {#p_general_traits_beta} ```dafny trait Trait { } diff --git a/latest/HowToFAQ/FAQFunctionByMethodProof.md b/latest/HowToFAQ/FAQFunctionByMethodProof.md new file mode 100644 index 0000000..e107e27 --- /dev/null +++ b/latest/HowToFAQ/FAQFunctionByMethodProof.md @@ -0,0 +1,87 @@ +--- +title: I can't prove the equivalence between the method part of a `function by method`` and the function itself +--- + +## Question + +I can't prove the equivalence between the method part of a function by method and the function itself. +It seems that my invariants can't be maintained by the loop, and I don't know how to prove them. + +## Answer + +Consider the simple problem of computing the sum of a sequence of integers. +You might be tempted to immediately write the following equivalence, +with your best guess of an invariant +and a hint at the end to help Dafny realize that the result is correct. +However you cannot prove the invariant you just wrote. + +``` +{% include_relative FAQFunctionByMethodProof1.dfy %} +``` + +Let's unroll the computation of the function on a sequence of 3 elements. +The function will compute: + +`s[0] + (s[1] + (s[2] + 0))` + +But the loop will compute + +`((0 + s[0]) + s[1]) + s[2]` + +In the function, we add the first element (`s[0]`) to the result of computing the sum of the remaining elements (`s[1] + (s[2] + 0))`). +In the by method, we add the last element (`s[2]`) to the accumulator, which contains the sum of the initial terms (`(0 + s[0]) + s[1]`). +If it was not the case that the addition was associative and 0 was a neutral element, there would be no immediate way to prove that the two computations are equivalent. + +There are essentially three solutions around that: + +* Improve the invariant, knowing `+` is associative +* Change the order of computation of the function so that it matches the by method +* Change the order of computation of the by method so that it matches the function + +There are more intrusive solutions, such as making the function tail-recursive by changing the function's signature to include an accumulator or a sequence of callbacks to perform a the end, but we will explore only the one that don't change the signature of `Sum()`. + +## Improved invariant + +You can change the invariant to be `invariant result + Sum(s[i..]) == Sum(s)`, as below: + +``` +{% include_relative FAQFunctionByMethodProof2.dfy %} +``` + +This works because, with `result'` being the result at the end of the loop and `+` being associative, +the lemma `IntermediateProperty()` shows the underlying reasoning that helps prove that the invariant +is indeed invariant. Dafny can prove it automatically, so the lemma is not needed in the loop body. +One nice thing is that we can get rid of the final hint. + +What if you had an operation more complex that "+", that is not associative? +This is when you need to ensure the loop and the function are computing in the same order. +Let's explore how to do so by changing either the function, or the by-method body. + +## Make the function compute what the by-method does +The by-method loop's first addition is 0 plus the first element (`s[0]`) of the sequence. For this to +be the first addition performed by the function, it has to be at the bottommost level of the call. +Indeed, each addition is performed after the recursive call finishes. This means that +the function needs to sum the `n-1` elements first and add the remaining last one. + +Since it's exactly what the method computes, it satisfies our initial invariant. + +``` +{% include_relative FAQFunctionByMethodProof3.dfy %} +``` + +Not only does this approach require more proof hints, but it might also break the proofs that dependend on the shape of the function, while all we wanted in the first place was to give a more efficient implementation to the function. +Therefore, it's reasonable to expect we will prefer to change the implementation of the by-method body to reflect the function, not the opposite, as follows: + +## Make the by-method body compute what the function computes + +To compute iteratively what the function computes recursively, you have to find what is the first +addition that will be computed by the method. As mentioned previously, the first addition is the one performed at the bottommost level of recursion: the first addition is `s[|s|-1] + 0`, +so the loop has to actually be in reverse, like this: + +``` +{% include_relative FAQFunctionByMethodProof4.dfy %} +``` + +Note that this approach results in the smallest invariant that actually closely matches the function itself. +Also, instead of adding to the right of `result`, adding to the left ensures the same order is kept, +in case the operation was not commutative (so that it would work for sequence append operation). \ No newline at end of file diff --git a/latest/HowToFAQ/FAQFunctionByMethodProof1.dfy b/latest/HowToFAQ/FAQFunctionByMethodProof1.dfy new file mode 100644 index 0000000..be5753e --- /dev/null +++ b/latest/HowToFAQ/FAQFunctionByMethodProof1.dfy @@ -0,0 +1,16 @@ +function Sum(s: seq): (result: int) { + if |s| == 0 then + 0 + else + s[0] + Sum(s[1..]) +} by method { + result := 0; + for i := 0 to |s| + invariant result == Sum(s[0..i]) + // ^^^^^^^^^^^^^^^^^^^^^^ + // Cannot be proved + { + result := result + s[i]; + } + assert s[0..|s|] == s; +} \ No newline at end of file diff --git a/latest/HowToFAQ/FAQFunctionByMethodProof1.txt b/latest/HowToFAQ/FAQFunctionByMethodProof1.txt new file mode 100644 index 0000000..c1cae25 --- /dev/null +++ b/latest/HowToFAQ/FAQFunctionByMethodProof1.txt @@ -0,0 +1,2 @@ +FAQFunctionByMethodProof1.dfy(9,14): Error: this invariant could not be proved to be maintained by the loop +Dafny program verifier finished with 1 verified, 1 error diff --git a/latest/HowToFAQ/FAQFunctionByMethodProof2..txt b/latest/HowToFAQ/FAQFunctionByMethodProof2..txt new file mode 100644 index 0000000..c39a053 --- /dev/null +++ b/latest/HowToFAQ/FAQFunctionByMethodProof2..txt @@ -0,0 +1 @@ +Dafny program verifier finished with 2 verified, 0 error diff --git a/latest/HowToFAQ/FAQFunctionByMethodProof2.dfy b/latest/HowToFAQ/FAQFunctionByMethodProof2.dfy new file mode 100644 index 0000000..2169f6e --- /dev/null +++ b/latest/HowToFAQ/FAQFunctionByMethodProof2.dfy @@ -0,0 +1,28 @@ +function Sum(s: seq): (result: int) { + if |s| == 0 then + 0 + else + s[0] + Sum(s[1..]) +} by method { + result := 0; + for i := 0 to |s| + invariant result + Sum(s[i..]) == Sum(s) // New invariant + { + result := result + s[i]; + } +} // No hint needed at the end + +lemma IntermediateProperty(result: int, result': int, i: int, s: seq) + requires 0 <= i < |s| + requires result' == result + s[i] + requires result + Sum(s[i..]) == Sum(s) + ensures result' + Sum(s[i+1..]) == Sum(s) +{ + calc { + Sum(s); + == result + Sum(s[i..]); // Requires definition + == result + (s[i] + Sum(s[i+1..])); // Definition of Sum() + ==(result + s[i]) + Sum(s[i+1..]); // Associativity + == result' + Sum(s[i+1..]); // Definition of result' + } +} \ No newline at end of file diff --git a/latest/HowToFAQ/FAQFunctionByMethodProof3.dfy b/latest/HowToFAQ/FAQFunctionByMethodProof3.dfy new file mode 100644 index 0000000..6229ab8 --- /dev/null +++ b/latest/HowToFAQ/FAQFunctionByMethodProof3.dfy @@ -0,0 +1,17 @@ +function Sum(s: seq): (result: int) { + if |s| == 0 then + 0 + else + Sum(s[0..|s|-1]) + s[|s| - 1] + // We add the last element to the sum of the first +} by method { + result := 0; + for i := 0 to |s| + invariant result == Sum(s[0..i]) + { + assert s[0..i+1][0..i] == s[0..i]; + // Minimum hint needed for proof + result := result + s[i]; + } + assert s[0..|s|] == s; +} // One last hint \ No newline at end of file diff --git a/latest/HowToFAQ/FAQFunctionByMethodProof3.txt b/latest/HowToFAQ/FAQFunctionByMethodProof3.txt new file mode 100644 index 0000000..c39a053 --- /dev/null +++ b/latest/HowToFAQ/FAQFunctionByMethodProof3.txt @@ -0,0 +1 @@ +Dafny program verifier finished with 2 verified, 0 error diff --git a/latest/HowToFAQ/FAQFunctionByMethodProof4.dfy b/latest/HowToFAQ/FAQFunctionByMethodProof4.dfy new file mode 100644 index 0000000..5fd07ce --- /dev/null +++ b/latest/HowToFAQ/FAQFunctionByMethodProof4.dfy @@ -0,0 +1,10 @@ +function Sum(s: seq): (result: int) { + if |s| == 0 then 0 else s[0] + Sum(s[1..]) +} by method { + result := 0; + for i := |s| downto 0 // Reverse. First i == |s| - 1 + invariant result == Sum(s[i..]) // The invariant looks like the function + { + result := s[i] + result; // Note how we sum in reverse as well. + } +} // No hint needed at the end \ No newline at end of file diff --git a/latest/HowToFAQ/FAQFunctionByMethodProof4.txt b/latest/HowToFAQ/FAQFunctionByMethodProof4.txt new file mode 100644 index 0000000..c39a053 --- /dev/null +++ b/latest/HowToFAQ/FAQFunctionByMethodProof4.txt @@ -0,0 +1 @@ +Dafny program verifier finished with 2 verified, 0 error diff --git a/latest/HowToFAQ/check-errors b/latest/HowToFAQ/check-errors old mode 100644 new mode 100755 diff --git a/latest/HowToFAQ/check-errors-a b/latest/HowToFAQ/check-errors-a old mode 100644 new mode 100755 diff --git a/latest/HowToFAQ/index.md b/latest/HowToFAQ/index.md index f4bc063..e4ff15a 100644 --- a/latest/HowToFAQ/index.md +++ b/latest/HowToFAQ/index.md @@ -86,6 +86,7 @@ If you have questions that are not addressed here, be sure to communicate them t - ["How do I model extern methods that return objects?"](FAQExternReturnsObject) - ["How do I tell Dafny that a class field may be updated?"](FAQUpdateArrayField) - ["Why does Dafny not know this obvious property of maps?"](FAQMapMembership) +- ["I can't prove the equivalence between the method part of a `function by method` and the function itself"](FAQFunctionByMethodProof) ## Dafny tools diff --git a/latest/HowToFAQ/make-error-catalog b/latest/HowToFAQ/make-error-catalog old mode 100644 new mode 100755 diff --git a/latest/HowToFAQ/make-onepage b/latest/HowToFAQ/make-onepage old mode 100644 new mode 100755 diff --git a/latest/HowToFAQ/onepage.md b/latest/HowToFAQ/onepage.md index d5360ae..5962fde 100644 --- a/latest/HowToFAQ/onepage.md +++ b/latest/HowToFAQ/onepage.md @@ -2307,6 +2307,92 @@ method mmm(m: map, k: K, v: V) { ``` proves just fine. +# I can't prove the equivalence between the method part of a `function by method`` and the function itself + + +## Question + +I can't prove the equivalence between the method part of a function by method and the function itself. +It seems that my invariants can't be maintained by the loop, and I don't know how to prove them. + +## Answer + +Consider the simple problem of computing the sum of a sequence of integers. +You might be tempted to immediately write the following equivalence, +with your best guess of an invariant +and a hint at the end to help Dafny realize that the result is correct. +However you cannot prove the invariant you just wrote. + +``` +{% include_relative FAQFunctionByMethodProof1.dfy %} +``` + +Let's unroll the computation of the function on a sequence of 3 elements. +The function will compute: + +`s[0] + (s[1] + (s[2] + 0))` + +But the loop will compute + +`((0 + s[0]) + s[1]) + s[2]` + +In the function, we add the first element (`s[0]`) to the result of computing the sum of the remaining elements (`s[1] + (s[2] + 0))`). +In the by method, we add the last element (`s[2]`) to the accumulator, which contains the sum of the initial terms (`(0 + s[0]) + s[1]`). +If it was not the case that the addition was associative and 0 was a neutral element, there would be no immediate way to prove that the two computations are equivalent. + +There are essentially three solutions around that: + +* Improve the invariant, knowing `+` is associative +* Change the order of computation of the function so that it matches the by method +* Change the order of computation of the by method so that it matches the function + +There are more intrusive solutions, such as making the function tail-recursive by changing the function's signature to include an accumulator or a sequence of callbacks to perform a the end, but we will explore only the one that don't change the signature of `Sum()`. + +## Improved invariant + +You can change the invariant to be `invariant result + Sum(s[i..]) == Sum(s)`, as below: + +``` +{% include_relative FAQFunctionByMethodProof2.dfy %} +``` + +This works because, with `result'` being the result at the end of the loop and `+` being associative, +the lemma `IntermediateProperty()` shows the underlying reasoning that helps prove that the invariant +is indeed invariant. Dafny can prove it automatically, so the lemma is not needed in the loop body. +One nice thing is that we can get rid of the final hint. + +What if you had an operation more complex that "+", that is not associative? +This is when you need to ensure the loop and the function are computing in the same order. +Let's explore how to do so by changing either the function, or the by-method body. + +## Make the function compute what the by-method does +The by-method loop's first addition is 0 plus the first element (`s[0]`) of the sequence. For this to +be the first addition performed by the function, it has to be at the bottommost level of the call. +Indeed, each addition is performed after the recursive call finishes. This means that +the function needs to sum the `n-1` elements first and add the remaining last one. + +Since it's exactly what the method computes, it satisfies our initial invariant. + +``` +{% include_relative FAQFunctionByMethodProof3.dfy %} +``` + +Not only does this approach require more proof hints, but it might also break the proofs that dependend on the shape of the function, while all we wanted in the first place was to give a more efficient implementation to the function. +Therefore, it's reasonable to expect we will prefer to change the implementation of the by-method body to reflect the function, not the opposite, as follows: + +## Make the by-method body compute what the function computes + +To compute iteratively what the function computes recursively, you have to find what is the first +addition that will be computed by the method. As mentioned previously, the first addition is the one performed at the bottommost level of recursion: the first addition is `s[|s|-1] + 0`, +so the loop has to actually be in reverse, like this: + +``` +{% include_relative FAQFunctionByMethodProof4.dfy %} +``` + +Note that this approach results in the smallest invariant that actually closely matches the function itself. +Also, instead of adding to the right of `result`, adding to the left ensures the same order is kept, +in case the operation was not commutative (so that it would work for sequence append operation). # Is there a Dafny style? and a Dafny linter (style checker and bad smell warnings)? @@ -2855,7 +2941,7 @@ Until then, the best you can do is to try to change the verification condition s This warning can occur if a file being compiled by Dafny is completely empty. -Previous other occurences of this warning were bugs. +Previous other occurrences of this warning were bugs. # "Duplicate name of import: ..." diff --git a/latest/Installation.md b/latest/Installation.md index b78b677..a52b2d4 100644 --- a/latest/Installation.md +++ b/latest/Installation.md @@ -140,16 +140,18 @@ After the compiler dependencies are installed, you can run a quick test of the i ## Mac (Binary) {#Mac-binary} -To install a binary installation of dafny on Mac OS, do one of the following: -Either +To install a binary installation of Dafny on macOS, do one of the following: + +Either * Install the Mac binary version of Dafny, from `https://github.com/dafny-lang/dafny/releases/latest` - * Unzip the downloaded file in a (empty) location of your choice ($INSTALL) - * cd into the installation directory (`$INSTALL/dafny`) and run the script `./allow_on_mac.sh` - * dafny is run with the command `$INSTALL/dafny/dafny` + * Unzip the downloaded file in a (empty) location of your choice (`$INSTALL`) + * `cd` into the installation directory (`$INSTALL/dafny`) and run the script `./allow_on_mac.sh` + * Dafny is run with the command `$INSTALL/dafny/dafny` + or - * install dafny using brew, with the command `brew install dafny` (the version on brew sometimes lags the + * Install Dafny using brew, with the command `brew install dafny` (the version on brew sometimes lags the project release page) - * run dafny with the command `dafny` + * Run Dafny with the command `dafny` If you intend to use the Dafny compiler, install the appropriate tools as described [here](#compiling-dafny). diff --git a/latest/OnlineTutorial/Lemmas.3.expect b/latest/OnlineTutorial/Lemmas.3.expect index 16d9852..741469b 100644 --- a/latest/OnlineTutorial/Lemmas.3.expect +++ b/latest/OnlineTutorial/Lemmas.3.expect @@ -1,6 +1,4 @@ text.dfy(6,0): Error: a postcondition could not be proved on this return path text.dfy(5,10): Related location: this is the postcondition that could not be proved -text.dfy(5,56): Related location -text.dfy(5,65): Related location Dafny program verifier finished with 1 verified, 1 error diff --git a/latest/OnlineTutorial/Lemmas.4.expect b/latest/OnlineTutorial/Lemmas.4.expect index 7bdfae0..dfd367e 100644 --- a/latest/OnlineTutorial/Lemmas.4.expect +++ b/latest/OnlineTutorial/Lemmas.4.expect @@ -1,6 +1,4 @@ text.dfy(6,0): Error: a postcondition could not be proved on this return path text.dfy(5,10): Related location: this is the postcondition that could not be proved -text.dfy(5,56): Related location -text.dfy(5,65): Related location Dafny program verifier finished with 3 verified, 1 error diff --git a/latest/OnlineTutorial/guide.18.expect b/latest/OnlineTutorial/guide.18.expect index cff5e59..271d2cb 100644 --- a/latest/OnlineTutorial/guide.18.expect +++ b/latest/OnlineTutorial/guide.18.expect @@ -1,6 +1,4 @@ text.dfy(4,0): Error: a postcondition could not be proved on this return path text.dfy(3,24): Related location: this is the postcondition that could not be proved -text.dfy(3,54): Related location -text.dfy(3,63): Related location Dafny program verifier finished with 1 verified, 1 error diff --git a/latest/OnlineTutorial/guide.md b/latest/OnlineTutorial/guide.md index 2363ea7..753d6ec 100644 --- a/latest/OnlineTutorial/guide.md +++ b/latest/OnlineTutorial/guide.md @@ -1426,7 +1426,7 @@ method Find(a: array, key: int) returns (index: int) ``` This says that everything before, but excluding, the current -index is not the key. Notice that upon entering the loop, `i` +index is not the key. Notice that upon entering the loop, `index` is zero, so the first part of the implication is always false, and thus the quantified property is always true. This common situation is known as *vacuous truth*: the diff --git a/latest/QuickReference.md b/latest/QuickReference.md old mode 100644 new mode 100755 diff --git a/latest/Snapshots.md b/latest/Snapshots.md index 71eb9ab..c84bc91 100644 --- a/latest/Snapshots.md +++ b/latest/Snapshots.md @@ -7,7 +7,9 @@ layout: default - [Current development version](https://dafny.org/dafny) - [Latest release snapshot](https://dafny.org/latest) +- [v4.4.0](https://dafny.org/v4.4.0) - [v4.3.0](https://dafny.org/v4.3.0) +- [v4.2.0](https://dafny.org/v4.2.0) - [v4.1.0](https://dafny.org/v4.1.0) - [v4.0.0](https://dafny.org/v4.0.0) - [v3.12.0](https://dafny.org/v3.12.0) diff --git a/latest/check-examples b/latest/check-examples old mode 100644 new mode 100755 diff --git a/latest/examples/README.md b/latest/examples/README.md index 5639dec..78cb9dd 100644 --- a/latest/examples/README.md +++ b/latest/examples/README.md @@ -7,10 +7,10 @@ demonstrating various coding techniques or proof capabilities. Each of these verify successfully. The files for these examples can be found in -the [examples folder of Dafny's github project](https://github.com/dafny-lang/dafny/tree/master/Test/examples). +the [examples folder of Dafny's github project](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples). -- [Simple Maximum method](https://github.com/dafny-lang/dafny/tree/master/Test/examples/maximum.dfy) -- [Tutorial on parser combinators](https://github.com/dafny-lang/dafny/tree/master/Test/examples/parser_combinators.dfy) -- [A simple compiler](https://github.com/dafny-lang/dafny/tree/master/Test/examples/Simple_compiler) -- [An example of significant use of induction on a mini-compiler](https://github.com/dafny-lang/dafny/tree/master/Test/examples/induction-principle.md) +- [Simple Maximum method](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples/maximum.dfy) +- [Tutorial on parser combinators](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples/parser_combinators.dfy) +- [A simple compiler](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples/Simple_compiler) +- [An example of significant use of induction on a mini-compiler](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples/induction-principle.md) diff --git a/latest/make-snapshot b/latest/make-snapshot old mode 100644 new mode 100755 index dc16ddd..56ddb78 --- a/latest/make-snapshot +++ b/latest/make-snapshot @@ -21,6 +21,11 @@ if [ ! `which gh` ]; then echo "This script requires that gh is installed"; exit 1; fi if [ ! `which git` ]; then echo "This script requires that git is installed"; exit 1; fi +## Check that gh is logged in by running gh auth status, and if not, run gh auth login +if [ -z "`gh auth status | grep -i logged`" ]; then + gh auth login; +fi + if [ "$#" == "0" ]; then echo "Usage: ./make-snapshot -b " exit 0 @@ -42,7 +47,7 @@ echo Making a snapshot from branch $branch named version $1 ## The version name V=v$1 ## Text string in index.html that marks where to put the version text -M="" +M='' ## Location of the development docs folder D=$(dirname "$BASH_SOURCE") @@ -53,12 +58,21 @@ B=`echo snapshot-$V | sed -e "s/\./_/g"` ## Temp folder in which to clone P=/tmp/docsnapshotT + +if [ -n "$WINDIR" ]; then + P=/c/tmp/docsnapshotT +fi + rm -rf $P -mkdir $P -pushd $P -git clone git@github.com:dafny-lang/dafny.git -b $branch --depth 1 -git clone git@github.com:dafny-lang/dafny-lang.github.io.git -b main --depth 1 -popd +mkdir -p $P + +CWD=`pwd` +cd $P +(git clone git@github.com:dafny-lang/dafny.git -b $branch --depth 1) || \ + (echo FAILED to clone dafny; exit 1) +(git clone git@github.com:dafny-lang/dafny-lang.github.io.git -b main --depth 1) || \ + (echo FAILED to clone dafny-lang.github.io; exit 1) +cd $CWD ## Location of the dafny-lang.github.io repo T=$P/dafny-lang.github.io @@ -78,7 +92,8 @@ rm Snapshots.md-e git add Snapshots.md git commit -m "Documentation snapshot for $V" git push --set-upstream origin "$B" -gh pr create --fill -R https://github.com/dafny-lang/dafny -B $branch --head "$B" | tail -1 > $P/url1 +(gh pr create --fill -R https://github.com/dafny-lang/dafny -B $branch --head "$B" | tail -1 > $P/url1) || \ + (echo FAILED to create PR with gh; exit 1) ## Changes on dafny-lang.github.io ( cd $T && git checkout -b "$B" main ) || \ @@ -87,7 +102,8 @@ gh pr create --fill -R https://github.com/dafny-lang/dafny -B $branch --head "$B (cd $T; git rm -r latest; rm -rf latest; mkdir latest; git commit -m "Removing old latest") cp -R . "$T/$V" || ( echo copy FAILED; exit 1 ) -cp -R "$T/$V/" "$T/latest/" +## Copy the latest snapshot "$T/$V" to the latest folder "$T/latest/" +cp -R "$T/$V/." "$T/latest" cp Snapshots.md "$T" ## Tweaks to snapshot files @@ -103,7 +119,8 @@ grep -q "$M" $T/$V/index.html || (echo FAILED: No Version marker line in "$T/$V/ sed -i -e "s/$M.*/${M}$V documentation snapshot/" $T/$V/index.html || (echo Version replacement FAILED; exit 1; ) sed -i -e "s/$M.*/${M}Latest release documentation snapshot/" $T/latest/index.html || (echo Version replacement FAILED; exit 1; ) -pushd $T +CWD=`pwd` +cd $T rm `find . -name index.html-e` (git add -u \ @@ -115,7 +132,7 @@ rm `find . -name index.html-e` git status git push --set-upstream origin "$B" gh pr create --fill -R https://github.com/dafny-lang/dafny-lang.github.io -B main --head "$B" | tail -1 > $P/url2 -popd +cd $CWD ##diff -r . $T/latest ##diff -r . $T/$V diff --git a/latest/v4.3.0/DafnyRef/version.txt b/latest/v4.3.0/DafnyRef/version.txt deleted file mode 100644 index 00113e6..0000000 --- a/latest/v4.3.0/DafnyRef/version.txt +++ /dev/null @@ -1 +0,0 @@ -v4.3.0 release snapshot diff --git a/latest/v4.3.0/dev/Coverage.md b/latest/v4.3.0/dev/Coverage.md deleted file mode 100644 index 068bae2..0000000 --- a/latest/v4.3.0/dev/Coverage.md +++ /dev/null @@ -1,15 +0,0 @@ - - -# Viewing Test coverage results - -Test coverage data is generated as part of each CI test run, in the "Build and Test" workflow - -- Open the [Actions page for this workflow](https://github.com/dafny-lang/dafny/actions/workflows/msbuild.yml) -- Click on a relevant run -- At the bottom of the page (you will likely need to scroll down), in the Artifacts section, click on "test-coverage-results" to download the detailed coverage results. - - Open (in a browser) the file 'coverage-html/index.html' within the dowloaded folder for an entree to the color-coded source code and data showing coverage numbers -- Also, opening the 'test-coverage-analysis' job at the end of the workflow graph - shows two job steps that report the summary coverage numbers: - - "Code-coverage report (Non-LSP)" - - "Code coverage report (LSP)" - diff --git a/latest/v4.3.0/dev/Dafny-Documentation-Status-31May2023.md b/latest/v4.3.0/dev/Dafny-Documentation-Status-31May2023.md deleted file mode 100644 index c3f34db..0000000 --- a/latest/v4.3.0/dev/Dafny-Documentation-Status-31May2023.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: Summary of Dafny Documentation ---- - -Author: David R. Cok (david.r.cok@gmail.com) - 31 May 2023 - -## dafny.org - -The user portal to Dafny documentation is the dafny.org website. -This is a GitHub Pages site, served by GitHub, from the dafny-lang/dafny.github.io repository. -However the material in this repository is a series of snapshots of the development version of the documentation. -That development version is maintained in the docs folder of the dafny-lang/dafny GitHub project. - -It is not intended that the dafny-lang/dafny.github.io (the GitHub pages) site be edited directly. -Instead, the process for creating a new Dafny release includes creating a snapshot of the current Dafny documentation (by running the script docs/make-snapshot) -dafny.org points by default to the documentation at the time of the latest release (at dafny.org/latest), with earlier release snapshots also available, -The bleeding-edge current development state is available at dafny.org/dafny. - -This documentation consists of a variety of large and small documents and links to other resources, such as books. - -Some issues to watch: -- Having the current version of documentation in dafny-lang/dafny keeps changes in documentation as part of the same commits as changes in code. -- However, maintaining the github pages site as a collecction of snapshots also has a maintenance cost. -- It is not known how much use users make of which material on these websites. Some analytics would inform future work. -- It is not known how frequently users access old material, to justify maintaining it. (One could always resurrect old version from GitHub directly.) - -## The GitHub project - -The Dafny project uses GitHub repositories to store all of its artifacts. There are a number of repositories, all under github.com/dafny-lang. - -The principal repository is github.com/dafny-lang/dafny, which contains the project source code and the project documentation. The latter is primarily in dafny/docs. - -## Dafny Reference Manual and User Guide - -This large document is the definition of the Dafny language and a guide to its use. - * It is a (GitHub) markdown document that is served by GitHub pages at dafny.org/latest/DafnyRef/DafnyRef (with snapshots at each release); the current development version is https://dafny.org/dafny/DafnyRef/DafnyRef - * The source material is in dafny/docs/DafnyRef - * The document is also rendered to pdf using pandoc; that pdf document is created and shipped with each release build. The Makefile to do the building is dafny/docs/DafnyRef/Makefile. The release build happens using GitHub actions on GitHub VMs. - * Section numbering is not built-in (because markdown does not support it). Run `make numbers` when sections need renumbering, which includes updating internal document hyperlinks. - Run `make options` when the command-line options documentation needs updating (this material is included by running the dafny tool to print out the in-app help information. - The CI build will fail if section numbering and options are not up-to-date in the manual. - -Maintenance of the reference manual. - * Team members are expected to add documentation when they add features. Such documentation should be reviewed for understandability and completeness. Also, periodically the whole document needs review for consistency. - * Particularly before each release, a check should be made that new functionality is described thoroughly in the release. - * The manual is large and has grown to include reference manual material (the definition of the Dafny language), user guide material (how to use the dafny tools) and tutorial material (detailed explanations and examples). It might be reasonable to separate these into different documents. - * Various touchup tasks are listed in the github issues list with the ‘documentation’ tag - -## FAQs - -The folder docs/HowToFAQ contains a large number of files named FAQ*.md. These along with index.md and one-page.md are a collection of FAQs and answers. -Each FAQ has a title and link in `index.md`, which points to a markdown file for that FAQ. -To aid searching, a (long) one page version is generated with the script `make-onepage`, which generates the `one-page.md` file (so that file should not be edited directly. - -Task for the future: -- add to FAQs based on more recent questions -- consider whether to have just the index.md and one-page.md and avoid the intermediate small files -- determine how much use is made of these files - -## Small documents - -- Installation instructions (these should be validated on clean systems every now and then, particularly when new versions of OSes are released) -- Landing page for dafny.org -- The Style Guide to writing Dafny programs. - -## Error message catalog - -The files `docs/HowToFAQ/Errors-*.md` contain a catalog of (ideally) every error message that Dafny tools can produce, along with (a) a small code example that elicits that error and (b) an extended explanation of the error, sufficient to aid the user in fixing the error. -This is a sizable body of work and needs continual updating as the Dafny tools evolve. -The code examples are written in such a way that running the `check-examples` script on each of these .md files checks that the code does indeed produce to reported error. This check is done as part of CI to ensure the error messages stay correct as the code evolves. - -TODO - add material about tools to check that the information is consistent. - -## Checking of examples - -Nearly all the examples in the reference manual, error catalog, FAQs and tutorials are written in a way such that scripts (`check-examples`) check that the examples work correctly (as dafny evolves). These checks are done as part of CI. - -## Material for developers of the dafny tools - -The folder ‘docs/dev’ contains material relevant to developers and not to users. This includes information like release instructions and measuring test coverage. - -## The Dafny Library - -The Dafny library is a set of (mostly) Dafny code that implements core modules and algorithms that many users might commonly use and should not have to reimplement. -Anything in the library should be documented, with examples. The examples should be checked during the regular CI of the library. -Making sure the documentation is accurate and complete as material is added to the library requires ongoing vigilance. - -The library is in the dafny-lang/libraries repository. - -## Dafny doc - -`dafny doc` is a dafny tool particularly relevant to documentation: it generates html pages from the docsstring content within Dafny programs. -It is meant both for user use and as a way to generate web-based documentation of the library. - -Task for the future: As of 31 May 2023, the library and the dafny doc tool are not yet released in a manner that there are published library documentation pages on the dafny web site. - -## Other material - -- Rustan Leino authors a number of ‘Dafny Power User’ notes and other Dafny technical references. These are typically hosted on his own professional web site at https://leino.science/dafny-power-user/. -They have typically not been reviewed directly by any Dafny technical documentation team. - -- John Tristan teaches courses and workshops on Dafny and authors course materials for that purpose. - -- Some tutorial material is written by developers separately and typically needs to be coralled into the docs arena, reviewed and edited, and with CI checks to make sure examples stay operational. - -- Blog posts as yet do not have mechanisms to check that code snippets are valid Dafny. - - diff --git a/latest/v4.3.0/dev/README.md b/latest/v4.3.0/dev/README.md deleted file mode 100644 index 5bd1226..0000000 --- a/latest/v4.3.0/dev/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Latest Dafny changes - -Each file in the `news/` folder describes one change in Dafny since the latest release. - -Files in this directory are named `.` (e.g. `1234.fix`) or `.kind` (`assign-such-that-null.fix`) and each contains release notes for one merged PR. `kind` is `break` (for breaking changes), `feat` (for new features and enhancements) or `fix` (for bug fixes). - -No need to include a link to a PR or issue in the file: it will be added automatically. Specifically: - -- With `.`, the link will point to that issue number. -- With `.`, the link will point to the PR that introduced the release note file (which should be the PR for the corresponding feature or fix; its number is determined automatically by the release script from the commit history). - -You can also use `.` to link to a PR manually. This is useful when using a a follow-up PR to add missing release notes for an already-merged feature (since the notes should contain a link to the original PR, not the follow-up one). - -## Examples - -- `1234.fix` - - ``` - Dafny will now detect and report burning toast. - ``` - -- `new-toast-patterns.feat` - - ``` - Two new toast patterns: - - Dafny waterfall logo - - Dafny haircut logo - (They are the same.) - ``` - -At release time, these two files become bullet points in a new section of `RELEASE_NOTES.md` with links to the corresponding PRs, like this: - -``` -## New features - -- Two new toast patterns: - - Dafny waterfall logo - - Dafny haircut logo - (They are the same.) - (https://github.com/dafny-lang/dafny/pull/5678) - -## Bug fixes - -- Dafny will now detect and report burning toast. (https://github.com/dafny-lang/dafny/pull/1234) -``` - -Note that a newline is added before the link only if the original is more than one line long. The link to the first PR is computed automatically by scanning the Git history. diff --git a/latest/v4.3.0/dev/RELEASE.md b/latest/v4.3.0/dev/RELEASE.md deleted file mode 100644 index 1368171..0000000 --- a/latest/v4.3.0/dev/RELEASE.md +++ /dev/null @@ -1,131 +0,0 @@ -# Preparing a new Dafny release - -## Making a new Github release - -1. Ensure that you are in a repository that: - * is clean and up-to-date with no uncommitted changes, - * was cloned with SSH so that you can push to it, and - * has the intended branch checked out (usually `master`, - but may be another mainline branch such as `main-3.x`). - -1. Select a version number `$VER` (e.g., "3.0.0" or "3.0.0-alpha"). - The `major`.`minor`.`patch` numbers may already have been - incremented since the last release, so they do not necessarily need - to be updated. However, you may want to increment them further - depending the types of changes that are in the release. - -1. Run `Scripts/prepare_release.py $VER prepare --source-branch ` - (`--source-branch` is optional and defaults to 'master') - from the root of the repository. The script will check that the repository is in a good - state, create and check out a new release branch, update - `Source/Directory.Build.props` and `RELEASE_NOTES.md`, prepare a release commit, - and push it. - -1. Run `./Scripts/prepare_release.py $VER - release` from the root of the repository. The script will tag the - current commit and push it. A - GitHub action will automatically run in reaction to the tag being - pushed, which will run the deep integration test suite, - build the artifacts and reference manual, - publish artifacts to nuget.org, and then - create a draft GitHub release. You can find and watch the progress of - this workflow at . - -1. Once the action completes, you should find the draft release at - . Edit the release body to add in - the release notes from `RELEASE_NOTES.md`. If this is not a pre-release, - check the box to create a new discussion based on the release. - -1. Push the "Publish" button. This will trigger yet another workflow - that will download the published artifacts and run a smoke test - on multiple platforms. Again you can watch for this workflow at - . - -1. Create a pull request to merge the newly created branch into the source branch (the - script will give you a link to do so). Get it approved and merged. - -1. Clone and run `publish_process.js` - to create a new release of the VSCode plugin. - -1. Make a documentation snapshot - 1. Run the (bash) command `dafny/docs/make-snapshot -b x.y.z` - where `x.y.z` is the new version number - and is the branch used (defaults to 'master') - 1. The script creates new PRs in dafny-lang/dafny - and dafny-lang/dafny-lang.github.io. - Approve and merge these PRs. - -1. Add the new version to the list of versions to be checked in the library repo, - namely the list in the file libraries/.github/workflows/tests.yml. - -1. Update the Homebrew formula for Dafny (see below). - Note that it is fine to leave this for the next day, - and other members of the community may update the formula - in the meantime anyway. - -1. Once the Homebrew formula is merged, test that it works correctly by - going to and manually - running the "Test Brew release on Mac" workflow. It doesn't matter - what branch you run it on because it won't actually check out the - code. It will just install Dafny from Homebrew and run it on some - examples. - -If something goes wrong with the `prepare` step: - -- Remove the release commit (`git reset --hard HEAD~1`) -- Commit fixes -- Re-run the `prepare` step; the script will recognize the `release-` branch and will not recreate it. - -If something goes wrong with the `release` step: -- Delete the local tag: `git tag -d vA.B.C` -- Delete the remote tag: `git push --delete origin vA.B.C` -- Return to the `prepare` step. - -1. Announce the new release to the world. - -## Updating Dafny on Homebrew - -Homebrew (`brew`) is a package manager for macOS. The Dafny project -maintains a brew "formula" that allows easy installation of Dafny and -its dependencies on macOS. - -These are the instructions for updating the formula, which must be done -each time a new release is issued. - -These instructions are meant to be executed on a Mac, in a Terminal shell. -All the Homebrew formulas are held in a GitHub repo, so some familiarity -with git commands and concepts is helpful. - -0. Install Homebrew if it is not already present on your machine. - Running `which brew` will tell you if it is. See - if not. - -1. Create a GitHub personal access token (if you don't have one handy), - and put it in an environment variable: - - ``` - export HOMEBREW_GITHUB_API_TOKEN=your_token_here - ``` - -2. Create a pull request following the instructions here: - - - - These instructions currently involve the following command: - -``` - brew bump-formula-pr \ - --url \ - --sha256 -``` - -3. Expect comments from the reviewers. If changes are needed, do 4-6 - again. Eventually the reviewers will accept and merge the PR. - -4. Test the installation by running - - brew reinstall dafny - - and then execute `dafny /version` see if it has the correct version - number. Even better is to try this step on a different machine than - the one on which the `dafny.rb` file was edited diff --git a/latest/v4.3.0/dev/TypeSystemRefresh.md b/latest/v4.3.0/dev/TypeSystemRefresh.md deleted file mode 100644 index fc8248f..0000000 --- a/latest/v4.3.0/dev/TypeSystemRefresh.md +++ /dev/null @@ -1,130 +0,0 @@ -# Dafny type system refresh - -## Overview - -The "type system refresh" is a reimplementation of Dafny's name resolution, type inference, and type checking. In many ways, it just improves the organization of the implementation. This will allow Dafny's type system to continue to evolve. For example, it has already enabled the support of traits on datatypes, and it has been building with non-numeric newtypes in mind. Most of this document is concerned with the new implementation. But the new type system also makes some changes in the language that are not backward compatible. Those breaking changes are: - -* An downcast from a trait to some type that implements the trait now requires an explicit cast (using `as`). Like the previous implicit cast, this explicit cast is checked statically. - - Other popular languages with static type checking also require such a cast. Note, subset types are unaffected by this change; for example, it is still possible to write an assignment from an `int` to a `nat` without an explicit cast. - -* Equality-checking expressions (like `==`) no longer treat formal type parameters in a special way. - - Previously, Dafny allowed, for example, an `array` and an `array` to be compared, where `X` is a type parameter, on the grounds that `X` may be `int` and thus the two arrays could be equal. Since Dafny, now since many years, has an `as` operator, such a comparison can easily be expressed without a special case in the type system: `a == b as object`. - -* The types of bound variables are inferred to be base types, not subset types. For example, bound variable `x` in `forall x :: P(x)` may be inferred to have type `int`, but never `nat`. - - This makes inference more predictable. It also removes the risk that, say, an intended quantifier `forall x: int :: P(x)` is instead inferred to be the logically weaker `forall x: nat :: P(x)`. - - (This design may soon change in one place, namely when a lambda expressions is known to be used in a limited number of places. This happens in array initializers and sequence comprehensions, where it would be friendly to try to infer the bound variable to be of type `nat` rather than `int`.) - -The new type system also fixes a number of bugs in the previous type system. Among them are bugs having to do with cyclic dependencies among declarations, which the new type system is equipped to handle. - -The rest of this document describes the implementation of the new type system. - -## Pre-types and type adjustments - -The earlier parts of the resolver are tricky, because of cyclic dependencies among the information that is to be computed. For example, to determine the type of an expression `o.f`, it is necessary to know what `f` is, which in turn requires knowing the type of `o`. As a concrete example, consider - -``` dafny -class Cell { - var data: bv32 - constructor (data: bv32) { - this.data := data; - } -} - -method Tricky() { - var c := null; // Cell? - var s := 0; // bv32 - for i := 0 to 100 { - if c == null { - c := new Cell(s + 10); - } - s := s + c.data; - } -} -``` - -For the expression `c.data` in the loop body, name resolution will determine that `c` is a local variable, then type inference will determine that the type of `c` is `Cell?`, then name resolution to look up `data` as a member in class `Cell`, and then type inference can determine the type of `c.data` to be `bv32`. (Type inference will then also determine that `s` has type `bv32`, and therefore that the literal `0` in the initial assignment to `s` also has type `bv32`.) So, name resolution and some part of type inference are mutually dependent. - -Define _pre-type_ to be a type that is completed handled by the static type system, without the later help of the verifier. In other words, a pre-type is a type that does not involve subset types. It is the inference of pre-types that is mutually dependent on name resolution, because subset types do not introduce any type members (like the `.f` in the example above). This suggests separating name resolution and pre-type inference from the further inference of types with subset types. But there is also another reason for such a separation, namely that assignments in Dafny (like `x := E;`) obey standard subtyping rules for pre-types, whereas types with subset types do not. For example, the pre-type of `E` must be a subtype of the pre-type of `x`. The subset type `nat` is a subtype of the base type `int`, and the type system allow any combination of `x` and `E` being `int` or `nat`; in particular, it allows `E` to have type `int` and `x` to have type `nat`. By separating concerns regarding subset types from the initial inference where names are resolved, the tricky part of resolving names gets to use simpler type constraints. - -After successfully completing pre-type inference, all names and operators have been resolved, and all expressions and variables have pre-types. Since subset types are the difference between pre-types and types, and since subset types are enforced by the verifier, one could imagine that type inference would be done. This is almost true, but not quite. For one, having only the pre-types means that the verifier has to work harder than necessary. For example, using the `Cell` class from above, consider the program - -``` dafny -method Add(x: bv32, y: bv32) returns (r: bv32) { - var c := new Cell(x); - var d := new Cell(y); - r := c.data + d.data; -} -``` - -The pre-types of `c` and `d` are `Cell?`. With just those types, the verifier would have to prove that `c` and `d` are non-null in the expressions `c.data` and `d.data`. However, if type inference could figure out that `c` and `d` have the non-null types `Cell` (recall, `Cell` in Dafny is a subset type with base type `Cell?`), then the verifier would not have anything to prove. There are also situations where the verifier would fail, because of lack of loop invariants. For example, - -``` dafny -method Natural(m: nat, n: nat, s: seq) returns (r: int) { - var k := m; - r := 0; - for i := 0 to |s| { - if k < |s| { - r := r + s[k]; - } - k := if k == m then n else m; - } -} -``` - -The pre-type of `k` is `int`. With only that information about `k`, the operation `s[k]` could not be verified to be using a non-negative index. The proof would go through if one adds `invariant 0 <= k` to the loop. A simpler way to make the proof go through is if `k` can be inferred to have the subset type `nat`, in which case the non-negative index property follows directly from the types. - -Once names have been resolved and pre-types inferred, the type system converts the pre-types into types and then goes into a phase of _adjusting_ those types into types that involve subset types. For example, if a local variable `x` (without a user-supplied type) is inferred to have pre-type `int` and all assignments to `x` are from variables declared to have `nat`, then `x` will, at the end of the type adjustment phase, have type `nat`. - -## Resolution phases - -Resolution proceeds in a number of phases. One group of these phases is called "pass 0" in the resolver (search for "`Pass 0`" in `ModuleResolver.cs`). This document is concerned with describe the phases in pass 0. - -The name "pass 0" is somewhat arbitrary, since resolution performs some important tasks before pass 0. Those initial tasks are quite delicate, since they don't even have pre-types available. It would be good to have a document that describes those initial tasks. For now, suffice it to mention three ingredients of those tasks (performed in the order here listed): - -* Resolve import relations between modules. This allows the rest of resolution to happen one module at a time. Indeed, the resolution phases described here at all performed for one module at a time (from inner modules to outer modules). -* Register the names of top-level declarations and member declarations in each module (that is, build a symbol table from names to declarations). -* Resolve the types that occur in top-level declarations and member declarations. (Note, `newtype`, subset type, and `const` declarations are allowed to omit types in their signatures. Such types will be inferred in pass 0. This issue is tricky, since it means that pass 0 can't rely on all type signatures to be known. More about that below.) - -After pass 0, the resolver has many more phases. Those are grouped into pass 1, 2, and 3. The division between those names is rather arbitrary, but it generally true that later phases have more information about the module being resolved. As Dafny evolves and new phases are added, it is therefore a good idea to add new phases as late as possible, since that means they have more information to start with. - -For the new type system, pass 0 consists of the following phases: - -* Resolve names and infer pre-types. Ostensibly, this iterates over all declarations (in the module being resolved), computing the pre-type signature and body of each declaration. When one declaration uses another (that is, when one declaration has a name that resolves to another declaration), then it is only the pre-type signature of the other declaration that is needed. Because `newtype`, subset type, and `const` declarations can omit their type signatures and let them be inferred, the order in which declarations have to visited cannot be _a priori_ determined (in particular, note that determining such an order requires names to be resolved, but this is the phase that resolves names!). Therefore, this phase keeps track of which declarations are in progress and which have finished, and so will visit the declarations on demand. If any cycles are detected, they are reported as errors. - -* Look for any under-specified pre-types, that is, places where pre-type inference did not come up with a type. This phase also fills in some additional information in the AST, like the `.ResolvedOp` field of binary expressions. - -* Convert pre-types to types. - - The central operation in this phase is the `Combine` method, which combines whatever portions of the type may have been given explicitly in the program with the portions of the type inferred as a pre-type. In some cases, the pre-type may have more information; for example, when a local variable is declared without any type information. In other cases, the user-declared type may have more information; for example, if a variable is declared to have type `nat`, in which case pre-type inference would only have used the fact that this type has a pre-type of `int`. There are also cases where the two need to be combined; for example, with a declaration `class C` in scope, the program may have declared a local variable `var c: C;` (where `C` is the subset type based on the nullable (pre-)type `C?`) and pre-type inference may have come up with `C?`, so these will be combined into something that has both the subset type `C` and the type argument `int`. - - Whenever this combination reaches a place where no user-supplied type is given, `Combine` will output an _adjustable type_. This will let the later type-adjustment phase change the type to take subset types into consideration. Such an adjustable type is a wrapper around another type, which is the "current approximation" of that type. At first, that approximation is a "bottom type" (see description below of the type-adjustment phase), which will be gradually adjusted in the next phase. - - The bottom type is also a kind of wrapper, since it keeps track of the base type for which it is a bottom type. At the moment, both the adjustable-type wrapper and the bottom-type wrapper are implemented as type proxies (that is, as subclasses of `TypeProxy`). This may not be the best representation. It means that the type-adjustment phase needs its own version of `.Normalize()`, or otherwise one would skip passed these two special wrappers, too. It also means that the `.Type` getter of `Expression` needs to have an `.UnnormalizedType` variation, since `.Type` (anticipates uses that occur after type inference and) normalizes the types it gets and sets. A property of these wrappers is that a bottom-type wrapper is only ever used as the type contained in an adjustable-type wrapper. - - This phase needs to start by processing `newtype`, subset type, and `const` declarations, because their type signatures are needed when converting other types. This may seem like the dependency issues that during pre-type inference necessitated an on-demand computation. Luckily, this phase is simpler, because all it needs to do is to combine any user-supplied type in the signatures of these declarations with any inferred pre-type. This `Combine` operation does not need to look at any other declarations. So, all that is needed in this phase is to process those three kinds of declarations first, and then process all the other declarations. - -* Adjust the initial user-supplied-type/inferred-pre-type combinations into types that take subset types into consideration. - -## Conversions of pre-types into types, and type adjustments - -Subset types form a hierarchy (a tree) rooted at a base type. Each subset type is declared with a predicate, but those predicates are not consulted during type adjustment. Instead, only the edges in the hierarchy are used. In other words, subset-type inference is done _nominally_, not semantically. For the purposes of type adjustments, we also use a "bottom type" for each base type. This bottom type is considered to be a subset of the base type and all its (transitive) subset types. - -This phase sets up "flows", where one or several types have an influence on another type. For example, there is a flow from the RHS of an assignment to the LHS of the assignment, and there is a flow from the `then` and `else` expressions of an `if-then-else` expression into the result of the expression. This phase defines a set of such flows for the module. The `Solve()` method then finds the more general types that satisfy these flows. - -The conversion from pre-types to types is coupled with the type-adjustment phase. The former needs to create adjustable types for the latter to adjust. Also, if there is a type that will not be adjusted, then the conversion phase should not set it to be a bottom type. For example, if the pre-types of expressions `x` and `y` are `int`, then the type of expression `x + y` is fixed to be `int`. That is, even if the types of `x` and `y` are eventually adjusted to, say, `nat`, the type of `x + y` is still defined to be `int`. For this situation, the type-adjustment phase does not define any flow from `x` and `y` to `x + y`, since it is not desirable to further adjust the type of `x + y`. - -## Solving constraints - -Pre-type inference builds up constraints that are required to hold among the pre-types to be inferred, and the type-adjustment phase builds up flows that are used to compute the final types as fix-points. At the moment, the data structures used in those phases are simple lists. Surely, there are far better ways to organize these constraints and flows. These can be improved and suitably optimized in the future. - -In the current implementation, pre-type constraints are built up and solved for each declaration, whereas the flows are built up and solved for the entire module. The flows in one declaration do not affect the flows of other declarations, so the flows could be changed to be solved after each declaration (and doing so would probably be more efficient, since it a set of smaller fix points would be faster to compute than one fix point for the whole module). - -Saying that pre-type constraints built up and then solved for each declaration is an over-simplification. In more detail, some parts of a declaration may be considered separately. For example, each attribute of a top-level declaration is considered separately. Moreover, pre-type inference sometimes _partially solves_ the constraints while building up more constraints. This currently happens in a few places, typified by member lookup, where pre-type inference will partially solve constraints in order to obtain enough of the type of `o` in an expression `o.f` before continuing to process the expression. If the partial solving does not yield enough of a pre-type for `o` to determine `f`, then an error is reported right away, rather than waiting until all constraints are solved. This design is a left-over from the old type system. The new type system has a notion of "guarded constraints", which could be used to eliminate any partial solving and instead just do solving at the end. However, in order to reduce changes between the old and new type system, it seemed wise to keep this design for now. Once the new type system is stable, it can be changed to use "guarded constraints" for expressions like member lookup, which will then admit strictly more programs. - -## Debugging - -The `/ntitrace:1` flag (for "New Type Inference TRACE") spills out information from pre-type inference and from type adjustment. diff --git a/latest/v4.3.0/.gitignore b/v4.4.0/.gitignore similarity index 100% rename from latest/v4.3.0/.gitignore rename to v4.4.0/.gitignore diff --git a/latest/v4.3.0/Compilation/AutoInitialization.md b/v4.4.0/Compilation/AutoInitialization.md similarity index 100% rename from latest/v4.3.0/Compilation/AutoInitialization.md rename to v4.4.0/Compilation/AutoInitialization.md diff --git a/latest/v4.3.0/Compilation/Boogie.md b/v4.4.0/Compilation/Boogie.md similarity index 100% rename from latest/v4.3.0/Compilation/Boogie.md rename to v4.4.0/Compilation/Boogie.md diff --git a/latest/v4.3.0/Compilation/Go.md b/v4.4.0/Compilation/Go.md similarity index 100% rename from latest/v4.3.0/Compilation/Go.md rename to v4.4.0/Compilation/Go.md diff --git a/latest/v4.3.0/Compilation/ReferenceTypes.md b/v4.4.0/Compilation/ReferenceTypes.md similarity index 100% rename from latest/v4.3.0/Compilation/ReferenceTypes.md rename to v4.4.0/Compilation/ReferenceTypes.md diff --git a/latest/v4.3.0/Compilation/StringsAndChars.md b/v4.4.0/Compilation/StringsAndChars.md similarity index 100% rename from latest/v4.3.0/Compilation/StringsAndChars.md rename to v4.4.0/Compilation/StringsAndChars.md diff --git a/latest/v4.3.0/Dafny-cheat-sheet.pdf b/v4.4.0/Dafny-cheat-sheet.pdf similarity index 100% rename from latest/v4.3.0/Dafny-cheat-sheet.pdf rename to v4.4.0/Dafny-cheat-sheet.pdf diff --git a/latest/v4.3.0/DafnyCheatsheet.docx b/v4.4.0/DafnyCheatsheet.docx similarity index 100% rename from latest/v4.3.0/DafnyCheatsheet.docx rename to v4.4.0/DafnyCheatsheet.docx diff --git a/latest/v4.3.0/DafnyCheatsheet.pdf b/v4.4.0/DafnyCheatsheet.pdf similarity index 100% rename from latest/v4.3.0/DafnyCheatsheet.pdf rename to v4.4.0/DafnyCheatsheet.pdf diff --git a/latest/v4.3.0/DafnyRef/.gitignore b/v4.4.0/DafnyRef/.gitignore similarity index 100% rename from latest/v4.3.0/DafnyRef/.gitignore rename to v4.4.0/DafnyRef/.gitignore diff --git a/latest/v4.3.0/DafnyRef/Attributes.1.expect b/v4.4.0/DafnyRef/Attributes.1.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Attributes.1.expect rename to v4.4.0/DafnyRef/Attributes.1.expect diff --git a/latest/v4.3.0/DafnyRef/Attributes.3.expect b/v4.4.0/DafnyRef/Attributes.3.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Attributes.3.expect rename to v4.4.0/DafnyRef/Attributes.3.expect diff --git a/latest/v4.3.0/DafnyRef/Attributes.4.expect b/v4.4.0/DafnyRef/Attributes.4.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Attributes.4.expect rename to v4.4.0/DafnyRef/Attributes.4.expect diff --git a/latest/v4.3.0/DafnyRef/Attributes.md b/v4.4.0/DafnyRef/Attributes.md similarity index 84% rename from latest/v4.3.0/DafnyRef/Attributes.md rename to v4.4.0/DafnyRef/Attributes.md index 5207d10..47ce6ac 100644 --- a/latest/v4.3.0/DafnyRef/Attributes.md +++ b/v4.4.0/DafnyRef/Attributes.md @@ -173,6 +173,9 @@ Dafny does not perform sanity checks on the arguments---it is the user's respons For more detail on the use of `{:extern}`, see the corresponding [section](#sec-extern-decls) in the user's guide. +### 11.1.5. `{:disable-nonlinear-arithmetic}` {#sec-disable-nonlinear-arithmetic} +This attribute only applies to module declarations. It overrides the global option `--disable-nonlinear-arithmetic` for that specific module. The attribute can be given true or false to disable or enable nonlinear arithmetic. When no value is given, the default value is true. + ## 11.2. Attributes on functions and methods ### 11.2.1. `{:abstemious}` @@ -256,10 +259,23 @@ The difference with [`{:extern}`](#sec-extern) is that [`{:extern}`](#sec-extern will still emit declaration code if necessary, whereas `{:compile false}` will just ignore the declaration for compilation purposes. -### 11.2.6. `{:extern }` {#sec-extern-method} +### 11.2.6. `{:concurrent}` {#sec-concurrent-attribute} +The `{:concurrent}` attribute indicates that the compiled code for a function or method +may be executed concurrently. +While Dafny is a sequential language and does not support any native concepts for spawning +or controlling concurrent execution, +it does support restricting the specification of declarations such that it is safe to execute them concurrently +using integration with the target language environment. + +Currently, the only way to satisfy this requirement is to ensure that the specification +of the function or method includes the equivalent of `reads {}` and `modifies {}`. +This ensures that the code does not read or write any shared mutable state, +although it is free to write and write newly allocated objects. + +### 11.2.7. `{:extern }` {#sec-extern-method} See [`{:extern }`](#sec-extern). -### 11.2.7. `{:fuel X}` {#sec-fuel} +### 11.2.8. `{:fuel X}` {#sec-fuel} The fuel attribute is used to specify how much "fuel" a function should have, i.e., how many times the verifier is permitted to unfold its definition. The `{:fuel}` annotation can be added to the function itself, in which @@ -282,11 +298,11 @@ fewer assert statements), but it may also increase verification time, so use it with care. Setting the fuel to 0,0 is similar to making the definition opaque, except when used with all literal arguments. -### 11.2.8. `{:id }` +### 11.2.9. `{:id }` Assign a custom unique ID to a function or a method to be used for verification result caching. -### 11.2.9. `{:induction}` {#sec-induction} +### 11.2.10. `{:induction}` {#sec-induction} The `{:induction}` attribute controls the application of proof by induction to two contexts. Given a list of variables on which induction might be applied, the @@ -336,7 +352,7 @@ lemma Correspondence() } ``` -### 11.2.10. `{:only}` {#sec-only-functions-methods} +### 11.2.11. `{:only}` {#sec-only-functions-methods} `method {:only} X() {}` or `function {:only} X() {}` temporarily disables the verification of all other non-`{:only}` members, e.g. other functions and methods, in the same file, even if they contain [assertions with `{:only}`](#sec-only). @@ -361,7 +377,9 @@ method TestUnverified() { `{:only}` can help focusing on a particular member, for example a lemma or a function, as it simply disables the verification of all other lemmas, methods and functions in the same file. It's equivalent to adding [`{:verify false}`](#sec-verify) to all other declarations simulatenously on the same file. Since it's meant to be a temporary construct, it always emits a warning. -### 11.2.11. `{:print}` {#sec-print} +More information about the Boogie implementation of `{:opaque}` is [here](https://github.com/dafny-lang/dafny/blob/master/docs/Compilation/Boogie.md). + +### 11.2.12. `{:print}` {#sec-print} This attribute declares that a method may have print effects, that is, it may use `print` statements and may call other methods that have print effects. The attribute can be applied to compiled @@ -371,11 +389,11 @@ allowed to use a `{:print}` attribute only if the overridden method does. Print effects are enforced only with `--track-print-effects`. -### 11.2.12. `{:priority}` +### 11.2.13. `{:priority}` `{:priority N}` assigns a positive priority 'N' to a method or function to control the order in which methods or functions are verified (default: N = 1). -### 11.2.13. `{:rlimit}` {#sec-rlimit} +### 11.2.14. `{:rlimit}` {#sec-rlimit} `{:rlimit N}` limits the verifier resource usage to verify the method or function at `N * 1000`. This is the per-method equivalent of the command-line flag `/rlimit:N`. @@ -421,15 +439,15 @@ To give orders of magnitude about resource usage, here is a list of examples ind Note that, the default solver Z3 tends to overshoot by `7K` to `8K`, so if you put `{:rlimit 20}` in the last example, the total resource usage would be `27K`. -### 11.2.14. `{:selective_checking}` +### 11.2.15. `{:selective_checking}` Turn all assertions into assumptions except for the ones reachable from after the assertions marked with the attribute `{:start_checking_here}`. Thus, `assume {:start_checking_here} something;` becomes an inverse of `assume false;`: the first one disables all verification before it, and the second one disables all verification after. -### 11.2.15. `{:tailrecursion}` -This attribute is used on method declarations. It has a boolean argument. +### 11.2.16. `{:tailrecursion}` +This attribute is used on method or function declarations. It has a boolean argument. If specified with a `false` value, it means the user specifically requested no tail recursion, so none is done. @@ -444,7 +462,81 @@ recursion was explicitly requested. * If `{:tailrecursion true}` was specified but the code does not allow it, an error message is given. -### 11.2.16. `{:test}` {#sec-test-attribute} +If you have a stack overflow, it might be that you have +a function on which automatic attempts of tail recursion +failed, but for which efficient iteration can be implemented by hand. To do this, +use a [function by method](#sec-function-by-method) and +define the loop in the method yourself, +proving that it implements the function. + +Using a function by method to implement recursion can +be tricky. It usually helps to look at the result of the function +on two to three iterations, without simplification, +and see what should be the first computation. For example, +consider the following tail-recursion implementation: + + +```dafny +datatype Result = Success(value: V) | Failure(error: E) + +function f(x: int): Result + +// {:tailrecursion true} Not possible here +function MakeTailRec( + obj: seq +): Result, string> +{ + if |obj| == 0 then Success([]) + else + var tail := MakeTailRec(obj[1..]); + var r := f(obj[0]); + if r.Failure? then + Failure(r.error) + else if tail.Failure? then + tail + else + Success([r.value] + tail.value) +} by method { + var i: nat := |obj|; + var tail := Success([]); // Base case + while i != 0 + decreases i + invariant tail == MakeTailRec(obj[i..]) + { + i := i - 1; + var r := f(obj[i]); + if r.Failure? { + tail := Failure(r.error); + } else if tail.Success? { + tail := Success([r.value] + tail.value); + } else { + } + } + return tail; +} +``` + +The rule of thumb to unroll a recursive call into a sequential one +is to look at how the result would be computed if the operations were not +simplified. For example, unrolling the function on `[1, 2, 3]` yields the result +`Success([f(1).value] + ([f(2).value] + ([f(3).value] + [])))`. +If you had to compute this expression manually, you'd start with +`([f(3).value] + [])`, then add `[f(2).value]` to the left, then +`[f(1).value]`. +This is why the method loop iterates with the objects +from the end, and why the intermediate invariants are +all about proving `tail == MakeTailRec(obj[i..])`, which +makes verification succeed easily because we replicate +exactly the behavior of `MakeTailRec`. +If we were not interested in the first error but the last one, +a possible optimization would be, on the first error, to finish +iterate with a ghost loop that is not executed. + +Note that the function definition can be changed by computing +the tail closer to where it's used or switching the order of computing +`r` and `tail`, but the `by method` body can stay the same. + +### 11.2.17. `{:test}` {#sec-test-attribute} This attribute indicates the target function or method is meant to be executed at runtime in order to test that the program is working as intended. @@ -482,10 +574,10 @@ harness that supplies input arguments but has no inputs of its own and that checks any output values, perhaps with `expect` statements. The test harness is then the method marked with `{:test}`. -### 11.2.17. `{:timeLimit N}` {#sec-time-limit} +### 11.2.18. `{:timeLimit N}` {#sec-time-limit} Set the time limit for verifying a given function or method. -### 11.2.18. `{:timeLimitMultiplier X}` +### 11.2.19. `{:timeLimitMultiplier X}` This attribute may be placed on a method or function declaration and has an integer argument. If `{:timeLimitMultiplier X}` was specified a `{:timeLimit Y}` attribute is passed on to Boogie @@ -493,11 +585,11 @@ where `Y` is `X` times either the default verification time limit for a function or method, or times the value specified by the Boogie `-timeLimit` command-line option. -### 11.2.19. `{:transparent}` {#sec-transparent} +### 11.2.20. `{:transparent}` {#sec-transparent} By default, the body of a function is transparent to its users. This can be overridden using the `--default-function-opacity` command line flag. If default function opacity is set to `opaque` or `autoRevealDependencies`, then this attribute can be used on functions to make them always non-opaque. -### 11.2.20. `{:verify false}` {#sec-verify} +### 11.2.21. `{:verify false}` {#sec-verify} Skip verification of a function or a method altogether, not even trying to verify the [well-formedness](#sec-assertion-batches) of postconditions and preconditions. @@ -506,7 +598,7 @@ which performs these minimal checks while not checking that the body satisfies t If you simply want to temporarily disable all verification except on a single function or method, use the [`{:only}`](#sec-only-functions-methods) attribute on that function or method. -### 11.2.21. `{:vcs_max_cost N}` {#sec-vcs_max_cost} +### 11.2.22. `{:vcs_max_cost N}` {#sec-vcs_max_cost} Per-method version of the command-line option `/vcsMaxCost`. The [assertion batch](#sec-assertion-batches) of a method @@ -515,7 +607,7 @@ number, defaults to 2000.0. In [keep-going mode](#sec-vcs_max_keep_going_splits), only applies to the first round. If [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) is set, then this parameter is useless. -### 11.2.22. `{:vcs_max_keep_going_splits N}` {#sec-vcs_max_keep_going_splits} +### 11.2.23. `{:vcs_max_keep_going_splits N}` {#sec-vcs_max_keep_going_splits} Per-method version of the command-line option `/vcsMaxKeepGoingSplits`. If set to more than 1, activates the _keep going mode_ where, after the first round of splitting, @@ -526,7 +618,7 @@ case an error is reported for that assertion). Defaults to 1. If [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) is set, then this parameter is useless. -### 11.2.23. `{:vcs_max_splits N}` {#sec-vcs_max_splits} +### 11.2.24. `{:vcs_max_splits N}` {#sec-vcs_max_splits} Per-method version of the command-line option `/vcsMaxSplits`. Maximal number of [assertion batches](#sec-assertion-batches) generated for this method. @@ -534,14 +626,14 @@ In [keep-going mode](#sec-vcs_max_keep_going_splits), only applies to the first Defaults to 1. If [`{:vcs_split_on_every_assert}`](#sec-vcs_split_on_every_assert) is set, then this parameter is useless. -### 11.2.24. `{:vcs_split_on_every_assert}` {#sec-vcs_split_on_every_assert} +### 11.2.25. `{:vcs_split_on_every_assert}` {#sec-vcs_split_on_every_assert} Per-method version of the command-line option `/vcsSplitOnEveryAssert`. In the first and only verification round, this option will split the original [assertion batch](#sec-assertion-batches) into one assertion batch per assertion. This is mostly helpful for debugging which assertion is taking the most time to prove, e.g. to profile them. -### 11.2.25. `{:synthesize}` {#sec-synthesize-attr} +### 11.2.26. `{:synthesize}` {#sec-synthesize-attr} The `{:synthesize}` attribute must be used on methods that have no body and return one or more fresh objects. During compilation, @@ -575,7 +667,7 @@ BOUNDVARS = ID : ID | BOUNDVARS, BOUNDVARS ``` -### 11.2.26. `{:options OPT0, OPT1, ... }` {#sec-attr-options} +### 11.2.27. `{:options OPT0, OPT1, ... }` {#sec-attr-options} This attribute applies only to modules. It configures Dafny as if `OPT0`, `OPT1`, … had been passed on the command line. Outside of the module, @@ -584,9 +676,22 @@ options revert to their previous values. Only a small subset of Dafny's command line options is supported. Use the `/attrHelp` flag to see which ones. -## 11.3. Attributes on assertions, preconditions and postconditions {#sec-verification-attributes-on-assertions} +## 11.3. Attributes on reads and modifies clauses + +### 11.3.1. `{:assume_concurrent}` +This attribute is used to allow non-empty `reads` or `modifies` clauses on methods +with the `{:concurrent}` attribute, which would otherwise reject them. + +In some cases it is possible to know that Dafny code that reads or writes shared mutable state +is in fact safe to use in a concurrent setting, especially when that state is exclusively ghost. +Since the semantics of `{:concurrent}` aren't directly expressible in Dafny syntax, +it isn't possible to express this assumption with an `assume {:axiom} ...` statement. + +See also the [`{:concurrent}`](#sec-concurrent-attribute) attribute. + +## 11.4. Attributes on assertions, preconditions and postconditions {#sec-verification-attributes-on-assertions} -### 11.3.1. `{:only}` {#sec-only} +### 11.4.1. `{:only}` {#sec-only} `assert {:only} X;` temporarily transforms all other non-`{:only}` assertions in the surrounding declaration into assumptions. @@ -623,7 +728,7 @@ As soon as a declaration contains one `assert {:only}`, none of the postconditio You can also isolate the verification of a single member using [a similar `{:only}` attribute](#sec-only-functions-methods). -### 11.3.2. `{:focus}` {#sec-focus} +### 11.4.2. `{:focus}` {#sec-focus} `assert {:focus} X;` splits verification into two [assertion batches](#sec-assertion-batches). The first batch considers all assertions that are not on the block containing the `assert {:focus} X;` The second batch considers all assertions that are on the block containing the `assert {:focus} X;` and those that will _always_ follow afterwards. @@ -680,7 +785,7 @@ method doFocus2(x: bool) returns (y: int) { } ``` -### 11.3.3. `{:split_here}` {#sec-split_here} +### 11.4.3. `{:split_here}` {#sec-split_here} `assert {:split_here} X;` splits verification into two [assertion batches](#sec-assertion-batches). It verifies the code leading to this point (excluded) in a first assertion batch, and the code leading from this point (included) to the next `{:split_here}` or until the end in a second assertion batch. @@ -709,12 +814,12 @@ method doSplitHere(x: bool) returns (y: int) { } ``` -### 11.3.4. `{:subsumption n}` +### 11.4.4. `{:subsumption n}` Overrides the `/subsumption` command-line setting for this assertion. `{:subsumption 0}` checks an assertion but does not assume it after proving it. You can achieve the same effect using [labelled assertions](#sec-labeling-revealing-assertions). -### 11.3.5. `{:error "errorMessage", "successMessage"}` {#sec-error-attribute} +### 11.4.5. `{:error "errorMessage", "successMessage"}` {#sec-error-attribute} Provides a custom error message in case the assertion fails. As a hint, messages indicating what the user needs to do to fix the error are usually better than messages that indicate the error only. For example: @@ -743,9 +848,9 @@ method Test() The success message is optional but is recommended if errorMessage is set. -## 11.4. Attributes on variable declarations +## 11.5. Attributes on variable declarations -### 11.4.1. `{:assumption}` {#sec-assumption} +### 11.5.1. `{:assumption}` {#sec-assumption} This attribute can only be placed on a local ghost bool variable of a method. Its declaration cannot have a rhs, but it is allowed to participate as the lhs of exactly one assignment of the @@ -754,16 +859,16 @@ Boogie output to a declaration followed by an `assume b` command. See [@LeinoWuestholz2015], Section 3, for example uses of the `{:assumption}` attribute in Boogie. -## 11.5. Attributes on quantifier expressions (forall, exists) +## 11.6. Attributes on quantifier expressions (forall, exists) -### 11.5.1. `{:heapQuantifier}` +### 11.6.1. `{:heapQuantifier}` _This attribute has been removed._ -### 11.5.2. `{:induction}` {#sec-induction-quantifier} +### 11.6.2. `{:induction}` {#sec-induction-quantifier} See [`{:induction}`](#sec-induction) for functions and methods. -### 11.5.3. `{:trigger}` {#sec-trigger} +### 11.6.3. `{:trigger}` {#sec-trigger} Trigger attributes are used on quantifiers and comprehensions. The verifier instantiates the body of a quantified expression only when it can find an expression that matches the provided trigger. @@ -809,7 +914,7 @@ Here are ways one can prove `assert P(j + 4);`: * Remove `{:trigger Q(i)}` so that it will automatically determine all possible triggers thanks to the option `/autoTriggers:1` which is the default. -## 11.6. Deprecated attributes +## 11.7. Deprecated attributes These attributes have been deprecated or removed. They are no longer useful (or perhaps never were) or were experimental. They will likely be removed entirely sometime soon after the release of Dafny 4. @@ -822,7 +927,7 @@ Removed: Deprecated: - :opaque : This attribute has been promoted to a first-class modifier for functions. Find more information [here](#sec-opaque). -## 11.7. Other undocumented verification attributes +## 11.8. Other undocumented verification attributes A scan of Dafny's sources shows it checks for the following attributes. diff --git a/latest/v4.3.0/DafnyRef/CommandLineOptions.md b/v4.4.0/DafnyRef/CommandLineOptions.md similarity index 100% rename from latest/v4.3.0/DafnyRef/CommandLineOptions.md rename to v4.4.0/DafnyRef/CommandLineOptions.md diff --git a/latest/v4.3.0/DafnyRef/DafnyRef.bib b/v4.4.0/DafnyRef/DafnyRef.bib similarity index 100% rename from latest/v4.3.0/DafnyRef/DafnyRef.bib rename to v4.4.0/DafnyRef/DafnyRef.bib diff --git a/latest/v4.3.0/DafnyRef/DafnyRef.md b/v4.4.0/DafnyRef/DafnyRef.md similarity index 100% rename from latest/v4.3.0/DafnyRef/DafnyRef.md rename to v4.4.0/DafnyRef/DafnyRef.md diff --git a/latest/v4.3.0/DafnyRef/Expressions.1.expect b/v4.4.0/DafnyRef/Expressions.1.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Expressions.1.expect rename to v4.4.0/DafnyRef/Expressions.1.expect diff --git a/latest/v4.3.0/DafnyRef/Expressions.2.expect b/v4.4.0/DafnyRef/Expressions.2.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Expressions.2.expect rename to v4.4.0/DafnyRef/Expressions.2.expect diff --git a/latest/v4.3.0/DafnyRef/Expressions.3.expect b/v4.4.0/DafnyRef/Expressions.3.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Expressions.3.expect rename to v4.4.0/DafnyRef/Expressions.3.expect diff --git a/latest/v4.3.0/DafnyRef/Expressions.4.expect b/v4.4.0/DafnyRef/Expressions.4.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Expressions.4.expect rename to v4.4.0/DafnyRef/Expressions.4.expect diff --git a/latest/v4.3.0/DafnyRef/Expressions.md b/v4.4.0/DafnyRef/Expressions.md similarity index 99% rename from latest/v4.3.0/DafnyRef/Expressions.md rename to v4.4.0/DafnyRef/Expressions.md index 35827e5..b4a346a 100644 --- a/latest/v4.3.0/DafnyRef/Expressions.md +++ b/v4.4.0/DafnyRef/Expressions.md @@ -900,7 +900,6 @@ Examples: ```dafny allocated(c) allocated({c1,c2}) -allocated@L(c) ``` For any expression `e`, the expression `allocated(e)` evaluates to `true` diff --git a/latest/v4.3.0/DafnyRef/Features.md b/v4.4.0/DafnyRef/Features.md similarity index 91% rename from latest/v4.3.0/DafnyRef/Features.md rename to v4.4.0/DafnyRef/Features.md index d2c5470..c09e18d 100644 --- a/latest/v4.3.0/DafnyRef/Features.md +++ b/v4.4.0/DafnyRef/Features.md @@ -37,11 +37,15 @@ | [Externally-implemented constructors](#sec-extern-decls) | X | | | X | X | X | X | | [Auto-initialization of tuple variables](#sec-tuple-types) | X | X | X | X | X | X | X | | [Subtype constraints in quantifiers](#sec-quantifier-expression) | X | X | X | X | X | X | X | -| [Tuples with more than 20 arguments](#sec-tuple-types) | | X | X | | X | X | X | +| [Tuples with more than 20 arguments](##sec-compilation-built-ins) | | X | X | | X | X | X | +| [Arrays with more than 16 dimensions](##sec-compilation-built-ins) | | X | X | | X | X | X | +| [Arrow types with more than 16 arguments](##sec-compilation-built-ins) | | X | X | | X | X | X | | [Unicode chars](##sec-characters) | X | X | X | X | X | | X | | [Converting values to strings](#sec-print-statement) | X | X | X | X | X | | X | | [Legacy CLI without commands](#sec-dafny-commands) | X | X | X | X | X | X | | | [Separate compilation](#sec-compilation) | X | | X | X | X | X | X | +| [All built-in types in runtime library](#sec-compilation-built-ins) | X | X | X | X | X | | X | +| [Execution coverage report](#sec-dafny-test) | X | | | | | | | [^compiler-feature-forall-note]: 'Sequentializing' a `forall` statement refers to compiling it directly to a series of nested loops with the statement's body directly inside. The alternative, default compilation strategy diff --git a/latest/v4.3.0/DafnyRef/Grammar.1.expect b/v4.4.0/DafnyRef/Grammar.1.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Grammar.1.expect rename to v4.4.0/DafnyRef/Grammar.1.expect diff --git a/latest/v4.3.0/DafnyRef/Grammar.2.expect b/v4.4.0/DafnyRef/Grammar.2.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Grammar.2.expect rename to v4.4.0/DafnyRef/Grammar.2.expect diff --git a/latest/v4.3.0/DafnyRef/Grammar.md b/v4.4.0/DafnyRef/Grammar.md similarity index 99% rename from latest/v4.3.0/DafnyRef/Grammar.md rename to v4.4.0/DafnyRef/Grammar.md index 826110a..a7b7662 100644 --- a/latest/v4.3.0/DafnyRef/Grammar.md +++ b/v4.4.0/DafnyRef/Grammar.md @@ -515,7 +515,7 @@ For example, in the quantifier domain `i | 0 <= i < |s|, y <- s[i] | i < y`, the because the range attached to `i` ensures `i` is a valid index in the sequence `s`. Allowing per-variable ranges is not fully backwards compatible, and so it is not yet allowed by default; -the `--quantifier-syntax:4` option needs to be provided to enable this feature (See [Section 13.8.5](#sec-controlling-language)). +the `--quantifier-syntax:4` option needs to be provided to enable this feature (See [Section 13.9.5](#sec-controlling-language)). ### 2.7.5. Numeric Literals ([grammar](#g-literal-expression)) {#sec-numeric-literals} diff --git a/latest/v4.3.0/DafnyRef/GrammarDetails.md b/v4.4.0/DafnyRef/GrammarDetails.md similarity index 99% rename from latest/v4.3.0/DafnyRef/GrammarDetails.md rename to v4.4.0/DafnyRef/GrammarDetails.md index 6a7b1d9..52f5182 100644 --- a/latest/v4.3.0/DafnyRef/GrammarDetails.md +++ b/v4.4.0/DafnyRef/GrammarDetails.md @@ -782,8 +782,7 @@ InvariantClause_ = ````grammar ReadsClause(allowLemma, allowLambda, allowWild) = - "reads" - { Attribute } + "reads" { Attribute } PossiblyWildFrameExpression(allowLemma, allowLambda, allowWild) { "," PossiblyWildFrameExpression(allowLemma, allowLambda, allowWild) } ```` diff --git a/latest/v4.3.0/DafnyRef/GrammarLinks.java b/v4.4.0/DafnyRef/GrammarLinks.java similarity index 100% rename from latest/v4.3.0/DafnyRef/GrammarLinks.java rename to v4.4.0/DafnyRef/GrammarLinks.java diff --git a/latest/v4.3.0/DafnyRef/Introduction.md b/v4.4.0/DafnyRef/Introduction.md similarity index 100% rename from latest/v4.3.0/DafnyRef/Introduction.md rename to v4.4.0/DafnyRef/Introduction.md diff --git a/latest/v4.3.0/DafnyRef/Makefile b/v4.4.0/DafnyRef/Makefile similarity index 100% rename from latest/v4.3.0/DafnyRef/Makefile rename to v4.4.0/DafnyRef/Makefile diff --git a/latest/v4.3.0/DafnyRef/Modules.1.expect b/v4.4.0/DafnyRef/Modules.1.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Modules.1.expect rename to v4.4.0/DafnyRef/Modules.1.expect diff --git a/latest/v4.3.0/DafnyRef/Modules.10.expect b/v4.4.0/DafnyRef/Modules.10.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Modules.10.expect rename to v4.4.0/DafnyRef/Modules.10.expect diff --git a/latest/v4.3.0/DafnyRef/Modules.2.expect b/v4.4.0/DafnyRef/Modules.2.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Modules.2.expect rename to v4.4.0/DafnyRef/Modules.2.expect diff --git a/latest/v4.3.0/DafnyRef/Modules.3.expect b/v4.4.0/DafnyRef/Modules.3.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Modules.3.expect rename to v4.4.0/DafnyRef/Modules.3.expect diff --git a/latest/v4.3.0/DafnyRef/Modules.4.expect b/v4.4.0/DafnyRef/Modules.4.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Modules.4.expect rename to v4.4.0/DafnyRef/Modules.4.expect diff --git a/latest/v4.3.0/DafnyRef/Modules.5.expect b/v4.4.0/DafnyRef/Modules.5.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Modules.5.expect rename to v4.4.0/DafnyRef/Modules.5.expect diff --git a/latest/v4.3.0/DafnyRef/Modules.6.expect b/v4.4.0/DafnyRef/Modules.6.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Modules.6.expect rename to v4.4.0/DafnyRef/Modules.6.expect diff --git a/latest/v4.3.0/DafnyRef/Modules.7.expect b/v4.4.0/DafnyRef/Modules.7.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Modules.7.expect rename to v4.4.0/DafnyRef/Modules.7.expect diff --git a/latest/v4.3.0/DafnyRef/Modules.md b/v4.4.0/DafnyRef/Modules.md similarity index 100% rename from latest/v4.3.0/DafnyRef/Modules.md rename to v4.4.0/DafnyRef/Modules.md diff --git a/latest/v4.3.0/DafnyRef/Numbers.java b/v4.4.0/DafnyRef/Numbers.java similarity index 100% rename from latest/v4.3.0/DafnyRef/Numbers.java rename to v4.4.0/DafnyRef/Numbers.java diff --git a/latest/v4.3.0/DafnyRef/Options.txt b/v4.4.0/DafnyRef/Options.txt similarity index 94% rename from latest/v4.3.0/DafnyRef/Options.txt rename to v4.4.0/DafnyRef/Options.txt index 5405c72..195121f 100644 --- a/latest/v4.3.0/DafnyRef/Options.txt +++ b/v4.4.0/DafnyRef/Options.txt @@ -106,13 +106,24 @@ Usage: dafny [ option ... ] [ filename ... ] `opaque` means functions are always opaque so the opaque keyword is not needed, and functions must be revealed everywhere needed for a proof. /generalTraits: - 0 (default) - Every trait implicitly extends 'object', and thus is a reference type. Only traits and classes can extend traits. - 1 - A trait is a reference type iff it or one of its ancestor traits is 'object'. Any type with members can extend traits. + legacy (default) - Every trait implicitly extends 'object', and thus is a reference type. Only traits and reference types can extend traits. + datatype - A trait is a reference type only if it or one of its ancestor traits is 'object'. Any non-'newtype' type with members can extend traits. + full - (don't use; not yet completely supported) A trait is a reference type only if it or one of its ancestor traits is 'object'. Any type with members can extend traits. /ntitrace: 0 (default) - Don't print debug information for the new type system. 1 - Print debug information for the new type system. + /readsClausesOnMethods: + 0 (default) - Reads clauses on methods are forbidden. + 1 - Reads clauses on methods are permitted (with a default of 'reads *'). + + /standardLibraries: + 0 (default) - Do not allow Dafny code to depend on the standard libraries included with the Dafny distribution. + 1 - Allow Dafny code to depend on the standard libraries included with the Dafny distribution. + See https://github.com/dafny-lang/dafny/blob/master/Source/DafnyStandardLibraries/README.md for more information. + Not compatible with the /unicodeChar:0 option. + /titrace: 0 (default) - Don't print type-inference debug information. 1 - Print type-inference debug information. @@ -485,6 +496,7 @@ Usage: dafny [ option ... ] [ filename ... ] /printWithUniqueIds : print augmented information that uniquely identifies variables /printUnstructured : with /print option, desugars all structured statements + /printPassive : with /print option, prints passive version of program /printDesugared : with /print option, desugars calls /printLambdaLifting : with /print option, desugars lambda lifting @@ -501,6 +513,8 @@ Usage: dafny [ option ... ] [ filename ... ] unroll loops, following up to n back edges (and then some) /soundLoopUnrolling sound loop unrolling + /doModSetAnalysis + automatically infer modifies clauses /printModel: 0 (default) - do not print Z3's error model 1 - print Z3's error model @@ -642,8 +656,6 @@ Usage: dafny [ option ... ] [ filename ... ] /smokeTimeout: Timeout, in seconds, for a single theorem prover invocation during smoke test, defaults to 10. - /causalImplies - Translate Boogie's A ==> B into prover's A ==> A && B. /typeEncoding: Encoding of types when generating VC of a polymorphic program: m = monomorphic (default) @@ -663,6 +675,10 @@ Usage: dafny [ option ... ] [ filename ... ] Without pruning, due to the unstable nature of SMT solvers, a change to any part of a Boogie program has the potential to affect the verification of any other part of the program. + + Only use this if your program contains uses clauses + where required, otherwise pruning will break your program. + More information can be found here: https://github.com/boogie-org/boogie/blob/afe8eb0ffbb48d593de1ae3bf89712246444daa8/Source/ExecutionEngine/CommandLineOptions.cs#L160 /printPruned: After pruning, print the Boogie program to the specified file. /relaxFocus Process foci in a bottom-up fashion. This way only generates @@ -684,6 +700,13 @@ Usage: dafny [ option ... ] [ filename ... ] This option is implemented by renaming variables and reordering declarations in the input, and by setting solver options that have similar effects. + /trackVerificationCoverage + Track and report which program elements labeled with an + `{:id ...}` attribute were necessary to complete verification. + Assumptions, assertions, requires clauses, ensures clauses, + assignments, and calls can be labeled for inclusion in this + report. This generalizes and replaces the previous + (undocumented) `/printNecessaryAssertions` option. ---- Verification-condition splitting -------------------------------------- @@ -752,7 +775,7 @@ Usage: dafny [ option ... ] [ filename ... ] Limit the number of seconds spent trying to verify each procedure /rlimit: - Limit the Z3 resource spent trying to verify each procedure + Limit the Z3 resource spent trying to verify each procedure. /errorTrace: 0 - no Trace labels in the error output, 1 (default) - include useful Trace labels in error output, diff --git a/latest/v4.3.0/DafnyRef/Plugins.md b/v4.4.0/DafnyRef/Plugins.md similarity index 100% rename from latest/v4.3.0/DafnyRef/Plugins.md rename to v4.4.0/DafnyRef/Plugins.md diff --git a/latest/v4.3.0/DafnyRef/Programs.md b/v4.4.0/DafnyRef/Programs.md similarity index 100% rename from latest/v4.3.0/DafnyRef/Programs.md rename to v4.4.0/DafnyRef/Programs.md diff --git a/latest/v4.3.0/DafnyRef/README.md b/v4.4.0/DafnyRef/README.md similarity index 100% rename from latest/v4.3.0/DafnyRef/README.md rename to v4.4.0/DafnyRef/README.md diff --git a/latest/v4.3.0/DafnyRef/Refinement.md b/v4.4.0/DafnyRef/Refinement.md similarity index 100% rename from latest/v4.3.0/DafnyRef/Refinement.md rename to v4.4.0/DafnyRef/Refinement.md diff --git a/latest/v4.3.0/DafnyRef/Specifications.1.expect b/v4.4.0/DafnyRef/Specifications.1.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Specifications.1.expect rename to v4.4.0/DafnyRef/Specifications.1.expect diff --git a/latest/v4.3.0/DafnyRef/Specifications.2.expect b/v4.4.0/DafnyRef/Specifications.2.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Specifications.2.expect rename to v4.4.0/DafnyRef/Specifications.2.expect diff --git a/latest/v4.3.0/DafnyRef/Specifications.md b/v4.4.0/DafnyRef/Specifications.md similarity index 92% rename from latest/v4.3.0/DafnyRef/Specifications.md rename to v4.4.0/DafnyRef/Specifications.md index 4b53caa..d068b05 100644 --- a/latest/v4.3.0/DafnyRef/Specifications.md +++ b/v4.4.0/DafnyRef/Specifications.md @@ -58,7 +58,7 @@ of all the given Attributes. The order of conjunctions can be important: earlier conjuncts can set conditions that establish that later conjuncts are well-defined. -The attributes recognized for requires clauses are discussed in [Section 11.3](#sec-verification-attributes-on-assertions). +The attributes recognized for requires clauses are discussed in [Section 11.4](#sec-verification-attributes-on-assertions). A requires clause can have [custom error and success messages](#sec-error-attribute). @@ -86,7 +86,7 @@ The order of conjunctions can be important: earlier conjuncts can set conditions that establish that later conjuncts are well-defined. -The attributes recognized for ensures clauses are discussed in [Section 11.3](#sec-verification-attributes-on-assertions). +The attributes recognized for ensures clauses are discussed in [Section 11.4](#sec-verification-attributes-on-assertions). An ensures clause can have [custom error and success messages](#sec-error-attribute). @@ -464,6 +464,12 @@ function g() reads o, oo function h() reads { o } +method f() + reads * +method g() + reads o, oo +method h() + reads { o } ``` Functions are not allowed to have side effects; they may also be restricted in @@ -479,11 +485,24 @@ able to give invariants to preserve it in this case, it gets even more complex when manipulating data structures. In this case, framing is essential to making the verification process feasible. -It is not just the body of a function that is subject to `reads` +By default, methods are not required to list the memory location they read. +However, there are use cases for restricting what methods can read as well. +In particular, if you want to verify that imperative code is safe to execute concurrently when compiled, +you can specify that a method does not read or write any shared state, +and therefore cannot encounter race conditions or runtime crashes related to +unsafe communication between concurrent executions. +See [the `{:concurrent}` attribute](#sec-concurrent-attribute) for more details. + +It is not just the body of a function or method that is subject to `reads` checks, but also its precondition and the `reads` clause itself. A `reads` clause can list a wildcard `*`, which allows the enclosing -function to read anything. In many cases, and in particular in all cases +function or method to read anything. +This is the implicit default for methods with no `reads` clauses, +allowing methods to read whatever they like. +The default for functions, however, is to not allow reading any memory. +Allowing functions to read arbitrary memory is more problematic: +in many cases, and in particular in all cases where the function is defined recursively, this makes it next to impossible to make any use of the function. Nevertheless, as an experimental feature, the language allows it (and it is sound). @@ -491,7 +510,7 @@ If a `reads` clause uses `*`, then the `reads` clause is not allowed to mention anything else (since anything else would be irrelevant, anyhow). A `reads` clause specifies the set of memory locations that a function, -lambda, or iterator may read. The readable memory locations are all the fields +lambda, or method may read. The readable memory locations are all the fields of all of the references given in the set specified in the frame expression and the single fields given in [`FrameField`](#sec-frame-expression) elements of the frame expression. For example, in @@ -546,7 +565,7 @@ another function. For example, function `Sum` adds up the values of ```dafny function Sum(f: int ~> real, lo: int, hi: int): real requires lo <= hi - requires forall i :: lo <= i < hi ==> f.requires(i) + requires forall i :: f.requires(i) reads f.reads decreases hi - lo { @@ -562,9 +581,29 @@ read. More precise would be to specify that `Sum` reads only what `f` reads on the values from `lo` to `hi`, but the larger set denoted by `reads f.reads` is easier to write down and is often good enough.) +Without such `reads` function, one could also write the more precise +and more verbose: + +```dafny +function Sum(f: int ~> real, lo: int, hi: int): real + requires lo <= hi + requires forall i :: lo <= i < hi ==> f.requires(i) + reads set i, o | lo <= i < hi && o in f.reads(i) :: o + decreases hi - lo +{ + if lo == hi then 0.0 else + f(lo) + Sum(f, lo + 1, hi) +} +``` + Note, only `reads` clauses, not `modifies` clauses, are allowed to include functions as just described. +Iterator specifications also allow `reads` clauses, +with the same syntax and interpretation of arguments as above, +but the meaning is quite different! +See [Section 5.11](#sec-iterator-types) for more details. + ### 7.1.6. Modifies Clause ([grammar](#g-modifies-clause)) {#sec-modifies-clause} Examples: @@ -581,12 +620,11 @@ method Q() modifies o, p`f ``` -Frames also affect methods. Methods are not -required to list the things they read. Methods are allowed to read +By default, methods are allowed to read whatever memory they like, but they are required to list which parts of memory they modify, with a `modifies` annotation. These are almost identical to their `reads` cousins, except they say what can be changed, rather than -what the value of the function depends on. In combination with reads, +what the definition depends on. In combination with reads, modification restrictions allow Dafny to prove properties of code that would otherwise be very difficult or impossible. Reads and modifies are one of the tools that allow Dafny to work on one method at a time, @@ -684,10 +722,12 @@ class C { } ``` -A method specification consists of zero or more `modifies`, `requires`, +A method specification consists of zero or more `reads`, `modifies`, `requires`, `ensures` or `decreases` clauses, in any order. -A method does not have `reads` clauses because methods are allowed to -read any memory. +A method does not need `reads` clauses in most cases, +because methods are allowed to read any memory by default, +but `reads` clauses are supported for use cases such as verifying safe concurrent execution. +See [the `{:concurrent}` attribute](#sec-concurrent-attribute) for more details. ## 7.3. Function Specification ([grammar](#g-function-specification)) {#sec-function-specification} @@ -735,7 +775,7 @@ and `yield ensures` clauses. An iterator specification applies both to the iterator's constructor method and to its `MoveNext` method. - The `reads` and `modifies` -clauses apply to both of them. +clauses apply to both of them (but `reads` clauses have a [different meaning on iterators](#sec-iterator-types) than on functions or methods). - The `requires` and `ensures` clauses apply to the constructor. - The `yield requires` and `yield ensures` clauses apply to the `MoveNext` method. @@ -746,6 +786,8 @@ Examples of iterators, including iterator specifications, are given in - a decreases clause is used to show that the iterator will eventually terminate - a yield requires clause is a precondition for calling `MoveNext` - a yield ensures clause is a postcondition for calling `MoveNext` +- a reads clause gives a set of memory locations that will be unchanged after a `yield` statement +- a modifies clause gives a set of memory locations the iterator may write to ## 7.6. Loop Specification ([grammar](#g-loop-specification)) {#sec-loop-specification} diff --git a/latest/v4.3.0/DafnyRef/Statements.1.expect b/v4.4.0/DafnyRef/Statements.1.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.1.expect rename to v4.4.0/DafnyRef/Statements.1.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.10.expect b/v4.4.0/DafnyRef/Statements.10.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.10.expect rename to v4.4.0/DafnyRef/Statements.10.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.13.expect b/v4.4.0/DafnyRef/Statements.13.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.13.expect rename to v4.4.0/DafnyRef/Statements.13.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.14.expect b/v4.4.0/DafnyRef/Statements.14.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.14.expect rename to v4.4.0/DafnyRef/Statements.14.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.15.expect b/v4.4.0/DafnyRef/Statements.15.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.15.expect rename to v4.4.0/DafnyRef/Statements.15.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.2.expect b/v4.4.0/DafnyRef/Statements.2.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.2.expect rename to v4.4.0/DafnyRef/Statements.2.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.3.expect b/v4.4.0/DafnyRef/Statements.3.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.3.expect rename to v4.4.0/DafnyRef/Statements.3.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.4.expect b/v4.4.0/DafnyRef/Statements.4.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.4.expect rename to v4.4.0/DafnyRef/Statements.4.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.5.expect b/v4.4.0/DafnyRef/Statements.5.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.5.expect rename to v4.4.0/DafnyRef/Statements.5.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.6.expect b/v4.4.0/DafnyRef/Statements.6.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.6.expect rename to v4.4.0/DafnyRef/Statements.6.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.7.expect b/v4.4.0/DafnyRef/Statements.7.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.7.expect rename to v4.4.0/DafnyRef/Statements.7.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.8.expect b/v4.4.0/DafnyRef/Statements.8.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.8.expect rename to v4.4.0/DafnyRef/Statements.8.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.9.expect b/v4.4.0/DafnyRef/Statements.9.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Statements.9.expect rename to v4.4.0/DafnyRef/Statements.9.expect diff --git a/latest/v4.3.0/DafnyRef/Statements.md b/v4.4.0/DafnyRef/Statements.md similarity index 99% rename from latest/v4.3.0/DafnyRef/Statements.md rename to v4.4.0/DafnyRef/Statements.md index 667c023..70c1a77 100644 --- a/latest/v4.3.0/DafnyRef/Statements.md +++ b/v4.4.0/DafnyRef/Statements.md @@ -1854,7 +1854,7 @@ Examples of this form of assert are given in the section of the [`reveal`](#sec- An assert statement may have a label, whose use is explained in [Section 8.20.1](#sec-reveal-assertions). -The attributes recognized for assert statements are discussed in [Section 11.3](#sec-verification-attributes-on-assertions). +The attributes recognized for assert statements are discussed in [Section 11.4](#sec-verification-attributes-on-assertions). Using `...` as the argument of the statement is deprecated. diff --git a/latest/v4.3.0/DafnyRef/SyntaxTests.md b/v4.4.0/DafnyRef/SyntaxTests.md similarity index 100% rename from latest/v4.3.0/DafnyRef/SyntaxTests.md rename to v4.4.0/DafnyRef/SyntaxTests.md diff --git a/latest/v4.3.0/DafnyRef/Topics.1.expect b/v4.4.0/DafnyRef/Topics.1.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Topics.1.expect rename to v4.4.0/DafnyRef/Topics.1.expect diff --git a/latest/v4.3.0/DafnyRef/Topics.2.expect b/v4.4.0/DafnyRef/Topics.2.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Topics.2.expect rename to v4.4.0/DafnyRef/Topics.2.expect diff --git a/latest/v4.3.0/DafnyRef/Topics.3.expect b/v4.4.0/DafnyRef/Topics.3.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Topics.3.expect rename to v4.4.0/DafnyRef/Topics.3.expect diff --git a/latest/v4.3.0/DafnyRef/Topics.md b/v4.4.0/DafnyRef/Topics.md similarity index 100% rename from latest/v4.3.0/DafnyRef/Topics.md rename to v4.4.0/DafnyRef/Topics.md diff --git a/latest/v4.3.0/DafnyRef/Types.1.expect b/v4.4.0/DafnyRef/Types.1.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.1.expect rename to v4.4.0/DafnyRef/Types.1.expect diff --git a/latest/v4.3.0/DafnyRef/Types.10.expect b/v4.4.0/DafnyRef/Types.10.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.10.expect rename to v4.4.0/DafnyRef/Types.10.expect diff --git a/latest/v4.3.0/DafnyRef/Types.10a.expect b/v4.4.0/DafnyRef/Types.10a.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.10a.expect rename to v4.4.0/DafnyRef/Types.10a.expect diff --git a/latest/v4.3.0/DafnyRef/Types.11.expect b/v4.4.0/DafnyRef/Types.11.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.11.expect rename to v4.4.0/DafnyRef/Types.11.expect diff --git a/latest/v4.3.0/DafnyRef/Types.12.expect b/v4.4.0/DafnyRef/Types.12.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.12.expect rename to v4.4.0/DafnyRef/Types.12.expect diff --git a/latest/v4.3.0/DafnyRef/Types.13.expect b/v4.4.0/DafnyRef/Types.13.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.13.expect rename to v4.4.0/DafnyRef/Types.13.expect diff --git a/latest/v4.3.0/DafnyRef/Types.14.expect b/v4.4.0/DafnyRef/Types.14.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.14.expect rename to v4.4.0/DafnyRef/Types.14.expect diff --git a/latest/v4.3.0/DafnyRef/Types.15.expect b/v4.4.0/DafnyRef/Types.15.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.15.expect rename to v4.4.0/DafnyRef/Types.15.expect diff --git a/latest/v4.3.0/DafnyRef/Types.16.expect b/v4.4.0/DafnyRef/Types.16.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.16.expect rename to v4.4.0/DafnyRef/Types.16.expect diff --git a/latest/v4.3.0/DafnyRef/Types.17.expect b/v4.4.0/DafnyRef/Types.17.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.17.expect rename to v4.4.0/DafnyRef/Types.17.expect diff --git a/latest/v4.3.0/DafnyRef/Types.18.expect b/v4.4.0/DafnyRef/Types.18.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.18.expect rename to v4.4.0/DafnyRef/Types.18.expect diff --git a/latest/v4.3.0/DafnyRef/Types.19.expect b/v4.4.0/DafnyRef/Types.19.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.19.expect rename to v4.4.0/DafnyRef/Types.19.expect diff --git a/latest/v4.3.0/DafnyRef/Types.2.expect b/v4.4.0/DafnyRef/Types.2.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.2.expect rename to v4.4.0/DafnyRef/Types.2.expect diff --git a/latest/v4.3.0/DafnyRef/Types.20.expect b/v4.4.0/DafnyRef/Types.20.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.20.expect rename to v4.4.0/DafnyRef/Types.20.expect diff --git a/latest/v4.3.0/DafnyRef/Types.21.expect b/v4.4.0/DafnyRef/Types.21.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.21.expect rename to v4.4.0/DafnyRef/Types.21.expect diff --git a/latest/v4.3.0/DafnyRef/Types.22.expect b/v4.4.0/DafnyRef/Types.22.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.22.expect rename to v4.4.0/DafnyRef/Types.22.expect diff --git a/latest/v4.3.0/DafnyRef/Types.25.expect b/v4.4.0/DafnyRef/Types.25.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.25.expect rename to v4.4.0/DafnyRef/Types.25.expect diff --git a/latest/v4.3.0/DafnyRef/Types.26.expect b/v4.4.0/DafnyRef/Types.26.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.26.expect rename to v4.4.0/DafnyRef/Types.26.expect diff --git a/latest/v4.3.0/DafnyRef/Types.3.expect b/v4.4.0/DafnyRef/Types.3.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.3.expect rename to v4.4.0/DafnyRef/Types.3.expect diff --git a/latest/v4.3.0/DafnyRef/Types.4.expect b/v4.4.0/DafnyRef/Types.4.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.4.expect rename to v4.4.0/DafnyRef/Types.4.expect diff --git a/latest/v4.3.0/DafnyRef/Types.5.expect b/v4.4.0/DafnyRef/Types.5.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.5.expect rename to v4.4.0/DafnyRef/Types.5.expect diff --git a/latest/v4.3.0/DafnyRef/Types.6.expect b/v4.4.0/DafnyRef/Types.6.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.6.expect rename to v4.4.0/DafnyRef/Types.6.expect diff --git a/latest/v4.3.0/DafnyRef/Types.7a.expect b/v4.4.0/DafnyRef/Types.7a.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.7a.expect rename to v4.4.0/DafnyRef/Types.7a.expect diff --git a/latest/v4.3.0/DafnyRef/Types.7b.expect b/v4.4.0/DafnyRef/Types.7b.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.7b.expect rename to v4.4.0/DafnyRef/Types.7b.expect diff --git a/latest/v4.3.0/DafnyRef/Types.8.expect b/v4.4.0/DafnyRef/Types.8.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.8.expect rename to v4.4.0/DafnyRef/Types.8.expect diff --git a/latest/v4.3.0/DafnyRef/Types.9.expect b/v4.4.0/DafnyRef/Types.9.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/Types.9.expect rename to v4.4.0/DafnyRef/Types.9.expect diff --git a/latest/v4.3.0/DafnyRef/Types.md b/v4.4.0/DafnyRef/Types.md similarity index 99% rename from latest/v4.3.0/DafnyRef/Types.md rename to v4.4.0/DafnyRef/Types.md index 0d170b3..27c90a9 100644 --- a/latest/v4.3.0/DafnyRef/Types.md +++ b/v4.4.0/DafnyRef/Types.md @@ -1262,7 +1262,8 @@ the domain, the range, and the 2-tuples holding the key-value associations in the map. Note that `m.Values` will have a different cardinality than `m.Keys` and `m.Items` if different keys are associated with the same value. If `m` is an `imap`, then these -expressions return `iset` values. +expressions return `iset` values. If `m` is a map, `m.Values` and `m.Items` +require the type of the range `U` to support equality. [^fn-map-membership]: This is likely to change in the future as follows: The `in` and `!in` operations will no longer be @@ -1684,13 +1685,14 @@ and the subset type `(TT) --> U` is called the _partial arrow type_. think of the little gap between the two hyphens in `-->` as showing a broken arrow.) -The built-in partial arrow type is defined as follows (here shown +Intuitively, the built-in partial arrow type is defined as follows (here shown for arrows with arity 1): ```dafny type A --> B = f: A ~> B | forall a :: f.reads(a) == {} ``` -(except that what is shown here left of the `=` is not legal Dafny syntax). +(except that what is shown here left of the `=` is not legal Dafny syntax +and that the restriction could not be verified as is). That is, the partial arrow type is defined as those functions `f` whose reads frame is empty for all inputs. More precisely, taking variance into account, the partial arrow type @@ -2669,6 +2671,16 @@ Note, in the precondition of the iterator, which is to hold upon construction of the iterator, the in-parameters are indeed in-parameters, not fields of `this`. +`reads` clauses on iterators have a different meaning than they do on functions and methods. +Iterators may read any memory they like, but because arbitrary code may be executed +whenever they `yield` control, they need to declare what memory locations must not be modified +by other code in order to maintain correctness. +The contents of an iterator's `reads` clauses become part of the `reads` clause +of the implicitly created `Valid()` predicate. +This means if client code modifies any of this state, +it will not be able to establish the precondition for the iterator's `MoveNext()` method, +and hence the iterator body will never resume if this state is modified. + It is regrettably tricky to use iterators. The language really ought to have a `foreach` statement to make this easier. Here is an example showing a definition and use of an iterator. @@ -2856,21 +2868,48 @@ body. For a function `f: T ~> U`, the value that the function yields for an input `t` of type `T` is denoted `f(t)` and has type `U`. Note that `f.reads` and `f.requires` are themselves functions. -Suppose `f` has type `T ~> U` and `t` has type `T`. Then, `f.reads` -is a function of type `T ~> set` whose `reads` and `requires` -properties are: +Without loss of generality, suppose `f` is defined as: + +```dafny +function f(x: T): U + reads R(x) + requires P(x) +{ + body(x) +} +``` +where `P`, `R`, and `body` are declared as: + +```dafny +predicate P(x: T) +function R(x: T): set +function body(x: T): U +``` +Then, `f.reads` is a function of type `T ~> set` +whose `reads` and `requires` properties are given by the definition: ```dafny -f.reads.reads(t) == f.reads(t) -f.reads.requires(t) == true +function f.reads(x: T): set + reads R(x) + requires P(x) +{ + R(x) +} ``` `f.requires` is a function of type `T ~> bool` whose `reads` and -`requires` properties are: +`requires` properties are given by the definition: ```dafny -f.requires.reads(t) == f.reads(t) -f.requires.requires(t) == true +predicate f_requires(x: T) + requires true + reads if P(x) then R(x) else * +{ + P(x) +} ``` +where `*` is a notation to indicate that any memory location can +be read, but is not valid Dafny syntax. + In these examples, if `f` instead had type `T --> U` or `T -> U`, then the type of `f.reads` is `T -> set` and the type of `f.requires` is `T -> bool`. diff --git a/latest/v4.3.0/DafnyRef/UserGuide.1.expect b/v4.4.0/DafnyRef/UserGuide.1.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/UserGuide.1.expect rename to v4.4.0/DafnyRef/UserGuide.1.expect diff --git a/latest/v4.3.0/DafnyRef/UserGuide.2.expect b/v4.4.0/DafnyRef/UserGuide.2.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/UserGuide.2.expect rename to v4.4.0/DafnyRef/UserGuide.2.expect diff --git a/latest/v4.3.0/DafnyRef/UserGuide.3.expect b/v4.4.0/DafnyRef/UserGuide.3.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/UserGuide.3.expect rename to v4.4.0/DafnyRef/UserGuide.3.expect diff --git a/latest/v4.3.0/DafnyRef/UserGuide.4.expect b/v4.4.0/DafnyRef/UserGuide.4.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/UserGuide.4.expect rename to v4.4.0/DafnyRef/UserGuide.4.expect diff --git a/latest/v4.3.0/DafnyRef/UserGuide.5.expect b/v4.4.0/DafnyRef/UserGuide.5.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/UserGuide.5.expect rename to v4.4.0/DafnyRef/UserGuide.5.expect diff --git a/latest/v4.3.0/DafnyRef/UserGuide.6.expect b/v4.4.0/DafnyRef/UserGuide.6.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/UserGuide.6.expect rename to v4.4.0/DafnyRef/UserGuide.6.expect diff --git a/latest/v4.3.0/DafnyRef/UserGuide.7.expect b/v4.4.0/DafnyRef/UserGuide.7.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/UserGuide.7.expect rename to v4.4.0/DafnyRef/UserGuide.7.expect diff --git a/latest/v4.3.0/DafnyRef/UserGuide.8.expect b/v4.4.0/DafnyRef/UserGuide.8.expect similarity index 100% rename from latest/v4.3.0/DafnyRef/UserGuide.8.expect rename to v4.4.0/DafnyRef/UserGuide.8.expect diff --git a/latest/v4.3.0/DafnyRef/UserGuide.md b/v4.4.0/DafnyRef/UserGuide.md similarity index 91% rename from latest/v4.3.0/DafnyRef/UserGuide.md rename to v4.4.0/DafnyRef/UserGuide.md index dc2d895..ef90686 100644 --- a/latest/v4.3.0/DafnyRef/UserGuide.md +++ b/v4.4.0/DafnyRef/UserGuide.md @@ -91,7 +91,7 @@ includes or on the command-line.[^fn-duplicate-files] All files recursively included are always parsed and type-checked. However, which files are verified, built, run, or processed by other dafny commands depends on the individual command. -These commands are described in [Section 13.5.1](#sec-dafny-commands). +These commands are described in [Section 13.6.1](#sec-dafny-commands). [^fn-duplicate-files]: Files may be included more than once or both included and listed on the command line. Duplicate inclusions are detected and each file processed only once. For the purpose of detecting duplicates, file names are considered equal if they have the same absolute path, compared as case-sensitive strings (regardless of whether the underlying file-system is case sensitive). Using symbolic links may make the same file have a different absolute path; this will generally cause duplicate declaration errors. @@ -131,15 +131,21 @@ The exact file format is internal and may evolve over time to support additional Note that the library backend only supports the [newer command-style CLI interface](#sec-dafny-commands). -## 13.4. Dafny Code Style +## 13.4. Dafny Standard Libraries + +As of Dafny 4.4, the `dafny` tool includes standard libraries that any Dafny code base can depend on. +For now they are only available when the `--standard-libraries` option is provided, +but they will likely be available by default in the next major version of Dafny. + +See https://github.com/dafny-lang/dafny/blob/master/Source/DafnyStandardLibraries/README.md for details. + +## 13.5. Dafny Code Style There are coding style conventions for Dafny code, recorded [here](https://dafny-lang.github.io/dafny/StyleGuide/Style-Guide). Most significantly, code is written without tabs and with a 2 space indentation. Following code style conventions improves readability but does not alter program semantics. - - -## 13.5. Using Dafny From the Command Line {#command-line} +## 13.6. Using Dafny From the Command Line {#command-line} `dafny` is a conventional command-line tool, operating just like other command-line tools in Windows and Unix-like systems. @@ -147,7 +153,7 @@ In general, the format of a command-line is determined by the shell program that (.e.g., bash, the windows shell, COMMAND, etc.), but is expected to be a series of space-separated "words", each representing a command, option, option argument, file, or folder. -### 13.5.1. dafny commands {#sec-dafny-commands} +### 13.6.1. dafny commands {#sec-dafny-commands} As of v3.9.0, `dafny` uses a command-style command-line (like `git` for example); prior to v3.9.0, the command line consisted only of options and files. @@ -191,7 +197,7 @@ it can be explicitly set false (do verification) using `--no-verify:false` or `- - There is a potential ambiguity when the form `--option value` is used if the value is optional (such as for boolean values). In such a case an argument afer an option (that does not have an argument given with `:` or `=`) is interpreted as the value if it is indeed a valid value for that option. However, better style advises always using a ':' or '=' to set option values. No valid option values in dafny look like filenames or begin with `--`. -#### 13.5.1.1. Options that are not associated with a command +#### 13.6.1.1. Options that are not associated with a command A few options are not part of a command. In these cases any single-hyphen spelling also permits a spelling beginning with '/'. - `dafny --help` or `dafny -h` lists all the available commands @@ -199,7 +205,7 @@ A few options are not part of a command. In these cases any single-hyphen spelli - `dafny --version` (or `-version`) prints out the number of the version this build of dafny implements -#### 13.5.1.2. `dafny resolve` {#sec-dafny-resolve} +#### 13.6.1.2. `dafny resolve` {#sec-dafny-resolve} The `dafny resolve` command checks the command-line and then parses and typechecks the given files and any included files. @@ -244,7 +250,7 @@ The options relevant to this command are - `--warn-missing-constructor-parentheses` -#### 13.5.1.3. `dafny verify` {#sec-dafny-verify} +#### 13.6.1.3. `dafny verify` {#sec-dafny-verify} The `dafny verify` command performs the [`dafny resolve`](#sec-dafny-resolve) checks and then attempts to verify each declaration in the program. @@ -283,7 +289,7 @@ Various options control the verification process, in addition to all those descr - `--solver-path` -#### 13.5.1.4. `dafny translate ` {#sec-dafny-translate} +#### 13.6.1.4. `dafny translate ` {#sec-dafny-translate} The `dafny translate` command translates Dafny source code to source code for another target programming language. The command always performs the actions of `dafny resolve` and, unless the `--no-verify` option is specified, does the actions of `dafny verify`. @@ -318,7 +324,7 @@ Various options control the translation process, in addition to all those descri - `--enforce-determinism` - `--test-assumptions` --- (experimental) inserts runtime checks for unverified assumptions when they are compilable -#### 13.5.1.5. `dafny build` {#sec-dafny-build} +#### 13.6.1.5. `dafny build` {#sec-dafny-build} The `dafny build` command runs `dafny translate` and then compiles the result into an executable artifact for the target platform, such as a `.exe` or `.dll` or executable `.jar`, or just the source code for an interpreted language. @@ -335,7 +341,7 @@ Note that `dafny build` may do optimizations that `dafny run` does not. Details for specific target platforms are described [in Section 25.7](#sec-compilation). -#### 13.5.1.6. `dafny run` {#sec-dafny-run} +#### 13.6.1.6. `dafny run` {#sec-dafny-run} The `dafny run` command compiles the Dafny program and then runs the resulting executable. Note that `dafny run` is engineered to quickly compile and launch the program; @@ -368,14 +374,14 @@ then runs it with the three command-line arguments `1 2 3` - performance --- `dafny run` may not optimize as much as `dafny build` - target-language-specific configuration issues --- e.g. encoding issues: `dafny run` sets language-specific flags to request UTF-8 output for the [`print`](#print-encoding) statement in all languages, whereas `dafny build` leaves language-specific runtime configuration to the user. -#### 13.5.1.7. `dafny server` {#sec-dafny-server} +#### 13.6.1.7. `dafny server` {#sec-dafny-server} The `dafny server` command starts the Dafny Language Server, which is an [LSP-compliant](https://microsoft.github.io/language-server-protocol/) implementation of Dafny. The [Dafny VSCode extension]() uses this LSP implementation, which in turn uses the same core Dafny implementation as the command-line tool. The Dafny Language Server is described in more detail [here](#sec-dafny-language-server-vscode). -#### 13.5.1.8. `dafny audit` {#sec-dafny-audit} +#### 13.6.1.8. `dafny audit` {#sec-dafny-audit} The `dafny audit` command reports issues in the Dafny code that might limit the soundness claims of verification. @@ -420,11 +426,6 @@ Since Dafny cannot prove properties about code written in other languages, adding tests to provide evidence that any `ensures` clauses do hold can improve assurance. The same considerations apply to `requires` clauses on Dafny code intended to be called from external code. -* Any declaration marked with the `{:concurrent}` attribute. -This is intended to indicate that the code is safe for use in a concurrent setting, but Dafny currently cannot prove that form of safety. -The [addition of `reads` clauses to methods](https://github.com/dafny-lang/rfcs/pull/6) will be a step toward being able to prove safety in this case, -but until it exists, careful inspection and testing are appropriate. - * Any definition with an `assume` statement in its body. To improve assurance, attempt to convert it to an `assert` statement and prove that it holds. Such a definition will not be compilable unless the statement is also marked with `{:axiom}`. @@ -447,7 +448,7 @@ To improve assurance, provide a body that establishes any stated invariants. Any code that calls this declaration will assume that all `ensures` clauses are true after it returns. To improve assurance, provide a body that proves that any `ensures` clauses hold. -#### 13.5.1.9. `dafny format` {#sec-dafny-format} +#### 13.6.1.9. `dafny format` {#sec-dafny-format} Dafny supports a formatter, which for now only changes the indentation of lines in a Dafny file, so that it conforms to the idiomatic Dafny code formatting style. @@ -466,7 +467,7 @@ Each version of `dafny format` returns a non-zero return code if there are any c errors or if --check is stipulated and at least one file is not the same as its formatted version. `dafny format` does not necessarily report name or type resolution errors and does not attempt verification. -#### 13.5.1.10. `dafny test` {#sec-dafny-test} +#### 13.6.1.10. `dafny test` {#sec-dafny-test} This command (verifies and compiles the program and) runs every method in the program that is annotated with the [`{:test}` attribute](#sec-test-attribute). Verification can be disabled using the `--no-verify` option. `dafny test` also accepts all other options of the `dafny build` command. @@ -478,6 +479,8 @@ In particular, it accepts the `--target` option that specifies the programming l - `--output` - gives the folder and filename root for compilation artifacts - `--methods-to-test` - the value is a (.NET) regular expression that is matched against the fully qualified name of the method; only those methods that match are tested +- `--coverage-report` - the value is a directory in which Dafny will save an html coverage report highlighting parts of + the program that execution of the tests covered. The order in which the tests are run is not specified. @@ -529,7 +532,7 @@ Hi! PASSED ``` -#### 13.5.1.11. `dafny doc` [Experimental] {#sec-dafny-doc} +#### 13.6.1.11. `dafny doc` [Experimental] {#sec-dafny-doc} The `dafny doc` command generates HTML documentation pages describing the contents of each module in a set of files, using the documentation comments in the source files. @@ -561,7 +564,7 @@ The output files are HTML files, all contained in the given folder, one per modu an alphabetical by name list of all the declarations in all the modules. The documentation for the root module is in `_.html`. -#### 13.5.1.12. `dafny generate-tests` {#sec-dafny-generate-tests} +#### 13.6.1.12. `dafny generate-tests` {#sec-dafny-generate-tests} This _experimental_ command allows generating tests from Dafny programs. The tests provide complete coverage of the implementation and one can execute them using the [`dafny test`](#sec-dafny-test) command. @@ -607,7 +610,7 @@ etc.) must be a member of an explicitly named module, which is called `M` in the _This command is under development and not yet fully functional._ -#### 13.5.1.13. `Inlining` {#sec-dafny-generate-tests-inlining} +#### 13.6.1.13. `Inlining` {#sec-dafny-generate-tests-inlining} By default, when asked to generate tests, Dafny will produce _unit tests_, which guarantee coverage of basic blocks within the method they call but not within any of its callees. By contrast, system-level tests can @@ -683,7 +686,7 @@ module M { } ``` -#### 13.5.1.14. `Command Line Options` {#sec-dafny-generate-tests-clo} +#### 13.6.1.14. `Command Line Options` {#sec-dafny-generate-tests-clo} Test generation supports a number of command-line options that control its behavior. @@ -712,7 +715,7 @@ The following is a list of command-line-options supported by Dafny during test g Dafny will also automatically enforce the following options during test generation: `--enforce-determinism`, `/typeEncoding:p` (an option passed on to Boogie). -#### 13.5.1.15. `dafny find-dead-code` {#sec-dafny-find-dead-code} +#### 13.6.1.15. `dafny find-dead-code` {#sec-dafny-find-dead-code} This _experimental_ command finds dead code in a program, that is, basic-blocks within a method that are not reachable by any inputs that satisfy the method's preconditions. The underlying implementation is identical to that of @@ -751,13 +754,13 @@ reviewed. _This command is under development and not yet fully functional._ -#### 13.5.1.16. `dafny measure-complexity` {#sec-dafny-measure-complexity} +#### 13.6.1.16. `dafny measure-complexity` {#sec-dafny-measure-complexity} This _experimental_ command reports complexity metrics of a program. _This command is under development and not yet functional._ -#### 13.5.1.17. Plugins +#### 13.6.1.17. Plugins This execution mode is not a command, per se, but rather a command-line option that enables executing plugins to the dafny tool. Plugins may be either standalone tools or be additions to existing commands. @@ -767,7 +770,7 @@ where the argument to `--plugin` gives the path to the compiled assembly of the More on writing and building plugins can be found [in this section](#sec-plugins). -#### 13.5.1.18. Legacy operation +#### 13.6.1.18. Legacy operation Prior to implementing the command-based CLI, the `dafny` command-line simply took files and options and the arguments to options. That legacy mode of operation is still supported, though discouraged. The command `dafny -?` produces the list of legacy options. @@ -776,14 +779,14 @@ options like `-compile`, `-compileTarget` and `-spillTargetCode`. Users are encouraged to migrate to the command-based style of command-lines and the double-hyphen options. -### 13.5.2. In-tool help +### 13.6.2. In-tool help As is typical for command-line tools, `dafny` provides in-tool help through the `-h` and `--help` options: - `dafny -h`, `dafny --help` list the commands available in the `dafny` tool - `dafny -?` lists all the (legacy) options implemented in `dafny` - `dafny -h`, `dafny --help`, `dafny -?` list the options available for that command -### 13.5.3. dafny exit codes {#sec-exit-codes} +### 13.6.3. dafny exit codes {#sec-exit-codes} The basic resolve, verify, translate, build, run and commands of dafny terminate with these exit codes. @@ -801,7 +804,7 @@ Other dafny commands may have their own conventions for exit codes. However in all cases, an exit code of 0 indicates successful completion of the command's task and small positive integer values indicate errors of some sort. -### 13.5.4. dafny output +### 13.6.4. dafny output Most output from `dafny` is directed to the standard output of the shell invoking the tool, though some goes to standard error. - Command-line errors: these are produced by the dotnet CommandLineOptions package are directed to **standard-error** @@ -811,7 +814,7 @@ Most output from `dafny` is directed to the standard output of the shell invokin - Dafny `expect` statements (when they fail) send a message to **standard-out**. - Dafny I/O libraries send output explicitly to either **standard-out or standard-error** -### 13.5.5. Project files {#sec-project-files} +### 13.6.5. Project files {#sec-project-files} Commands on the Dafny CLI that can be passed a Dafny file can also be passed a Dafny project file. Such a project file may define which Dafny files the project contains and which Dafny options it uses. The project file must be a [TOML](https://toml.io/en/) file named `dfyconfig.toml` for it to work on both the CLI and in the Dafny IDE, although the CLI will accept any `.toml` file. Here's an example of a Dafny project file: @@ -836,18 +839,18 @@ The `excludes` does not remove any files that are listed explicitly on the comma It's not possible to use Dafny project files in combination with the legacy CLI UI. -## 13.6. Verification {#sec-verification} +## 13.7. Verification {#sec-verification} In this section, we suggest a methodology to figure out [why a single assertion might not hold](#sec-verification-debugging), we propose techniques to deal with [assertions that slow a proof down](#sec-verification-debugging-slow), we explain how to [verify assertions in parallel or in a focused way](#sec-assertion-batches), and we also give some more examples of [useful options and attributes to control verification](#sec-command-line-options-and-attributes-for-verification). -### 13.6.1. Verification debugging when verification fails {#sec-verification-debugging} +### 13.7.1. Verification debugging when verification fails {#sec-verification-debugging} Let's assume one assertion is failing ("assertion might not hold" or "postcondition might not hold"). What should you do next? The following section is textual description of the animation below, which illustrates the principle of debugging an assertion by computing the weakest precondition: ![weakestpreconditionDemo](https://user-images.githubusercontent.com/3601079/157976402-83fe4d37-8042-40fc-940f-bcfc235c7d2b.gif) -#### 13.6.1.1. Failing postconditions {#sec-failing-postconditions} +#### 13.7.1.1. Failing postconditions {#sec-failing-postconditions} Let's look at an example of a failing postcondition. ```dafny @@ -893,7 +896,7 @@ method FailingPostcondition(b: bool) returns (i: int) That's it! Now the postcondition is not failing anymore, but the `assert` contains the error! you can now move to the next section to find out how to debug this `assert`. -#### 13.6.1.2. Failing asserts {#sec-failing-asserts} +#### 13.7.1.2. Failing asserts {#sec-failing-asserts} In the [previous section](#sec-failing-postconditions), we arrived at the point where we have a failing assertion: ```dafny @@ -977,7 +980,7 @@ b ==> 2 <= (if !b then 3 else 1) Now we can understand what went wrong: When b is true, all of these formulas above are false, this is why the `dafny` verifier was not able to prove them. In the next section, we will explain how to "move asserts up" in certain useful patterns. -#### 13.6.1.3. Failing asserts cases {#sec-failing-asserts-special-cases} +#### 13.7.1.3. Failing asserts cases {#sec-failing-asserts-special-cases} This list is not exhaustive but can definitely be useful to provide the next step to figure out why Dafny could not prove an assertion. @@ -1007,13 +1010,13 @@ This list is not exhaustive but can definitely be useful to provide the next ste `method m_mod(i) returns (j: T)`
  ` requires A(i)`
  ` modifies this, i`
  ` ensures B(i, j)`
`{`
  ` ...`
`}`

`method n_mod() {`
  ` ...`




  ` var x: m_mod(a);`
  ` assert P(x);` | `method m_mod(i) returns (j: T)`
  ` requires A(i)`
  ` modifies this, i`
  ` ensures B(i, j)`
`{`
  ` ...`
`}`

`method n_mod() {`
  ` ...`
  ` assert A(k);`
  ` modify this, i; // Temporarily`
  ` var x := T; // Temporarily`
  ` assume B(k, x);`
  `// var x := m_mod(k);`
  ` assert P(x);`
`modify x, y;`
`assert P(x, y, z);` | `assert x != z && y != z;`
`modify x, y;`
`assert P(x, y, z);` -### 13.6.2. Verification debugging when verification is slow {#sec-verification-debugging-slow} +### 13.7.2. Verification debugging when verification is slow {#sec-verification-debugging-slow} In this section, we describe techniques to apply in the case when verification is slower than expected, does not terminate, or times out. Additional detail is available in the [verification optimization guide](../VerificationOptimization/VerificationOptimization). -#### 13.6.2.1. `assume false;` {#sec-assume-false} +#### 13.7.2.1. `assume false;` {#sec-assume-false} Assuming `false` is an empirical way to short-circuit the verifier and usually stop verification at a given point,[^explainer-assume-false] and since the final compilation steps do not accept this command, it is safe to use it during development. Another similar command, `assert false;`, would also short-circuit the verifier, but it would still make the verifier try to prove `false`, which can also lead to timeouts. @@ -1052,7 +1055,7 @@ method NotTerminating() { } ``` -This verifies instantly. This gives use a strategy to bisect, or do binary search to find the assertion that slows everything down. +This verifies instantly. This gives us a strategy to bisect, or do binary search to find the assertion that slows everything down. Now, we move the `assume false;` below the next assertion: @@ -1137,7 +1140,7 @@ If verification is fast, which of the two assertions `assert Z;` or `assert P;` We now hope you know enough of `assume false;` to locate assertions that make verification slow. Next, we will describe some other strategies at the assertion level to figure out what happens and perhaps fix it. -#### 13.6.2.2. `assert ... by {}` {#sec-verification-debugging-assert-by} +#### 13.7.2.2. `assert ... by {}` {#sec-verification-debugging-assert-by} If an assertion `assert X;` is slow, it is possible that calling a lemma or invoking other assertions can help to prove it: The postcondition of this lemma, or the added assertions, could help the `dafny` verifier figure out faster how to prove the result. @@ -1169,7 +1172,7 @@ Now, only `X` is available for the `dafny` verifier to prove the rest of the met [^verifier-lost]: By default, the expression of an assertion or a precondition is added to the knowledge base of the `dafny` verifier for further assertions or postconditions. However, this is not always desirable, because if the verifier has too much knowledge, it might get lost trying to prove something in the wrong direction. -#### 13.6.2.3. Labeling and revealing assertions {#sec-labeling-revealing-assertions} +#### 13.7.2.3. Labeling and revealing assertions {#sec-labeling-revealing-assertions} Another way to prevent assertions or preconditions from cluttering the verifier[^verifier-lost] is to label and reveal them. Labeling an assertion has the effect of "hiding" its result, until there is a "reveal" calling that label. @@ -1237,13 +1240,13 @@ method TestMethod(x: bool) To lift assertions, please refer to the techniques described in [Verification Debugging](#sec-verification-debugging). -#### 13.6.2.4. Non-opaque `function method` {#sec-non-opaque-function-method} +#### 13.7.2.4. Non-opaque `function method` {#sec-non-opaque-function-method} Functions are normally used for specifications, but their functional syntax is sometimes also desirable to write application code. However, doing so naively results in the body of a `function method Fun()` be available for every caller, which can cause the verifier to time out or get extremely slow[^verifier-lost]. A solution for that is to add the attribute [`{:opaque}`](#sec-opaque) right between `function method` and `Fun()`, and use [`reveal Fun();`](#sec-reveal-statement) in the calling functions or methods when needed. -#### 13.6.2.5. Conversion to and from bitvectors {#sec-conversion-to-and-from-bitvectors} +#### 13.7.2.5. Conversion to and from bitvectors {#sec-conversion-to-and-from-bitvectors} Bitvectors and natural integers are very similar, but they are not treated the same by the `dafny` verifier. As such, conversion from `bv8` to an `int` and vice-versa is not straightforward, and can result in slowdowns. @@ -1285,7 +1288,7 @@ method m() { One might consider refactoring this code into separate functions if used over and over. -#### 13.6.2.6. Nested loops {#sec-nested-loops} +#### 13.7.2.6. Nested loops {#sec-nested-loops} In the case of nested loops, the verifier might timeout sometimes because of inadequate or too much available information[^verifier-lost]. One way to mitigate this problem, when it happens, is to isolate the inner loop by refactoring it into a separate method, with suitable pre and postconditions that will usually assume and prove the invariant again. @@ -1321,7 +1324,7 @@ method innerLoop() In the next section, when everything can be proven in a timely manner, we explain another strategy to decrease proof time by parallelizing it if needed, and making the verifier focus on certain parts. -### 13.6.3. Assertion batches, well-formedness, correctness {#sec-assertion-batches} +### 13.7.3. Assertion batches, well-formedness, correctness {#sec-assertion-batches} To understand how to control verification, it is first useful to understand how `dafny` verifies functions and methods. @@ -1373,7 +1376,7 @@ assert c != 5/a; // Correctness Well-formedness is proved at the same time as correctness, except for [well-formedness of requires and ensures clauses](#sec-well-formedness-specifications) which is proved separatedly from the well-formedness and correctness of the rest of the method/function. -For the rest of this section, we don't diifferentiate between well-formedness assertions and correctness assertions. +For the rest of this section, we don't differentiate between well-formedness assertions and correctness assertions. We can also classify the assertions extracted by Dafny in a few categories: @@ -1438,7 +1441,7 @@ The fundamental unit of verification in `dafny` is an _assertion batch_, which c [^smaller-batches]: To create a smaller batch, `dafny` duplicates the assertion batch, and arbitrarily transforms the clones of an assertion into assumptions except in exactly one batch, so that each assertion is verified only in one batch. This results in "easier" formulas for the verifier because it has less to prove, but it takes more overhead because every verification instance have a common set of axioms and there is no knowledge sharing between instances because they run independently. -#### 13.6.3.1. Controlling assertion batches {#sec-assertion-batches-control} +#### 13.7.3.1. Controlling assertion batches {#sec-assertion-batches-control} Here is how you can control how `dafny` partitions assertions into batches. @@ -1452,7 +1455,7 @@ The effect of these attributes may vary, because they are low-level attributes a Usually, you would set [`{:vcs_max_cost 0}`](#sec-vcs_max_cost) and [`{:vcs_max_splits N}`](#sec-vcs_max_splits) to ensure it generates N assertion batches. * [`{:vcs_max_keep_going_splits N}`](#sec-vcs_max_keep_going_splits) where N > 1 on a method dynamically splits the initial assertion batch up to N components if the verifier is stuck the first time. -### 13.6.4. Command-line options and other attributes to control verification {#sec-command-line-options-and-attributes-for-verification} +### 13.7.4. Command-line options and other attributes to control verification {#sec-command-line-options-and-attributes-for-verification} There are many great options that control various aspects of verifying dafny programs. Here we mention only a few: @@ -1465,43 +1468,103 @@ There are many great options that control various aspects of verifying dafny pro You can search for them in [this file](https://dafny-lang.github.io/dafny/DafnyRef/DafnyRef) as some of them are still documented in raw text format. -### 13.6.5. Debugging variable verification +### 13.7.5. Analyzing proof dependencies {#sec-proof-dependencies} + +When Dafny successfully verifies a particular definition, it can ask the +solver for information about what parts of the program were actually +used in completing the proof. The program components that can +potentially form part of a proof include: + +* `assert` statements (and the implicit assumption that they hold in subsequent code), +* implicit assertions (such as array or sequence bounds checks), +* `assume` statements, +* `ensures` clauses, +* `requires` clauses, +* function definitions, +* method calls, and +* assignment statements. + +Understanding what portions of the program the proof depended on can +help identify mistakes, and to better understand the structure of your +proof (which can help when optimizing it, among other things). In +particular, there are two key dependency structures that tend to +indicate mistakes, both focused on what parts of the program were _not_ +included in the proof. + +* Redundant assumptions. In some cases, a proof can be completed without + the need of certain `assume` statements or `requires` clauses. This + situation might represent a mistake, and when the mistake is corrected + those program elements may become required. However, they may also + simply be redundant, and the program will become simpler if they're + removed. Dafny will report assumptions of this form when verifying + with the flag `--warn-redundant-assumptions`. Note that `assert` + statements may be warned about, as well, indicating that the fact + proved by the assertion wasn't needed to prove anything else in the + program. + +* Contradictory assumptions. If the combination of all assumptions in + scope at a particular program point is contradictory, anything can be + proved at that point. This indicates the serious situation that, unless done on purpose like in a proof by contradiction, your + proof may be entirely vacuous, and not say what you intended, giving + you a false sense of confidence. The + `--warn-contradictory-assumptions` flag instructs Dafny to warn about + any assertion that was proved through the use of contradictions + between assumptions. + +These options can be specified in `dfyconfig.toml`, and this is typically the most convenient way to use them with the IDE. + +More detailed information is available using either the `--log-format +text` or `--verification-coverage-report` option to `dafny verify`. The former will +include a list of proof dependencies (including source location and +description) alongside every assertion batch in the generated log +whenever one of the two warning options above is also included. The +latter will produce a highlighted HTML version of your source code, in +the same format used by `dafny test --coverage-report` +and `dafny generate-tests --verification-coverage-report`, +indicating which parts of the program were used, not used, or partly +used in the verification of the entire program. + +### 13.7.6. Debugging brittle verification When evolving a Dafny codebase, it can sometimes occur that a proof obligation succeeds at first only for the prover to time out or report a -potential error after minor, valid changes. This is ultimately due to -decidability limitations in the form of automated reasoning that Dafny -uses. The Z3 SMT solver that Dafny depends on attempts to efficiently -search for proofs, but does so using both incomplete heuristics and a -degree of randomness, with the result that it can sometimes fail to find -a proof even when one exists (or continue searching forever). +potential error after minor, valid changes. We refer to such a proof +obligation as _brittle_. This is ultimately due to decidability +limitations in the form of automated reasoning that Dafny uses. The Z3 +SMT solver that Dafny depends on attempts to efficiently search for +proofs, but does so using both incomplete heuristics and a degree of +randomness, with the result that it can sometimes fail to find a proof +even when one exists (or continue searching forever). Dafny provides some features to mitigate this issue, primarily focused on early detection. The philosophy is that, if Dafny programmers are -alerted to proofs that show early signs of variability, before they are -obviously so, they can refactor the proofs to make them less variable +alerted to proofs that show early signs of brittleness, before they are +obviously so, they can refactor the proofs to make them less brittle before further development becomes difficult. The mechanism for early detection focuses on measuring the resources -used to complete a proof (either using duration or a more deterministic -"resource count" metric available from Z3). Dafny can re-run a given -proof attempt multiple times after automatically making minor changes to -the structure of the input or to the random choices made by the solver. -If the resources used during these attempts (or the ability to find a -proof at all) vary widely, we say that the verification of the relevant -properties is _highly variable_. - -#### 13.6.5.1. Measuring proof variability - -To measure the variability of your proofs, start by using the -`-randomSeedIterations:N` flag to instruct Dafny to attempt each proof -goal `N` times, using a different random seed each time. The random seed -used for each attempt is derived from the global random seed `S` -specified with `-randomSeed:S`, which defaults to `0` (which means use -an arbitrary -- e.g. clock-based -- seed). +used to discharge a proof obligation (either using duration or a more +deterministic "resource count" metric available from Z3). Dafny can +re-run a given proof attempt multiple times after automatically making +minor changes to the structure of the input or to the random choices +made by the solver. If the resources used during these attempts (or the +ability to find a proof at all) vary widely, we use this as a proxy +metric indicating that the proof may be brittle. + +#### 13.7.6.1. Measuring proof brittleness + +To measure the brittleness of your proofs, start by using the `dafny +measure-complexity` command with the `--iterations N` flag to instruct +Dafny to attempt each proof goal `N` times, using a different random +seed each time. The random seed used for each attempt is derived from +the global random seed `S` specified with `-randomSeed:S`, which +defaults to `0`. The random seed affects the structure of the SMT +queries sent to the solver, changing the ordering of SMT commands, the +variable names used, and the random seed the solver itself uses when +making decisions that can be arbitary. For most use cases, it also makes sense to specify the -`-verificationLogger:csv` flag, to log verification cost statistics to a +`--log-format csv` flag, to log verification cost statistics to a CSV file. By default, the resulting CSV files will be created in the `TestResults` folder of the current directory. @@ -1529,24 +1592,24 @@ than 20%, perhaps even as low as 5%. However, when beginning to analyze a new project, it may be necessary to set limits as high as a few hundred percent and incrementally ratchet down the limit over time. -When first analyzing proof variability, you may also find that certain proof +When first analyzing proof brittleness, you may also find that certain proof goals succeed on some iterations and fail on others. If your aim is -first to ensure that variability doesn't worsen and then to start -improving it, integrating `dafny-reportgenerator` into CI and using the +first to ensure that brittleness doesn't worsen and then to start +reducing it, integrating `dafny-reportgenerator` into CI and using the `--allow-different-outcomes` flag may be appropriate. Then, once you've -improved variability sufficiently, you can likely remove that flag (and -likely have significantly lower limits on other variability metrics). +improved brittleness sufficiently, you can likely remove that flag (and +likely have significantly lower limits on other metrics). -#### 13.6.5.2. Improving proof variability +#### 13.7.6.2. Improving proof brittleness -Improving proof variability is typically closely related to improving +Reducing proof brittleness is typically closely related to improving performance overall. As such, [techniques for debugging slow verification](#sec-verification-debugging-slow) are typically useful for -debugging highly variable verification, as well. See also the +debugging brittle proofs, as well. See also the [verification optimization guide](../VerificationOptimization/VerificationOptimization). -## 13.7. Compilation {#sec-compilation} +## 13.8. Compilation {#sec-compilation} The `dafny` tool can compile a Dafny program to one of several target languages. Details and idiosyncrasies of each of these are described in the following subsections. In general note the following: @@ -1560,7 +1623,18 @@ included by default and must be explicitly requested using `--include-runtime`. To be compilable to an executable program, a Dafny program must contain a `Main` entry point, as described [here](#sec-user-guide-main). -### 13.7.1. `extern` declarations {#sec-extern-decls} +### 13.8.1.1 Built-in declarations {#sec-compilation-built-ins} + +Dafny includes several built-in types such as tuples, arrays, arrows (functions), and the `nat` subset type. +The supporting target language code for these declarations could be emitted on-demand, +but these could then become multiple definitions of the same symbols when compiling multiple components separately. +Instead, all such built-ins up to a pre-configured maximum size are included in most of the runtime libraries. +This means that when compiling to certain target languages, the use of such built-ins above these maximum sizes, +such as tuples with more than 20 elements, is not supported. +See the [Supported features by target language](#sec-supported-features-by-target-language) table +for the details on these limits. + +### 13.8.2. `extern` declarations {#sec-extern-decls} A Dafny declaration can be marked with the [`{:extern}`](#sec-extern) attribute to indicate that it refers to an external definition that is already @@ -1673,7 +1747,35 @@ Detailed description of the `dafny build` and `dafny run` commands and the `--input` option (needed when `dafny run` has more than one input file) is contained [in the section on command-line structure](#command-line). -### 13.7.2. C\# +### 13.8.3. Replaceable modules +To enable easily customising runtime behavior across an entire Dafny program, Dafny has placeholder modules. Here follows an example: + + +```dafny +replaceable module Foo { + method Bar() returns (i: int) + ensures i >= 2 +} + +method Main() { + var x := Foo.Bar(); + print x; +} +// At this point, the program can be verified but not run. + +module ConcreteFoo replaces Foo { + method Bar() returns (i: int) { + return 3; // Main will print 3. + } +} +// ConcreteFoo can be swapped out for different replacements of Foo, to customize runtime behavior. +``` + +When replacing a replaceable module, the same rules apply as when refining an abstract module. However, unlike an abstract module, a placeholder module can be used as if it is a concrete module. When executing code, using for example `dafny run` or `dafny translate`, any program that contains a placeholder module must also contain a replacement of this placeholder. When using `dafny verify`, placeholder modules do not have to be replaced. + +Replaceable modules are particularly useful for defining behavior that depends on which target language Dafny is translated to. + +### 13.8.4. C\# For a simple Dafny-only program, the translation step converts a `A.dfy` file into `A.cs`; the build step then produces a `A.dll`, which can be used as a library or as an executable (run using `dotnet A.dll`). @@ -1694,7 +1796,7 @@ which is then compiled by `dotnet` to a `.dll`. Examples of how to integrate C# libraries and source code with Dafny source code are contained in [this separate document](integration-cs/IntegrationCS). -### 13.7.3. Java +### 13.8.5. Java The Dafny-to-Java compiler translation phase writes out the translated files of a file _A_`.dfy` to a directory _A_`-java`. @@ -1716,7 +1818,7 @@ but not if dafny is only doing translation. Examples of how to integrate Java source code and libraries with Dafny source are contained in [this separate document](integration-java/IntegrationJava). -### 13.7.4. Javascript +### 13.8.6. Javascript The Dafny-to-Javascript compiler translates all the given `.dfy` files into a single `.js` file, which can then be run using `node`. (Javascript has no compilation step). @@ -1730,7 +1832,7 @@ Or, in one step, Examples of how to integrate Javascript libraries and source code with Dafny source are contained in [this separate document](integration-js/IntegrationJS). -### 13.7.5. Go +### 13.8.7. Go The Dafny-to-Go compiler translates all the given `.dfy` files into a single `.go` file in `A-go/src/A.go`; the output folder can be specified with the @@ -1754,7 +1856,7 @@ change, though the `./A` alternative will still be supported. Examples of how to integrate Go source code and libraries with Dafny source are contained in [this separate document](integration-go/IntegrationGo). -### 13.7.6. Python +### 13.8.8. Python The Dafny-to-Python compiler is still under development. However, simple Dafny programs can be built and run as follows. The Dafny-to-Python @@ -1772,7 +1874,7 @@ In one step: Examples of how to integrate Python libraries and source code with Dafny source are contained in [this separate document](integration-py/IntegrationPython). -### 13.7.7. C++ +### 13.8.9. C++ The C++ backend was written assuming that it would primarily support writing C/C++ style code in Dafny, which leads to some limitations in the current @@ -1792,7 +1894,7 @@ implementation. - The current backend also assumes the use of C++17 in order to cleanly and performantly implement datatypes. -### 13.7.8. Supported features by target language {#sec-supported-features-by-target-language} +### 13.8.10. Supported features by target language {#sec-supported-features-by-target-language} Some Dafny features are not supported by every target language. The table below shows which features are supported by each backend. @@ -1801,7 +1903,7 @@ while an X indicates that it is. {% include_relative Features.md %} -## 13.8. Dafny Command Line Options {#sec-command-line-options} +## 13.9. Dafny Command Line Options {#sec-command-line-options} There are many command-line options to the `dafny` tool. The most current documentation of the options is within the tool itself, @@ -1812,7 +1914,7 @@ Remember that options are typically stated with either a leading `--`. Legacy options begin with either '-' or '/'; however they are being migrated to the POSIX-compliant `--` form as needed. -### 13.8.1. Help and version information {#sec-controlling-help} +### 13.9.1. Help and version information {#sec-controlling-help} These options emit general information about commands, options and attributes. When present, the dafny program will terminates after emitting the requested information @@ -1842,7 +1944,7 @@ Legacy options: * `-wait` - wait for the user to press `Enter` before terminating after a successful execution. -### 13.8.2. Controlling input {#sec-controlling-input} +### 13.9.2. Controlling input {#sec-controlling-input} These options control how Dafny processes its input. @@ -1861,7 +1963,7 @@ a list of all .dfy files contained, recursively, in those folders how Dafny constructs are modeled. The default prelude is [here](https://github.com/dafny-lang/dafny/blob/master/Source/Dafny/DafnyPrelude.bpl). -### 13.8.3. Controlling plugins {#sec-controlling-plugins} +### 13.9.3. Controlling plugins {#sec-controlling-plugins} Dafny has a plugin capability. A plugin has access to an AST of the dafny input files @@ -1877,7 +1979,7 @@ and (b) example plugins in the The value of the option `--plugin` is a path to a dotnet dll that contains the compiled plugin. -### 13.8.4. Controlling output {#sec-controlling-output} +### 13.9.4. Controlling output {#sec-controlling-output} These options instruct Dafny to print various information about your program during processing, including variations of the original source @@ -2020,7 +2122,7 @@ Legacy options: } ``` -### 13.8.5. Controlling language features {#sec-controlling-language} +### 13.9.5. Controlling language features {#sec-controlling-language} These options allow some Dafny language features to be enabled or disabled. Some of these options exist for backward compatibility with @@ -2127,7 +2229,7 @@ Legacy options: implicitly static and field declarations are not allowed at the module scope. -### 13.8.6. Controlling warnings {#sec-controlling-warnings} +### 13.9.6. Controlling warnings {#sec-controlling-warnings} These options control what warnings Dafny produces, and whether to treat warnings as errors. @@ -2150,7 +2252,7 @@ Legacy options * `2` - issue warnings and advise about alternate syntax. -### 13.8.7. Controlling verification {#sec-controlling-verification} +### 13.9.7. Controlling verification {#sec-controlling-verification} These options control how Dafny verifies the input program, including how much it verifies, what techniques it uses to perform verification, @@ -2200,6 +2302,10 @@ and what information it produces about the verification process. operators. (This option will perhaps be replaced by `-arith` in the future. For now, it takes precedence over `-arith`.) + The behavior of `disable-nonlinear-arithmetic` can be turned on and off on a per-module basis + by placing the attribute [`{:disable-nonlinear-arithmetic}`](#sec-disable-nonlinear-arithmetic) after the module keyword. + The attribute optionally takes the value `false` to enable nonlinear arithmetic. + * `--manual-lemma-induction` - diables automatic inducntion for lemmas * `--isolate-assertions` - verify assertions individually @@ -2364,7 +2470,7 @@ Legacy options: `-proverOpt:O:model_compress=false` and `-proverOpt:O:model.completion=true` options. -### 13.8.8. Controlling compilation {#sec-controlling-compilation} +### 13.9.8. Controlling compilation {#sec-controlling-compilation} These options control what code gets compiled, what target language is used, how compilation proceeds, and whether the compiled program is @@ -2518,7 +2624,7 @@ out the textual target program as part of compilation, in which case method marked with the `{:extern}` attribute directly from a function or method marked with the `{:test}` attribute. -### 13.8.9. Controlling Boogie {#sec-controlling-boogie} +### 13.9.9. Controlling Boogie {#sec-controlling-boogie} Dafny builds on top of Boogie, a general-purpose intermediate language for verification. Options supported by Boogie on its own are also @@ -2620,11 +2726,11 @@ PROVER_OPTIONS="\ #"$BOOGIE" $BOOGIE_OPTIONS $PROVER_OPTIONS "$@" ``` -### 13.8.10. Controlling the prover {#sec-controlling-prover} +### 13.9.10. Controlling the prover {#sec-controlling-prover} Much of controlling the prover is accomplished by controlling verification condition generation ([25.9.7](#sec-controlling-verification)) or Boogie -([Section 13.8.9](#sec-controlling-boogie)). +([Section 13.9.9](#sec-controlling-boogie)). The following options are also commonly used: * `--verification-error-limit:` - limits the number of verification errors reported per procedure. @@ -2635,7 +2741,7 @@ The following options are also commonly used: the number of seconds spent trying to verify each procedure. -### 13.8.11. Controlling test generation {#sec-controlling-test-gen} +### 13.9.11. Controlling test generation {#sec-controlling-test-gen} Dafny is capable of generating unit (runtime) tests. It does so by asking the prover to solve for values of inputs to a method that cause the program to execute specific blocks or paths. diff --git a/latest/v4.3.0/DafnyRef/VSCodeIDE.md b/v4.4.0/DafnyRef/VSCodeIDE.md similarity index 100% rename from latest/v4.3.0/DafnyRef/VSCodeIDE.md rename to v4.4.0/DafnyRef/VSCodeIDE.md diff --git a/latest/v4.3.0/DafnyRef/concat b/v4.4.0/DafnyRef/concat old mode 100644 new mode 100755 similarity index 100% rename from latest/v4.3.0/DafnyRef/concat rename to v4.4.0/DafnyRef/concat diff --git a/latest/v4.3.0/DafnyRef/integration-cs/IntegrationCS.md b/v4.4.0/DafnyRef/integration-cs/IntegrationCS.md similarity index 100% rename from latest/v4.3.0/DafnyRef/integration-cs/IntegrationCS.md rename to v4.4.0/DafnyRef/integration-cs/IntegrationCS.md diff --git a/latest/v4.3.0/DafnyRef/integration-go/IntegrationGo.md b/v4.4.0/DafnyRef/integration-go/IntegrationGo.md similarity index 100% rename from latest/v4.3.0/DafnyRef/integration-go/IntegrationGo.md rename to v4.4.0/DafnyRef/integration-go/IntegrationGo.md diff --git a/latest/v4.3.0/DafnyRef/integration-java/IntegrationJava.md b/v4.4.0/DafnyRef/integration-java/IntegrationJava.md similarity index 100% rename from latest/v4.3.0/DafnyRef/integration-java/IntegrationJava.md rename to v4.4.0/DafnyRef/integration-java/IntegrationJava.md diff --git a/latest/v4.3.0/DafnyRef/integration-js/IntegrationJS.md b/v4.4.0/DafnyRef/integration-js/IntegrationJS.md similarity index 100% rename from latest/v4.3.0/DafnyRef/integration-js/IntegrationJS.md rename to v4.4.0/DafnyRef/integration-js/IntegrationJS.md diff --git a/latest/v4.3.0/DafnyRef/integration-py/IntegrationPython.md b/v4.4.0/DafnyRef/integration-py/IntegrationPython.md similarity index 100% rename from latest/v4.3.0/DafnyRef/integration-py/IntegrationPython.md rename to v4.4.0/DafnyRef/integration-py/IntegrationPython.md diff --git a/latest/v4.3.0/DafnyRef/krml250.bib b/v4.4.0/DafnyRef/krml250.bib similarity index 100% rename from latest/v4.3.0/DafnyRef/krml250.bib rename to v4.4.0/DafnyRef/krml250.bib diff --git a/latest/v4.3.0/DafnyRef/out/README b/v4.4.0/DafnyRef/out/README similarity index 100% rename from latest/v4.3.0/DafnyRef/out/README rename to v4.4.0/DafnyRef/out/README diff --git a/latest/v4.3.0/DafnyRef/paper-full.bib b/v4.4.0/DafnyRef/paper-full.bib similarity index 100% rename from latest/v4.3.0/DafnyRef/paper-full.bib rename to v4.4.0/DafnyRef/paper-full.bib diff --git a/latest/v4.3.0/DafnyRef/poc.bib b/v4.4.0/DafnyRef/poc.bib similarity index 100% rename from latest/v4.3.0/DafnyRef/poc.bib rename to v4.4.0/DafnyRef/poc.bib diff --git a/latest/v4.3.0/DafnyRef/references.bib b/v4.4.0/DafnyRef/references.bib similarity index 100% rename from latest/v4.3.0/DafnyRef/references.bib rename to v4.4.0/DafnyRef/references.bib diff --git a/v4.4.0/DafnyRef/version.txt b/v4.4.0/DafnyRef/version.txt new file mode 100644 index 0000000..f8a638e --- /dev/null +++ b/v4.4.0/DafnyRef/version.txt @@ -0,0 +1 @@ +v4.4.0 release snapshot diff --git a/latest/v4.3.0/Gemfile b/v4.4.0/Gemfile similarity index 100% rename from latest/v4.3.0/Gemfile rename to v4.4.0/Gemfile diff --git a/latest/v4.3.0/Gemfile.lock b/v4.4.0/Gemfile.lock similarity index 100% rename from latest/v4.3.0/Gemfile.lock rename to v4.4.0/Gemfile.lock diff --git a/latest/v4.3.0/HowToFAQ/.gitignore b/v4.4.0/HowToFAQ/.gitignore similarity index 100% rename from latest/v4.3.0/HowToFAQ/.gitignore rename to v4.4.0/HowToFAQ/.gitignore diff --git a/latest/v4.3.0/HowToFAQ/ERROR_CloseParen.dfy b/v4.4.0/HowToFAQ/ERROR_CloseParen.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_CloseParen.dfy rename to v4.4.0/HowToFAQ/ERROR_CloseParen.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_CloseParen.md b/v4.4.0/HowToFAQ/ERROR_CloseParen.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_CloseParen.md rename to v4.4.0/HowToFAQ/ERROR_CloseParen.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_CloseParen.txt b/v4.4.0/HowToFAQ/ERROR_CloseParen.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_CloseParen.txt rename to v4.4.0/HowToFAQ/ERROR_CloseParen.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Covariance.dfy b/v4.4.0/HowToFAQ/ERROR_Covariance.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Covariance.dfy rename to v4.4.0/HowToFAQ/ERROR_Covariance.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Covariance.md b/v4.4.0/HowToFAQ/ERROR_Covariance.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Covariance.md rename to v4.4.0/HowToFAQ/ERROR_Covariance.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Covariance.txt b/v4.4.0/HowToFAQ/ERROR_Covariance.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Covariance.txt rename to v4.4.0/HowToFAQ/ERROR_Covariance.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_DataTypeName.md b/v4.4.0/HowToFAQ/ERROR_DataTypeName.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_DataTypeName.md rename to v4.4.0/HowToFAQ/ERROR_DataTypeName.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_DuplicateImportName.md b/v4.4.0/HowToFAQ/ERROR_DuplicateImportName.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_DuplicateImportName.md rename to v4.4.0/HowToFAQ/ERROR_DuplicateImportName.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_FunctionPrecondition.md b/v4.4.0/HowToFAQ/ERROR_FunctionPrecondition.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_FunctionPrecondition.md rename to v4.4.0/HowToFAQ/ERROR_FunctionPrecondition.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_InsufficientReads.dfy b/v4.4.0/HowToFAQ/ERROR_InsufficientReads.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_InsufficientReads.dfy rename to v4.4.0/HowToFAQ/ERROR_InsufficientReads.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_InsufficientReads.md b/v4.4.0/HowToFAQ/ERROR_InsufficientReads.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_InsufficientReads.md rename to v4.4.0/HowToFAQ/ERROR_InsufficientReads.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_InsufficientReads.txt b/v4.4.0/HowToFAQ/ERROR_InsufficientReads.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_InsufficientReads.txt rename to v4.4.0/HowToFAQ/ERROR_InsufficientReads.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_InsufficientReads1.dfy b/v4.4.0/HowToFAQ/ERROR_InsufficientReads1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_InsufficientReads1.dfy rename to v4.4.0/HowToFAQ/ERROR_InsufficientReads1.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_IsFailure.md b/v4.4.0/HowToFAQ/ERROR_IsFailure.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_IsFailure.md rename to v4.4.0/HowToFAQ/ERROR_IsFailure.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_ModifiesValue.dfy b/v4.4.0/HowToFAQ/ERROR_ModifiesValue.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_ModifiesValue.dfy rename to v4.4.0/HowToFAQ/ERROR_ModifiesValue.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_ModifiesValue.md b/v4.4.0/HowToFAQ/ERROR_ModifiesValue.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_ModifiesValue.md rename to v4.4.0/HowToFAQ/ERROR_ModifiesValue.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_ModifiesValue.txt b/v4.4.0/HowToFAQ/ERROR_ModifiesValue.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_ModifiesValue.txt rename to v4.4.0/HowToFAQ/ERROR_ModifiesValue.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_ModifiesValue1.dfy b/v4.4.0/HowToFAQ/ERROR_ModifiesValue1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_ModifiesValue1.dfy rename to v4.4.0/HowToFAQ/ERROR_ModifiesValue1.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_MutableField.dfy b/v4.4.0/HowToFAQ/ERROR_MutableField.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_MutableField.dfy rename to v4.4.0/HowToFAQ/ERROR_MutableField.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_MutableField.md b/v4.4.0/HowToFAQ/ERROR_MutableField.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_MutableField.md rename to v4.4.0/HowToFAQ/ERROR_MutableField.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_MutableField.txt b/v4.4.0/HowToFAQ/ERROR_MutableField.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_MutableField.txt rename to v4.4.0/HowToFAQ/ERROR_MutableField.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_MutableField1.dfy b/v4.4.0/HowToFAQ/ERROR_MutableField1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_MutableField1.dfy rename to v4.4.0/HowToFAQ/ERROR_MutableField1.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_NoCode.md b/v4.4.0/HowToFAQ/ERROR_NoCode.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_NoCode.md rename to v4.4.0/HowToFAQ/ERROR_NoCode.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_NoLHS.dfy b/v4.4.0/HowToFAQ/ERROR_NoLHS.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_NoLHS.dfy rename to v4.4.0/HowToFAQ/ERROR_NoLHS.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_NoLHS.md b/v4.4.0/HowToFAQ/ERROR_NoLHS.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_NoLHS.md rename to v4.4.0/HowToFAQ/ERROR_NoLHS.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_NoLHS.txt b/v4.4.0/HowToFAQ/ERROR_NoLHS.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_NoLHS.txt rename to v4.4.0/HowToFAQ/ERROR_NoLHS.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_NoLHS1.dfy b/v4.4.0/HowToFAQ/ERROR_NoLHS1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_NoLHS1.dfy rename to v4.4.0/HowToFAQ/ERROR_NoLHS1.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_NoLHS1.txt b/v4.4.0/HowToFAQ/ERROR_NoLHS1.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_NoLHS1.txt rename to v4.4.0/HowToFAQ/ERROR_NoLHS1.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_NoReferenceTypeParameter.md b/v4.4.0/HowToFAQ/ERROR_NoReferenceTypeParameter.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_NoReferenceTypeParameter.md rename to v4.4.0/HowToFAQ/ERROR_NoReferenceTypeParameter.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_NoTriggers.md b/v4.4.0/HowToFAQ/ERROR_NoTriggers.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_NoTriggers.md rename to v4.4.0/HowToFAQ/ERROR_NoTriggers.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_PostconditionLemma.dfy b/v4.4.0/HowToFAQ/ERROR_PostconditionLemma.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_PostconditionLemma.dfy rename to v4.4.0/HowToFAQ/ERROR_PostconditionLemma.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_PostconditionLemma.md b/v4.4.0/HowToFAQ/ERROR_PostconditionLemma.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_PostconditionLemma.md rename to v4.4.0/HowToFAQ/ERROR_PostconditionLemma.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_PostconditionLemma.txt b/v4.4.0/HowToFAQ/ERROR_PostconditionLemma.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_PostconditionLemma.txt rename to v4.4.0/HowToFAQ/ERROR_PostconditionLemma.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_ProverError1.md b/v4.4.0/HowToFAQ/ERROR_ProverError1.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_ProverError1.md rename to v4.4.0/HowToFAQ/ERROR_ProverError1.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Rbrace.md b/v4.4.0/HowToFAQ/ERROR_Rbrace.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Rbrace.md rename to v4.4.0/HowToFAQ/ERROR_Rbrace.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Rbrace1.dfy b/v4.4.0/HowToFAQ/ERROR_Rbrace1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Rbrace1.dfy rename to v4.4.0/HowToFAQ/ERROR_Rbrace1.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Rbrace1.txt b/v4.4.0/HowToFAQ/ERROR_Rbrace1.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Rbrace1.txt rename to v4.4.0/HowToFAQ/ERROR_Rbrace1.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Rbrace2.dfy b/v4.4.0/HowToFAQ/ERROR_Rbrace2.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Rbrace2.dfy rename to v4.4.0/HowToFAQ/ERROR_Rbrace2.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Rbrace2.txt b/v4.4.0/HowToFAQ/ERROR_Rbrace2.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Rbrace2.txt rename to v4.4.0/HowToFAQ/ERROR_Rbrace2.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Rbrace3.dfy b/v4.4.0/HowToFAQ/ERROR_Rbrace3.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Rbrace3.dfy rename to v4.4.0/HowToFAQ/ERROR_Rbrace3.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Rbrace3.txt b/v4.4.0/HowToFAQ/ERROR_Rbrace3.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Rbrace3.txt rename to v4.4.0/HowToFAQ/ERROR_Rbrace3.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Rbrace4.dfy b/v4.4.0/HowToFAQ/ERROR_Rbrace4.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Rbrace4.dfy rename to v4.4.0/HowToFAQ/ERROR_Rbrace4.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Rbrace4.txt b/v4.4.0/HowToFAQ/ERROR_Rbrace4.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Rbrace4.txt rename to v4.4.0/HowToFAQ/ERROR_Rbrace4.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_SeqComp.dfy b/v4.4.0/HowToFAQ/ERROR_SeqComp.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_SeqComp.dfy rename to v4.4.0/HowToFAQ/ERROR_SeqComp.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_SeqComp.md b/v4.4.0/HowToFAQ/ERROR_SeqComp.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_SeqComp.md rename to v4.4.0/HowToFAQ/ERROR_SeqComp.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_SeqComp.txt b/v4.4.0/HowToFAQ/ERROR_SeqComp.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_SeqComp.txt rename to v4.4.0/HowToFAQ/ERROR_SeqComp.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_SeqComp1.dfy b/v4.4.0/HowToFAQ/ERROR_SeqComp1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_SeqComp1.dfy rename to v4.4.0/HowToFAQ/ERROR_SeqComp1.dfy diff --git a/latest/v4.3.0/HowToFAQ/ERROR_SeqComp1.txt b/v4.4.0/HowToFAQ/ERROR_SeqComp1.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_SeqComp1.txt rename to v4.4.0/HowToFAQ/ERROR_SeqComp1.txt diff --git a/latest/v4.3.0/HowToFAQ/ERROR_SubsetConstraints.md b/v4.4.0/HowToFAQ/ERROR_SubsetConstraints.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_SubsetConstraints.md rename to v4.4.0/HowToFAQ/ERROR_SubsetConstraints.md diff --git a/latest/v4.3.0/HowToFAQ/ERROR_Z3.md b/v4.4.0/HowToFAQ/ERROR_Z3.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/ERROR_Z3.md rename to v4.4.0/HowToFAQ/ERROR_Z3.md diff --git a/latest/v4.3.0/HowToFAQ/Errors-CommandLine.md b/v4.4.0/HowToFAQ/Errors-CommandLine.md similarity index 98% rename from latest/v4.3.0/HowToFAQ/Errors-CommandLine.md rename to v4.4.0/HowToFAQ/Errors-CommandLine.md index 0a7c0ed..e12b193 100644 --- a/latest/v4.3.0/HowToFAQ/Errors-CommandLine.md +++ b/v4.4.0/HowToFAQ/Errors-CommandLine.md @@ -14,7 +14,7 @@ The `-t` or `--target` options specifies which backend compiler to use for those dafny commands that compile dafny to other programming languages. This error message says that the named language is not supported. -## **Error: No input files were specified in command-line _command_** {#cli_no_files} +## **Error: No input files were specified in command-line. Command-line arguments: _command_** {#cli_no_files} ```bash diff --git a/latest/v4.3.0/HowToFAQ/Errors-Compiler.md b/v4.4.0/HowToFAQ/Errors-Compiler.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/Errors-Compiler.md rename to v4.4.0/HowToFAQ/Errors-Compiler.md diff --git a/latest/v4.3.0/HowToFAQ/Errors-Compiler.template b/v4.4.0/HowToFAQ/Errors-Compiler.template similarity index 100% rename from latest/v4.3.0/HowToFAQ/Errors-Compiler.template rename to v4.4.0/HowToFAQ/Errors-Compiler.template diff --git a/latest/v4.3.0/HowToFAQ/Errors-Generic.md b/v4.4.0/HowToFAQ/Errors-Generic.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/Errors-Generic.md rename to v4.4.0/HowToFAQ/Errors-Generic.md diff --git a/latest/v4.3.0/HowToFAQ/Errors-Parser.md b/v4.4.0/HowToFAQ/Errors-Parser.md similarity index 99% rename from latest/v4.3.0/HowToFAQ/Errors-Parser.md rename to v4.4.0/HowToFAQ/Errors-Parser.md index 51af89b..7d93407 100644 --- a/latest/v4.3.0/HowToFAQ/Errors-Parser.md +++ b/v4.4.0/HowToFAQ/Errors-Parser.md @@ -248,14 +248,14 @@ module N refines M { datatype D = ... Y | Z } There are limitations on refining a datatype, namely that the set of constructors cannot be changed. It is only allowed to add members to the body of the datatype. -## **Error: datatype extending traits is a beta feature; use /generalTraits:1 to engage** {#p_general_traits_beta} +## **Error: datatype extending traits is a beta feature; use /generalTraits:datatype to engage** {#p_general_traits_beta} ```dafny trait Trait { } datatype D extends Trait = A | B ``` -Use of traits as non-reference types is a beta feature. To engage, use /generalTraits:1. +Use of traits as non-reference types is a beta feature. To engage, use /generalTraits:datatype. ## **Warning: module-level const declarations are always non-instance, so the 'static' keyword is not allowed here {#p_module_level_const_always_static} diff --git a/latest/v4.3.0/HowToFAQ/Errors-Parser.template b/v4.4.0/HowToFAQ/Errors-Parser.template similarity index 99% rename from latest/v4.3.0/HowToFAQ/Errors-Parser.template rename to v4.4.0/HowToFAQ/Errors-Parser.template index 571c711..f895891 100644 --- a/latest/v4.3.0/HowToFAQ/Errors-Parser.template +++ b/v4.4.0/HowToFAQ/Errors-Parser.template @@ -204,7 +204,7 @@ module N refines M { datatype D = ... Y | Z } -## **Error: datatype extending traits is a beta feature; use /generalTraits:1 to engage** {#p_general_traits_beta} +## **Error: datatype extending traits is a beta feature; use /generalTraits:datatype to engage** {#p_general_traits_beta} ```dafny trait Trait { } diff --git a/latest/v4.3.0/HowToFAQ/Errors-Refinement.md b/v4.4.0/HowToFAQ/Errors-Refinement.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/Errors-Refinement.md rename to v4.4.0/HowToFAQ/Errors-Refinement.md diff --git a/latest/v4.3.0/HowToFAQ/Errors-Resolution.md b/v4.4.0/HowToFAQ/Errors-Resolution.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/Errors-Resolution.md rename to v4.4.0/HowToFAQ/Errors-Resolution.md diff --git a/latest/v4.3.0/HowToFAQ/Errors-Resolver2.md b/v4.4.0/HowToFAQ/Errors-Resolver2.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/Errors-Resolver2.md rename to v4.4.0/HowToFAQ/Errors-Resolver2.md diff --git a/latest/v4.3.0/HowToFAQ/Errors-Resolver3.md b/v4.4.0/HowToFAQ/Errors-Resolver3.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/Errors-Resolver3.md rename to v4.4.0/HowToFAQ/Errors-Resolver3.md diff --git a/latest/v4.3.0/HowToFAQ/Errors-Rewriter.md b/v4.4.0/HowToFAQ/Errors-Rewriter.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/Errors-Rewriter.md rename to v4.4.0/HowToFAQ/Errors-Rewriter.md diff --git a/latest/v4.3.0/HowToFAQ/Errors.md b/v4.4.0/HowToFAQ/Errors.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/Errors.md rename to v4.4.0/HowToFAQ/Errors.md diff --git a/latest/v4.3.0/HowToFAQ/FAQAttribute.md b/v4.4.0/HowToFAQ/FAQAttribute.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQAttribute.md rename to v4.4.0/HowToFAQ/FAQAttribute.md diff --git a/latest/v4.3.0/HowToFAQ/FAQBVNegation.md b/v4.4.0/HowToFAQ/FAQBVNegation.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQBVNegation.md rename to v4.4.0/HowToFAQ/FAQBVNegation.md diff --git a/latest/v4.3.0/HowToFAQ/FAQBoogie.md b/v4.4.0/HowToFAQ/FAQBoogie.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQBoogie.md rename to v4.4.0/HowToFAQ/FAQBoogie.md diff --git a/latest/v4.3.0/HowToFAQ/FAQClassInSpec.md b/v4.4.0/HowToFAQ/FAQClassInSpec.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQClassInSpec.md rename to v4.4.0/HowToFAQ/FAQClassInSpec.md diff --git a/latest/v4.3.0/HowToFAQ/FAQCompileTargets.md b/v4.4.0/HowToFAQ/FAQCompileTargets.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQCompileTargets.md rename to v4.4.0/HowToFAQ/FAQCompileTargets.md diff --git a/latest/v4.3.0/HowToFAQ/FAQCurry.md b/v4.4.0/HowToFAQ/FAQCurry.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQCurry.md rename to v4.4.0/HowToFAQ/FAQCurry.md diff --git a/latest/v4.3.0/HowToFAQ/FAQDafnyAsLibrary.md b/v4.4.0/HowToFAQ/FAQDafnyAsLibrary.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQDafnyAsLibrary.md rename to v4.4.0/HowToFAQ/FAQDafnyAsLibrary.md diff --git a/latest/v4.3.0/HowToFAQ/FAQDefaultInitialValue.md b/v4.4.0/HowToFAQ/FAQDefaultInitialValue.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQDefaultInitialValue.md rename to v4.4.0/HowToFAQ/FAQDefaultInitialValue.md diff --git a/latest/v4.3.0/HowToFAQ/FAQDefaultParameter.md b/v4.4.0/HowToFAQ/FAQDefaultParameter.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQDefaultParameter.md rename to v4.4.0/HowToFAQ/FAQDefaultParameter.md diff --git a/latest/v4.3.0/HowToFAQ/FAQDie.md b/v4.4.0/HowToFAQ/FAQDie.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQDie.md rename to v4.4.0/HowToFAQ/FAQDie.md diff --git a/latest/v4.3.0/HowToFAQ/FAQDocGenerator.md b/v4.4.0/HowToFAQ/FAQDocGenerator.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQDocGenerator.md rename to v4.4.0/HowToFAQ/FAQDocGenerator.md diff --git a/latest/v4.3.0/HowToFAQ/FAQElephant.md b/v4.4.0/HowToFAQ/FAQElephant.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQElephant.md rename to v4.4.0/HowToFAQ/FAQElephant.md diff --git a/latest/v4.3.0/HowToFAQ/FAQExternReturnsObject.md b/v4.4.0/HowToFAQ/FAQExternReturnsObject.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQExternReturnsObject.md rename to v4.4.0/HowToFAQ/FAQExternReturnsObject.md diff --git a/latest/v4.3.0/HowToFAQ/FAQFailingPost.md b/v4.4.0/HowToFAQ/FAQFailingPost.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQFailingPost.md rename to v4.4.0/HowToFAQ/FAQFailingPost.md diff --git a/latest/v4.3.0/HowToFAQ/FAQForall.md b/v4.4.0/HowToFAQ/FAQForall.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQForall.md rename to v4.4.0/HowToFAQ/FAQForall.md diff --git a/latest/v4.3.0/HowToFAQ/FAQForallTricks.md b/v4.4.0/HowToFAQ/FAQForallTricks.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQForallTricks.md rename to v4.4.0/HowToFAQ/FAQForallTricks.md diff --git a/v4.4.0/HowToFAQ/FAQFunctionByMethodProof.md b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof.md new file mode 100644 index 0000000..e107e27 --- /dev/null +++ b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof.md @@ -0,0 +1,87 @@ +--- +title: I can't prove the equivalence between the method part of a `function by method`` and the function itself +--- + +## Question + +I can't prove the equivalence between the method part of a function by method and the function itself. +It seems that my invariants can't be maintained by the loop, and I don't know how to prove them. + +## Answer + +Consider the simple problem of computing the sum of a sequence of integers. +You might be tempted to immediately write the following equivalence, +with your best guess of an invariant +and a hint at the end to help Dafny realize that the result is correct. +However you cannot prove the invariant you just wrote. + +``` +{% include_relative FAQFunctionByMethodProof1.dfy %} +``` + +Let's unroll the computation of the function on a sequence of 3 elements. +The function will compute: + +`s[0] + (s[1] + (s[2] + 0))` + +But the loop will compute + +`((0 + s[0]) + s[1]) + s[2]` + +In the function, we add the first element (`s[0]`) to the result of computing the sum of the remaining elements (`s[1] + (s[2] + 0))`). +In the by method, we add the last element (`s[2]`) to the accumulator, which contains the sum of the initial terms (`(0 + s[0]) + s[1]`). +If it was not the case that the addition was associative and 0 was a neutral element, there would be no immediate way to prove that the two computations are equivalent. + +There are essentially three solutions around that: + +* Improve the invariant, knowing `+` is associative +* Change the order of computation of the function so that it matches the by method +* Change the order of computation of the by method so that it matches the function + +There are more intrusive solutions, such as making the function tail-recursive by changing the function's signature to include an accumulator or a sequence of callbacks to perform a the end, but we will explore only the one that don't change the signature of `Sum()`. + +## Improved invariant + +You can change the invariant to be `invariant result + Sum(s[i..]) == Sum(s)`, as below: + +``` +{% include_relative FAQFunctionByMethodProof2.dfy %} +``` + +This works because, with `result'` being the result at the end of the loop and `+` being associative, +the lemma `IntermediateProperty()` shows the underlying reasoning that helps prove that the invariant +is indeed invariant. Dafny can prove it automatically, so the lemma is not needed in the loop body. +One nice thing is that we can get rid of the final hint. + +What if you had an operation more complex that "+", that is not associative? +This is when you need to ensure the loop and the function are computing in the same order. +Let's explore how to do so by changing either the function, or the by-method body. + +## Make the function compute what the by-method does +The by-method loop's first addition is 0 plus the first element (`s[0]`) of the sequence. For this to +be the first addition performed by the function, it has to be at the bottommost level of the call. +Indeed, each addition is performed after the recursive call finishes. This means that +the function needs to sum the `n-1` elements first and add the remaining last one. + +Since it's exactly what the method computes, it satisfies our initial invariant. + +``` +{% include_relative FAQFunctionByMethodProof3.dfy %} +``` + +Not only does this approach require more proof hints, but it might also break the proofs that dependend on the shape of the function, while all we wanted in the first place was to give a more efficient implementation to the function. +Therefore, it's reasonable to expect we will prefer to change the implementation of the by-method body to reflect the function, not the opposite, as follows: + +## Make the by-method body compute what the function computes + +To compute iteratively what the function computes recursively, you have to find what is the first +addition that will be computed by the method. As mentioned previously, the first addition is the one performed at the bottommost level of recursion: the first addition is `s[|s|-1] + 0`, +so the loop has to actually be in reverse, like this: + +``` +{% include_relative FAQFunctionByMethodProof4.dfy %} +``` + +Note that this approach results in the smallest invariant that actually closely matches the function itself. +Also, instead of adding to the right of `result`, adding to the left ensures the same order is kept, +in case the operation was not commutative (so that it would work for sequence append operation). \ No newline at end of file diff --git a/v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.dfy b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.dfy new file mode 100644 index 0000000..be5753e --- /dev/null +++ b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.dfy @@ -0,0 +1,16 @@ +function Sum(s: seq): (result: int) { + if |s| == 0 then + 0 + else + s[0] + Sum(s[1..]) +} by method { + result := 0; + for i := 0 to |s| + invariant result == Sum(s[0..i]) + // ^^^^^^^^^^^^^^^^^^^^^^ + // Cannot be proved + { + result := result + s[i]; + } + assert s[0..|s|] == s; +} \ No newline at end of file diff --git a/v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.txt b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.txt new file mode 100644 index 0000000..c1cae25 --- /dev/null +++ b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof1.txt @@ -0,0 +1,2 @@ +FAQFunctionByMethodProof1.dfy(9,14): Error: this invariant could not be proved to be maintained by the loop +Dafny program verifier finished with 1 verified, 1 error diff --git a/v4.4.0/HowToFAQ/FAQFunctionByMethodProof2..txt b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof2..txt new file mode 100644 index 0000000..c39a053 --- /dev/null +++ b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof2..txt @@ -0,0 +1 @@ +Dafny program verifier finished with 2 verified, 0 error diff --git a/v4.4.0/HowToFAQ/FAQFunctionByMethodProof2.dfy b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof2.dfy new file mode 100644 index 0000000..2169f6e --- /dev/null +++ b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof2.dfy @@ -0,0 +1,28 @@ +function Sum(s: seq): (result: int) { + if |s| == 0 then + 0 + else + s[0] + Sum(s[1..]) +} by method { + result := 0; + for i := 0 to |s| + invariant result + Sum(s[i..]) == Sum(s) // New invariant + { + result := result + s[i]; + } +} // No hint needed at the end + +lemma IntermediateProperty(result: int, result': int, i: int, s: seq) + requires 0 <= i < |s| + requires result' == result + s[i] + requires result + Sum(s[i..]) == Sum(s) + ensures result' + Sum(s[i+1..]) == Sum(s) +{ + calc { + Sum(s); + == result + Sum(s[i..]); // Requires definition + == result + (s[i] + Sum(s[i+1..])); // Definition of Sum() + ==(result + s[i]) + Sum(s[i+1..]); // Associativity + == result' + Sum(s[i+1..]); // Definition of result' + } +} \ No newline at end of file diff --git a/v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.dfy b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.dfy new file mode 100644 index 0000000..6229ab8 --- /dev/null +++ b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.dfy @@ -0,0 +1,17 @@ +function Sum(s: seq): (result: int) { + if |s| == 0 then + 0 + else + Sum(s[0..|s|-1]) + s[|s| - 1] + // We add the last element to the sum of the first +} by method { + result := 0; + for i := 0 to |s| + invariant result == Sum(s[0..i]) + { + assert s[0..i+1][0..i] == s[0..i]; + // Minimum hint needed for proof + result := result + s[i]; + } + assert s[0..|s|] == s; +} // One last hint \ No newline at end of file diff --git a/v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.txt b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.txt new file mode 100644 index 0000000..c39a053 --- /dev/null +++ b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof3.txt @@ -0,0 +1 @@ +Dafny program verifier finished with 2 verified, 0 error diff --git a/v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.dfy b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.dfy new file mode 100644 index 0000000..5fd07ce --- /dev/null +++ b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.dfy @@ -0,0 +1,10 @@ +function Sum(s: seq): (result: int) { + if |s| == 0 then 0 else s[0] + Sum(s[1..]) +} by method { + result := 0; + for i := |s| downto 0 // Reverse. First i == |s| - 1 + invariant result == Sum(s[i..]) // The invariant looks like the function + { + result := s[i] + result; // Note how we sum in reverse as well. + } +} // No hint needed at the end \ No newline at end of file diff --git a/v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.txt b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.txt new file mode 100644 index 0000000..c39a053 --- /dev/null +++ b/v4.4.0/HowToFAQ/FAQFunctionByMethodProof4.txt @@ -0,0 +1 @@ +Dafny program verifier finished with 2 verified, 0 error diff --git a/latest/v4.3.0/HowToFAQ/FAQFunctionMethod.md b/v4.4.0/HowToFAQ/FAQFunctionMethod.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQFunctionMethod.md rename to v4.4.0/HowToFAQ/FAQFunctionMethod.md diff --git a/latest/v4.3.0/HowToFAQ/FAQFunctionMethodDiffs.md b/v4.4.0/HowToFAQ/FAQFunctionMethodDiffs.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQFunctionMethodDiffs.md rename to v4.4.0/HowToFAQ/FAQFunctionMethodDiffs.md diff --git a/latest/v4.3.0/HowToFAQ/FAQFunctionTypes.md b/v4.4.0/HowToFAQ/FAQFunctionTypes.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQFunctionTypes.md rename to v4.4.0/HowToFAQ/FAQFunctionTypes.md diff --git a/latest/v4.3.0/HowToFAQ/FAQFunctionUnroll.md b/v4.4.0/HowToFAQ/FAQFunctionUnroll.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQFunctionUnroll.md rename to v4.4.0/HowToFAQ/FAQFunctionUnroll.md diff --git a/latest/v4.3.0/HowToFAQ/FAQFunctionUnroll0.dfy b/v4.4.0/HowToFAQ/FAQFunctionUnroll0.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQFunctionUnroll0.dfy rename to v4.4.0/HowToFAQ/FAQFunctionUnroll0.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQFunctionUnroll0.txt b/v4.4.0/HowToFAQ/FAQFunctionUnroll0.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQFunctionUnroll0.txt rename to v4.4.0/HowToFAQ/FAQFunctionUnroll0.txt diff --git a/latest/v4.3.0/HowToFAQ/FAQFunctionUnroll1.dfy b/v4.4.0/HowToFAQ/FAQFunctionUnroll1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQFunctionUnroll1.dfy rename to v4.4.0/HowToFAQ/FAQFunctionUnroll1.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQFunctionUnroll2.dfy b/v4.4.0/HowToFAQ/FAQFunctionUnroll2.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQFunctionUnroll2.dfy rename to v4.4.0/HowToFAQ/FAQFunctionUnroll2.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQGhostConstAsWitness.md b/v4.4.0/HowToFAQ/FAQGhostConstAsWitness.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQGhostConstAsWitness.md rename to v4.4.0/HowToFAQ/FAQGhostConstAsWitness.md diff --git a/latest/v4.3.0/HowToFAQ/FAQGhostMethod.md b/v4.4.0/HowToFAQ/FAQGhostMethod.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQGhostMethod.md rename to v4.4.0/HowToFAQ/FAQGhostMethod.md diff --git a/latest/v4.3.0/HowToFAQ/FAQGhostSideEffects.md b/v4.4.0/HowToFAQ/FAQGhostSideEffects.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQGhostSideEffects.md rename to v4.4.0/HowToFAQ/FAQGhostSideEffects.md diff --git a/latest/v4.3.0/HowToFAQ/FAQIff.md b/v4.4.0/HowToFAQ/FAQIff.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQIff.md rename to v4.4.0/HowToFAQ/FAQIff.md diff --git a/latest/v4.3.0/HowToFAQ/FAQImportAbstractModule.md b/v4.4.0/HowToFAQ/FAQImportAbstractModule.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQImportAbstractModule.md rename to v4.4.0/HowToFAQ/FAQImportAbstractModule.md diff --git a/latest/v4.3.0/HowToFAQ/FAQImportOneThing.md b/v4.4.0/HowToFAQ/FAQImportOneThing.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQImportOneThing.md rename to v4.4.0/HowToFAQ/FAQImportOneThing.md diff --git a/latest/v4.3.0/HowToFAQ/FAQImportOpened.md b/v4.4.0/HowToFAQ/FAQImportOpened.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQImportOpened.md rename to v4.4.0/HowToFAQ/FAQImportOpened.md diff --git a/latest/v4.3.0/HowToFAQ/FAQIncludes.md b/v4.4.0/HowToFAQ/FAQIncludes.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQIncludes.md rename to v4.4.0/HowToFAQ/FAQIncludes.md diff --git a/latest/v4.3.0/HowToFAQ/FAQIssues.md b/v4.4.0/HowToFAQ/FAQIssues.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQIssues.md rename to v4.4.0/HowToFAQ/FAQIssues.md diff --git a/latest/v4.3.0/HowToFAQ/FAQIterator.md b/v4.4.0/HowToFAQ/FAQIterator.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQIterator.md rename to v4.4.0/HowToFAQ/FAQIterator.md diff --git a/latest/v4.3.0/HowToFAQ/FAQLambdaSpecifications.md b/v4.4.0/HowToFAQ/FAQLambdaSpecifications.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQLambdaSpecifications.md rename to v4.4.0/HowToFAQ/FAQLambdaSpecifications.md diff --git a/latest/v4.3.0/HowToFAQ/FAQLoopModifies.md b/v4.4.0/HowToFAQ/FAQLoopModifies.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQLoopModifies.md rename to v4.4.0/HowToFAQ/FAQLoopModifies.md diff --git a/latest/v4.3.0/HowToFAQ/FAQMapExtensionality.md b/v4.4.0/HowToFAQ/FAQMapExtensionality.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQMapExtensionality.md rename to v4.4.0/HowToFAQ/FAQMapExtensionality.md diff --git a/latest/v4.3.0/HowToFAQ/FAQMapMembership.md b/v4.4.0/HowToFAQ/FAQMapMembership.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQMapMembership.md rename to v4.4.0/HowToFAQ/FAQMapMembership.md diff --git a/latest/v4.3.0/HowToFAQ/FAQMatchOnSet.md b/v4.4.0/HowToFAQ/FAQMatchOnSet.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQMatchOnSet.md rename to v4.4.0/HowToFAQ/FAQMatchOnSet.md diff --git a/latest/v4.3.0/HowToFAQ/FAQMepSetSeq.md b/v4.4.0/HowToFAQ/FAQMepSetSeq.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQMepSetSeq.md rename to v4.4.0/HowToFAQ/FAQMepSetSeq.md diff --git a/latest/v4.3.0/HowToFAQ/FAQMethodSequence.md b/v4.4.0/HowToFAQ/FAQMethodSequence.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQMethodSequence.md rename to v4.4.0/HowToFAQ/FAQMethodSequence.md diff --git a/latest/v4.3.0/HowToFAQ/FAQModifiesOne.md b/v4.4.0/HowToFAQ/FAQModifiesOne.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModifiesOne.md rename to v4.4.0/HowToFAQ/FAQModifiesOne.md diff --git a/latest/v4.3.0/HowToFAQ/FAQModifiesThis.md b/v4.4.0/HowToFAQ/FAQModifiesThis.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModifiesThis.md rename to v4.4.0/HowToFAQ/FAQModifiesThis.md diff --git a/latest/v4.3.0/HowToFAQ/FAQModuleImport.dfy b/v4.4.0/HowToFAQ/FAQModuleImport.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModuleImport.dfy rename to v4.4.0/HowToFAQ/FAQModuleImport.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQModuleImport.md b/v4.4.0/HowToFAQ/FAQModuleImport.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModuleImport.md rename to v4.4.0/HowToFAQ/FAQModuleImport.md diff --git a/latest/v4.3.0/HowToFAQ/FAQModuleImport.txt b/v4.4.0/HowToFAQ/FAQModuleImport.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModuleImport.txt rename to v4.4.0/HowToFAQ/FAQModuleImport.txt diff --git a/latest/v4.3.0/HowToFAQ/FAQModuleImport1.dfy b/v4.4.0/HowToFAQ/FAQModuleImport1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModuleImport1.dfy rename to v4.4.0/HowToFAQ/FAQModuleImport1.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQModuleNames.dfy b/v4.4.0/HowToFAQ/FAQModuleNames.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModuleNames.dfy rename to v4.4.0/HowToFAQ/FAQModuleNames.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQModuleNames.md b/v4.4.0/HowToFAQ/FAQModuleNames.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModuleNames.md rename to v4.4.0/HowToFAQ/FAQModuleNames.md diff --git a/latest/v4.3.0/HowToFAQ/FAQModuleNames0.dfy b/v4.4.0/HowToFAQ/FAQModuleNames0.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModuleNames0.dfy rename to v4.4.0/HowToFAQ/FAQModuleNames0.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQModuleNames0.txt b/v4.4.0/HowToFAQ/FAQModuleNames0.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQModuleNames0.txt rename to v4.4.0/HowToFAQ/FAQModuleNames0.txt diff --git a/latest/v4.3.0/HowToFAQ/FAQMonadic.md b/v4.4.0/HowToFAQ/FAQMonadic.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQMonadic.md rename to v4.4.0/HowToFAQ/FAQMonadic.md diff --git a/latest/v4.3.0/HowToFAQ/FAQMultClauses.md b/v4.4.0/HowToFAQ/FAQMultClauses.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQMultClauses.md rename to v4.4.0/HowToFAQ/FAQMultClauses.md diff --git a/latest/v4.3.0/HowToFAQ/FAQMutualRecursion.md b/v4.4.0/HowToFAQ/FAQMutualRecursion.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQMutualRecursion.md rename to v4.4.0/HowToFAQ/FAQMutualRecursion.md diff --git a/latest/v4.3.0/HowToFAQ/FAQNameConflict.dfy b/v4.4.0/HowToFAQ/FAQNameConflict.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNameConflict.dfy rename to v4.4.0/HowToFAQ/FAQNameConflict.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQNameConflict.md b/v4.4.0/HowToFAQ/FAQNameConflict.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNameConflict.md rename to v4.4.0/HowToFAQ/FAQNameConflict.md diff --git a/latest/v4.3.0/HowToFAQ/FAQNameConflict.txt b/v4.4.0/HowToFAQ/FAQNameConflict.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNameConflict.txt rename to v4.4.0/HowToFAQ/FAQNameConflict.txt diff --git a/latest/v4.3.0/HowToFAQ/FAQNameConflict1.dfy b/v4.4.0/HowToFAQ/FAQNameConflict1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNameConflict1.dfy rename to v4.4.0/HowToFAQ/FAQNameConflict1.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQNeedsAssert.md b/v4.4.0/HowToFAQ/FAQNeedsAssert.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNeedsAssert.md rename to v4.4.0/HowToFAQ/FAQNeedsAssert.md diff --git a/latest/v4.3.0/HowToFAQ/FAQNestedModule.dfy b/v4.4.0/HowToFAQ/FAQNestedModule.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNestedModule.dfy rename to v4.4.0/HowToFAQ/FAQNestedModule.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQNestedModule.md b/v4.4.0/HowToFAQ/FAQNestedModule.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNestedModule.md rename to v4.4.0/HowToFAQ/FAQNestedModule.md diff --git a/latest/v4.3.0/HowToFAQ/FAQNestedModule.txt b/v4.4.0/HowToFAQ/FAQNestedModule.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNestedModule.txt rename to v4.4.0/HowToFAQ/FAQNestedModule.txt diff --git a/latest/v4.3.0/HowToFAQ/FAQNewline.md b/v4.4.0/HowToFAQ/FAQNewline.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNewline.md rename to v4.4.0/HowToFAQ/FAQNewline.md diff --git a/latest/v4.3.0/HowToFAQ/FAQNewtype.dfy b/v4.4.0/HowToFAQ/FAQNewtype.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNewtype.dfy rename to v4.4.0/HowToFAQ/FAQNewtype.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQNewtype.md b/v4.4.0/HowToFAQ/FAQNewtype.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNewtype.md rename to v4.4.0/HowToFAQ/FAQNewtype.md diff --git a/latest/v4.3.0/HowToFAQ/FAQNoBody.md b/v4.4.0/HowToFAQ/FAQNoBody.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNoBody.md rename to v4.4.0/HowToFAQ/FAQNoBody.md diff --git a/latest/v4.3.0/HowToFAQ/FAQNoTermCheck.md b/v4.4.0/HowToFAQ/FAQNoTermCheck.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNoTermCheck.md rename to v4.4.0/HowToFAQ/FAQNoTermCheck.md diff --git a/latest/v4.3.0/HowToFAQ/FAQNonlinearArith.md b/v4.4.0/HowToFAQ/FAQNonlinearArith.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNonlinearArith.md rename to v4.4.0/HowToFAQ/FAQNonlinearArith.md diff --git a/latest/v4.3.0/HowToFAQ/FAQNuget.md b/v4.4.0/HowToFAQ/FAQNuget.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQNuget.md rename to v4.4.0/HowToFAQ/FAQNuget.md diff --git a/latest/v4.3.0/HowToFAQ/FAQOld.md b/v4.4.0/HowToFAQ/FAQOld.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQOld.md rename to v4.4.0/HowToFAQ/FAQOld.md diff --git a/latest/v4.3.0/HowToFAQ/FAQParallel.md b/v4.4.0/HowToFAQ/FAQParallel.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQParallel.md rename to v4.4.0/HowToFAQ/FAQParallel.md diff --git a/latest/v4.3.0/HowToFAQ/FAQPreconditionLabels.dfy b/v4.4.0/HowToFAQ/FAQPreconditionLabels.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQPreconditionLabels.dfy rename to v4.4.0/HowToFAQ/FAQPreconditionLabels.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQPreconditionLabels.md b/v4.4.0/HowToFAQ/FAQPreconditionLabels.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQPreconditionLabels.md rename to v4.4.0/HowToFAQ/FAQPreconditionLabels.md diff --git a/latest/v4.3.0/HowToFAQ/FAQPreconditionLabels.txt b/v4.4.0/HowToFAQ/FAQPreconditionLabels.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQPreconditionLabels.txt rename to v4.4.0/HowToFAQ/FAQPreconditionLabels.txt diff --git a/latest/v4.3.0/HowToFAQ/FAQReadFile.md b/v4.4.0/HowToFAQ/FAQReadFile.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQReadFile.md rename to v4.4.0/HowToFAQ/FAQReadFile.md diff --git a/latest/v4.3.0/HowToFAQ/FAQReadsClause.dfy b/v4.4.0/HowToFAQ/FAQReadsClause.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQReadsClause.dfy rename to v4.4.0/HowToFAQ/FAQReadsClause.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQReadsClause.md b/v4.4.0/HowToFAQ/FAQReadsClause.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQReadsClause.md rename to v4.4.0/HowToFAQ/FAQReadsClause.md diff --git a/latest/v4.3.0/HowToFAQ/FAQReadsClause.txt b/v4.4.0/HowToFAQ/FAQReadsClause.txt similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQReadsClause.txt rename to v4.4.0/HowToFAQ/FAQReadsClause.txt diff --git a/latest/v4.3.0/HowToFAQ/FAQRecord.md b/v4.4.0/HowToFAQ/FAQRecord.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQRecord.md rename to v4.4.0/HowToFAQ/FAQRecord.md diff --git a/latest/v4.3.0/HowToFAQ/FAQRecursiveCalls.md b/v4.4.0/HowToFAQ/FAQRecursiveCalls.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQRecursiveCalls.md rename to v4.4.0/HowToFAQ/FAQRecursiveCalls.md diff --git a/latest/v4.3.0/HowToFAQ/FAQRecursiveTermination.md b/v4.4.0/HowToFAQ/FAQRecursiveTermination.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQRecursiveTermination.md rename to v4.4.0/HowToFAQ/FAQRecursiveTermination.md diff --git a/latest/v4.3.0/HowToFAQ/FAQRedundantCase.md b/v4.4.0/HowToFAQ/FAQRedundantCase.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQRedundantCase.md rename to v4.4.0/HowToFAQ/FAQRedundantCase.md diff --git a/latest/v4.3.0/HowToFAQ/FAQReferences.md b/v4.4.0/HowToFAQ/FAQReferences.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQReferences.md rename to v4.4.0/HowToFAQ/FAQReferences.md diff --git a/latest/v4.3.0/HowToFAQ/FAQSeqTrait.md b/v4.4.0/HowToFAQ/FAQSeqTrait.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQSeqTrait.md rename to v4.4.0/HowToFAQ/FAQSeqTrait.md diff --git a/latest/v4.3.0/HowToFAQ/FAQSetConstructor.md b/v4.4.0/HowToFAQ/FAQSetConstructor.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQSetConstructor.md rename to v4.4.0/HowToFAQ/FAQSetConstructor.md diff --git a/latest/v4.3.0/HowToFAQ/FAQSetToSeq.md b/v4.4.0/HowToFAQ/FAQSetToSeq.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQSetToSeq.md rename to v4.4.0/HowToFAQ/FAQSetToSeq.md diff --git a/latest/v4.3.0/HowToFAQ/FAQSplitHere.md b/v4.4.0/HowToFAQ/FAQSplitHere.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQSplitHere.md rename to v4.4.0/HowToFAQ/FAQSplitHere.md diff --git a/latest/v4.3.0/HowToFAQ/FAQStandardLibrary.md b/v4.4.0/HowToFAQ/FAQStandardLibrary.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQStandardLibrary.md rename to v4.4.0/HowToFAQ/FAQStandardLibrary.md diff --git a/latest/v4.3.0/HowToFAQ/FAQStringOutput.md b/v4.4.0/HowToFAQ/FAQStringOutput.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQStringOutput.md rename to v4.4.0/HowToFAQ/FAQStringOutput.md diff --git a/latest/v4.3.0/HowToFAQ/FAQStyle.md b/v4.4.0/HowToFAQ/FAQStyle.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQStyle.md rename to v4.4.0/HowToFAQ/FAQStyle.md diff --git a/latest/v4.3.0/HowToFAQ/FAQTermination.md b/v4.4.0/HowToFAQ/FAQTermination.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQTermination.md rename to v4.4.0/HowToFAQ/FAQTermination.md diff --git a/latest/v4.3.0/HowToFAQ/FAQTerminationFalse.md b/v4.4.0/HowToFAQ/FAQTerminationFalse.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQTerminationFalse.md rename to v4.4.0/HowToFAQ/FAQTerminationFalse.md diff --git a/latest/v4.3.0/HowToFAQ/FAQThisFrameField.md b/v4.4.0/HowToFAQ/FAQThisFrameField.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQThisFrameField.md rename to v4.4.0/HowToFAQ/FAQThisFrameField.md diff --git a/latest/v4.3.0/HowToFAQ/FAQTraitsForDatatypes.md b/v4.4.0/HowToFAQ/FAQTraitsForDatatypes.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQTraitsForDatatypes.md rename to v4.4.0/HowToFAQ/FAQTraitsForDatatypes.md diff --git a/latest/v4.3.0/HowToFAQ/FAQTriggers.md b/v4.4.0/HowToFAQ/FAQTriggers.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQTriggers.md rename to v4.4.0/HowToFAQ/FAQTriggers.md diff --git a/latest/v4.3.0/HowToFAQ/FAQTypeCompare.dfy b/v4.4.0/HowToFAQ/FAQTypeCompare.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQTypeCompare.dfy rename to v4.4.0/HowToFAQ/FAQTypeCompare.dfy diff --git a/latest/v4.3.0/HowToFAQ/FAQTypeCompare.md b/v4.4.0/HowToFAQ/FAQTypeCompare.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQTypeCompare.md rename to v4.4.0/HowToFAQ/FAQTypeCompare.md diff --git a/latest/v4.3.0/HowToFAQ/FAQTypeInference.md b/v4.4.0/HowToFAQ/FAQTypeInference.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQTypeInference.md rename to v4.4.0/HowToFAQ/FAQTypeInference.md diff --git a/latest/v4.3.0/HowToFAQ/FAQTypeParameterRestriction.md b/v4.4.0/HowToFAQ/FAQTypeParameterRestriction.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQTypeParameterRestriction.md rename to v4.4.0/HowToFAQ/FAQTypeParameterRestriction.md diff --git a/latest/v4.3.0/HowToFAQ/FAQTypeReasoning.md b/v4.4.0/HowToFAQ/FAQTypeReasoning.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQTypeReasoning.md rename to v4.4.0/HowToFAQ/FAQTypeReasoning.md diff --git a/latest/v4.3.0/HowToFAQ/FAQUpdateArrayField.md b/v4.4.0/HowToFAQ/FAQUpdateArrayField.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQUpdateArrayField.md rename to v4.4.0/HowToFAQ/FAQUpdateArrayField.md diff --git a/latest/v4.3.0/HowToFAQ/FAQWitness.md b/v4.4.0/HowToFAQ/FAQWitness.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQWitness.md rename to v4.4.0/HowToFAQ/FAQWitness.md diff --git a/latest/v4.3.0/HowToFAQ/FAQZ3.md b/v4.4.0/HowToFAQ/FAQZ3.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQZ3.md rename to v4.4.0/HowToFAQ/FAQZ3.md diff --git a/latest/v4.3.0/HowToFAQ/FAQ_GenericType.md b/v4.4.0/HowToFAQ/FAQ_GenericType.md similarity index 100% rename from latest/v4.3.0/HowToFAQ/FAQ_GenericType.md rename to v4.4.0/HowToFAQ/FAQ_GenericType.md diff --git a/latest/v4.3.0/HowToFAQ/MakeErrorCatalog.java b/v4.4.0/HowToFAQ/MakeErrorCatalog.java similarity index 100% rename from latest/v4.3.0/HowToFAQ/MakeErrorCatalog.java rename to v4.4.0/HowToFAQ/MakeErrorCatalog.java diff --git a/latest/v4.3.0/HowToFAQ/check-errors b/v4.4.0/HowToFAQ/check-errors old mode 100644 new mode 100755 similarity index 100% rename from latest/v4.3.0/HowToFAQ/check-errors rename to v4.4.0/HowToFAQ/check-errors diff --git a/latest/v4.3.0/HowToFAQ/check-errors-a b/v4.4.0/HowToFAQ/check-errors-a old mode 100644 new mode 100755 similarity index 100% rename from latest/v4.3.0/HowToFAQ/check-errors-a rename to v4.4.0/HowToFAQ/check-errors-a diff --git a/latest/v4.3.0/HowToFAQ/index.md b/v4.4.0/HowToFAQ/index.md similarity index 98% rename from latest/v4.3.0/HowToFAQ/index.md rename to v4.4.0/HowToFAQ/index.md index f4bc063..e4ff15a 100644 --- a/latest/v4.3.0/HowToFAQ/index.md +++ b/v4.4.0/HowToFAQ/index.md @@ -86,6 +86,7 @@ If you have questions that are not addressed here, be sure to communicate them t - ["How do I model extern methods that return objects?"](FAQExternReturnsObject) - ["How do I tell Dafny that a class field may be updated?"](FAQUpdateArrayField) - ["Why does Dafny not know this obvious property of maps?"](FAQMapMembership) +- ["I can't prove the equivalence between the method part of a `function by method` and the function itself"](FAQFunctionByMethodProof) ## Dafny tools diff --git a/latest/v4.3.0/HowToFAQ/make-error-catalog b/v4.4.0/HowToFAQ/make-error-catalog old mode 100644 new mode 100755 similarity index 100% rename from latest/v4.3.0/HowToFAQ/make-error-catalog rename to v4.4.0/HowToFAQ/make-error-catalog diff --git a/latest/v4.3.0/HowToFAQ/make-onepage b/v4.4.0/HowToFAQ/make-onepage old mode 100644 new mode 100755 similarity index 100% rename from latest/v4.3.0/HowToFAQ/make-onepage rename to v4.4.0/HowToFAQ/make-onepage diff --git a/latest/v4.3.0/HowToFAQ/onepage.md b/v4.4.0/HowToFAQ/onepage.md similarity index 96% rename from latest/v4.3.0/HowToFAQ/onepage.md rename to v4.4.0/HowToFAQ/onepage.md index d5360ae..5962fde 100644 --- a/latest/v4.3.0/HowToFAQ/onepage.md +++ b/v4.4.0/HowToFAQ/onepage.md @@ -2307,6 +2307,92 @@ method mmm(m: map, k: K, v: V) { ``` proves just fine. +# I can't prove the equivalence between the method part of a `function by method`` and the function itself + + +## Question + +I can't prove the equivalence between the method part of a function by method and the function itself. +It seems that my invariants can't be maintained by the loop, and I don't know how to prove them. + +## Answer + +Consider the simple problem of computing the sum of a sequence of integers. +You might be tempted to immediately write the following equivalence, +with your best guess of an invariant +and a hint at the end to help Dafny realize that the result is correct. +However you cannot prove the invariant you just wrote. + +``` +{% include_relative FAQFunctionByMethodProof1.dfy %} +``` + +Let's unroll the computation of the function on a sequence of 3 elements. +The function will compute: + +`s[0] + (s[1] + (s[2] + 0))` + +But the loop will compute + +`((0 + s[0]) + s[1]) + s[2]` + +In the function, we add the first element (`s[0]`) to the result of computing the sum of the remaining elements (`s[1] + (s[2] + 0))`). +In the by method, we add the last element (`s[2]`) to the accumulator, which contains the sum of the initial terms (`(0 + s[0]) + s[1]`). +If it was not the case that the addition was associative and 0 was a neutral element, there would be no immediate way to prove that the two computations are equivalent. + +There are essentially three solutions around that: + +* Improve the invariant, knowing `+` is associative +* Change the order of computation of the function so that it matches the by method +* Change the order of computation of the by method so that it matches the function + +There are more intrusive solutions, such as making the function tail-recursive by changing the function's signature to include an accumulator or a sequence of callbacks to perform a the end, but we will explore only the one that don't change the signature of `Sum()`. + +## Improved invariant + +You can change the invariant to be `invariant result + Sum(s[i..]) == Sum(s)`, as below: + +``` +{% include_relative FAQFunctionByMethodProof2.dfy %} +``` + +This works because, with `result'` being the result at the end of the loop and `+` being associative, +the lemma `IntermediateProperty()` shows the underlying reasoning that helps prove that the invariant +is indeed invariant. Dafny can prove it automatically, so the lemma is not needed in the loop body. +One nice thing is that we can get rid of the final hint. + +What if you had an operation more complex that "+", that is not associative? +This is when you need to ensure the loop and the function are computing in the same order. +Let's explore how to do so by changing either the function, or the by-method body. + +## Make the function compute what the by-method does +The by-method loop's first addition is 0 plus the first element (`s[0]`) of the sequence. For this to +be the first addition performed by the function, it has to be at the bottommost level of the call. +Indeed, each addition is performed after the recursive call finishes. This means that +the function needs to sum the `n-1` elements first and add the remaining last one. + +Since it's exactly what the method computes, it satisfies our initial invariant. + +``` +{% include_relative FAQFunctionByMethodProof3.dfy %} +``` + +Not only does this approach require more proof hints, but it might also break the proofs that dependend on the shape of the function, while all we wanted in the first place was to give a more efficient implementation to the function. +Therefore, it's reasonable to expect we will prefer to change the implementation of the by-method body to reflect the function, not the opposite, as follows: + +## Make the by-method body compute what the function computes + +To compute iteratively what the function computes recursively, you have to find what is the first +addition that will be computed by the method. As mentioned previously, the first addition is the one performed at the bottommost level of recursion: the first addition is `s[|s|-1] + 0`, +so the loop has to actually be in reverse, like this: + +``` +{% include_relative FAQFunctionByMethodProof4.dfy %} +``` + +Note that this approach results in the smallest invariant that actually closely matches the function itself. +Also, instead of adding to the right of `result`, adding to the left ensures the same order is kept, +in case the operation was not commutative (so that it would work for sequence append operation). # Is there a Dafny style? and a Dafny linter (style checker and bad smell warnings)? @@ -2855,7 +2941,7 @@ Until then, the best you can do is to try to change the verification condition s This warning can occur if a file being compiled by Dafny is completely empty. -Previous other occurences of this warning were bugs. +Previous other occurrences of this warning were bugs. # "Duplicate name of import: ..." diff --git a/latest/v4.3.0/HowToFAQ/testfiles/a.dfy b/v4.4.0/HowToFAQ/testfiles/a.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/testfiles/a.dfy rename to v4.4.0/HowToFAQ/testfiles/a.dfy diff --git a/latest/v4.3.0/HowToFAQ/testsource/BadDoo.doo b/v4.4.0/HowToFAQ/testsource/BadDoo.doo similarity index 100% rename from latest/v4.3.0/HowToFAQ/testsource/BadDoo.doo rename to v4.4.0/HowToFAQ/testsource/BadDoo.doo diff --git a/latest/v4.3.0/HowToFAQ/testsource/TestA.dfy b/v4.4.0/HowToFAQ/testsource/TestA.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/testsource/TestA.dfy rename to v4.4.0/HowToFAQ/testsource/TestA.dfy diff --git a/latest/v4.3.0/HowToFAQ/testsource/test1.dfy b/v4.4.0/HowToFAQ/testsource/test1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/testsource/test1.dfy rename to v4.4.0/HowToFAQ/testsource/test1.dfy diff --git a/latest/v4.3.0/HowToFAQ/testsource/test2.dfy b/v4.4.0/HowToFAQ/testsource/test2.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/testsource/test2.dfy rename to v4.4.0/HowToFAQ/testsource/test2.dfy diff --git a/latest/v4.3.0/HowToFAQ/text1.dfy b/v4.4.0/HowToFAQ/text1.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/text1.dfy rename to v4.4.0/HowToFAQ/text1.dfy diff --git a/latest/v4.3.0/HowToFAQ/text2.dfy b/v4.4.0/HowToFAQ/text2.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/text2.dfy rename to v4.4.0/HowToFAQ/text2.dfy diff --git a/latest/v4.3.0/HowToFAQ/text3.dfy b/v4.4.0/HowToFAQ/text3.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/text3.dfy rename to v4.4.0/HowToFAQ/text3.dfy diff --git a/latest/v4.3.0/HowToFAQ/text4.dfy b/v4.4.0/HowToFAQ/text4.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/text4.dfy rename to v4.4.0/HowToFAQ/text4.dfy diff --git a/latest/v4.3.0/HowToFAQ/text5.dfy b/v4.4.0/HowToFAQ/text5.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/text5.dfy rename to v4.4.0/HowToFAQ/text5.dfy diff --git a/latest/v4.3.0/HowToFAQ/text6.dfy b/v4.4.0/HowToFAQ/text6.dfy similarity index 100% rename from latest/v4.3.0/HowToFAQ/text6.dfy rename to v4.4.0/HowToFAQ/text6.dfy diff --git a/latest/v4.3.0/Installation.md b/v4.4.0/Installation.md similarity index 96% rename from latest/v4.3.0/Installation.md rename to v4.4.0/Installation.md index b78b677..a52b2d4 100644 --- a/latest/v4.3.0/Installation.md +++ b/v4.4.0/Installation.md @@ -140,16 +140,18 @@ After the compiler dependencies are installed, you can run a quick test of the i ## Mac (Binary) {#Mac-binary} -To install a binary installation of dafny on Mac OS, do one of the following: -Either +To install a binary installation of Dafny on macOS, do one of the following: + +Either * Install the Mac binary version of Dafny, from `https://github.com/dafny-lang/dafny/releases/latest` - * Unzip the downloaded file in a (empty) location of your choice ($INSTALL) - * cd into the installation directory (`$INSTALL/dafny`) and run the script `./allow_on_mac.sh` - * dafny is run with the command `$INSTALL/dafny/dafny` + * Unzip the downloaded file in a (empty) location of your choice (`$INSTALL`) + * `cd` into the installation directory (`$INSTALL/dafny`) and run the script `./allow_on_mac.sh` + * Dafny is run with the command `$INSTALL/dafny/dafny` + or - * install dafny using brew, with the command `brew install dafny` (the version on brew sometimes lags the + * Install Dafny using brew, with the command `brew install dafny` (the version on brew sometimes lags the project release page) - * run dafny with the command `dafny` + * Run Dafny with the command `dafny` If you intend to use the Dafny compiler, install the appropriate tools as described [here](#compiling-dafny). diff --git a/latest/v4.3.0/KDESyntaxDefinition/dafny.theme b/v4.4.0/KDESyntaxDefinition/dafny.theme similarity index 100% rename from latest/v4.3.0/KDESyntaxDefinition/dafny.theme rename to v4.4.0/KDESyntaxDefinition/dafny.theme diff --git a/latest/v4.3.0/KDESyntaxDefinition/dafny.theme-comments b/v4.4.0/KDESyntaxDefinition/dafny.theme-comments similarity index 100% rename from latest/v4.3.0/KDESyntaxDefinition/dafny.theme-comments rename to v4.4.0/KDESyntaxDefinition/dafny.theme-comments diff --git a/latest/v4.3.0/KDESyntaxDefinition/dafny.xml b/v4.4.0/KDESyntaxDefinition/dafny.xml similarity index 100% rename from latest/v4.3.0/KDESyntaxDefinition/dafny.xml rename to v4.4.0/KDESyntaxDefinition/dafny.xml diff --git a/latest/v4.3.0/KDESyntaxDefinition/grammar.theme b/v4.4.0/KDESyntaxDefinition/grammar.theme similarity index 100% rename from latest/v4.3.0/KDESyntaxDefinition/grammar.theme rename to v4.4.0/KDESyntaxDefinition/grammar.theme diff --git a/latest/v4.3.0/KDESyntaxDefinition/grammar.xml b/v4.4.0/KDESyntaxDefinition/grammar.xml similarity index 100% rename from latest/v4.3.0/KDESyntaxDefinition/grammar.xml rename to v4.4.0/KDESyntaxDefinition/grammar.xml diff --git a/latest/v4.3.0/LICENSE b/v4.4.0/LICENSE similarity index 100% rename from latest/v4.3.0/LICENSE rename to v4.4.0/LICENSE diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.1.expect b/v4.4.0/OnlineTutorial/Lemmas.1.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Lemmas.1.expect rename to v4.4.0/OnlineTutorial/Lemmas.1.expect diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.10.expect b/v4.4.0/OnlineTutorial/Lemmas.10.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Lemmas.10.expect rename to v4.4.0/OnlineTutorial/Lemmas.10.expect diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.2.expect b/v4.4.0/OnlineTutorial/Lemmas.2.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Lemmas.2.expect rename to v4.4.0/OnlineTutorial/Lemmas.2.expect diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.3.expect b/v4.4.0/OnlineTutorial/Lemmas.3.expect similarity index 77% rename from latest/v4.3.0/OnlineTutorial/Lemmas.3.expect rename to v4.4.0/OnlineTutorial/Lemmas.3.expect index 16d9852..741469b 100644 --- a/latest/v4.3.0/OnlineTutorial/Lemmas.3.expect +++ b/v4.4.0/OnlineTutorial/Lemmas.3.expect @@ -1,6 +1,4 @@ text.dfy(6,0): Error: a postcondition could not be proved on this return path text.dfy(5,10): Related location: this is the postcondition that could not be proved -text.dfy(5,56): Related location -text.dfy(5,65): Related location Dafny program verifier finished with 1 verified, 1 error diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.4.expect b/v4.4.0/OnlineTutorial/Lemmas.4.expect similarity index 77% rename from latest/v4.3.0/OnlineTutorial/Lemmas.4.expect rename to v4.4.0/OnlineTutorial/Lemmas.4.expect index 7bdfae0..dfd367e 100644 --- a/latest/v4.3.0/OnlineTutorial/Lemmas.4.expect +++ b/v4.4.0/OnlineTutorial/Lemmas.4.expect @@ -1,6 +1,4 @@ text.dfy(6,0): Error: a postcondition could not be proved on this return path text.dfy(5,10): Related location: this is the postcondition that could not be proved -text.dfy(5,56): Related location -text.dfy(5,65): Related location Dafny program verifier finished with 3 verified, 1 error diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.5.expect b/v4.4.0/OnlineTutorial/Lemmas.5.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Lemmas.5.expect rename to v4.4.0/OnlineTutorial/Lemmas.5.expect diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.6.expect b/v4.4.0/OnlineTutorial/Lemmas.6.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Lemmas.6.expect rename to v4.4.0/OnlineTutorial/Lemmas.6.expect diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.7.expect b/v4.4.0/OnlineTutorial/Lemmas.7.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Lemmas.7.expect rename to v4.4.0/OnlineTutorial/Lemmas.7.expect diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.8.expect b/v4.4.0/OnlineTutorial/Lemmas.8.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Lemmas.8.expect rename to v4.4.0/OnlineTutorial/Lemmas.8.expect diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.9.expect b/v4.4.0/OnlineTutorial/Lemmas.9.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Lemmas.9.expect rename to v4.4.0/OnlineTutorial/Lemmas.9.expect diff --git a/latest/v4.3.0/OnlineTutorial/Lemmas.md b/v4.4.0/OnlineTutorial/Lemmas.md similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Lemmas.md rename to v4.4.0/OnlineTutorial/Lemmas.md diff --git a/latest/v4.3.0/OnlineTutorial/Modules.1.expect b/v4.4.0/OnlineTutorial/Modules.1.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Modules.1.expect rename to v4.4.0/OnlineTutorial/Modules.1.expect diff --git a/latest/v4.3.0/OnlineTutorial/Modules.2.expect b/v4.4.0/OnlineTutorial/Modules.2.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Modules.2.expect rename to v4.4.0/OnlineTutorial/Modules.2.expect diff --git a/latest/v4.3.0/OnlineTutorial/Modules.3.expect b/v4.4.0/OnlineTutorial/Modules.3.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Modules.3.expect rename to v4.4.0/OnlineTutorial/Modules.3.expect diff --git a/latest/v4.3.0/OnlineTutorial/Modules.4.expect b/v4.4.0/OnlineTutorial/Modules.4.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Modules.4.expect rename to v4.4.0/OnlineTutorial/Modules.4.expect diff --git a/latest/v4.3.0/OnlineTutorial/Modules.5.expect b/v4.4.0/OnlineTutorial/Modules.5.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Modules.5.expect rename to v4.4.0/OnlineTutorial/Modules.5.expect diff --git a/latest/v4.3.0/OnlineTutorial/Modules.6.expect b/v4.4.0/OnlineTutorial/Modules.6.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Modules.6.expect rename to v4.4.0/OnlineTutorial/Modules.6.expect diff --git a/latest/v4.3.0/OnlineTutorial/Modules.7.expect b/v4.4.0/OnlineTutorial/Modules.7.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Modules.7.expect rename to v4.4.0/OnlineTutorial/Modules.7.expect diff --git a/latest/v4.3.0/OnlineTutorial/Modules.md b/v4.4.0/OnlineTutorial/Modules.md similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Modules.md rename to v4.4.0/OnlineTutorial/Modules.md diff --git a/latest/v4.3.0/OnlineTutorial/Sequences.md b/v4.4.0/OnlineTutorial/Sequences.md similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Sequences.md rename to v4.4.0/OnlineTutorial/Sequences.md diff --git a/latest/v4.3.0/OnlineTutorial/Sets.1.expect b/v4.4.0/OnlineTutorial/Sets.1.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Sets.1.expect rename to v4.4.0/OnlineTutorial/Sets.1.expect diff --git a/latest/v4.3.0/OnlineTutorial/Sets.W1.expect b/v4.4.0/OnlineTutorial/Sets.W1.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Sets.W1.expect rename to v4.4.0/OnlineTutorial/Sets.W1.expect diff --git a/latest/v4.3.0/OnlineTutorial/Sets.W2.expect b/v4.4.0/OnlineTutorial/Sets.W2.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Sets.W2.expect rename to v4.4.0/OnlineTutorial/Sets.W2.expect diff --git a/latest/v4.3.0/OnlineTutorial/Sets.W3.expect b/v4.4.0/OnlineTutorial/Sets.W3.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Sets.W3.expect rename to v4.4.0/OnlineTutorial/Sets.W3.expect diff --git a/latest/v4.3.0/OnlineTutorial/Sets.md b/v4.4.0/OnlineTutorial/Sets.md similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Sets.md rename to v4.4.0/OnlineTutorial/Sets.md diff --git a/latest/v4.3.0/OnlineTutorial/Termination.md b/v4.4.0/OnlineTutorial/Termination.md similarity index 100% rename from latest/v4.3.0/OnlineTutorial/Termination.md rename to v4.4.0/OnlineTutorial/Termination.md diff --git a/latest/v4.3.0/OnlineTutorial/ValueTypes.md b/v4.4.0/OnlineTutorial/ValueTypes.md similarity index 100% rename from latest/v4.3.0/OnlineTutorial/ValueTypes.md rename to v4.4.0/OnlineTutorial/ValueTypes.md diff --git a/latest/v4.3.0/OnlineTutorial/guide.1.expect b/v4.4.0/OnlineTutorial/guide.1.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.1.expect rename to v4.4.0/OnlineTutorial/guide.1.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.10.expect b/v4.4.0/OnlineTutorial/guide.10.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.10.expect rename to v4.4.0/OnlineTutorial/guide.10.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.11.expect b/v4.4.0/OnlineTutorial/guide.11.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.11.expect rename to v4.4.0/OnlineTutorial/guide.11.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.12.expect b/v4.4.0/OnlineTutorial/guide.12.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.12.expect rename to v4.4.0/OnlineTutorial/guide.12.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.13.expect b/v4.4.0/OnlineTutorial/guide.13.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.13.expect rename to v4.4.0/OnlineTutorial/guide.13.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.14.expect b/v4.4.0/OnlineTutorial/guide.14.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.14.expect rename to v4.4.0/OnlineTutorial/guide.14.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.15.expect b/v4.4.0/OnlineTutorial/guide.15.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.15.expect rename to v4.4.0/OnlineTutorial/guide.15.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.16.expect b/v4.4.0/OnlineTutorial/guide.16.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.16.expect rename to v4.4.0/OnlineTutorial/guide.16.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.17.expect b/v4.4.0/OnlineTutorial/guide.17.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.17.expect rename to v4.4.0/OnlineTutorial/guide.17.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.18.expect b/v4.4.0/OnlineTutorial/guide.18.expect similarity index 77% rename from latest/v4.3.0/OnlineTutorial/guide.18.expect rename to v4.4.0/OnlineTutorial/guide.18.expect index cff5e59..271d2cb 100644 --- a/latest/v4.3.0/OnlineTutorial/guide.18.expect +++ b/v4.4.0/OnlineTutorial/guide.18.expect @@ -1,6 +1,4 @@ text.dfy(4,0): Error: a postcondition could not be proved on this return path text.dfy(3,24): Related location: this is the postcondition that could not be proved -text.dfy(3,54): Related location -text.dfy(3,63): Related location Dafny program verifier finished with 1 verified, 1 error diff --git a/latest/v4.3.0/OnlineTutorial/guide.19.expect b/v4.4.0/OnlineTutorial/guide.19.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.19.expect rename to v4.4.0/OnlineTutorial/guide.19.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.2.expect b/v4.4.0/OnlineTutorial/guide.2.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.2.expect rename to v4.4.0/OnlineTutorial/guide.2.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.20.expect b/v4.4.0/OnlineTutorial/guide.20.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.20.expect rename to v4.4.0/OnlineTutorial/guide.20.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.3.expect b/v4.4.0/OnlineTutorial/guide.3.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.3.expect rename to v4.4.0/OnlineTutorial/guide.3.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.4.expect b/v4.4.0/OnlineTutorial/guide.4.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.4.expect rename to v4.4.0/OnlineTutorial/guide.4.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.5.expect b/v4.4.0/OnlineTutorial/guide.5.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.5.expect rename to v4.4.0/OnlineTutorial/guide.5.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.6.expect b/v4.4.0/OnlineTutorial/guide.6.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.6.expect rename to v4.4.0/OnlineTutorial/guide.6.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.7.expect b/v4.4.0/OnlineTutorial/guide.7.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.7.expect rename to v4.4.0/OnlineTutorial/guide.7.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.8.expect b/v4.4.0/OnlineTutorial/guide.8.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.8.expect rename to v4.4.0/OnlineTutorial/guide.8.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.9.expect b/v4.4.0/OnlineTutorial/guide.9.expect similarity index 100% rename from latest/v4.3.0/OnlineTutorial/guide.9.expect rename to v4.4.0/OnlineTutorial/guide.9.expect diff --git a/latest/v4.3.0/OnlineTutorial/guide.md b/v4.4.0/OnlineTutorial/guide.md similarity index 99% rename from latest/v4.3.0/OnlineTutorial/guide.md rename to v4.4.0/OnlineTutorial/guide.md index 2363ea7..753d6ec 100644 --- a/latest/v4.3.0/OnlineTutorial/guide.md +++ b/v4.4.0/OnlineTutorial/guide.md @@ -1426,7 +1426,7 @@ method Find(a: array, key: int) returns (index: int) ``` This says that everything before, but excluding, the current -index is not the key. Notice that upon entering the loop, `i` +index is not the key. Notice that upon entering the loop, `index` is zero, so the first part of the implication is always false, and thus the quantified property is always true. This common situation is known as *vacuous truth*: the diff --git a/latest/v4.3.0/QuickReference.md b/v4.4.0/QuickReference.md old mode 100644 new mode 100755 similarity index 100% rename from latest/v4.3.0/QuickReference.md rename to v4.4.0/QuickReference.md diff --git a/latest/v4.3.0/README.md b/v4.4.0/README.md similarity index 100% rename from latest/v4.3.0/README.md rename to v4.4.0/README.md diff --git a/latest/v4.3.0/Snapshots.md b/v4.4.0/Snapshots.md similarity index 87% rename from latest/v4.3.0/Snapshots.md rename to v4.4.0/Snapshots.md index 71eb9ab..c84bc91 100644 --- a/latest/v4.3.0/Snapshots.md +++ b/v4.4.0/Snapshots.md @@ -7,7 +7,9 @@ layout: default - [Current development version](https://dafny.org/dafny) - [Latest release snapshot](https://dafny.org/latest) +- [v4.4.0](https://dafny.org/v4.4.0) - [v4.3.0](https://dafny.org/v4.3.0) +- [v4.2.0](https://dafny.org/v4.2.0) - [v4.1.0](https://dafny.org/v4.1.0) - [v4.0.0](https://dafny.org/v4.0.0) - [v3.12.0](https://dafny.org/v3.12.0) diff --git a/latest/v4.3.0/StyleGuide/Style-Guide.md b/v4.4.0/StyleGuide/Style-Guide.md similarity index 100% rename from latest/v4.3.0/StyleGuide/Style-Guide.md rename to v4.4.0/StyleGuide/Style-Guide.md diff --git a/latest/v4.3.0/VerificationOptimization/VerificationOptimization.md b/v4.4.0/VerificationOptimization/VerificationOptimization.md similarity index 100% rename from latest/v4.3.0/VerificationOptimization/VerificationOptimization.md rename to v4.4.0/VerificationOptimization/VerificationOptimization.md diff --git a/latest/v4.3.0/VerificationOptimization/hover-assertion.png b/v4.4.0/VerificationOptimization/hover-assertion.png similarity index 100% rename from latest/v4.3.0/VerificationOptimization/hover-assertion.png rename to v4.4.0/VerificationOptimization/hover-assertion.png diff --git a/latest/v4.3.0/VerificationOptimization/hover-method.png b/v4.4.0/VerificationOptimization/hover-method.png similarity index 100% rename from latest/v4.3.0/VerificationOptimization/hover-method.png rename to v4.4.0/VerificationOptimization/hover-method.png diff --git a/latest/v4.3.0/_config.yml b/v4.4.0/_config.yml similarity index 100% rename from latest/v4.3.0/_config.yml rename to v4.4.0/_config.yml diff --git a/latest/v4.3.0/_includes/README b/v4.4.0/_includes/README similarity index 100% rename from latest/v4.3.0/_includes/README rename to v4.4.0/_includes/README diff --git a/latest/v4.3.0/_includes/footer.html b/v4.4.0/_includes/footer.html similarity index 100% rename from latest/v4.3.0/_includes/footer.html rename to v4.4.0/_includes/footer.html diff --git a/latest/v4.3.0/_includes/head.html b/v4.4.0/_includes/head.html similarity index 100% rename from latest/v4.3.0/_includes/head.html rename to v4.4.0/_includes/head.html diff --git a/latest/v4.3.0/_layouts/default.html b/v4.4.0/_layouts/default.html similarity index 100% rename from latest/v4.3.0/_layouts/default.html rename to v4.4.0/_layouts/default.html diff --git a/latest/v4.3.0/check-examples b/v4.4.0/check-examples old mode 100644 new mode 100755 similarity index 100% rename from latest/v4.3.0/check-examples rename to v4.4.0/check-examples diff --git a/latest/v4.3.0/dafny.sty b/v4.4.0/dafny.sty similarity index 100% rename from latest/v4.3.0/dafny.sty rename to v4.4.0/dafny.sty diff --git a/latest/v4.3.0/examples/README.md b/v4.4.0/examples/README.md similarity index 53% rename from latest/v4.3.0/examples/README.md rename to v4.4.0/examples/README.md index 5639dec..78cb9dd 100644 --- a/latest/v4.3.0/examples/README.md +++ b/v4.4.0/examples/README.md @@ -7,10 +7,10 @@ demonstrating various coding techniques or proof capabilities. Each of these verify successfully. The files for these examples can be found in -the [examples folder of Dafny's github project](https://github.com/dafny-lang/dafny/tree/master/Test/examples). +the [examples folder of Dafny's github project](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples). -- [Simple Maximum method](https://github.com/dafny-lang/dafny/tree/master/Test/examples/maximum.dfy) -- [Tutorial on parser combinators](https://github.com/dafny-lang/dafny/tree/master/Test/examples/parser_combinators.dfy) -- [A simple compiler](https://github.com/dafny-lang/dafny/tree/master/Test/examples/Simple_compiler) -- [An example of significant use of induction on a mini-compiler](https://github.com/dafny-lang/dafny/tree/master/Test/examples/induction-principle.md) +- [Simple Maximum method](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples/maximum.dfy) +- [Tutorial on parser combinators](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples/parser_combinators.dfy) +- [A simple compiler](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples/Simple_compiler) +- [An example of significant use of induction on a mini-compiler](https://github.com/dafny-lang/dafny/tree/master/Source/IntegrationTests/TestFiles/LitTests/LitTest/examples/induction-principle.md) diff --git a/latest/v4.3.0/images/Demo.png b/v4.4.0/images/Demo.png similarity index 100% rename from latest/v4.3.0/images/Demo.png rename to v4.4.0/images/Demo.png diff --git a/latest/v4.3.0/images/DutchFlag.dfy b/v4.4.0/images/DutchFlag.dfy similarity index 100% rename from latest/v4.3.0/images/DutchFlag.dfy rename to v4.4.0/images/DutchFlag.dfy diff --git a/latest/v4.3.0/images/dafny-banner.png b/v4.4.0/images/dafny-banner.png similarity index 100% rename from latest/v4.3.0/images/dafny-banner.png rename to v4.4.0/images/dafny-banner.png diff --git a/latest/v4.3.0/images/dafny-banner.xcf b/v4.4.0/images/dafny-banner.xcf similarity index 100% rename from latest/v4.3.0/images/dafny-banner.xcf rename to v4.4.0/images/dafny-banner.xcf diff --git a/latest/v4.3.0/images/dafny-favicon.png b/v4.4.0/images/dafny-favicon.png similarity index 100% rename from latest/v4.3.0/images/dafny-favicon.png rename to v4.4.0/images/dafny-favicon.png diff --git a/latest/v4.3.0/images/dafny-favicon.svg b/v4.4.0/images/dafny-favicon.svg similarity index 100% rename from latest/v4.3.0/images/dafny-favicon.svg rename to v4.4.0/images/dafny-favicon.svg diff --git a/latest/v4.3.0/images/dafny-logo-230.png b/v4.4.0/images/dafny-logo-230.png similarity index 100% rename from latest/v4.3.0/images/dafny-logo-230.png rename to v4.4.0/images/dafny-logo-230.png diff --git a/latest/v4.3.0/images/dafny-logo.jpg b/v4.4.0/images/dafny-logo.jpg similarity index 100% rename from latest/v4.3.0/images/dafny-logo.jpg rename to v4.4.0/images/dafny-logo.jpg diff --git a/latest/v4.3.0/images/dafny-thumbnail.jpg b/v4.4.0/images/dafny-thumbnail.jpg similarity index 100% rename from latest/v4.3.0/images/dafny-thumbnail.jpg rename to v4.4.0/images/dafny-thumbnail.jpg diff --git a/latest/v4.3.0/index.html b/v4.4.0/index.html similarity index 98% rename from latest/v4.3.0/index.html rename to v4.4.0/index.html index 1799d66..d876ee7 100644 --- a/latest/v4.3.0/index.html +++ b/v4.4.0/index.html @@ -23,7 +23,7 @@

The Dafny Programming and Verification Language

-

Development version

+v4.4.0 documentation snapshot